iwl-bus.h 7.5 KB
Newer Older
1 2 3 4 5 6 7
/******************************************************************************
 *
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * GPL LICENSE SUMMARY
 *
W
Wey-Yi Guy 已提交
8
 * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
 * USA
 *
 * The full GNU General Public License is included in this distribution
 * in the file called LICENSE.GPL.
 *
 * Contact Information:
 *  Intel Linux Wireless <ilw@linux.intel.com>
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 *
 * BSD LICENSE
 *
W
Wey-Yi Guy 已提交
33
 * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/
63 64 65
#ifndef __iwl_bus_h__
#define __iwl_bus_h__

E
Emmanuel Grumbach 已提交
66
#include <linux/types.h>
67
#include <linux/spinlock.h>
E
Emmanuel Grumbach 已提交
68

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
/**
 * DOC: Bus layer - role and goal
 *
 * iwl-bus.h defines the API to the bus layer of the iwlwifi driver.
 * The bus layer is responsible for doing very basic bus operations that are
 * listed in the iwl_bus_ops structure.
 * The bus layer registers to the bus driver, advertises the supported HW and
 * gets notifications about enumeration, suspend, resume.
 * For the moment, the bus layer is not a linux kernel module as itself, and
 * the module_init function of the driver must call the bus specific
 * registration functions. These functions are listed at the end of this file.
 * For the moment, there is only one implementation of this interface: PCI-e.
 * This implementation is iwl-pci.c
 */

/**
 * DOC: encapsulation and type safety
 *
 * The iwl_bus describes the data that is shared amongst all the bus layer
 * implementations. This data is visible to other layers. Data in the bus
 * specific area is not visible outside the bus specific implementation.
 * iwl_bus holds a pointer to iwl_shared which holds pointer to all the other
 * layers of the driver (iwl_priv, iwl_trans). In fact, this is the way to go
 * when the transport layer needs to call a function of another layer.
 *
 * In order to achieve encapsulation, iwl_priv cannot be dereferenced from the
 * bus layer. Type safety is still kept since functions that gets iwl_priv gets
 * a typed pointer (as opposed to void *).
 */

/**
 * DOC: probe flow
 *
 * The module_init calls the bus specific registration function. The
 * registration to the bus layer will trigger an enumeration of the bus which
 * will call the bus specific probe function.
 * The first thing this function must do is to allocate the memory needed by
 * iwl_bus + the bus_specific data.
 * Once the bus specific probe function has configured the hardware, it
 * chooses the appropriate transport layer and calls iwl_probe that will run
 * the bus independent probe flow.
 *
 * Note: The bus specific code must set the following data in iwl_bus before it
 *       calls iwl_probe:
 *	* bus->dev
 *	* bus->irq
 *	* bus->ops
 */

118
struct iwl_shared;
119 120 121 122 123
struct iwl_bus;

/**
 * struct iwl_bus_ops - bus specific operations
 * @get_pm_support: must returns true if the bus can go to sleep
124
 * @apm_config: will be called during the config of the APM
125 126
 * @get_hw_id_string: prints the hw_id in the provided buffer
 * @get_hw_id: get hw_id in u32
127 128 129 130 131 132 133
 * @write8: write a byte to register at offset ofs
 * @write32: write a dword to register at offset ofs
 * @wread32: read a dword at register at offset ofs
 */
struct iwl_bus_ops {
	bool (*get_pm_support)(struct iwl_bus *bus);
	void (*apm_config)(struct iwl_bus *bus);
134 135
	void (*get_hw_id_string)(struct iwl_bus *bus, char buf[], int buf_len);
	u32 (*get_hw_id)(struct iwl_bus *bus);
136 137 138 139 140
	void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val);
	void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val);
	u32 (*read32)(struct iwl_bus *bus, u32 ofs);
};

141 142
/**
 * struct iwl_bus - bus common data
143 144 145 146
 *
 * This data is common to all bus layer implementations.
 *
 * @dev - pointer to struct device * that represents the device
147 148
 * @ops - pointer to iwl_bus_ops
 * @shrd - pointer to iwl_shared which holds shared data from the upper layer
149 150
 *	NB: for the time being this needs to be set by the upper layer since
 *	it allocates the shared data
151
 * @reg_lock - protect hw register access
152
 */
153 154
struct iwl_bus {
	struct device *dev;
155
	const struct iwl_bus_ops *ops;
156
	struct iwl_shared *shrd;
157

158
	spinlock_t reg_lock;
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174

	/* pointer to bus specific struct */
	/*Ensure that this pointer will always be aligned to sizeof pointer */
	char bus_specific[0] __attribute__((__aligned__(sizeof(void *))));
};

static inline bool bus_get_pm_support(struct iwl_bus *bus)
{
	return bus->ops->get_pm_support(bus);
}

static inline void bus_apm_config(struct iwl_bus *bus)
{
	bus->ops->apm_config(bus);
}

175 176
static inline void bus_get_hw_id_string(struct iwl_bus *bus, char buf[],
		int buf_len)
177
{
178 179 180 181 182 183
	bus->ops->get_hw_id_string(bus, buf, buf_len);
}

static inline u32 bus_get_hw_id(struct iwl_bus *bus)
{
	return bus->ops->get_hw_id(bus);
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
}

static inline void bus_write8(struct iwl_bus *bus, u32 ofs, u8 val)
{
	bus->ops->write8(bus, ofs, val);
}

static inline void bus_write32(struct iwl_bus *bus, u32 ofs, u32 val)
{
	bus->ops->write32(bus, ofs, val);
}

static inline u32 bus_read32(struct iwl_bus *bus, u32 ofs)
{
	return bus->ops->read32(bus, ofs);
}

201 202 203
/*****************************************************
* Bus layer registration functions
******************************************************/
204 205 206
int __must_check iwl_pci_register_driver(void);
void iwl_pci_unregister_driver(void);

207
#endif /* __iwl_bus_h__ */