aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Ketrenos <jketreno@linux.intel.com>2005-03-23 18:32:29 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-05-27 21:57:53 -0400
commit2c86c275015c880e810830304a3a4ab94803b38b (patch)
tree219bf554765cd7bacf1e120290359dfa8370c0f7
parent0a989b24fd59e8867274246587b46f5595fa0baa (diff)
Add ipw2100 wireless driver.
-rw-r--r--Documentation/networking/README.ipw2100246
-rw-r--r--drivers/net/wireless/Kconfig53
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/ipw2100.c8649
-rw-r--r--drivers/net/wireless/ipw2100.h1278
5 files changed, 10228 insertions, 0 deletions
diff --git a/Documentation/networking/README.ipw2100 b/Documentation/networking/README.ipw2100
new file mode 100644
index 000000000000..2046948b020d
--- /dev/null
+++ b/Documentation/networking/README.ipw2100
@@ -0,0 +1,246 @@
1
2===========================
3Intel(R) PRO/Wireless 2100 Network Connection Driver for Linux
4README.ipw2100
5
6March 14, 2005
7
8===========================
9Index
10---------------------------
110. Introduction
121. Release 1.1.0 Current Features
132. Command Line Parameters
143. Sysfs Helper Files
154. Radio Kill Switch
165. Dynamic Firmware
176. Power Management
187. Support
198. License
20
21
22===========================
230. Introduction
24------------ ----- ----- ---- --- -- -
25
26This document provides a brief overview of the features supported by the
27IPW2100 driver project. The main project website, where the latest
28development version of the driver can be found, is:
29
30 http://ipw2100.sourceforge.net
31
32There you can find the not only the latest releases, but also information about
33potential fixes and patches, as well as links to the development mailing list
34for the driver project.
35
36
37===========================
381. Release 1.1.0 Current Supported Features
39---------------------------
40- Managed (BSS) and Ad-Hoc (IBSS)
41- WEP (shared key and open)
42- Wireless Tools support
43- 802.1x (tested with XSupplicant 1.0.1)
44
45Enabled (but not supported) features:
46- Monitor/RFMon mode
47- WPA/WPA2
48
49The distinction between officially supported and enabled is a reflection
50on the amount of validation and interoperability testing that has been
51performed on a given feature.
52
53
54===========================
552. Command Line Parameters
56---------------------------
57
58If the driver is built as a module, the following optional parameters are used
59by entering them on the command line with the modprobe command using this
60syntax:
61
62 modprobe ipw2100 [<option>=<VAL1><,VAL2>...]
63
64For example, to disable the radio on driver loading, enter:
65
66 modprobe ipw2100 disable=1
67
68The ipw2100 driver supports the following module parameters:
69
70Name Value Example:
71debug 0x0-0xffffffff debug=1024
72mode 0,1,2 mode=1 /* AdHoc */
73channel int channel=3 /* Only valid in AdHoc or Monitor */
74associate boolean associate=0 /* Do NOT auto associate */
75disable boolean disable=1 /* Do not power the HW */
76
77
78===========================
793. Sysfs Helper Files
80---------------------------
81
82There are several ways to control the behavior of the driver. Many of the
83general capabilities are exposed through the Wireless Tools (iwconfig). There
84are a few capabilities that are exposed through entries in the Linux Sysfs.
85
86
87----- Driver Level ------
88For the driver level files, look in /sys/bus/pci/drivers/ipw2100/
89
90 debug_level
91
92 This controls the same global as the 'debug' module parameter. For
93 information on the various debugging levels available, run the 'dvals'
94 script found in the driver source directory.
95
96 NOTE: 'debug_level' is only enabled if CONFIG_IPW2100_DEBUG is turn
97 on.
98
99----- Device Level ------
100For the device level files look in
101
102 /sys/bus/pci/drivers/ipw2100/{PCI-ID}/
103
104For example:
105 /sys/bus/pci/drivers/ipw2100/0000:02:01.0
106
107For the device level files, see /sys/bus/pci/drivers/ipw2100:
108
109 rf_kill
110 read -
111 0 = RF kill not enabled (radio on)
112 1 = SW based RF kill active (radio off)
113 2 = HW based RF kill active (radio off)
114 3 = Both HW and SW RF kill active (radio off)
115 write -
116 0 = If SW based RF kill active, turn the radio back on
117 1 = If radio is on, activate SW based RF kill
118
119 NOTE: If you enable the SW based RF kill and then toggle the HW
120 based RF kill from ON -> OFF -> ON, the radio will NOT come back on
121
122
123===========================
1244. Radio Kill Switch
125---------------------------
126Most laptops provide the ability for the user to physically disable the radio.
127Some vendors have implemented this as a physical switch that requires no
128software to turn the radio off and on. On other laptops, however, the switch
129is controlled through a button being pressed and a software driver then making
130calls to turn the radio off and on. This is referred to as a "software based
131RF kill switch"
132
133See the Sysfs helper file 'rf_kill' for determining the state of the RF switch
134on your system.
135
136
137===========================
1385. Dynamic Firmware
139---------------------------
140As the firmware is licensed under a restricted use license, it can not be
141included within the kernel sources. To enable the IPW2100 you will need a
142firmware image to load into the wireless NIC's processors.
143
144You can obtain these images from <http://ipw2100.sf.net/firmware.php>.
145
146See INSTALL for instructions on installing the firmware.
147
148
149===========================
1506. Power Management
151---------------------------
152The IPW2100 supports the configuration of the Power Save Protocol
153through a private wireless extension interface. The IPW2100 supports
154the following different modes:
155
156 off No power management. Radio is always on.
157 on Automatic power management
158 1-5 Different levels of power management. The higher the
159 number the greater the power savings, but with an impact to
160 packet latencies.
161
162Power management works by powering down the radio after a certain
163interval of time has passed where no packets are passed through the
164radio. Once powered down, the radio remains in that state for a given
165period of time. For higher power savings, the interval between last
166packet processed to sleep is shorter and the sleep period is longer.
167
168When the radio is asleep, the access point sending data to the station
169must buffer packets at the AP until the station wakes up and requests
170any buffered packets. If you have an AP that does not correctly support
171the PSP protocol you may experience packet loss or very poor performance
172while power management is enabled. If this is the case, you will need
173to try and find a firmware update for your AP, or disable power
174management (via `iwconfig eth1 power off`)
175
176To configure the power level on the IPW2100 you use a combination of
177iwconfig and iwpriv. iwconfig is used to turn power management on, off,
178and set it to auto.
179
180 iwconfig eth1 power off Disables radio power down
181 iwconfig eth1 power on Enables radio power management to
182 last set level (defaults to AUTO)
183 iwpriv eth1 set_power 0 Sets power level to AUTO and enables
184 power management if not previously
185 enabled.
186 iwpriv eth1 set_power 1-5 Set the power level as specified,
187 enabling power management if not
188 previously enabled.
189
190You can view the current power level setting via:
191
192 iwpriv eth1 get_power
193
194It will return the current period or timeout that is configured as a string
195in the form of xxxx/yyyy (z) where xxxx is the timeout interval (amount of
196time after packet processing), yyyy is the period to sleep (amount of time to
197wait before powering the radio and querying the access point for buffered
198packets), and z is the 'power level'. If power management is turned off the
199xxxx/yyyy will be replaced with 'off' -- the level reported will be the active
200level if `iwconfig eth1 power on` is invoked.
201
202
203===========================
2047. Support
205---------------------------
206
207For general development information and support,
208go to:
209
210 http://ipw2100.sf.net/
211
212The ipw2100 1.1.0 driver and firmware can be downloaded from:
213
214 http://support.intel.com
215
216For installation support on the ipw2100 1.1.0 driver on Linux kernels
2172.6.8 or greater, email support is available from:
218
219 http://supportmail.intel.com
220
221===========================
2228. License
223---------------------------
224
225 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
226
227 This program is free software; you can redistribute it and/or modify it
228 under the terms of the GNU General Public License (version 2) as
229 published by the Free Software Foundation.
230
231 This program is distributed in the hope that it will be useful, but WITHOUT
232 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
233 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
234 more details.
235
236 You should have received a copy of the GNU General Public License along with
237 this program; if not, write to the Free Software Foundation, Inc., 59
238 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
239
240 The full GNU General Public License is included in this distribution in the
241 file called LICENSE.
242
243 License Contact Information:
244 James P. Ketrenos <ipw2100-admin@linux.intel.com>
245 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
246
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 0aaa12c0c098..7cd0aee18f55 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -137,6 +137,59 @@ config PCMCIA_RAYCS
137comment "Wireless 802.11b ISA/PCI cards support" 137comment "Wireless 802.11b ISA/PCI cards support"
138 depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA) 138 depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA)
139 139
140config IPW2100
141 tristate "Intel PRO/Wireless 2100 Network Connection"
142 depends on NET_RADIO && PCI && IEEE80211
143 select FW_LOADER
144 ---help---
145 A driver for the Intel PRO/Wireless 2100 Network
146 Connection 802.11b wireless network adapter.
147
148 See <file:Documentation/networking/README.ipw2100> for information on
149 the capabilities currently enabled in this driver and for tips
150 for debugging issues and problems.
151
152 In order to use this driver, you will need a firmware image for it.
153 You can obtain the firmware from
154 <http://ipw2100.sf.net/>. Once you have the firmware image, you
155 will need to place it in /etc/firmware.
156
157 You will also very likely need the Wireless Tools in order to
158 configure your card:
159
160 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
161
162 If you want to compile the driver as a module ( = code which can be
163 inserted in and remvoed from the running kernel whenever you want),
164 say M here and read <file:Documentation/modules.txt>. The module
165 will be called ipw2100.ko.
166
167config IPW2100_PROMISC
168 bool "Enable promiscuous mode"
169 depends on IPW2100
170 ---help---
171 Enables promiscuous/monitor mode support for the ipw2100 driver.
172 With this feature compiled into the driver, you can switch to
173 promiscuous mode via the Wireless Tool's Monitor mode. While in this
174 mode, no packets can be sent.
175
176config IPW_DEBUG
177 bool "Enable full debugging output in IPW2100 module."
178 depends on IPW2100
179 ---help---
180 This option will enable debug tracing output for the IPW2100.
181
182 This will result in the kernel module being ~60k larger. You can
183 control which debug output is sent to the kernel log by setting the
184 value in
185
186 /sys/bus/pci/drivers/ipw2100/debug_level
187
188 This entry will only exist if this option is enabled.
189
190 If you are not trying to debug or develop the IPW2100 driver, you
191 most likely want to say N here.
192
140config AIRO 193config AIRO
141 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" 194 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
142 depends on NET_RADIO && ISA && (PCI || BROKEN) 195 depends on NET_RADIO && ISA && (PCI || BROKEN)
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 2b87841322cc..2426885c7a5e 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -2,6 +2,8 @@
2# Makefile for the Linux Wireless network device drivers. 2# Makefile for the Linux Wireless network device drivers.
3# 3#
4 4
5obj-$(CONFIG_IPW2100) += ipw2100.o
6
5obj-$(CONFIG_STRIP) += strip.o 7obj-$(CONFIG_STRIP) += strip.o
6obj-$(CONFIG_ARLAN) += arlan.o 8obj-$(CONFIG_ARLAN) += arlan.o
7 9
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
new file mode 100644
index 000000000000..d296d464946f
--- /dev/null
+++ b/drivers/net/wireless/ipw2100.c
@@ -0,0 +1,8649 @@
1/******************************************************************************
2
3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as
7 published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Contact Information:
22 James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25 Portions of this file are based on the sample_* files provided by Wireless
26 Extensions 0.26 package and copyright (c) 1997-2003 Jean Tourrilhes
27 <jt@hpl.hp.com>
28
29 Portions of this file are based on the Host AP project,
30 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
31 <jkmaline@cc.hut.fi>
32 Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
33
34 Portions of ipw2100_mod_firmware_load, ipw2100_do_mod_firmware_load, and
35 ipw2100_fw_load are loosely based on drivers/sound/sound_firmware.c
36 available in the 2.4.25 kernel sources, and are copyright (c) Alan Cox
37
38******************************************************************************/
39/*
40
41 Initial driver on which this is based was developed by Janusz Gorycki,
42 Maciej Urbaniak, and Maciej Sosnowski.
43
44 Promiscuous mode support added by Jacek Wysoczynski and Maciej Urbaniak.
45
46Theory of Operation
47
48Tx - Commands and Data
49
50Firmware and host share a circular queue of Transmit Buffer Descriptors (TBDs)
51Each TBD contains a pointer to the physical (dma_addr_t) address of data being
52sent to the firmware as well as the length of the data.
53
54The host writes to the TBD queue at the WRITE index. The WRITE index points
55to the _next_ packet to be written and is advanced when after the TBD has been
56filled.
57
58The firmware pulls from the TBD queue at the READ index. The READ index points
59to the currently being read entry, and is advanced once the firmware is
60done with a packet.
61
62When data is sent to the firmware, the first TBD is used to indicate to the
63firmware if a Command or Data is being sent. If it is Command, all of the
64command information is contained within the physical address referred to by the
65TBD. If it is Data, the first TBD indicates the type of data packet, number
66of fragments, etc. The next TBD then referrs to the actual packet location.
67
68The Tx flow cycle is as follows:
69
701) ipw2100_tx() is called by kernel with SKB to transmit
712) Packet is move from the tx_free_list and appended to the transmit pending
72 list (tx_pend_list)
733) work is scheduled to move pending packets into the shared circular queue.
744) when placing packet in the circular queue, the incoming SKB is DMA mapped
75 to a physical address. That address is entered into a TBD. Two TBDs are
76 filled out. The first indicating a data packet, the second referring to the
77 actual payload data.
785) the packet is removed from tx_pend_list and placed on the end of the
79 firmware pending list (fw_pend_list)
806) firmware is notified that the WRITE index has
817) Once the firmware has processed the TBD, INTA is triggered.
828) For each Tx interrupt received from the firmware, the READ index is checked
83 to see which TBDs are done being processed.
849) For each TBD that has been processed, the ISR pulls the oldest packet
85 from the fw_pend_list.
8610)The packet structure contained in the fw_pend_list is then used
87 to unmap the DMA address and to free the SKB originally passed to the driver
88 from the kernel.
8911)The packet structure is placed onto the tx_free_list
90
91The above steps are the same for commands, only the msg_free_list/msg_pend_list
92are used instead of tx_free_list/tx_pend_list
93
94...
95
96Critical Sections / Locking :
97
98There are two locks utilized. The first is the low level lock (priv->low_lock)
99that protects the following:
100
101- Access to the Tx/Rx queue lists via priv->low_lock. The lists are as follows:
102
103 tx_free_list : Holds pre-allocated Tx buffers.
104 TAIL modified in __ipw2100_tx_process()
105 HEAD modified in ipw2100_tx()
106
107 tx_pend_list : Holds used Tx buffers waiting to go into the TBD ring
108 TAIL modified ipw2100_tx()
109 HEAD modified by X__ipw2100_tx_send_data()
110
111 msg_free_list : Holds pre-allocated Msg (Command) buffers
112 TAIL modified in __ipw2100_tx_process()
113 HEAD modified in ipw2100_hw_send_command()
114
115 msg_pend_list : Holds used Msg buffers waiting to go into the TBD ring
116 TAIL modified in ipw2100_hw_send_command()
117 HEAD modified in X__ipw2100_tx_send_commands()
118
119 The flow of data on the TX side is as follows:
120
121 MSG_FREE_LIST + COMMAND => MSG_PEND_LIST => TBD => MSG_FREE_LIST
122 TX_FREE_LIST + DATA => TX_PEND_LIST => TBD => TX_FREE_LIST
123
124 The methods that work on the TBD ring are protected via priv->low_lock.
125
126- The internal data state of the device itself
127- Access to the firmware read/write indexes for the BD queues
128 and associated logic
129
130All external entry functions are locked with the priv->action_lock to ensure
131that only one external action is invoked at a time.
132
133
134*/
135
136#include <linux/compiler.h>
137#include <linux/config.h>
138#include <linux/errno.h>
139#include <linux/if_arp.h>
140#include <linux/in6.h>
141#include <linux/in.h>
142#include <linux/ip.h>
143#include <linux/kernel.h>
144#include <linux/kmod.h>
145#include <linux/module.h>
146#include <linux/netdevice.h>
147#include <linux/ethtool.h>
148#include <linux/pci.h>
149#include <linux/proc_fs.h>
150#include <linux/skbuff.h>
151#include <asm/uaccess.h>
152#include <asm/io.h>
153#define __KERNEL_SYSCALLS__
154#include <linux/fs.h>
155#include <linux/mm.h>
156#include <linux/slab.h>
157#include <linux/unistd.h>
158#include <linux/stringify.h>
159#include <linux/tcp.h>
160#include <linux/types.h>
161#include <linux/version.h>
162#include <linux/time.h>
163#include <linux/firmware.h>
164#include <linux/acpi.h>
165#include <linux/ctype.h>
166
167#include "ipw2100.h"
168
169#define IPW2100_VERSION "1.1.0"
170
171#define DRV_NAME "ipw2100"
172#define DRV_VERSION IPW2100_VERSION
173#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
174#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation"
175
176
177/* Debugging stuff */
178#ifdef CONFIG_IPW_DEBUG
179#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */
180#endif
181
182MODULE_DESCRIPTION(DRV_DESCRIPTION);
183MODULE_VERSION(DRV_VERSION);
184MODULE_AUTHOR(DRV_COPYRIGHT);
185MODULE_LICENSE("GPL");
186
187static int debug = 0;
188static int mode = 0;
189static int channel = 0;
190static int associate = 1;
191static int disable = 0;
192#ifdef CONFIG_PM
193static struct ipw2100_fw ipw2100_firmware;
194#endif
195
196#include <linux/moduleparam.h>
197module_param(debug, int, 0444);
198module_param(mode, int, 0444);
199module_param(channel, int, 0444);
200module_param(associate, int, 0444);
201module_param(disable, int, 0444);
202
203MODULE_PARM_DESC(debug, "debug level");
204MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
205MODULE_PARM_DESC(channel, "channel");
206MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
207MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
208
209u32 ipw2100_debug_level = IPW_DL_NONE;
210
211#ifdef CONFIG_IPW_DEBUG
212static const char *command_types[] = {
213 "undefined",
214 "unused", /* HOST_ATTENTION */
215 "HOST_COMPLETE",
216 "unused", /* SLEEP */
217 "unused", /* HOST_POWER_DOWN */
218 "unused",
219 "SYSTEM_CONFIG",
220 "unused", /* SET_IMR */
221 "SSID",
222 "MANDATORY_BSSID",
223 "AUTHENTICATION_TYPE",
224 "ADAPTER_ADDRESS",
225 "PORT_TYPE",
226 "INTERNATIONAL_MODE",
227 "CHANNEL",
228 "RTS_THRESHOLD",
229 "FRAG_THRESHOLD",
230 "POWER_MODE",
231 "TX_RATES",
232 "BASIC_TX_RATES",
233 "WEP_KEY_INFO",
234 "unused",
235 "unused",
236 "unused",
237 "unused",
238 "WEP_KEY_INDEX",
239 "WEP_FLAGS",
240 "ADD_MULTICAST",
241 "CLEAR_ALL_MULTICAST",
242 "BEACON_INTERVAL",
243 "ATIM_WINDOW",
244 "CLEAR_STATISTICS",
245 "undefined",
246 "undefined",
247 "undefined",
248 "undefined",
249 "TX_POWER_INDEX",
250 "undefined",
251 "undefined",
252 "undefined",
253 "undefined",
254 "undefined",
255 "undefined",
256 "BROADCAST_SCAN",
257 "CARD_DISABLE",
258 "PREFERRED_BSSID",
259 "SET_SCAN_OPTIONS",
260 "SCAN_DWELL_TIME",
261 "SWEEP_TABLE",
262 "AP_OR_STATION_TABLE",
263 "GROUP_ORDINALS",
264 "SHORT_RETRY_LIMIT",
265 "LONG_RETRY_LIMIT",
266 "unused", /* SAVE_CALIBRATION */
267 "unused", /* RESTORE_CALIBRATION */
268 "undefined",
269 "undefined",
270 "undefined",
271 "HOST_PRE_POWER_DOWN",
272 "unused", /* HOST_INTERRUPT_COALESCING */
273 "undefined",
274 "CARD_DISABLE_PHY_OFF",
275 "MSDU_TX_RATES"
276 "undefined",
277 "undefined",
278 "SET_STATION_STAT_BITS",
279 "CLEAR_STATIONS_STAT_BITS",
280 "LEAP_ROGUE_MODE",
281 "SET_SECURITY_INFORMATION",
282 "DISASSOCIATION_BSSID",
283 "SET_WPA_ASS_IE"
284};
285#endif
286
287
288/* Pre-decl until we get the code solid and then we can clean it up */
289static void X__ipw2100_tx_send_commands(struct ipw2100_priv *priv);
290static void X__ipw2100_tx_send_data(struct ipw2100_priv *priv);
291static int ipw2100_adapter_setup(struct ipw2100_priv *priv);
292
293static void ipw2100_queues_initialize(struct ipw2100_priv *priv);
294static void ipw2100_queues_free(struct ipw2100_priv *priv);
295static int ipw2100_queues_allocate(struct ipw2100_priv *priv);
296
297
298static inline void read_register(struct net_device *dev, u32 reg, u32 *val)
299{
300 *val = readl((void *)(dev->base_addr + reg));
301 IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
302}
303
304static inline void write_register(struct net_device *dev, u32 reg, u32 val)
305{
306 writel(val, (void *)(dev->base_addr + reg));
307 IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
308}
309
310static inline void read_register_word(struct net_device *dev, u32 reg, u16 *val)
311{
312 *val = readw((void *)(dev->base_addr + reg));
313 IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
314}
315
316static inline void read_register_byte(struct net_device *dev, u32 reg, u8 *val)
317{
318 *val = readb((void *)(dev->base_addr + reg));
319 IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
320}
321
322static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
323{
324 writew(val, (void *)(dev->base_addr + reg));
325 IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
326}
327
328
329static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
330{
331 writeb(val, (void *)(dev->base_addr + reg));
332 IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
333}
334
335static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 *val)
336{
337 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
338 addr & IPW_REG_INDIRECT_ADDR_MASK);
339 read_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
340}
341
342static inline void write_nic_dword(struct net_device *dev, u32 addr, u32 val)
343{
344 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
345 addr & IPW_REG_INDIRECT_ADDR_MASK);
346 write_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
347}
348
349static inline void read_nic_word(struct net_device *dev, u32 addr, u16 *val)
350{
351 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
352 addr & IPW_REG_INDIRECT_ADDR_MASK);
353 read_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
354}
355
356static inline void write_nic_word(struct net_device *dev, u32 addr, u16 val)
357{
358 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
359 addr & IPW_REG_INDIRECT_ADDR_MASK);
360 write_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
361}
362
363static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 *val)
364{
365 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
366 addr & IPW_REG_INDIRECT_ADDR_MASK);
367 read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
368}
369
370static inline void write_nic_byte(struct net_device *dev, u32 addr, u8 val)
371{
372 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
373 addr & IPW_REG_INDIRECT_ADDR_MASK);
374 write_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
375}
376
377static inline void write_nic_auto_inc_address(struct net_device *dev, u32 addr)
378{
379 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS,
380 addr & IPW_REG_INDIRECT_ADDR_MASK);
381}
382
383static inline void write_nic_dword_auto_inc(struct net_device *dev, u32 val)
384{
385 write_register(dev, IPW_REG_AUTOINCREMENT_DATA, val);
386}
387
388static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
389 const u8 *buf)
390{
391 u32 aligned_addr;
392 u32 aligned_len;
393 u32 dif_len;
394 u32 i;
395
396 /* read first nibble byte by byte */
397 aligned_addr = addr & (~0x3);
398 dif_len = addr - aligned_addr;
399 if (dif_len) {
400 /* Start reading at aligned_addr + dif_len */
401 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
402 aligned_addr);
403 for (i = dif_len; i < 4; i++, buf++)
404 write_register_byte(
405 dev, IPW_REG_INDIRECT_ACCESS_DATA + i,
406 *buf);
407
408 len -= dif_len;
409 aligned_addr += 4;
410 }
411
412 /* read DWs through autoincrement registers */
413 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS,
414 aligned_addr);
415 aligned_len = len & (~0x3);
416 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
417 write_register(
418 dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *)buf);
419
420 /* copy the last nibble */
421 dif_len = len - aligned_len;
422 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr);
423 for (i = 0; i < dif_len; i++, buf++)
424 write_register_byte(
425 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, *buf);
426}
427
428static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
429 u8 *buf)
430{
431 u32 aligned_addr;
432 u32 aligned_len;
433 u32 dif_len;
434 u32 i;
435
436 /* read first nibble byte by byte */
437 aligned_addr = addr & (~0x3);
438 dif_len = addr - aligned_addr;
439 if (dif_len) {
440 /* Start reading at aligned_addr + dif_len */
441 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
442 aligned_addr);
443 for (i = dif_len; i < 4; i++, buf++)
444 read_register_byte(
445 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf);
446
447 len -= dif_len;
448 aligned_addr += 4;
449 }
450
451 /* read DWs through autoincrement registers */
452 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS,
453 aligned_addr);
454 aligned_len = len & (~0x3);
455 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
456 read_register(dev, IPW_REG_AUTOINCREMENT_DATA,
457 (u32 *)buf);
458
459 /* copy the last nibble */
460 dif_len = len - aligned_len;
461 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
462 aligned_addr);
463 for (i = 0; i < dif_len; i++, buf++)
464 read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA +
465 i, buf);
466}
467
468static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
469{
470 return (dev->base_addr &&
471 (readl((void *)(dev->base_addr + IPW_REG_DOA_DEBUG_AREA_START))
472 == IPW_DATA_DOA_DEBUG_VALUE));
473}
474
475int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
476 void *val, u32 *len)
477{
478 struct ipw2100_ordinals *ordinals = &priv->ordinals;
479 u32 addr;
480 u32 field_info;
481 u16 field_len;
482 u16 field_count;
483 u32 total_length;
484
485 if (ordinals->table1_addr == 0) {
486 IPW_DEBUG_WARNING(DRV_NAME ": attempt to use fw ordinals "
487 "before they have been loaded.\n");
488 return -EINVAL;
489 }
490
491 if (IS_ORDINAL_TABLE_ONE(ordinals, ord)) {
492 if (*len < IPW_ORD_TAB_1_ENTRY_SIZE) {
493 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
494
495 IPW_DEBUG_WARNING(DRV_NAME
496 ": ordinal buffer length too small, need %d\n",
497 IPW_ORD_TAB_1_ENTRY_SIZE);
498
499 return -EINVAL;
500 }
501
502 read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2),
503 &addr);
504 read_nic_dword(priv->net_dev, addr, val);
505
506 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
507
508 return 0;
509 }
510
511 if (IS_ORDINAL_TABLE_TWO(ordinals, ord)) {
512
513 ord -= IPW_START_ORD_TAB_2;
514
515 /* get the address of statistic */
516 read_nic_dword(priv->net_dev, ordinals->table2_addr + (ord << 3),
517 &addr);
518
519 /* get the second DW of statistics ;
520 * two 16-bit words - first is length, second is count */
521 read_nic_dword(priv->net_dev,
522 ordinals->table2_addr + (ord << 3) + sizeof(u32),
523 &field_info);
524
525 /* get each entry length */
526 field_len = *((u16 *)&field_info);
527
528 /* get number of entries */
529 field_count = *(((u16 *)&field_info) + 1);
530
531 /* abort if no enought memory */
532 total_length = field_len * field_count;
533 if (total_length > *len) {
534 *len = total_length;
535 return -EINVAL;
536 }
537
538 *len = total_length;
539 if (!total_length)
540 return 0;
541
542 /* read the ordinal data from the SRAM */
543 read_nic_memory(priv->net_dev, addr, total_length, val);
544
545 return 0;
546 }
547
548 IPW_DEBUG_WARNING(DRV_NAME ": ordinal %d neither in table 1 nor "
549 "in table 2\n", ord);
550
551 return -EINVAL;
552}
553
554static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val,
555 u32 *len)
556{
557 struct ipw2100_ordinals *ordinals = &priv->ordinals;
558 u32 addr;
559
560 if (IS_ORDINAL_TABLE_ONE(ordinals, ord)) {
561 if (*len != IPW_ORD_TAB_1_ENTRY_SIZE) {
562 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
563 IPW_DEBUG_INFO("wrong size\n");
564 return -EINVAL;
565 }
566
567 read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2),
568 &addr);
569
570 write_nic_dword(priv->net_dev, addr, *val);
571
572 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
573
574 return 0;
575 }
576
577 IPW_DEBUG_INFO("wrong table\n");
578 if (IS_ORDINAL_TABLE_TWO(ordinals, ord))
579 return -EINVAL;
580
581 return -EINVAL;
582}
583
584static char *snprint_line(char *buf, size_t count,
585 const u8 *data, u32 len, u32 ofs)
586{
587 int out, i, j, l;
588 char c;
589
590 out = snprintf(buf, count, "%08X", ofs);
591
592 for (l = 0, i = 0; i < 2; i++) {
593 out += snprintf(buf + out, count - out, " ");
594 for (j = 0; j < 8 && l < len; j++, l++)
595 out += snprintf(buf + out, count - out, "%02X ",
596 data[(i * 8 + j)]);
597 for (; j < 8; j++)
598 out += snprintf(buf + out, count - out, " ");
599 }
600
601 out += snprintf(buf + out, count - out, " ");
602 for (l = 0, i = 0; i < 2; i++) {
603 out += snprintf(buf + out, count - out, " ");
604 for (j = 0; j < 8 && l < len; j++, l++) {
605 c = data[(i * 8 + j)];
606 if (!isascii(c) || !isprint(c))
607 c = '.';
608
609 out += snprintf(buf + out, count - out, "%c", c);
610 }
611
612 for (; j < 8; j++)
613 out += snprintf(buf + out, count - out, " ");
614 }
615
616 return buf;
617}
618
619static void printk_buf(int level, const u8 *data, u32 len)
620{
621 char line[81];
622 u32 ofs = 0;
623 if (!(ipw2100_debug_level & level))
624 return;
625
626 while (len) {
627 printk(KERN_DEBUG "%s\n",
628 snprint_line(line, sizeof(line), &data[ofs],
629 min(len, 16U), ofs));
630 ofs += 16;
631 len -= min(len, 16U);
632 }
633}
634
635
636
637#define MAX_RESET_BACKOFF 10
638
639static inline void schedule_reset(struct ipw2100_priv *priv)
640{
641 unsigned long now = get_seconds();
642
643 /* If we haven't received a reset request within the backoff period,
644 * then we can reset the backoff interval so this reset occurs
645 * immediately */
646 if (priv->reset_backoff &&
647 (now - priv->last_reset > priv->reset_backoff))
648 priv->reset_backoff = 0;
649
650 priv->last_reset = get_seconds();
651
652 if (!(priv->status & STATUS_RESET_PENDING)) {
653 IPW_DEBUG_INFO("%s: Scheduling firmware restart (%ds).\n",
654 priv->net_dev->name, priv->reset_backoff);
655 netif_carrier_off(priv->net_dev);
656 netif_stop_queue(priv->net_dev);
657 priv->status |= STATUS_RESET_PENDING;
658 if (priv->reset_backoff)
659 queue_delayed_work(priv->workqueue, &priv->reset_work,
660 priv->reset_backoff * HZ);
661 else
662 queue_work(priv->workqueue, &priv->reset_work);
663
664 if (priv->reset_backoff < MAX_RESET_BACKOFF)
665 priv->reset_backoff++;
666
667 wake_up_interruptible(&priv->wait_command_queue);
668 } else
669 IPW_DEBUG_INFO("%s: Firmware restart already in progress.\n",
670 priv->net_dev->name);
671
672}
673
674#define HOST_COMPLETE_TIMEOUT (2 * HZ)
675static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
676 struct host_command * cmd)
677{
678 struct list_head *element;
679 struct ipw2100_tx_packet *packet;
680 unsigned long flags;
681 int err = 0;
682
683 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n",
684 command_types[cmd->host_command], cmd->host_command,
685 cmd->host_command_length);
686 printk_buf(IPW_DL_HC, (u8*)cmd->host_command_parameters,
687 cmd->host_command_length);
688
689 spin_lock_irqsave(&priv->low_lock, flags);
690
691 if (priv->fatal_error) {
692 IPW_DEBUG_INFO("Attempt to send command while hardware in fatal error condition.\n");
693 err = -EIO;
694 goto fail_unlock;
695 }
696
697 if (!(priv->status & STATUS_RUNNING)) {
698 IPW_DEBUG_INFO("Attempt to send command while hardware is not running.\n");
699 err = -EIO;
700 goto fail_unlock;
701 }
702
703 if (priv->status & STATUS_CMD_ACTIVE) {
704 IPW_DEBUG_INFO("Attempt to send command while another command is pending.\n");
705 err = -EBUSY;
706 goto fail_unlock;
707 }
708
709 if (list_empty(&priv->msg_free_list)) {
710 IPW_DEBUG_INFO("no available msg buffers\n");
711 goto fail_unlock;
712 }
713
714 priv->status |= STATUS_CMD_ACTIVE;
715 priv->messages_sent++;
716
717 element = priv->msg_free_list.next;
718
719 packet = list_entry(element, struct ipw2100_tx_packet, list);
720 packet->jiffy_start = jiffies;
721
722 /* initialize the firmware command packet */
723 packet->info.c_struct.cmd->host_command_reg = cmd->host_command;
724 packet->info.c_struct.cmd->host_command_reg1 = cmd->host_command1;
725 packet->info.c_struct.cmd->host_command_len_reg = cmd->host_command_length;
726 packet->info.c_struct.cmd->sequence = cmd->host_command_sequence;
727
728 memcpy(packet->info.c_struct.cmd->host_command_params_reg,
729 cmd->host_command_parameters,
730 sizeof(packet->info.c_struct.cmd->host_command_params_reg));
731
732 list_del(element);
733 DEC_STAT(&priv->msg_free_stat);
734
735 list_add_tail(element, &priv->msg_pend_list);
736 INC_STAT(&priv->msg_pend_stat);
737
738 X__ipw2100_tx_send_commands(priv);
739 X__ipw2100_tx_send_data(priv);
740
741 spin_unlock_irqrestore(&priv->low_lock, flags);
742
743 /*
744 * We must wait for this command to complete before another
745 * command can be sent... but if we wait more than 3 seconds
746 * then there is a problem.
747 */
748
749 err = wait_event_interruptible_timeout(
750 priv->wait_command_queue, !(priv->status & STATUS_CMD_ACTIVE),
751 HOST_COMPLETE_TIMEOUT);
752
753 if (err == 0) {
754 IPW_DEBUG_INFO("Command completion failed out after %dms.\n",
755 HOST_COMPLETE_TIMEOUT / (HZ / 100));
756 priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT;
757 priv->status &= ~STATUS_CMD_ACTIVE;
758 schedule_reset(priv);
759 return -EIO;
760 }
761
762 if (priv->fatal_error) {
763 IPW_DEBUG_WARNING("%s: firmware fatal error\n",
764 priv->net_dev->name);
765 return -EIO;
766 }
767
768 /* !!!!! HACK TEST !!!!!
769 * When lots of debug trace statements are enabled, the driver
770 * doesn't seem to have as many firmware restart cycles...
771 *
772 * As a test, we're sticking in a 1/100s delay here */
773 set_current_state(TASK_UNINTERRUPTIBLE);
774 schedule_timeout(HZ / 100);
775
776 return 0;
777
778 fail_unlock:
779 spin_unlock_irqrestore(&priv->low_lock, flags);
780
781 return err;
782}
783
784
785/*
786 * Verify the values and data access of the hardware
787 * No locks needed or used. No functions called.
788 */
789static int ipw2100_verify(struct ipw2100_priv *priv)
790{
791 u32 data1, data2;
792 u32 address;
793
794 u32 val1 = 0x76543210;
795 u32 val2 = 0xFEDCBA98;
796
797 /* Domain 0 check - all values should be DOA_DEBUG */
798 for (address = IPW_REG_DOA_DEBUG_AREA_START;
799 address < IPW_REG_DOA_DEBUG_AREA_END;
800 address += sizeof(u32)) {
801 read_register(priv->net_dev, address, &data1);
802 if (data1 != IPW_DATA_DOA_DEBUG_VALUE)
803 return -EIO;
804 }
805
806 /* Domain 1 check - use arbitrary read/write compare */
807 for (address = 0; address < 5; address++) {
808 /* The memory area is not used now */
809 write_register(priv->net_dev, IPW_REG_DOMAIN_1_OFFSET + 0x32,
810 val1);
811 write_register(priv->net_dev, IPW_REG_DOMAIN_1_OFFSET + 0x36,
812 val2);
813 read_register(priv->net_dev, IPW_REG_DOMAIN_1_OFFSET + 0x32,
814 &data1);
815 read_register(priv->net_dev, IPW_REG_DOMAIN_1_OFFSET + 0x36,
816 &data2);
817 if (val1 == data1 && val2 == data2)
818 return 0;
819 }
820
821 return -EIO;
822}
823
824/*
825 *
826 * Loop until the CARD_DISABLED bit is the same value as the
827 * supplied parameter
828 *
829 * TODO: See if it would be more efficient to do a wait/wake
830 * cycle and have the completion event trigger the wakeup
831 *
832 */
833#define IPW_CARD_DISABLE_COMPLETE_WAIT 100 // 100 milli
834static int ipw2100_wait_for_card_state(struct ipw2100_priv *priv, int state)
835{
836 int i;
837 u32 card_state;
838 u32 len = sizeof(card_state);
839 int err;
840
841 for (i = 0; i <= IPW_CARD_DISABLE_COMPLETE_WAIT * 1000; i += 50) {
842 err = ipw2100_get_ordinal(priv, IPW_ORD_CARD_DISABLED,
843 &card_state, &len);
844 if (err) {
845 IPW_DEBUG_INFO("Query of CARD_DISABLED ordinal "
846 "failed.\n");
847 return 0;
848 }
849
850 /* We'll break out if either the HW state says it is
851 * in the state we want, or if HOST_COMPLETE command
852 * finishes */
853 if ((card_state == state) ||
854 ((priv->status & STATUS_ENABLED) ?
855 IPW_HW_STATE_ENABLED : IPW_HW_STATE_DISABLED) == state) {
856 if (state == IPW_HW_STATE_ENABLED)
857 priv->status |= STATUS_ENABLED;
858 else
859 priv->status &= ~STATUS_ENABLED;
860
861 return 0;
862 }
863
864 udelay(50);
865 }
866
867 IPW_DEBUG_INFO("ipw2100_wait_for_card_state to %s state timed out\n",
868 state ? "DISABLED" : "ENABLED");
869 return -EIO;
870}
871
872
873/*********************************************************************
874 Procedure : sw_reset_and_clock
875 Purpose : Asserts s/w reset, asserts clock initialization
876 and waits for clock stabilization
877 ********************************************************************/
878static int sw_reset_and_clock(struct ipw2100_priv *priv)
879{
880 int i;
881 u32 r;
882
883 // assert s/w reset
884 write_register(priv->net_dev, IPW_REG_RESET_REG,
885 IPW_AUX_HOST_RESET_REG_SW_RESET);
886
887 // wait for clock stabilization
888 for (i = 0; i < 1000; i++) {
889 udelay(IPW_WAIT_RESET_ARC_COMPLETE_DELAY);
890
891 // check clock ready bit
892 read_register(priv->net_dev, IPW_REG_RESET_REG, &r);
893 if (r & IPW_AUX_HOST_RESET_REG_PRINCETON_RESET)
894 break;
895 }
896
897 if (i == 1000)
898 return -EIO; // TODO: better error value
899
900 /* set "initialization complete" bit to move adapter to
901 * D0 state */
902 write_register(priv->net_dev, IPW_REG_GP_CNTRL,
903 IPW_AUX_HOST_GP_CNTRL_BIT_INIT_DONE);
904
905 /* wait for clock stabilization */
906 for (i = 0; i < 10000; i++) {
907 udelay(IPW_WAIT_CLOCK_STABILIZATION_DELAY * 4);
908
909 /* check clock ready bit */
910 read_register(priv->net_dev, IPW_REG_GP_CNTRL, &r);
911 if (r & IPW_AUX_HOST_GP_CNTRL_BIT_CLOCK_READY)
912 break;
913 }
914
915 if (i == 10000)
916 return -EIO; /* TODO: better error value */
917
918//#if CONFIG_IPW2100_D0ENABLED
919 /* set D0 standby bit */
920 read_register(priv->net_dev, IPW_REG_GP_CNTRL, &r);
921 write_register(priv->net_dev, IPW_REG_GP_CNTRL,
922 r | IPW_AUX_HOST_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
923//#endif
924
925 return 0;
926}
927
928/*********************************************************************
929 Procedure : ipw2100_ipw2100_download_firmware
930 Purpose : Initiaze adapter after power on.
931 The sequence is:
932 1. assert s/w reset first!
933 2. awake clocks & wait for clock stabilization
934 3. hold ARC (don't ask me why...)
935 4. load Dino ucode and reset/clock init again
936 5. zero-out shared mem
937 6. download f/w
938 *******************************************************************/
939static int ipw2100_download_firmware(struct ipw2100_priv *priv)
940{
941 u32 address;
942 int err;
943
944#ifndef CONFIG_PM
945 /* Fetch the firmware and microcode */
946 struct ipw2100_fw ipw2100_firmware;
947#endif
948
949 if (priv->fatal_error) {
950 IPW_DEBUG_ERROR("%s: ipw2100_download_firmware called after "
951 "fatal error %d. Interface must be brought down.\n",
952 priv->net_dev->name, priv->fatal_error);
953 return -EINVAL;
954 }
955
956#ifdef CONFIG_PM
957 if (!ipw2100_firmware.version) {
958 err = ipw2100_get_firmware(priv, &ipw2100_firmware);
959 if (err) {
960 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
961 priv->net_dev->name, err);
962 priv->fatal_error = IPW2100_ERR_FW_LOAD;
963 goto fail;
964 }
965 }
966#else
967 err = ipw2100_get_firmware(priv, &ipw2100_firmware);
968 if (err) {
969 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
970 priv->net_dev->name, err);
971 priv->fatal_error = IPW2100_ERR_FW_LOAD;
972 goto fail;
973 }
974#endif
975 priv->firmware_version = ipw2100_firmware.version;
976
977 /* s/w reset and clock stabilization */
978 err = sw_reset_and_clock(priv);
979 if (err) {
980 IPW_DEBUG_ERROR("%s: sw_reset_and_clock failed: %d\n",
981 priv->net_dev->name, err);
982 goto fail;
983 }
984
985 err = ipw2100_verify(priv);
986 if (err) {
987 IPW_DEBUG_ERROR("%s: ipw2100_verify failed: %d\n",
988 priv->net_dev->name, err);
989 goto fail;
990 }
991
992 /* Hold ARC */
993 write_nic_dword(priv->net_dev,
994 IPW_INTERNAL_REGISTER_HALT_AND_RESET,
995 0x80000000);
996
997 /* allow ARC to run */
998 write_register(priv->net_dev, IPW_REG_RESET_REG, 0);
999
1000 /* load microcode */
1001 err = ipw2100_ucode_download(priv, &ipw2100_firmware);
1002 if (err) {
1003 IPW_DEBUG_ERROR("%s: Error loading microcode: %d\n",
1004 priv->net_dev->name, err);
1005 goto fail;
1006 }
1007
1008 /* release ARC */
1009 write_nic_dword(priv->net_dev,
1010 IPW_INTERNAL_REGISTER_HALT_AND_RESET,
1011 0x00000000);
1012
1013 /* s/w reset and clock stabilization (again!!!) */
1014 err = sw_reset_and_clock(priv);
1015 if (err) {
1016 IPW_DEBUG_ERROR("%s: sw_reset_and_clock failed: %d\n",
1017 priv->net_dev->name, err);
1018 goto fail;
1019 }
1020
1021 /* load f/w */
1022 err = ipw2100_fw_download(priv, &ipw2100_firmware);
1023 if (err) {
1024 IPW_DEBUG_ERROR("%s: Error loading firmware: %d\n",
1025 priv->net_dev->name, err);
1026 goto fail;
1027 }
1028
1029#ifndef CONFIG_PM
1030 /*
1031 * When the .resume method of the driver is called, the other
1032 * part of the system, i.e. the ide driver could still stay in
1033 * the suspend stage. This prevents us from loading the firmware
1034 * from the disk. --YZ
1035 */
1036
1037 /* free any storage allocated for firmware image */
1038 ipw2100_release_firmware(priv, &ipw2100_firmware);
1039#endif
1040
1041 /* zero out Domain 1 area indirectly (Si requirement) */
1042 for (address = IPW_HOST_FW_SHARED_AREA0;
1043 address < IPW_HOST_FW_SHARED_AREA0_END; address += 4)
1044 write_nic_dword(priv->net_dev, address, 0);
1045 for (address = IPW_HOST_FW_SHARED_AREA1;
1046 address < IPW_HOST_FW_SHARED_AREA1_END; address += 4)
1047 write_nic_dword(priv->net_dev, address, 0);
1048 for (address = IPW_HOST_FW_SHARED_AREA2;
1049 address < IPW_HOST_FW_SHARED_AREA2_END; address += 4)
1050 write_nic_dword(priv->net_dev, address, 0);
1051 for (address = IPW_HOST_FW_SHARED_AREA3;
1052 address < IPW_HOST_FW_SHARED_AREA3_END; address += 4)
1053 write_nic_dword(priv->net_dev, address, 0);
1054 for (address = IPW_HOST_FW_INTERRUPT_AREA;
1055 address < IPW_HOST_FW_INTERRUPT_AREA_END; address += 4)
1056 write_nic_dword(priv->net_dev, address, 0);
1057
1058 return 0;
1059
1060 fail:
1061 ipw2100_release_firmware(priv, &ipw2100_firmware);
1062 return err;
1063}
1064
1065static inline void ipw2100_enable_interrupts(struct ipw2100_priv *priv)
1066{
1067 if (priv->status & STATUS_INT_ENABLED)
1068 return;
1069 priv->status |= STATUS_INT_ENABLED;
1070 write_register(priv->net_dev, IPW_REG_INTA_MASK, IPW_INTERRUPT_MASK);
1071}
1072
1073static inline void ipw2100_disable_interrupts(struct ipw2100_priv *priv)
1074{
1075 if (!(priv->status & STATUS_INT_ENABLED))
1076 return;
1077 priv->status &= ~STATUS_INT_ENABLED;
1078 write_register(priv->net_dev, IPW_REG_INTA_MASK, 0x0);
1079}
1080
1081
1082static void ipw2100_initialize_ordinals(struct ipw2100_priv *priv)
1083{
1084 struct ipw2100_ordinals *ord = &priv->ordinals;
1085
1086 IPW_DEBUG_INFO("enter\n");
1087
1088 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_ORDINALS_TABLE_1,
1089 &ord->table1_addr);
1090
1091 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_ORDINALS_TABLE_2,
1092 &ord->table2_addr);
1093
1094 read_nic_dword(priv->net_dev, ord->table1_addr, &ord->table1_size);
1095 read_nic_dword(priv->net_dev, ord->table2_addr, &ord->table2_size);
1096
1097 ord->table2_size &= 0x0000FFFF;
1098
1099 IPW_DEBUG_INFO("table 1 size: %d\n", ord->table1_size);
1100 IPW_DEBUG_INFO("table 2 size: %d\n", ord->table2_size);
1101 IPW_DEBUG_INFO("exit\n");
1102}
1103
1104static inline void ipw2100_hw_set_gpio(struct ipw2100_priv *priv)
1105{
1106 u32 reg = 0;
1107 /*
1108 * Set GPIO 3 writable by FW; GPIO 1 writable
1109 * by driver and enable clock
1110 */
1111 reg = (IPW_BIT_GPIO_GPIO3_MASK | IPW_BIT_GPIO_GPIO1_ENABLE |
1112 IPW_BIT_GPIO_LED_OFF);
1113 write_register(priv->net_dev, IPW_REG_GPIO, reg);
1114}
1115
1116static inline int rf_kill_active(struct ipw2100_priv *priv)
1117{
1118#define MAX_RF_KILL_CHECKS 5
1119#define RF_KILL_CHECK_DELAY 40
1120#define RF_KILL_CHECK_THRESHOLD 3
1121
1122 unsigned short value = 0;
1123 u32 reg = 0;
1124 int i;
1125
1126 if (!(priv->hw_features & HW_FEATURE_RFKILL)) {
1127 priv->status &= ~STATUS_RF_KILL_HW;
1128 return 0;
1129 }
1130
1131 for (i = 0; i < MAX_RF_KILL_CHECKS; i++) {
1132 udelay(RF_KILL_CHECK_DELAY);
1133 read_register(priv->net_dev, IPW_REG_GPIO, &reg);
1134 value = (value << 1) | ((reg & IPW_BIT_GPIO_RF_KILL) ? 0 : 1);
1135 }
1136
1137 if (value == 0)
1138 priv->status |= STATUS_RF_KILL_HW;
1139 else
1140 priv->status &= ~STATUS_RF_KILL_HW;
1141
1142 return (value == 0);
1143}
1144
1145static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1146{
1147 u32 addr, len;
1148 u32 val;
1149
1150 /*
1151 * EEPROM_SRAM_DB_START_ADDRESS using ordinal in ordinal table 1
1152 */
1153 len = sizeof(addr);
1154 if (ipw2100_get_ordinal(
1155 priv, IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS,
1156 &addr, &len)) {
1157 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1158 __LINE__);
1159 return -EIO;
1160 }
1161
1162 IPW_DEBUG_INFO("EEPROM address: %08X\n", addr);
1163
1164 /*
1165 * EEPROM version is the byte at offset 0xfd in firmware
1166 * We read 4 bytes, then shift out the byte we actually want */
1167 read_nic_dword(priv->net_dev, addr + 0xFC, &val);
1168 priv->eeprom_version = (val >> 24) & 0xFF;
1169 IPW_DEBUG_INFO("EEPROM version: %d\n", priv->eeprom_version);
1170
1171 /*
1172 * HW RF Kill enable is bit 0 in byte at offset 0x21 in firmware
1173 *
1174 * notice that the EEPROM bit is reverse polarity, i.e.
1175 * bit = 0 signifies HW RF kill switch is supported
1176 * bit = 1 signifies HW RF kill switch is NOT supported
1177 */
1178 read_nic_dword(priv->net_dev, addr + 0x20, &val);
1179 if (!((val >> 24) & 0x01))
1180 priv->hw_features |= HW_FEATURE_RFKILL;
1181
1182 IPW_DEBUG_INFO("HW RF Kill: %ssupported.\n",
1183 (priv->hw_features & HW_FEATURE_RFKILL) ?
1184 "" : "not ");
1185
1186 return 0;
1187}
1188
1189/*
1190 * Start firmware execution after power on and intialization
1191 * The sequence is:
1192 * 1. Release ARC
1193 * 2. Wait for f/w initialization completes;
1194 */
1195static int ipw2100_start_adapter(struct ipw2100_priv *priv)
1196{
1197#define IPW_WAIT_FW_INIT_COMPLETE_DELAY (40 * HZ / 1000)
1198 int i;
1199 u32 inta, inta_mask, gpio;
1200
1201 IPW_DEBUG_INFO("enter\n");
1202
1203 if (priv->status & STATUS_RUNNING)
1204 return 0;
1205
1206 /*
1207 * Initialize the hw - drive adapter to DO state by setting
1208 * init_done bit. Wait for clk_ready bit and Download
1209 * fw & dino ucode
1210 */
1211 if (ipw2100_download_firmware(priv)) {
1212 IPW_DEBUG_ERROR("%s: Failed to power on the adapter.\n",
1213 priv->net_dev->name);
1214 return -EIO;
1215 }
1216
1217 /* Clear the Tx, Rx and Msg queues and the r/w indexes
1218 * in the firmware RBD and TBD ring queue */
1219 ipw2100_queues_initialize(priv);
1220
1221 ipw2100_hw_set_gpio(priv);
1222
1223 /* TODO -- Look at disabling interrupts here to make sure none
1224 * get fired during FW initialization */
1225
1226 /* Release ARC - clear reset bit */
1227 write_register(priv->net_dev, IPW_REG_RESET_REG, 0);
1228
1229 /* wait for f/w intialization complete */
1230 IPW_DEBUG_FW("Waiting for f/w initialization to complete...\n");
1231 i = 5000;
1232 do {
1233 set_current_state(TASK_UNINTERRUPTIBLE);
1234 schedule_timeout(IPW_WAIT_FW_INIT_COMPLETE_DELAY);
1235 /* Todo... wait for sync command ... */
1236
1237 read_register(priv->net_dev, IPW_REG_INTA, &inta);
1238
1239 /* check "init done" bit */
1240 if (inta & IPW2100_INTA_FW_INIT_DONE) {
1241 /* reset "init done" bit */
1242 write_register(priv->net_dev, IPW_REG_INTA,
1243 IPW2100_INTA_FW_INIT_DONE);
1244 break;
1245 }
1246
1247 /* check error conditions : we check these after the firmware
1248 * check so that if there is an error, the interrupt handler
1249 * will see it and the adapter will be reset */
1250 if (inta &
1251 (IPW2100_INTA_FATAL_ERROR | IPW2100_INTA_PARITY_ERROR)) {
1252 /* clear error conditions */
1253 write_register(priv->net_dev, IPW_REG_INTA,
1254 IPW2100_INTA_FATAL_ERROR |
1255 IPW2100_INTA_PARITY_ERROR);
1256 }
1257 } while (i--);
1258
1259 /* Clear out any pending INTAs since we aren't supposed to have
1260 * interrupts enabled at this point... */
1261 read_register(priv->net_dev, IPW_REG_INTA, &inta);
1262 read_register(priv->net_dev, IPW_REG_INTA_MASK, &inta_mask);
1263 inta &= IPW_INTERRUPT_MASK;
1264 /* Clear out any pending interrupts */
1265 if (inta & inta_mask)
1266 write_register(priv->net_dev, IPW_REG_INTA, inta);
1267
1268 IPW_DEBUG_FW("f/w initialization complete: %s\n",
1269 i ? "SUCCESS" : "FAILED");
1270
1271 if (!i) {
1272 IPW_DEBUG_WARNING("%s: Firmware did not initialize.\n",
1273 priv->net_dev->name);
1274 return -EIO;
1275 }
1276
1277 /* allow firmware to write to GPIO1 & GPIO3 */
1278 read_register(priv->net_dev, IPW_REG_GPIO, &gpio);
1279
1280 gpio |= (IPW_BIT_GPIO_GPIO1_MASK | IPW_BIT_GPIO_GPIO3_MASK);
1281
1282 write_register(priv->net_dev, IPW_REG_GPIO, gpio);
1283
1284 /* Ready to receive commands */
1285 priv->status |= STATUS_RUNNING;
1286
1287 /* The adapter has been reset; we are not associated */
1288 priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
1289
1290 IPW_DEBUG_INFO("exit\n");
1291
1292 return 0;
1293}
1294
1295static inline void ipw2100_reset_fatalerror(struct ipw2100_priv *priv)
1296{
1297 if (!priv->fatal_error)
1298 return;
1299
1300 priv->fatal_errors[priv->fatal_index++] = priv->fatal_error;
1301 priv->fatal_index %= IPW2100_ERROR_QUEUE;
1302 priv->fatal_error = 0;
1303}
1304
1305
1306/* NOTE: Our interrupt is disabled when this method is called */
1307static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
1308{
1309 u32 reg;
1310 int i;
1311
1312 IPW_DEBUG_INFO("Power cycling the hardware.\n");
1313
1314 ipw2100_hw_set_gpio(priv);
1315
1316 /* Step 1. Stop Master Assert */
1317 write_register(priv->net_dev, IPW_REG_RESET_REG,
1318 IPW_AUX_HOST_RESET_REG_STOP_MASTER);
1319
1320 /* Step 2. Wait for stop Master Assert
1321 * (not more then 50us, otherwise ret error */
1322 i = 5;
1323 do {
1324 udelay(IPW_WAIT_RESET_MASTER_ASSERT_COMPLETE_DELAY);
1325 read_register(priv->net_dev, IPW_REG_RESET_REG, &reg);
1326
1327 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
1328 break;
1329 } while(i--);
1330
1331 priv->status &= ~STATUS_RESET_PENDING;
1332
1333 if (!i) {
1334 IPW_DEBUG_INFO("exit - waited too long for master assert stop\n");
1335 return -EIO;
1336 }
1337
1338 write_register(priv->net_dev, IPW_REG_RESET_REG,
1339 IPW_AUX_HOST_RESET_REG_SW_RESET);
1340
1341
1342 /* Reset any fatal_error conditions */
1343 ipw2100_reset_fatalerror(priv);
1344
1345 /* At this point, the adapter is now stopped and disabled */
1346 priv->status &= ~(STATUS_RUNNING | STATUS_ASSOCIATING |
1347 STATUS_ASSOCIATED | STATUS_ENABLED);
1348
1349 return 0;
1350}
1351
1352/*
1353 * Send the CARD_DISABLE_PHY_OFF comamnd to the card to disable it
1354 *
1355 * After disabling, if the card was associated, a STATUS_ASSN_LOST will be sent.
1356 *
1357 * STATUS_CARD_DISABLE_NOTIFICATION will be sent regardless of
1358 * if STATUS_ASSN_LOST is sent.
1359 */
1360static int ipw2100_hw_phy_off(struct ipw2100_priv *priv)
1361{
1362
1363#define HW_PHY_OFF_LOOP_DELAY (HZ / 5000)
1364
1365 struct host_command cmd = {
1366 .host_command = CARD_DISABLE_PHY_OFF,
1367 .host_command_sequence = 0,
1368 .host_command_length = 0,
1369 };
1370 int err, i;
1371 u32 val1, val2;
1372
1373 IPW_DEBUG_HC("CARD_DISABLE_PHY_OFF\n");
1374
1375 /* Turn off the radio */
1376 err = ipw2100_hw_send_command(priv, &cmd);
1377 if (err)
1378 return err;
1379
1380 for (i = 0; i < 2500; i++) {
1381 read_nic_dword(priv->net_dev, IPW2100_CONTROL_REG, &val1);
1382 read_nic_dword(priv->net_dev, IPW2100_COMMAND, &val2);
1383
1384 if ((val1 & IPW2100_CONTROL_PHY_OFF) &&
1385 (val2 & IPW2100_COMMAND_PHY_OFF))
1386 return 0;
1387
1388 set_current_state(TASK_UNINTERRUPTIBLE);
1389 schedule_timeout(HW_PHY_OFF_LOOP_DELAY);
1390 }
1391
1392 return -EIO;
1393}
1394
1395
1396static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1397{
1398 struct host_command cmd = {
1399 .host_command = HOST_COMPLETE,
1400 .host_command_sequence = 0,
1401 .host_command_length = 0
1402 };
1403 int err = 0;
1404
1405 IPW_DEBUG_HC("HOST_COMPLETE\n");
1406
1407 if (priv->status & STATUS_ENABLED)
1408 return 0;
1409
1410 down(&priv->adapter_sem);
1411
1412 if (rf_kill_active(priv)) {
1413 IPW_DEBUG_HC("Command aborted due to RF kill active.\n");
1414 goto fail_up;
1415 }
1416
1417 err = ipw2100_hw_send_command(priv, &cmd);
1418 if (err) {
1419 IPW_DEBUG_INFO("Failed to send HOST_COMPLETE command\n");
1420 goto fail_up;
1421 }
1422
1423 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_ENABLED);
1424 if (err) {
1425 IPW_DEBUG_INFO(
1426 "%s: card not responding to init command.\n",
1427 priv->net_dev->name);
1428 goto fail_up;
1429 }
1430
1431 if (priv->stop_hang_check) {
1432 priv->stop_hang_check = 0;
1433 queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
1434 }
1435
1436fail_up:
1437 up(&priv->adapter_sem);
1438 return err;
1439}
1440
1441static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
1442{
1443#define HW_POWER_DOWN_DELAY (HZ / 10)
1444
1445 struct host_command cmd = {
1446 .host_command = HOST_PRE_POWER_DOWN,
1447 .host_command_sequence = 0,
1448 .host_command_length = 0,
1449 };
1450 int err, i;
1451 u32 reg;
1452
1453 if (!(priv->status & STATUS_RUNNING))
1454 return 0;
1455
1456 priv->status |= STATUS_STOPPING;
1457
1458 /* We can only shut down the card if the firmware is operational. So,
1459 * if we haven't reset since a fatal_error, then we can not send the
1460 * shutdown commands. */
1461 if (!priv->fatal_error) {
1462 /* First, make sure the adapter is enabled so that the PHY_OFF
1463 * command can shut it down */
1464 ipw2100_enable_adapter(priv);
1465
1466 err = ipw2100_hw_phy_off(priv);
1467 if (err)
1468 IPW_DEBUG_WARNING("Error disabling radio %d\n", err);
1469
1470 /*
1471 * If in D0-standby mode going directly to D3 may cause a
1472 * PCI bus violation. Therefore we must change out of the D0
1473 * state.
1474 *
1475 * Sending the PREPARE_FOR_POWER_DOWN will restrict the
1476 * hardware from going into standby mode and will transition
1477 * out of D0-standy if it is already in that state.
1478 *
1479 * STATUS_PREPARE_POWER_DOWN_COMPLETE will be sent by the
1480 * driver upon completion. Once received, the driver can
1481 * proceed to the D3 state.
1482 *
1483 * Prepare for power down command to fw. This command would
1484 * take HW out of D0-standby and prepare it for D3 state.
1485 *
1486 * Currently FW does not support event notification for this
1487 * event. Therefore, skip waiting for it. Just wait a fixed
1488 * 100ms
1489 */
1490 IPW_DEBUG_HC("HOST_PRE_POWER_DOWN\n");
1491
1492 err = ipw2100_hw_send_command(priv, &cmd);
1493 if (err)
1494 IPW_DEBUG_WARNING(
1495 "%s: Power down command failed: Error %d\n",
1496 priv->net_dev->name, err);
1497 else {
1498 set_current_state(TASK_UNINTERRUPTIBLE);
1499 schedule_timeout(HW_POWER_DOWN_DELAY);
1500 }
1501 }
1502
1503 priv->status &= ~STATUS_ENABLED;
1504
1505 /*
1506 * Set GPIO 3 writable by FW; GPIO 1 writable
1507 * by driver and enable clock
1508 */
1509 ipw2100_hw_set_gpio(priv);
1510
1511 /*
1512 * Power down adapter. Sequence:
1513 * 1. Stop master assert (RESET_REG[9]=1)
1514 * 2. Wait for stop master (RESET_REG[8]==1)
1515 * 3. S/w reset assert (RESET_REG[7] = 1)
1516 */
1517
1518 /* Stop master assert */
1519 write_register(priv->net_dev, IPW_REG_RESET_REG,
1520 IPW_AUX_HOST_RESET_REG_STOP_MASTER);
1521
1522 /* wait stop master not more than 50 usec.
1523 * Otherwise return error. */
1524 for (i = 5; i > 0; i--) {
1525 udelay(10);
1526
1527 /* Check master stop bit */
1528 read_register(priv->net_dev, IPW_REG_RESET_REG, &reg);
1529
1530 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
1531 break;
1532 }
1533
1534 if (i == 0)
1535 IPW_DEBUG_WARNING(DRV_NAME
1536 ": %s: Could now power down adapter.\n",
1537 priv->net_dev->name);
1538
1539 /* assert s/w reset */
1540 write_register(priv->net_dev, IPW_REG_RESET_REG,
1541 IPW_AUX_HOST_RESET_REG_SW_RESET);
1542
1543 priv->status &= ~(STATUS_RUNNING | STATUS_STOPPING);
1544
1545 return 0;
1546}
1547
1548
1549static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
1550{
1551 struct host_command cmd = {
1552 .host_command = CARD_DISABLE,
1553 .host_command_sequence = 0,
1554 .host_command_length = 0
1555 };
1556 int err = 0;
1557
1558 IPW_DEBUG_HC("CARD_DISABLE\n");
1559
1560 if (!(priv->status & STATUS_ENABLED))
1561 return 0;
1562
1563 /* Make sure we clear the associated state */
1564 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1565
1566 if (!priv->stop_hang_check) {
1567 priv->stop_hang_check = 1;
1568 cancel_delayed_work(&priv->hang_check);
1569 }
1570
1571 down(&priv->adapter_sem);
1572
1573 err = ipw2100_hw_send_command(priv, &cmd);
1574 if (err) {
1575 IPW_DEBUG_WARNING("exit - failed to send CARD_DISABLE command\n");
1576 goto fail_up;
1577 }
1578
1579 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_DISABLED);
1580 if (err) {
1581 IPW_DEBUG_WARNING("exit - card failed to change to DISABLED\n");
1582 goto fail_up;
1583 }
1584
1585 IPW_DEBUG_INFO("TODO: implement scan state machine\n");
1586
1587fail_up:
1588 up(&priv->adapter_sem);
1589 return err;
1590}
1591
1592int ipw2100_set_scan_options(struct ipw2100_priv *priv)
1593{
1594 struct host_command cmd = {
1595 .host_command = SET_SCAN_OPTIONS,
1596 .host_command_sequence = 0,
1597 .host_command_length = 8
1598 };
1599 int err;
1600
1601 IPW_DEBUG_INFO("enter\n");
1602
1603 IPW_DEBUG_SCAN("setting scan options\n");
1604
1605 cmd.host_command_parameters[0] = 0;
1606
1607 if (!(priv->config & CFG_ASSOCIATE))
1608 cmd.host_command_parameters[0] |= IPW_SCAN_NOASSOCIATE;
1609 if ((priv->sec.flags & SEC_ENABLED) && priv->sec.enabled)
1610 cmd.host_command_parameters[0] |= IPW_SCAN_MIXED_CELL;
1611 if (priv->config & CFG_PASSIVE_SCAN)
1612 cmd.host_command_parameters[0] |= IPW_SCAN_PASSIVE;
1613
1614 cmd.host_command_parameters[1] = priv->channel_mask;
1615
1616 err = ipw2100_hw_send_command(priv, &cmd);
1617
1618 IPW_DEBUG_HC("SET_SCAN_OPTIONS 0x%04X\n",
1619 cmd.host_command_parameters[0]);
1620
1621 return err;
1622}
1623
1624int ipw2100_start_scan(struct ipw2100_priv *priv)
1625{
1626 struct host_command cmd = {
1627 .host_command = BROADCAST_SCAN,
1628 .host_command_sequence = 0,
1629 .host_command_length = 4
1630 };
1631 int err;
1632
1633 IPW_DEBUG_HC("START_SCAN\n");
1634
1635 cmd.host_command_parameters[0] = 0;
1636
1637 /* No scanning if in monitor mode */
1638 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
1639 return 1;
1640
1641 if (priv->status & STATUS_SCANNING) {
1642 IPW_DEBUG_SCAN("Scan requested while already in scan...\n");
1643 return 0;
1644 }
1645
1646 IPW_DEBUG_INFO("enter\n");
1647
1648 /* Not clearing here; doing so makes iwlist always return nothing...
1649 *
1650 * We should modify the table logic to use aging tables vs. clearing
1651 * the table on each scan start.
1652 */
1653 IPW_DEBUG_SCAN("starting scan\n");
1654
1655 priv->status |= STATUS_SCANNING;
1656 err = ipw2100_hw_send_command(priv, &cmd);
1657 if (err)
1658 priv->status &= ~STATUS_SCANNING;
1659
1660 IPW_DEBUG_INFO("exit\n");
1661
1662 return err;
1663}
1664
1665static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1666{
1667 unsigned long flags;
1668 int rc = 0;
1669 u32 lock;
1670 u32 ord_len = sizeof(lock);
1671
1672 /* Quite if manually disabled. */
1673 if (priv->status & STATUS_RF_KILL_SW) {
1674 IPW_DEBUG_INFO("%s: Radio is disabled by Manual Disable "
1675 "switch\n", priv->net_dev->name);
1676 return 0;
1677 }
1678
1679 /* If the interrupt is enabled, turn it off... */
1680 spin_lock_irqsave(&priv->low_lock, flags);
1681 ipw2100_disable_interrupts(priv);
1682
1683 /* Reset any fatal_error conditions */
1684 ipw2100_reset_fatalerror(priv);
1685 spin_unlock_irqrestore(&priv->low_lock, flags);
1686
1687 if (priv->status & STATUS_POWERED ||
1688 (priv->status & STATUS_RESET_PENDING)) {
1689 /* Power cycle the card ... */
1690 if (ipw2100_power_cycle_adapter(priv)) {
1691 IPW_DEBUG_WARNING("%s: Could not cycle adapter.\n",
1692 priv->net_dev->name);
1693 rc = 1;
1694 goto exit;
1695 }
1696 } else
1697 priv->status |= STATUS_POWERED;
1698
1699 /* Load the firmeware, start the clocks, etc. */
1700 if (ipw2100_start_adapter(priv)) {
1701 IPW_DEBUG_ERROR("%s: Failed to start the firmware.\n",
1702 priv->net_dev->name);
1703 rc = 1;
1704 goto exit;
1705 }
1706
1707 ipw2100_initialize_ordinals(priv);
1708
1709 /* Determine capabilities of this particular HW configuration */
1710 if (ipw2100_get_hw_features(priv)) {
1711 IPW_DEBUG_ERROR("%s: Failed to determine HW features.\n",
1712 priv->net_dev->name);
1713 rc = 1;
1714 goto exit;
1715 }
1716
1717 lock = LOCK_NONE;
1718 if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) {
1719 IPW_DEBUG_ERROR("%s: Failed to clear ordinal lock.\n",
1720 priv->net_dev->name);
1721 rc = 1;
1722 goto exit;
1723 }
1724
1725 priv->status &= ~STATUS_SCANNING;
1726
1727 if (rf_kill_active(priv)) {
1728 printk(KERN_INFO "%s: Radio is disabled by RF switch.\n",
1729 priv->net_dev->name);
1730
1731 if (priv->stop_rf_kill) {
1732 priv->stop_rf_kill = 0;
1733 queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
1734 }
1735
1736 deferred = 1;
1737 }
1738
1739 /* Turn on the interrupt so that commands can be processed */
1740 ipw2100_enable_interrupts(priv);
1741
1742 /* Send all of the commands that must be sent prior to
1743 * HOST_COMPLETE */
1744 if (ipw2100_adapter_setup(priv)) {
1745 IPW_DEBUG_ERROR("%s: Failed to start the card.\n",
1746 priv->net_dev->name);
1747 rc = 1;
1748 goto exit;
1749 }
1750
1751 if (!deferred) {
1752 /* Enable the adapter - sends HOST_COMPLETE */
1753 if (ipw2100_enable_adapter(priv)) {
1754 IPW_DEBUG_ERROR(
1755 "%s: failed in call to enable adapter.\n",
1756 priv->net_dev->name);
1757 ipw2100_hw_stop_adapter(priv);
1758 rc = 1;
1759 goto exit;
1760 }
1761
1762
1763 /* Start a scan . . . */
1764 ipw2100_set_scan_options(priv);
1765 ipw2100_start_scan(priv);
1766 }
1767
1768 exit:
1769 return rc;
1770}
1771
1772/* Called by register_netdev() */
1773static int ipw2100_net_init(struct net_device *dev)
1774{
1775 struct ipw2100_priv *priv = ieee80211_priv(dev);
1776 return ipw2100_up(priv, 1);
1777}
1778
1779static void ipw2100_down(struct ipw2100_priv *priv)
1780{
1781 unsigned long flags;
1782 union iwreq_data wrqu = {
1783 .ap_addr = {
1784 .sa_family = ARPHRD_ETHER
1785 }
1786 };
1787 int associated = priv->status & STATUS_ASSOCIATED;
1788
1789 /* Kill the RF switch timer */
1790 if (!priv->stop_rf_kill) {
1791 priv->stop_rf_kill = 1;
1792 cancel_delayed_work(&priv->rf_kill);
1793 }
1794
1795 /* Kill the firmare hang check timer */
1796 if (!priv->stop_hang_check) {
1797 priv->stop_hang_check = 1;
1798 cancel_delayed_work(&priv->hang_check);
1799 }
1800
1801 /* Kill any pending resets */
1802 if (priv->status & STATUS_RESET_PENDING)
1803 cancel_delayed_work(&priv->reset_work);
1804
1805 /* Make sure the interrupt is on so that FW commands will be
1806 * processed correctly */
1807 spin_lock_irqsave(&priv->low_lock, flags);
1808 ipw2100_enable_interrupts(priv);
1809 spin_unlock_irqrestore(&priv->low_lock, flags);
1810
1811 if (ipw2100_hw_stop_adapter(priv))
1812 IPW_DEBUG_ERROR("%s: Error stopping adapter.\n",
1813 priv->net_dev->name);
1814
1815 /* Do not disable the interrupt until _after_ we disable
1816 * the adaptor. Otherwise the CARD_DISABLE command will never
1817 * be ack'd by the firmware */
1818 spin_lock_irqsave(&priv->low_lock, flags);
1819 ipw2100_disable_interrupts(priv);
1820 spin_unlock_irqrestore(&priv->low_lock, flags);
1821
1822#ifdef ACPI_CSTATE_LIMIT_DEFINED
1823 if (priv->config & CFG_C3_DISABLED) {
1824 IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n");
1825 acpi_set_cstate_limit(priv->cstate_limit);
1826 priv->config &= ~CFG_C3_DISABLED;
1827 }
1828#endif
1829
1830 /* We have to signal any supplicant if we are disassociating */
1831 if (associated)
1832 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1833
1834 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1835 netif_carrier_off(priv->net_dev);
1836 netif_stop_queue(priv->net_dev);
1837}
1838
1839void ipw2100_reset_adapter(struct ipw2100_priv *priv)
1840{
1841 unsigned long flags;
1842 union iwreq_data wrqu = {
1843 .ap_addr = {
1844 .sa_family = ARPHRD_ETHER
1845 }
1846 };
1847 int associated = priv->status & STATUS_ASSOCIATED;
1848
1849 spin_lock_irqsave(&priv->low_lock, flags);
1850 IPW_DEBUG_INFO(DRV_NAME ": %s: Restarting adapter.\n",
1851 priv->net_dev->name);
1852 priv->resets++;
1853 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1854 priv->status |= STATUS_SECURITY_UPDATED;
1855
1856 /* Force a power cycle even if interface hasn't been opened
1857 * yet */
1858 cancel_delayed_work(&priv->reset_work);
1859 priv->status |= STATUS_RESET_PENDING;
1860 spin_unlock_irqrestore(&priv->low_lock, flags);
1861
1862 down(&priv->action_sem);
1863 /* stop timed checks so that they don't interfere with reset */
1864 priv->stop_hang_check = 1;
1865 cancel_delayed_work(&priv->hang_check);
1866
1867 /* We have to signal any supplicant if we are disassociating */
1868 if (associated)
1869 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1870
1871 ipw2100_up(priv, 0);
1872 up(&priv->action_sem);
1873
1874}
1875
1876
1877static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1878{
1879
1880#define MAC_ASSOCIATION_READ_DELAY (HZ)
1881 int ret, len, essid_len;
1882 char essid[IW_ESSID_MAX_SIZE];
1883 u32 txrate;
1884 u32 chan;
1885 char *txratename;
1886 u8 bssid[ETH_ALEN];
1887
1888 /*
1889 * TBD: BSSID is usually 00:00:00:00:00:00 here and not
1890 * an actual MAC of the AP. Seems like FW sets this
1891 * address too late. Read it later and expose through
1892 * /proc or schedule a later task to query and update
1893 */
1894
1895 essid_len = IW_ESSID_MAX_SIZE;
1896 ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_SSID,
1897 essid, &essid_len);
1898 if (ret) {
1899 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1900 __LINE__);
1901 return;
1902 }
1903
1904 len = sizeof(u32);
1905 ret = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE,
1906 &txrate, &len);
1907 if (ret) {
1908 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1909 __LINE__);
1910 return;
1911 }
1912
1913 len = sizeof(u32);
1914 ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &len);
1915 if (ret) {
1916 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1917 __LINE__);
1918 return;
1919 }
1920 len = ETH_ALEN;
1921 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len);
1922 if (ret) {
1923 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1924 __LINE__);
1925 return;
1926 }
1927 memcpy(priv->ieee->bssid, bssid, ETH_ALEN);
1928
1929
1930 switch (txrate) {
1931 case TX_RATE_1_MBIT:
1932 txratename = "1Mbps";
1933 break;
1934 case TX_RATE_2_MBIT:
1935 txratename = "2Mbsp";
1936 break;
1937 case TX_RATE_5_5_MBIT:
1938 txratename = "5.5Mbps";
1939 break;
1940 case TX_RATE_11_MBIT:
1941 txratename = "11Mbps";
1942 break;
1943 default:
1944 IPW_DEBUG_INFO("Unknown rate: %d\n", txrate);
1945 txratename = "unknown rate";
1946 break;
1947 }
1948
1949 IPW_DEBUG_INFO("%s: Associated with '%s' at %s, channel %d (BSSID="
1950 MAC_FMT ")\n",
1951 priv->net_dev->name, escape_essid(essid, essid_len),
1952 txratename, chan, MAC_ARG(bssid));
1953
1954 /* now we copy read ssid into dev */
1955 if (!(priv->config & CFG_STATIC_ESSID)) {
1956 priv->essid_len = min((u8)essid_len, (u8)IW_ESSID_MAX_SIZE);
1957 memcpy(priv->essid, essid, priv->essid_len);
1958 }
1959 priv->channel = chan;
1960 memcpy(priv->bssid, bssid, ETH_ALEN);
1961
1962 priv->status |= STATUS_ASSOCIATING;
1963 priv->connect_start = get_seconds();
1964
1965 queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10);
1966}
1967
1968
1969int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
1970 int length, int batch_mode)
1971{
1972 int ssid_len = min(length, IW_ESSID_MAX_SIZE);
1973 struct host_command cmd = {
1974 .host_command = SSID,
1975 .host_command_sequence = 0,
1976 .host_command_length = ssid_len
1977 };
1978 int err;
1979
1980 IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len));
1981
1982 if (ssid_len)
1983 memcpy((char*)cmd.host_command_parameters,
1984 essid, ssid_len);
1985
1986 if (!batch_mode) {
1987 err = ipw2100_disable_adapter(priv);
1988 if (err)
1989 return err;
1990 }
1991
1992 /* Bug in FW currently doesn't honor bit 0 in SET_SCAN_OPTIONS to
1993 * disable auto association -- so we cheat by setting a bogus SSID */
1994 if (!ssid_len && !(priv->config & CFG_ASSOCIATE)) {
1995 int i;
1996 u8 *bogus = (u8*)cmd.host_command_parameters;
1997 for (i = 0; i < IW_ESSID_MAX_SIZE; i++)
1998 bogus[i] = 0x18 + i;
1999 cmd.host_command_length = IW_ESSID_MAX_SIZE;
2000 }
2001
2002 /* NOTE: We always send the SSID command even if the provided ESSID is
2003 * the same as what we currently think is set. */
2004
2005 err = ipw2100_hw_send_command(priv, &cmd);
2006 if (!err) {
2007 memset(priv->essid + ssid_len, 0,
2008 IW_ESSID_MAX_SIZE - ssid_len);
2009 memcpy(priv->essid, essid, ssid_len);
2010 priv->essid_len = ssid_len;
2011 }
2012
2013 if (!batch_mode) {
2014 if (ipw2100_enable_adapter(priv))
2015 err = -EIO;
2016 }
2017
2018 return err;
2019}
2020
2021static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
2022{
2023 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
2024 "disassociated: '%s' " MAC_FMT " \n",
2025 escape_essid(priv->essid, priv->essid_len),
2026 MAC_ARG(priv->bssid));
2027
2028 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
2029
2030 if (priv->status & STATUS_STOPPING) {
2031 IPW_DEBUG_INFO("Card is stopping itself, discard ASSN_LOST.\n");
2032 return;
2033 }
2034
2035 memset(priv->bssid, 0, ETH_ALEN);
2036 memset(priv->ieee->bssid, 0, ETH_ALEN);
2037
2038 netif_carrier_off(priv->net_dev);
2039 netif_stop_queue(priv->net_dev);
2040
2041 if (!(priv->status & STATUS_RUNNING))
2042 return;
2043
2044 if (priv->status & STATUS_SECURITY_UPDATED)
2045 queue_work(priv->workqueue, &priv->security_work);
2046
2047 queue_work(priv->workqueue, &priv->wx_event_work);
2048}
2049
2050static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
2051{
2052 IPW_DEBUG_INFO("%s: RF Kill state changed to radio OFF.\n",
2053 priv->net_dev->name);
2054
2055 /* RF_KILL is now enabled (else we wouldn't be here) */
2056 priv->status |= STATUS_RF_KILL_HW;
2057
2058#ifdef ACPI_CSTATE_LIMIT_DEFINED
2059 if (priv->config & CFG_C3_DISABLED) {
2060 IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n");
2061 acpi_set_cstate_limit(priv->cstate_limit);
2062 priv->config &= ~CFG_C3_DISABLED;
2063 }
2064#endif
2065
2066 /* Make sure the RF Kill check timer is running */
2067 priv->stop_rf_kill = 0;
2068 cancel_delayed_work(&priv->rf_kill);
2069 queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
2070}
2071
2072static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
2073{
2074 IPW_DEBUG_SCAN("scan complete\n");
2075 /* Age the scan results... */
2076 priv->ieee->scans++;
2077 priv->status &= ~STATUS_SCANNING;
2078}
2079
2080#ifdef CONFIG_IPW_DEBUG
2081#define IPW2100_HANDLER(v, f) { v, f, # v }
2082struct ipw2100_status_indicator {
2083 int status;
2084 void (*cb)(struct ipw2100_priv *priv, u32 status);
2085 char *name;
2086};
2087#else
2088#define IPW2100_HANDLER(v, f) { v, f }
2089struct ipw2100_status_indicator {
2090 int status;
2091 void (*cb)(struct ipw2100_priv *priv, u32 status);
2092};
2093#endif /* CONFIG_IPW_DEBUG */
2094
2095static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
2096{
2097 IPW_DEBUG_SCAN("Scanning...\n");
2098 priv->status |= STATUS_SCANNING;
2099}
2100
2101const struct ipw2100_status_indicator status_handlers[] = {
2102 IPW2100_HANDLER(IPW_STATE_INITIALIZED, 0),
2103 IPW2100_HANDLER(IPW_STATE_COUNTRY_FOUND, 0),
2104 IPW2100_HANDLER(IPW_STATE_ASSOCIATED, isr_indicate_associated),
2105 IPW2100_HANDLER(IPW_STATE_ASSN_LOST, isr_indicate_association_lost),
2106 IPW2100_HANDLER(IPW_STATE_ASSN_CHANGED, 0),
2107 IPW2100_HANDLER(IPW_STATE_SCAN_COMPLETE, isr_scan_complete),
2108 IPW2100_HANDLER(IPW_STATE_ENTERED_PSP, 0),
2109 IPW2100_HANDLER(IPW_STATE_LEFT_PSP, 0),
2110 IPW2100_HANDLER(IPW_STATE_RF_KILL, isr_indicate_rf_kill),
2111 IPW2100_HANDLER(IPW_STATE_DISABLED, 0),
2112 IPW2100_HANDLER(IPW_STATE_POWER_DOWN, 0),
2113 IPW2100_HANDLER(IPW_STATE_SCANNING, isr_indicate_scanning),
2114 IPW2100_HANDLER(-1, 0)
2115};
2116
2117
2118static void isr_status_change(struct ipw2100_priv *priv, int status)
2119{
2120 int i;
2121
2122 if (status == IPW_STATE_SCANNING &&
2123 priv->status & STATUS_ASSOCIATED &&
2124 !(priv->status & STATUS_SCANNING)) {
2125 IPW_DEBUG_INFO("Scan detected while associated, with "
2126 "no scan request. Restarting firmware.\n");
2127
2128 /* Wake up any sleeping jobs */
2129 schedule_reset(priv);
2130 }
2131
2132 for (i = 0; status_handlers[i].status != -1; i++) {
2133 if (status == status_handlers[i].status) {
2134 IPW_DEBUG_NOTIF("Status change: %s\n",
2135 status_handlers[i].name);
2136 if (status_handlers[i].cb)
2137 status_handlers[i].cb(priv, status);
2138 priv->wstats.status = status;
2139 return;
2140 }
2141 }
2142
2143 IPW_DEBUG_NOTIF("unknown status received: %04x\n", status);
2144}
2145
2146static void isr_rx_complete_command(
2147 struct ipw2100_priv *priv,
2148 struct ipw2100_cmd_header *cmd)
2149{
2150#ifdef CONFIG_IPW_DEBUG
2151 if (cmd->host_command_reg < ARRAY_SIZE(command_types)) {
2152 IPW_DEBUG_HC("Command completed '%s (%d)'\n",
2153 command_types[cmd->host_command_reg],
2154 cmd->host_command_reg);
2155 }
2156#endif
2157 if (cmd->host_command_reg == HOST_COMPLETE)
2158 priv->status |= STATUS_ENABLED;
2159
2160 if (cmd->host_command_reg == CARD_DISABLE)
2161 priv->status &= ~STATUS_ENABLED;
2162
2163 priv->status &= ~STATUS_CMD_ACTIVE;
2164
2165 wake_up_interruptible(&priv->wait_command_queue);
2166}
2167
2168#ifdef CONFIG_IPW_DEBUG
2169const char *frame_types[] = {
2170 "COMMAND_STATUS_VAL",
2171 "STATUS_CHANGE_VAL",
2172 "P80211_DATA_VAL",
2173 "P8023_DATA_VAL",
2174 "HOST_NOTIFICATION_VAL"
2175};
2176#endif
2177
2178
2179static inline int ipw2100_alloc_skb(
2180 struct ipw2100_priv *priv,
2181 struct ipw2100_rx_packet *packet)
2182{
2183 packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx));
2184 if (!packet->skb)
2185 return -ENOMEM;
2186
2187 packet->rxp = (struct ipw2100_rx *)packet->skb->data;
2188 packet->dma_addr = pci_map_single(priv->pci_dev, packet->skb->data,
2189 sizeof(struct ipw2100_rx),
2190 PCI_DMA_FROMDEVICE);
2191 /* NOTE: pci_map_single does not return an error code, and 0 is a valid
2192 * dma_addr */
2193
2194 return 0;
2195}
2196
2197
2198#define SEARCH_ERROR 0xffffffff
2199#define SEARCH_FAIL 0xfffffffe
2200#define SEARCH_SUCCESS 0xfffffff0
2201#define SEARCH_DISCARD 0
2202#define SEARCH_SNAPSHOT 1
2203
2204#define SNAPSHOT_ADDR(ofs) (priv->snapshot[((ofs) >> 12) & 0xff] + ((ofs) & 0xfff))
2205static inline int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
2206{
2207 int i;
2208 if (priv->snapshot[0])
2209 return 1;
2210 for (i = 0; i < 0x30; i++) {
2211 priv->snapshot[i] = (u8*)kmalloc(0x1000, GFP_ATOMIC);
2212 if (!priv->snapshot[i]) {
2213 IPW_DEBUG_INFO("%s: Error allocating snapshot "
2214 "buffer %d\n", priv->net_dev->name, i);
2215 while (i > 0)
2216 kfree(priv->snapshot[--i]);
2217 priv->snapshot[0] = NULL;
2218 return 0;
2219 }
2220 }
2221
2222 return 1;
2223}
2224
2225static inline void ipw2100_snapshot_free(struct ipw2100_priv *priv)
2226{
2227 int i;
2228 if (!priv->snapshot[0])
2229 return;
2230 for (i = 0; i < 0x30; i++)
2231 kfree(priv->snapshot[i]);
2232 priv->snapshot[0] = NULL;
2233}
2234
2235static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf,
2236 size_t len, int mode)
2237{
2238 u32 i, j;
2239 u32 tmp;
2240 u8 *s, *d;
2241 u32 ret;
2242
2243 s = in_buf;
2244 if (mode == SEARCH_SNAPSHOT) {
2245 if (!ipw2100_snapshot_alloc(priv))
2246 mode = SEARCH_DISCARD;
2247 }
2248
2249 for (ret = SEARCH_FAIL, i = 0; i < 0x30000; i += 4) {
2250 read_nic_dword(priv->net_dev, i, &tmp);
2251 if (mode == SEARCH_SNAPSHOT)
2252 *(u32 *)SNAPSHOT_ADDR(i) = tmp;
2253 if (ret == SEARCH_FAIL) {
2254 d = (u8*)&tmp;
2255 for (j = 0; j < 4; j++) {
2256 if (*s != *d) {
2257 s = in_buf;
2258 continue;
2259 }
2260
2261 s++;
2262 d++;
2263
2264 if ((s - in_buf) == len)
2265 ret = (i + j) - len + 1;
2266 }
2267 } else if (mode == SEARCH_DISCARD)
2268 return ret;
2269 }
2270
2271 return ret;
2272}
2273
2274/*
2275 *
2276 * 0) Disconnect the SKB from the firmware (just unmap)
2277 * 1) Pack the ETH header into the SKB
2278 * 2) Pass the SKB to the network stack
2279 *
2280 * When packet is provided by the firmware, it contains the following:
2281 *
2282 * . ieee80211_hdr
2283 * . ieee80211_snap_hdr
2284 *
2285 * The size of the constructed ethernet
2286 *
2287 */
2288#ifdef CONFIG_IPW2100_RX_DEBUG
2289u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
2290#endif
2291
2292static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2293 int i)
2294{
2295#ifdef CONFIG_IPW_DEBUG_C3
2296 struct ipw2100_status *status = &priv->status_queue.drv[i];
2297 u32 match, reg;
2298 int j;
2299#endif
2300#ifdef ACPI_CSTATE_LIMIT_DEFINED
2301 int limit;
2302#endif
2303
2304 IPW_DEBUG_INFO(DRV_NAME ": PCI latency error detected at "
2305 "0x%04X.\n", i * sizeof(struct ipw2100_status));
2306
2307#ifdef ACPI_CSTATE_LIMIT_DEFINED
2308 IPW_DEBUG_INFO(DRV_NAME ": Disabling C3 transitions.\n");
2309 limit = acpi_get_cstate_limit();
2310 if (limit > 2) {
2311 priv->cstate_limit = limit;
2312 acpi_set_cstate_limit(2);
2313 priv->config |= CFG_C3_DISABLED;
2314 }
2315#endif
2316
2317#ifdef CONFIG_IPW_DEBUG_C3
2318 /* Halt the fimrware so we can get a good image */
2319 write_register(priv->net_dev, IPW_REG_RESET_REG,
2320 IPW_AUX_HOST_RESET_REG_STOP_MASTER);
2321 j = 5;
2322 do {
2323 udelay(IPW_WAIT_RESET_MASTER_ASSERT_COMPLETE_DELAY);
2324 read_register(priv->net_dev, IPW_REG_RESET_REG, &reg);
2325
2326 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
2327 break;
2328 } while (j--);
2329
2330 match = ipw2100_match_buf(priv, (u8*)status,
2331 sizeof(struct ipw2100_status),
2332 SEARCH_SNAPSHOT);
2333 if (match < SEARCH_SUCCESS)
2334 IPW_DEBUG_INFO("%s: DMA status match in Firmware at "
2335 "offset 0x%06X, length %d:\n",
2336 priv->net_dev->name, match,
2337 sizeof(struct ipw2100_status));
2338 else
2339 IPW_DEBUG_INFO("%s: No DMA status match in "
2340 "Firmware.\n", priv->net_dev->name);
2341
2342 printk_buf((u8*)priv->status_queue.drv,
2343 sizeof(struct ipw2100_status) * RX_QUEUE_LENGTH);
2344#endif
2345
2346 priv->fatal_error = IPW2100_ERR_C3_CORRUPTION;
2347 priv->ieee->stats.rx_errors++;
2348 schedule_reset(priv);
2349}
2350
2351static inline void isr_rx(struct ipw2100_priv *priv, int i,
2352 struct ieee80211_rx_stats *stats)
2353{
2354 struct ipw2100_status *status = &priv->status_queue.drv[i];
2355 struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
2356
2357 IPW_DEBUG_RX("Handler...\n");
2358
2359 if (unlikely(status->frame_size > skb_tailroom(packet->skb))) {
2360 IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
2361 " Dropping.\n",
2362 priv->net_dev->name,
2363 status->frame_size, skb_tailroom(packet->skb));
2364 priv->ieee->stats.rx_errors++;
2365 return;
2366 }
2367
2368 if (unlikely(!netif_running(priv->net_dev))) {
2369 priv->ieee->stats.rx_errors++;
2370 priv->wstats.discard.misc++;
2371 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
2372 return;
2373 }
2374
2375 if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR &&
2376 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
2377 IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
2378 priv->ieee->stats.rx_errors++;
2379 return;
2380 }
2381
2382 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR &&
2383 !(priv->status & STATUS_ASSOCIATED))) {
2384 IPW_DEBUG_DROP("Dropping packet while not associated.\n");
2385 priv->wstats.discard.misc++;
2386 return;
2387 }
2388
2389
2390 pci_unmap_single(priv->pci_dev,
2391 packet->dma_addr,
2392 sizeof(struct ipw2100_rx),
2393 PCI_DMA_FROMDEVICE);
2394
2395 skb_put(packet->skb, status->frame_size);
2396
2397#ifdef CONFIG_IPW2100_RX_DEBUG
2398 /* Make a copy of the frame so we can dump it to the logs if
2399 * ieee80211_rx fails */
2400 memcpy(packet_data, packet->skb->data,
2401 min(status->frame_size, IPW_RX_NIC_BUFFER_LENGTH));
2402#endif
2403
2404 if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
2405#ifdef CONFIG_IPW2100_RX_DEBUG
2406 IPW_DEBUG_DROP("%s: Non consumed packet:\n",
2407 priv->net_dev->name);
2408 printk_buf(IPW_DL_DROP, packet_data, status->frame_size);
2409#endif
2410 priv->ieee->stats.rx_errors++;
2411
2412 /* ieee80211_rx failed, so it didn't free the SKB */
2413 dev_kfree_skb_any(packet->skb);
2414 packet->skb = NULL;
2415 }
2416
2417 /* We need to allocate a new SKB and attach it to the RDB. */
2418 if (unlikely(ipw2100_alloc_skb(priv, packet))) {
2419 IPW_DEBUG_WARNING(
2420 "%s: Unable to allocate SKB onto RBD ring - disabling "
2421 "adapter.\n", priv->net_dev->name);
2422 /* TODO: schedule adapter shutdown */
2423 IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
2424 }
2425
2426 /* Update the RDB entry */
2427 priv->rx_queue.drv[i].host_addr = packet->dma_addr;
2428}
2429
2430static inline int ipw2100_corruption_check(struct ipw2100_priv *priv, int i)
2431{
2432 struct ipw2100_status *status = &priv->status_queue.drv[i];
2433 struct ipw2100_rx *u = priv->rx_buffers[i].rxp;
2434 u16 frame_type = status->status_fields & STATUS_TYPE_MASK;
2435
2436 switch (frame_type) {
2437 case COMMAND_STATUS_VAL:
2438 return (status->frame_size != sizeof(u->rx_data.command));
2439 case STATUS_CHANGE_VAL:
2440 return (status->frame_size != sizeof(u->rx_data.status));
2441 case HOST_NOTIFICATION_VAL:
2442 return (status->frame_size < sizeof(u->rx_data.notification));
2443 case P80211_DATA_VAL:
2444 case P8023_DATA_VAL:
2445#ifdef CONFIG_IPW2100_MONITOR
2446 return 0;
2447#else
2448 switch (WLAN_FC_GET_TYPE(u->rx_data.header.frame_ctl)) {
2449 case IEEE80211_FTYPE_MGMT:
2450 case IEEE80211_FTYPE_CTL:
2451 return 0;
2452 case IEEE80211_FTYPE_DATA:
2453 return (status->frame_size >
2454 IPW_MAX_802_11_PAYLOAD_LENGTH);
2455 }
2456#endif
2457 }
2458
2459 return 1;
2460}
2461
2462/*
2463 * ipw2100 interrupts are disabled at this point, and the ISR
2464 * is the only code that calls this method. So, we do not need
2465 * to play with any locks.
2466 *
2467 * RX Queue works as follows:
2468 *
2469 * Read index - firmware places packet in entry identified by the
2470 * Read index and advances Read index. In this manner,
2471 * Read index will always point to the next packet to
2472 * be filled--but not yet valid.
2473 *
2474 * Write index - driver fills this entry with an unused RBD entry.
2475 * This entry has not filled by the firmware yet.
2476 *
2477 * In between the W and R indexes are the RBDs that have been received
2478 * but not yet processed.
2479 *
2480 * The process of handling packets will start at WRITE + 1 and advance
2481 * until it reaches the READ index.
2482 *
2483 * The WRITE index is cached in the variable 'priv->rx_queue.next'.
2484 *
2485 */
2486static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2487{
2488 struct ipw2100_bd_queue *rxq = &priv->rx_queue;
2489 struct ipw2100_status_queue *sq = &priv->status_queue;
2490 struct ipw2100_rx_packet *packet;
2491 u16 frame_type;
2492 u32 r, w, i, s;
2493 struct ipw2100_rx *u;
2494 struct ieee80211_rx_stats stats = {
2495 .mac_time = jiffies,
2496 };
2497
2498 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_RX_READ_INDEX, &r);
2499 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_RX_WRITE_INDEX, &w);
2500
2501 if (r >= rxq->entries) {
2502 IPW_DEBUG_RX("exit - bad read index\n");
2503 return;
2504 }
2505
2506 i = (rxq->next + 1) % rxq->entries;
2507 s = i;
2508 while (i != r) {
2509 /* IPW_DEBUG_RX("r = %d : w = %d : processing = %d\n",
2510 r, rxq->next, i); */
2511
2512 packet = &priv->rx_buffers[i];
2513
2514 /* Sync the DMA for the STATUS buffer so CPU is sure to get
2515 * the correct values */
2516 pci_dma_sync_single_for_cpu(
2517 priv->pci_dev,
2518 sq->nic + sizeof(struct ipw2100_status) * i,
2519 sizeof(struct ipw2100_status),
2520 PCI_DMA_FROMDEVICE);
2521
2522 /* Sync the DMA for the RX buffer so CPU is sure to get
2523 * the correct values */
2524 pci_dma_sync_single_for_cpu(priv->pci_dev, packet->dma_addr,
2525 sizeof(struct ipw2100_rx),
2526 PCI_DMA_FROMDEVICE);
2527
2528 if (unlikely(ipw2100_corruption_check(priv, i))) {
2529 ipw2100_corruption_detected(priv, i);
2530 goto increment;
2531 }
2532
2533 u = packet->rxp;
2534 frame_type = sq->drv[i].status_fields &
2535 STATUS_TYPE_MASK;
2536 stats.rssi = sq->drv[i].rssi + IPW2100_RSSI_TO_DBM;
2537 stats.len = sq->drv[i].frame_size;
2538
2539 stats.mask = 0;
2540 if (stats.rssi != 0)
2541 stats.mask |= IEEE80211_STATMASK_RSSI;
2542 stats.freq = IEEE80211_24GHZ_BAND;
2543
2544 IPW_DEBUG_RX(
2545 "%s: '%s' frame type received (%d).\n",
2546 priv->net_dev->name, frame_types[frame_type],
2547 stats.len);
2548
2549 switch (frame_type) {
2550 case COMMAND_STATUS_VAL:
2551 /* Reset Rx watchdog */
2552 isr_rx_complete_command(
2553 priv, &u->rx_data.command);
2554 break;
2555
2556 case STATUS_CHANGE_VAL:
2557 isr_status_change(priv, u->rx_data.status);
2558 break;
2559
2560 case P80211_DATA_VAL:
2561 case P8023_DATA_VAL:
2562#ifdef CONFIG_IPW2100_MONITOR
2563 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
2564 isr_rx(priv, i, &stats);
2565 break;
2566 }
2567#endif
2568 if (stats.len < sizeof(u->rx_data.header))
2569 break;
2570 switch (WLAN_FC_GET_TYPE(u->rx_data.header.
2571 frame_ctl)) {
2572 case IEEE80211_FTYPE_MGMT:
2573 ieee80211_rx_mgt(priv->ieee,
2574 &u->rx_data.header,
2575 &stats);
2576 break;
2577
2578 case IEEE80211_FTYPE_CTL:
2579 break;
2580
2581 case IEEE80211_FTYPE_DATA:
2582 isr_rx(priv, i, &stats);
2583 break;
2584
2585 }
2586 break;
2587 }
2588
2589 increment:
2590 /* clear status field associated with this RBD */
2591 rxq->drv[i].status.info.field = 0;
2592
2593 i = (i + 1) % rxq->entries;
2594 }
2595
2596 if (i != s) {
2597 /* backtrack one entry, wrapping to end if at 0 */
2598 rxq->next = (i ? i : rxq->entries) - 1;
2599
2600 write_register(priv->net_dev,
2601 IPW_MEM_HOST_SHARED_RX_WRITE_INDEX,
2602 rxq->next);
2603 }
2604}
2605
2606
2607/*
2608 * __ipw2100_tx_process
2609 *
2610 * This routine will determine whether the next packet on
2611 * the fw_pend_list has been processed by the firmware yet.
2612 *
2613 * If not, then it does nothing and returns.
2614 *
2615 * If so, then it removes the item from the fw_pend_list, frees
2616 * any associated storage, and places the item back on the
2617 * free list of its source (either msg_free_list or tx_free_list)
2618 *
2619 * TX Queue works as follows:
2620 *
2621 * Read index - points to the next TBD that the firmware will
2622 * process. The firmware will read the data, and once
2623 * done processing, it will advance the Read index.
2624 *
2625 * Write index - driver fills this entry with an constructed TBD
2626 * entry. The Write index is not advanced until the
2627 * packet has been configured.
2628 *
2629 * In between the W and R indexes are the TBDs that have NOT been
2630 * processed. Lagging behind the R index are packets that have
2631 * been processed but have not been freed by the driver.
2632 *
2633 * In order to free old storage, an internal index will be maintained
2634 * that points to the next packet to be freed. When all used
2635 * packets have been freed, the oldest index will be the same as the
2636 * firmware's read index.
2637 *
2638 * The OLDEST index is cached in the variable 'priv->tx_queue.oldest'
2639 *
2640 * Because the TBD structure can not contain arbitrary data, the
2641 * driver must keep an internal queue of cached allocations such that
2642 * it can put that data back into the tx_free_list and msg_free_list
2643 * for use by future command and data packets.
2644 *
2645 */
2646static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2647{
2648 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2649 struct ipw2100_bd *tbd;
2650 struct list_head *element;
2651 struct ipw2100_tx_packet *packet;
2652 int descriptors_used;
2653 int e, i;
2654 u32 r, w, frag_num = 0;
2655
2656 if (list_empty(&priv->fw_pend_list))
2657 return 0;
2658
2659 element = priv->fw_pend_list.next;
2660
2661 packet = list_entry(element, struct ipw2100_tx_packet, list);
2662 tbd = &txq->drv[packet->index];
2663
2664 /* Determine how many TBD entries must be finished... */
2665 switch (packet->type) {
2666 case COMMAND:
2667 /* COMMAND uses only one slot; don't advance */
2668 descriptors_used = 1;
2669 e = txq->oldest;
2670 break;
2671
2672 case DATA:
2673 /* DATA uses two slots; advance and loop position. */
2674 descriptors_used = tbd->num_fragments;
2675 frag_num = tbd->num_fragments - 1;
2676 e = txq->oldest + frag_num;
2677 e %= txq->entries;
2678 break;
2679
2680 default:
2681 IPW_DEBUG_WARNING("%s: Bad fw_pend_list entry!\n",
2682 priv->net_dev->name);
2683 return 0;
2684 }
2685
2686 /* if the last TBD is not done by NIC yet, then packet is
2687 * not ready to be released.
2688 *
2689 */
2690 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX,
2691 &r);
2692 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
2693 &w);
2694 if (w != txq->next)
2695 IPW_DEBUG_WARNING("%s: write index mismatch\n",
2696 priv->net_dev->name);
2697
2698 /*
2699 * txq->next is the index of the last packet written txq->oldest is
2700 * the index of the r is the index of the next packet to be read by
2701 * firmware
2702 */
2703
2704
2705 /*
2706 * Quick graphic to help you visualize the following
2707 * if / else statement
2708 *
2709 * ===>| s---->|===============
2710 * e>|
2711 * | a | b | c | d | e | f | g | h | i | j | k | l
2712 * r---->|
2713 * w
2714 *
2715 * w - updated by driver
2716 * r - updated by firmware
2717 * s - start of oldest BD entry (txq->oldest)
2718 * e - end of oldest BD entry
2719 *
2720 */
2721 if (!((r <= w && (e < r || e >= w)) || (e < r && e >= w))) {
2722 IPW_DEBUG_TX("exit - no processed packets ready to release.\n");
2723 return 0;
2724 }
2725
2726 list_del(element);
2727 DEC_STAT(&priv->fw_pend_stat);
2728
2729#ifdef CONFIG_IPW_DEBUG
2730 {
2731 int i = txq->oldest;
2732 IPW_DEBUG_TX(
2733 "TX%d V=%p P=%p T=%p L=%d\n", i,
2734 &txq->drv[i],
2735 (void*)txq->nic + i * sizeof(struct ipw2100_bd),
2736 (void*)txq->drv[i].host_addr,
2737 txq->drv[i].buf_length);
2738
2739 if (packet->type == DATA) {
2740 i = (i + 1) % txq->entries;
2741
2742 IPW_DEBUG_TX(
2743 "TX%d V=%p P=%p T=%p L=%d\n", i,
2744 &txq->drv[i],
2745 (void*)txq->nic + i *
2746 sizeof(struct ipw2100_bd),
2747 (void*)txq->drv[i].host_addr,
2748 txq->drv[i].buf_length);
2749 }
2750 }
2751#endif
2752
2753 switch (packet->type) {
2754 case DATA:
2755 if (txq->drv[txq->oldest].status.info.fields.txType != 0)
2756 IPW_DEBUG_WARNING("%s: Queue mismatch. "
2757 "Expecting DATA TBD but pulled "
2758 "something else: ids %d=%d.\n",
2759 priv->net_dev->name, txq->oldest, packet->index);
2760
2761 /* DATA packet; we have to unmap and free the SKB */
2762 priv->ieee->stats.tx_packets++;
2763 for (i = 0; i < frag_num; i++) {
2764 tbd = &txq->drv[(packet->index + 1 + i) %
2765 txq->entries];
2766
2767 IPW_DEBUG_TX(
2768 "TX%d P=%08x L=%d\n",
2769 (packet->index + 1 + i) % txq->entries,
2770 tbd->host_addr, tbd->buf_length);
2771
2772 pci_unmap_single(priv->pci_dev,
2773 tbd->host_addr,
2774 tbd->buf_length,
2775 PCI_DMA_TODEVICE);
2776 }
2777
2778 priv->ieee->stats.tx_bytes += packet->info.d_struct.txb->payload_size;
2779 ieee80211_txb_free(packet->info.d_struct.txb);
2780 packet->info.d_struct.txb = NULL;
2781
2782 list_add_tail(element, &priv->tx_free_list);
2783 INC_STAT(&priv->tx_free_stat);
2784
2785 /* We have a free slot in the Tx queue, so wake up the
2786 * transmit layer if it is stopped. */
2787 if (priv->status & STATUS_ASSOCIATED &&
2788 netif_queue_stopped(priv->net_dev)) {
2789 IPW_DEBUG_INFO(KERN_INFO
2790 "%s: Waking net queue.\n",
2791 priv->net_dev->name);
2792 netif_wake_queue(priv->net_dev);
2793 }
2794
2795 /* A packet was processed by the hardware, so update the
2796 * watchdog */
2797 priv->net_dev->trans_start = jiffies;
2798
2799 break;
2800
2801 case COMMAND:
2802 if (txq->drv[txq->oldest].status.info.fields.txType != 1)
2803 IPW_DEBUG_WARNING("%s: Queue mismatch. "
2804 "Expecting COMMAND TBD but pulled "
2805 "something else: ids %d=%d.\n",
2806 priv->net_dev->name, txq->oldest, packet->index);
2807
2808#ifdef CONFIG_IPW_DEBUG
2809 if (packet->info.c_struct.cmd->host_command_reg <
2810 sizeof(command_types) / sizeof(*command_types))
2811 IPW_DEBUG_TX(
2812 "Command '%s (%d)' processed: %d.\n",
2813 command_types[packet->info.c_struct.cmd->host_command_reg],
2814 packet->info.c_struct.cmd->host_command_reg,
2815 packet->info.c_struct.cmd->cmd_status_reg);
2816#endif
2817
2818 list_add_tail(element, &priv->msg_free_list);
2819 INC_STAT(&priv->msg_free_stat);
2820 break;
2821 }
2822
2823 /* advance oldest used TBD pointer to start of next entry */
2824 txq->oldest = (e + 1) % txq->entries;
2825 /* increase available TBDs number */
2826 txq->available += descriptors_used;
2827 SET_STAT(&priv->txq_stat, txq->available);
2828
2829 IPW_DEBUG_TX("packet latency (send to process) %ld jiffies\n",
2830 jiffies - packet->jiffy_start);
2831
2832 return (!list_empty(&priv->fw_pend_list));
2833}
2834
2835
2836static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv)
2837{
2838 int i = 0;
2839
2840 while (__ipw2100_tx_process(priv) && i < 200) i++;
2841
2842 if (i == 200) {
2843 IPW_DEBUG_WARNING(
2844 "%s: Driver is running slow (%d iters).\n",
2845 priv->net_dev->name, i);
2846 }
2847}
2848
2849
2850static void X__ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2851{
2852 struct list_head *element;
2853 struct ipw2100_tx_packet *packet;
2854 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2855 struct ipw2100_bd *tbd;
2856 int next = txq->next;
2857
2858 while (!list_empty(&priv->msg_pend_list)) {
2859 /* if there isn't enough space in TBD queue, then
2860 * don't stuff a new one in.
2861 * NOTE: 3 are needed as a command will take one,
2862 * and there is a minimum of 2 that must be
2863 * maintained between the r and w indexes
2864 */
2865 if (txq->available <= 3) {
2866 IPW_DEBUG_TX("no room in tx_queue\n");
2867 break;
2868 }
2869
2870 element = priv->msg_pend_list.next;
2871 list_del(element);
2872 DEC_STAT(&priv->msg_pend_stat);
2873
2874 packet = list_entry(element,
2875 struct ipw2100_tx_packet, list);
2876
2877 IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n",
2878 &txq->drv[txq->next],
2879 (void*)(txq->nic + txq->next *
2880 sizeof(struct ipw2100_bd)));
2881
2882 packet->index = txq->next;
2883
2884 tbd = &txq->drv[txq->next];
2885
2886 /* initialize TBD */
2887 tbd->host_addr = packet->info.c_struct.cmd_phys;
2888 tbd->buf_length = sizeof(struct ipw2100_cmd_header);
2889 /* not marking number of fragments causes problems
2890 * with f/w debug version */
2891 tbd->num_fragments = 1;
2892 tbd->status.info.field =
2893 IPW_BD_STATUS_TX_FRAME_COMMAND |
2894 IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
2895
2896 /* update TBD queue counters */
2897 txq->next++;
2898 txq->next %= txq->entries;
2899 txq->available--;
2900 DEC_STAT(&priv->txq_stat);
2901
2902 list_add_tail(element, &priv->fw_pend_list);
2903 INC_STAT(&priv->fw_pend_stat);
2904 }
2905
2906 if (txq->next != next) {
2907 /* kick off the DMA by notifying firmware the
2908 * write index has moved; make sure TBD stores are sync'd */
2909 wmb();
2910 write_register(priv->net_dev,
2911 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
2912 txq->next);
2913 }
2914}
2915
2916
2917/*
2918 * X__ipw2100_tx_send_data
2919 *
2920 */
2921static void X__ipw2100_tx_send_data(struct ipw2100_priv *priv)
2922{
2923 struct list_head *element;
2924 struct ipw2100_tx_packet *packet;
2925 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2926 struct ipw2100_bd *tbd;
2927 int next = txq->next;
2928 int i = 0;
2929 struct ipw2100_data_header *ipw_hdr;
2930 struct ieee80211_hdr *hdr;
2931
2932 while (!list_empty(&priv->tx_pend_list)) {
2933 /* if there isn't enough space in TBD queue, then
2934 * don't stuff a new one in.
2935 * NOTE: 4 are needed as a data will take two,
2936 * and there is a minimum of 2 that must be
2937 * maintained between the r and w indexes
2938 */
2939 element = priv->tx_pend_list.next;
2940 packet = list_entry(element, struct ipw2100_tx_packet, list);
2941
2942 if (unlikely(1 + packet->info.d_struct.txb->nr_frags >
2943 IPW_MAX_BDS)) {
2944 /* TODO: Support merging buffers if more than
2945 * IPW_MAX_BDS are used */
2946 IPW_DEBUG_INFO(
2947 "%s: Maximum BD theshold exceeded. "
2948 "Increase fragmentation level.\n",
2949 priv->net_dev->name);
2950 }
2951
2952 if (txq->available <= 3 +
2953 packet->info.d_struct.txb->nr_frags) {
2954 IPW_DEBUG_TX("no room in tx_queue\n");
2955 break;
2956 }
2957
2958 list_del(element);
2959 DEC_STAT(&priv->tx_pend_stat);
2960
2961 tbd = &txq->drv[txq->next];
2962
2963 packet->index = txq->next;
2964
2965 ipw_hdr = packet->info.d_struct.data;
2966 hdr = (struct ieee80211_hdr *)packet->info.d_struct.txb->
2967 fragments[0]->data;
2968
2969 if (priv->ieee->iw_mode == IW_MODE_INFRA) {
2970 /* To DS: Addr1 = BSSID, Addr2 = SA,
2971 Addr3 = DA */
2972 memcpy(ipw_hdr->src_addr, hdr->addr2, ETH_ALEN);
2973 memcpy(ipw_hdr->dst_addr, hdr->addr3, ETH_ALEN);
2974 } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
2975 /* not From/To DS: Addr1 = DA, Addr2 = SA,
2976 Addr3 = BSSID */
2977 memcpy(ipw_hdr->src_addr, hdr->addr2, ETH_ALEN);
2978 memcpy(ipw_hdr->dst_addr, hdr->addr1, ETH_ALEN);
2979 }
2980
2981 ipw_hdr->host_command_reg = SEND;
2982 ipw_hdr->host_command_reg1 = 0;
2983
2984 /* For now we only support host based encryption */
2985 ipw_hdr->needs_encryption = 0;
2986 ipw_hdr->encrypted = packet->info.d_struct.txb->encrypted;
2987 if (packet->info.d_struct.txb->nr_frags > 1)
2988 ipw_hdr->fragment_size =
2989 packet->info.d_struct.txb->frag_size - IEEE80211_3ADDR_LEN;
2990 else
2991 ipw_hdr->fragment_size = 0;
2992
2993 tbd->host_addr = packet->info.d_struct.data_phys;
2994 tbd->buf_length = sizeof(struct ipw2100_data_header);
2995 tbd->num_fragments = 1 + packet->info.d_struct.txb->nr_frags;
2996 tbd->status.info.field =
2997 IPW_BD_STATUS_TX_FRAME_802_3 |
2998 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
2999 txq->next++;
3000 txq->next %= txq->entries;
3001
3002 IPW_DEBUG_TX(
3003 "data header tbd TX%d P=%08x L=%d\n",
3004 packet->index, tbd->host_addr,
3005 tbd->buf_length);
3006#ifdef CONFIG_IPW_DEBUG
3007 if (packet->info.d_struct.txb->nr_frags > 1)
3008 IPW_DEBUG_FRAG("fragment Tx: %d frames\n",
3009 packet->info.d_struct.txb->nr_frags);
3010#endif
3011
3012 for (i = 0; i < packet->info.d_struct.txb->nr_frags; i++) {
3013 tbd = &txq->drv[txq->next];
3014 if (i == packet->info.d_struct.txb->nr_frags - 1)
3015 tbd->status.info.field =
3016 IPW_BD_STATUS_TX_FRAME_802_3 |
3017 IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
3018 else
3019 tbd->status.info.field =
3020 IPW_BD_STATUS_TX_FRAME_802_3 |
3021 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
3022
3023 tbd->buf_length = packet->info.d_struct.txb->
3024 fragments[i]->len - IEEE80211_3ADDR_LEN;
3025
3026 tbd->host_addr = pci_map_single(
3027 priv->pci_dev,
3028 packet->info.d_struct.txb->fragments[i]->data +
3029 IEEE80211_3ADDR_LEN,
3030 tbd->buf_length,
3031 PCI_DMA_TODEVICE);
3032
3033 IPW_DEBUG_TX(
3034 "data frag tbd TX%d P=%08x L=%d\n",
3035 txq->next, tbd->host_addr, tbd->buf_length);
3036
3037 pci_dma_sync_single_for_device(
3038 priv->pci_dev, tbd->host_addr,
3039 tbd->buf_length,
3040 PCI_DMA_TODEVICE);
3041
3042 txq->next++;
3043 txq->next %= txq->entries;
3044 }
3045
3046 txq->available -= 1 + packet->info.d_struct.txb->nr_frags;
3047 SET_STAT(&priv->txq_stat, txq->available);
3048
3049 list_add_tail(element, &priv->fw_pend_list);
3050 INC_STAT(&priv->fw_pend_stat);
3051 }
3052
3053 if (txq->next != next) {
3054 /* kick off the DMA by notifying firmware the
3055 * write index has moved; make sure TBD stores are sync'd */
3056 write_register(priv->net_dev,
3057 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
3058 txq->next);
3059 }
3060 return;
3061}
3062
3063static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3064{
3065 struct net_device *dev = priv->net_dev;
3066 unsigned long flags;
3067 u32 inta, tmp;
3068
3069 spin_lock_irqsave(&priv->low_lock, flags);
3070 ipw2100_disable_interrupts(priv);
3071
3072 read_register(dev, IPW_REG_INTA, &inta);
3073
3074 IPW_DEBUG_ISR("enter - INTA: 0x%08lX\n",
3075 (unsigned long)inta & IPW_INTERRUPT_MASK);
3076
3077 priv->in_isr++;
3078 priv->interrupts++;
3079
3080 /* We do not loop and keep polling for more interrupts as this
3081 * is frowned upon and doesn't play nicely with other potentially
3082 * chained IRQs */
3083 IPW_DEBUG_ISR("INTA: 0x%08lX\n",
3084 (unsigned long)inta & IPW_INTERRUPT_MASK);
3085
3086 if (inta & IPW2100_INTA_FATAL_ERROR) {
3087 IPW_DEBUG_WARNING(DRV_NAME
3088 ": Fatal interrupt. Scheduling firmware restart.\n");
3089 priv->inta_other++;
3090 write_register(
3091 dev, IPW_REG_INTA,
3092 IPW2100_INTA_FATAL_ERROR);
3093
3094 read_nic_dword(dev, IPW_NIC_FATAL_ERROR, &priv->fatal_error);
3095 IPW_DEBUG_INFO("%s: Fatal error value: 0x%08X\n",
3096 priv->net_dev->name, priv->fatal_error);
3097
3098 read_nic_dword(dev, IPW_ERROR_ADDR(priv->fatal_error), &tmp);
3099 IPW_DEBUG_INFO("%s: Fatal error address value: 0x%08X\n",
3100 priv->net_dev->name, tmp);
3101
3102 /* Wake up any sleeping jobs */
3103 schedule_reset(priv);
3104 }
3105
3106 if (inta & IPW2100_INTA_PARITY_ERROR) {
3107 IPW_DEBUG_ERROR("***** PARITY ERROR INTERRUPT !!!! \n");
3108 priv->inta_other++;
3109 write_register(
3110 dev, IPW_REG_INTA,
3111 IPW2100_INTA_PARITY_ERROR);
3112 }
3113
3114 if (inta & IPW2100_INTA_RX_TRANSFER) {
3115 IPW_DEBUG_ISR("RX interrupt\n");
3116
3117 priv->rx_interrupts++;
3118
3119 write_register(
3120 dev, IPW_REG_INTA,
3121 IPW2100_INTA_RX_TRANSFER);
3122
3123 __ipw2100_rx_process(priv);
3124 __ipw2100_tx_complete(priv);
3125 }
3126
3127 if (inta & IPW2100_INTA_TX_TRANSFER) {
3128 IPW_DEBUG_ISR("TX interrupt\n");
3129
3130 priv->tx_interrupts++;
3131
3132 write_register(dev, IPW_REG_INTA,
3133 IPW2100_INTA_TX_TRANSFER);
3134
3135 __ipw2100_tx_complete(priv);
3136 X__ipw2100_tx_send_commands(priv);
3137 X__ipw2100_tx_send_data(priv);
3138 }
3139
3140 if (inta & IPW2100_INTA_TX_COMPLETE) {
3141 IPW_DEBUG_ISR("TX complete\n");
3142 priv->inta_other++;
3143 write_register(
3144 dev, IPW_REG_INTA,
3145 IPW2100_INTA_TX_COMPLETE);
3146
3147 __ipw2100_tx_complete(priv);
3148 }
3149
3150 if (inta & IPW2100_INTA_EVENT_INTERRUPT) {
3151 /* ipw2100_handle_event(dev); */
3152 priv->inta_other++;
3153 write_register(
3154 dev, IPW_REG_INTA,
3155 IPW2100_INTA_EVENT_INTERRUPT);
3156 }
3157
3158 if (inta & IPW2100_INTA_FW_INIT_DONE) {
3159 IPW_DEBUG_ISR("FW init done interrupt\n");
3160 priv->inta_other++;
3161
3162 read_register(dev, IPW_REG_INTA, &tmp);
3163 if (tmp & (IPW2100_INTA_FATAL_ERROR |
3164 IPW2100_INTA_PARITY_ERROR)) {
3165 write_register(
3166 dev, IPW_REG_INTA,
3167 IPW2100_INTA_FATAL_ERROR |
3168 IPW2100_INTA_PARITY_ERROR);
3169 }
3170
3171 write_register(dev, IPW_REG_INTA,
3172 IPW2100_INTA_FW_INIT_DONE);
3173 }
3174
3175 if (inta & IPW2100_INTA_STATUS_CHANGE) {
3176 IPW_DEBUG_ISR("Status change interrupt\n");
3177 priv->inta_other++;
3178 write_register(
3179 dev, IPW_REG_INTA,
3180 IPW2100_INTA_STATUS_CHANGE);
3181 }
3182
3183 if (inta & IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE) {
3184 IPW_DEBUG_ISR("slave host mode interrupt\n");
3185 priv->inta_other++;
3186 write_register(
3187 dev, IPW_REG_INTA,
3188 IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE);
3189 }
3190
3191 priv->in_isr--;
3192 ipw2100_enable_interrupts(priv);
3193
3194 spin_unlock_irqrestore(&priv->low_lock, flags);
3195
3196 IPW_DEBUG_ISR("exit\n");
3197}
3198
3199
3200static irqreturn_t ipw2100_interrupt(int irq, void *data,
3201 struct pt_regs *regs)
3202{
3203 struct ipw2100_priv *priv = data;
3204 u32 inta, inta_mask;
3205
3206 if (!data)
3207 return IRQ_NONE;
3208
3209 spin_lock(&priv->low_lock);
3210
3211 /* We check to see if we should be ignoring interrupts before
3212 * we touch the hardware. During ucode load if we try and handle
3213 * an interrupt we can cause keyboard problems as well as cause
3214 * the ucode to fail to initialize */
3215 if (!(priv->status & STATUS_INT_ENABLED)) {
3216 /* Shared IRQ */
3217 goto none;
3218 }
3219
3220 read_register(priv->net_dev, IPW_REG_INTA_MASK, &inta_mask);
3221 read_register(priv->net_dev, IPW_REG_INTA, &inta);
3222
3223 if (inta == 0xFFFFFFFF) {
3224 /* Hardware disappeared */
3225 IPW_DEBUG_WARNING("IRQ INTA == 0xFFFFFFFF\n");
3226 goto none;
3227 }
3228
3229 inta &= IPW_INTERRUPT_MASK;
3230
3231 if (!(inta & inta_mask)) {
3232 /* Shared interrupt */
3233 goto none;
3234 }
3235
3236 /* We disable the hardware interrupt here just to prevent unneeded
3237 * calls to be made. We disable this again within the actual
3238 * work tasklet, so if another part of the code re-enables the
3239 * interrupt, that is fine */
3240 ipw2100_disable_interrupts(priv);
3241
3242 tasklet_schedule(&priv->irq_tasklet);
3243 spin_unlock(&priv->low_lock);
3244
3245 return IRQ_HANDLED;
3246 none:
3247 spin_unlock(&priv->low_lock);
3248 return IRQ_NONE;
3249}
3250
3251static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev)
3252{
3253 struct ipw2100_priv *priv = ieee80211_priv(dev);
3254 struct list_head *element;
3255 struct ipw2100_tx_packet *packet;
3256 unsigned long flags;
3257
3258 spin_lock_irqsave(&priv->low_lock, flags);
3259
3260 if (!(priv->status & STATUS_ASSOCIATED)) {
3261 IPW_DEBUG_INFO("Can not transmit when not connected.\n");
3262 priv->ieee->stats.tx_carrier_errors++;
3263 netif_stop_queue(dev);
3264 goto fail_unlock;
3265 }
3266
3267 if (list_empty(&priv->tx_free_list))
3268 goto fail_unlock;
3269
3270 element = priv->tx_free_list.next;
3271 packet = list_entry(element, struct ipw2100_tx_packet, list);
3272
3273 packet->info.d_struct.txb = txb;
3274
3275 IPW_DEBUG_TX("Sending fragment (%d bytes):\n",
3276 txb->fragments[0]->len);
3277 printk_buf(IPW_DL_TX, txb->fragments[0]->data,
3278 txb->fragments[0]->len);
3279
3280 packet->jiffy_start = jiffies;
3281
3282 list_del(element);
3283 DEC_STAT(&priv->tx_free_stat);
3284
3285 list_add_tail(element, &priv->tx_pend_list);
3286 INC_STAT(&priv->tx_pend_stat);
3287
3288 X__ipw2100_tx_send_data(priv);
3289
3290 spin_unlock_irqrestore(&priv->low_lock, flags);
3291 return 0;
3292
3293 fail_unlock:
3294 netif_stop_queue(dev);
3295 spin_unlock_irqrestore(&priv->low_lock, flags);
3296 return 1;
3297}
3298
3299
3300static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3301{
3302 int i, j, err = -EINVAL;
3303 void *v;
3304 dma_addr_t p;
3305
3306 priv->msg_buffers = (struct ipw2100_tx_packet *)kmalloc(
3307 IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet),
3308 GFP_KERNEL);
3309 if (!priv->msg_buffers) {
3310 IPW_DEBUG_ERROR("%s: PCI alloc failed for msg "
3311 "buffers.\n", priv->net_dev->name);
3312 return -ENOMEM;
3313 }
3314
3315 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
3316 v = pci_alloc_consistent(
3317 priv->pci_dev,
3318 sizeof(struct ipw2100_cmd_header),
3319 &p);
3320 if (!v) {
3321 IPW_DEBUG_ERROR(
3322 "%s: PCI alloc failed for msg "
3323 "buffers.\n",
3324 priv->net_dev->name);
3325 err = -ENOMEM;
3326 break;
3327 }
3328
3329 memset(v, 0, sizeof(struct ipw2100_cmd_header));
3330
3331 priv->msg_buffers[i].type = COMMAND;
3332 priv->msg_buffers[i].info.c_struct.cmd =
3333 (struct ipw2100_cmd_header*)v;
3334 priv->msg_buffers[i].info.c_struct.cmd_phys = p;
3335 }
3336
3337 if (i == IPW_COMMAND_POOL_SIZE)
3338 return 0;
3339
3340 for (j = 0; j < i; j++) {
3341 pci_free_consistent(
3342 priv->pci_dev,
3343 sizeof(struct ipw2100_cmd_header),
3344 priv->msg_buffers[j].info.c_struct.cmd,
3345 priv->msg_buffers[j].info.c_struct.cmd_phys);
3346 }
3347
3348 kfree(priv->msg_buffers);
3349 priv->msg_buffers = NULL;
3350
3351 return err;
3352}
3353
3354static int ipw2100_msg_initialize(struct ipw2100_priv *priv)
3355{
3356 int i;
3357
3358 INIT_LIST_HEAD(&priv->msg_free_list);
3359 INIT_LIST_HEAD(&priv->msg_pend_list);
3360
3361 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++)
3362 list_add_tail(&priv->msg_buffers[i].list, &priv->msg_free_list);
3363 SET_STAT(&priv->msg_free_stat, i);
3364
3365 return 0;
3366}
3367
3368static void ipw2100_msg_free(struct ipw2100_priv *priv)
3369{
3370 int i;
3371
3372 if (!priv->msg_buffers)
3373 return;
3374
3375 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
3376 pci_free_consistent(priv->pci_dev,
3377 sizeof(struct ipw2100_cmd_header),
3378 priv->msg_buffers[i].info.c_struct.cmd,
3379 priv->msg_buffers[i].info.c_struct.cmd_phys);
3380 }
3381
3382 kfree(priv->msg_buffers);
3383 priv->msg_buffers = NULL;
3384}
3385
3386static ssize_t show_pci(struct device *d, char *buf)
3387{
3388 struct pci_dev *pci_dev = container_of(d, struct pci_dev, dev);
3389 char *out = buf;
3390 int i, j;
3391 u32 val;
3392
3393 for (i = 0; i < 16; i++) {
3394 out += sprintf(out, "[%08X] ", i * 16);
3395 for (j = 0; j < 16; j += 4) {
3396 pci_read_config_dword(pci_dev, i * 16 + j, &val);
3397 out += sprintf(out, "%08X ", val);
3398 }
3399 out += sprintf(out, "\n");
3400 }
3401
3402 return out - buf;
3403}
3404static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL);
3405
3406static ssize_t show_cfg(struct device *d, char *buf)
3407{
3408 struct ipw2100_priv *p = (struct ipw2100_priv *)d->driver_data;
3409 return sprintf(buf, "0x%08x\n", (int)p->config);
3410}
3411static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
3412
3413static ssize_t show_status(struct device *d, char *buf)
3414{
3415 struct ipw2100_priv *p = (struct ipw2100_priv *)d->driver_data;
3416 return sprintf(buf, "0x%08x\n", (int)p->status);
3417}
3418static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
3419
3420static ssize_t show_capability(struct device *d, char *buf)
3421{
3422 struct ipw2100_priv *p = (struct ipw2100_priv *)d->driver_data;
3423 return sprintf(buf, "0x%08x\n", (int)p->capability);
3424}
3425static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL);
3426
3427
3428#define IPW2100_REG(x) { IPW_ ##x, #x }
3429const struct {
3430 u32 addr;
3431 const char *name;
3432} hw_data[] = {
3433 IPW2100_REG(REG_GP_CNTRL),
3434 IPW2100_REG(REG_GPIO),
3435 IPW2100_REG(REG_INTA),
3436 IPW2100_REG(REG_INTA_MASK),
3437 IPW2100_REG(REG_RESET_REG),
3438};
3439#define IPW2100_NIC(x, s) { x, #x, s }
3440const struct {
3441 u32 addr;
3442 const char *name;
3443 size_t size;
3444} nic_data[] = {
3445 IPW2100_NIC(IPW2100_CONTROL_REG, 2),
3446 IPW2100_NIC(0x210014, 1),
3447 IPW2100_NIC(0x210000, 1),
3448};
3449#define IPW2100_ORD(x, d) { IPW_ORD_ ##x, #x, d }
3450const struct {
3451 u8 index;
3452 const char *name;
3453 const char *desc;
3454} ord_data[] = {
3455 IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"),
3456 IPW2100_ORD(STAT_TX_HOST_COMPLETE, "successful Host Tx's (MSDU)"),
3457 IPW2100_ORD(STAT_TX_DIR_DATA, "successful Directed Tx's (MSDU)"),
3458 IPW2100_ORD(STAT_TX_DIR_DATA1, "successful Directed Tx's (MSDU) @ 1MB"),
3459 IPW2100_ORD(STAT_TX_DIR_DATA2, "successful Directed Tx's (MSDU) @ 2MB"),
3460 IPW2100_ORD(STAT_TX_DIR_DATA5_5, "successful Directed Tx's (MSDU) @ 5_5MB"),
3461 IPW2100_ORD(STAT_TX_DIR_DATA11, "successful Directed Tx's (MSDU) @ 11MB"),
3462 IPW2100_ORD(STAT_TX_NODIR_DATA1, "successful Non_Directed Tx's (MSDU) @ 1MB"),
3463 IPW2100_ORD(STAT_TX_NODIR_DATA2, "successful Non_Directed Tx's (MSDU) @ 2MB"),
3464 IPW2100_ORD(STAT_TX_NODIR_DATA5_5, "successful Non_Directed Tx's (MSDU) @ 5.5MB"),
3465 IPW2100_ORD(STAT_TX_NODIR_DATA11, "successful Non_Directed Tx's (MSDU) @ 11MB"),
3466 IPW2100_ORD(STAT_NULL_DATA, "successful NULL data Tx's"),
3467 IPW2100_ORD(STAT_TX_RTS, "successful Tx RTS"),
3468 IPW2100_ORD(STAT_TX_CTS, "successful Tx CTS"),
3469 IPW2100_ORD(STAT_TX_ACK, "successful Tx ACK"),
3470 IPW2100_ORD(STAT_TX_ASSN, "successful Association Tx's"),
3471 IPW2100_ORD(STAT_TX_ASSN_RESP, "successful Association response Tx's"),
3472 IPW2100_ORD(STAT_TX_REASSN, "successful Reassociation Tx's"),
3473 IPW2100_ORD(STAT_TX_REASSN_RESP, "successful Reassociation response Tx's"),
3474 IPW2100_ORD(STAT_TX_PROBE, "probes successfully transmitted"),
3475 IPW2100_ORD(STAT_TX_PROBE_RESP, "probe responses successfully transmitted"),
3476 IPW2100_ORD(STAT_TX_BEACON, "tx beacon"),
3477 IPW2100_ORD(STAT_TX_ATIM, "Tx ATIM"),
3478 IPW2100_ORD(STAT_TX_DISASSN, "successful Disassociation TX"),
3479 IPW2100_ORD(STAT_TX_AUTH, "successful Authentication Tx"),
3480 IPW2100_ORD(STAT_TX_DEAUTH, "successful Deauthentication TX"),
3481 IPW2100_ORD(STAT_TX_TOTAL_BYTES, "Total successful Tx data bytes"),
3482 IPW2100_ORD(STAT_TX_RETRIES, "Tx retries"),
3483 IPW2100_ORD(STAT_TX_RETRY1, "Tx retries at 1MBPS"),
3484 IPW2100_ORD(STAT_TX_RETRY2, "Tx retries at 2MBPS"),
3485 IPW2100_ORD(STAT_TX_RETRY5_5, "Tx retries at 5.5MBPS"),
3486 IPW2100_ORD(STAT_TX_RETRY11, "Tx retries at 11MBPS"),
3487 IPW2100_ORD(STAT_TX_FAILURES, "Tx Failures"),
3488 IPW2100_ORD(STAT_TX_MAX_TRIES_IN_HOP,"times max tries in a hop failed"),
3489 IPW2100_ORD(STAT_TX_DISASSN_FAIL, "times disassociation failed"),
3490 IPW2100_ORD(STAT_TX_ERR_CTS, "missed/bad CTS frames"),
3491 IPW2100_ORD(STAT_TX_ERR_ACK, "tx err due to acks"),
3492 IPW2100_ORD(STAT_RX_HOST, "packets passed to host"),
3493 IPW2100_ORD(STAT_RX_DIR_DATA, "directed packets"),
3494 IPW2100_ORD(STAT_RX_DIR_DATA1, "directed packets at 1MB"),
3495 IPW2100_ORD(STAT_RX_DIR_DATA2, "directed packets at 2MB"),
3496 IPW2100_ORD(STAT_RX_DIR_DATA5_5, "directed packets at 5.5MB"),
3497 IPW2100_ORD(STAT_RX_DIR_DATA11, "directed packets at 11MB"),
3498 IPW2100_ORD(STAT_RX_NODIR_DATA,"nondirected packets"),
3499 IPW2100_ORD(STAT_RX_NODIR_DATA1, "nondirected packets at 1MB"),
3500 IPW2100_ORD(STAT_RX_NODIR_DATA2, "nondirected packets at 2MB"),
3501 IPW2100_ORD(STAT_RX_NODIR_DATA5_5, "nondirected packets at 5.5MB"),
3502 IPW2100_ORD(STAT_RX_NODIR_DATA11, "nondirected packets at 11MB"),
3503 IPW2100_ORD(STAT_RX_NULL_DATA, "null data rx's"),
3504 IPW2100_ORD(STAT_RX_RTS, "Rx RTS"),
3505 IPW2100_ORD(STAT_RX_CTS, "Rx CTS"),
3506 IPW2100_ORD(STAT_RX_ACK, "Rx ACK"),
3507 IPW2100_ORD(STAT_RX_CFEND, "Rx CF End"),
3508 IPW2100_ORD(STAT_RX_CFEND_ACK, "Rx CF End + CF Ack"),
3509 IPW2100_ORD(STAT_RX_ASSN, "Association Rx's"),
3510 IPW2100_ORD(STAT_RX_ASSN_RESP, "Association response Rx's"),
3511 IPW2100_ORD(STAT_RX_REASSN, "Reassociation Rx's"),
3512 IPW2100_ORD(STAT_RX_REASSN_RESP, "Reassociation response Rx's"),
3513 IPW2100_ORD(STAT_RX_PROBE, "probe Rx's"),
3514 IPW2100_ORD(STAT_RX_PROBE_RESP, "probe response Rx's"),
3515 IPW2100_ORD(STAT_RX_BEACON, "Rx beacon"),
3516 IPW2100_ORD(STAT_RX_ATIM, "Rx ATIM"),
3517 IPW2100_ORD(STAT_RX_DISASSN, "disassociation Rx"),
3518 IPW2100_ORD(STAT_RX_AUTH, "authentication Rx"),
3519 IPW2100_ORD(STAT_RX_DEAUTH, "deauthentication Rx"),
3520 IPW2100_ORD(STAT_RX_TOTAL_BYTES,"Total rx data bytes received"),
3521 IPW2100_ORD(STAT_RX_ERR_CRC, "packets with Rx CRC error"),
3522 IPW2100_ORD(STAT_RX_ERR_CRC1, "Rx CRC errors at 1MB"),
3523 IPW2100_ORD(STAT_RX_ERR_CRC2, "Rx CRC errors at 2MB"),
3524 IPW2100_ORD(STAT_RX_ERR_CRC5_5, "Rx CRC errors at 5.5MB"),
3525 IPW2100_ORD(STAT_RX_ERR_CRC11, "Rx CRC errors at 11MB"),
3526 IPW2100_ORD(STAT_RX_DUPLICATE1, "duplicate rx packets at 1MB"),
3527 IPW2100_ORD(STAT_RX_DUPLICATE2, "duplicate rx packets at 2MB"),
3528 IPW2100_ORD(STAT_RX_DUPLICATE5_5, "duplicate rx packets at 5.5MB"),
3529 IPW2100_ORD(STAT_RX_DUPLICATE11, "duplicate rx packets at 11MB"),
3530 IPW2100_ORD(STAT_RX_DUPLICATE, "duplicate rx packets"),
3531 IPW2100_ORD(PERS_DB_LOCK, "locking fw permanent db"),
3532 IPW2100_ORD(PERS_DB_SIZE, "size of fw permanent db"),
3533 IPW2100_ORD(PERS_DB_ADDR, "address of fw permanent db"),
3534 IPW2100_ORD(STAT_RX_INVALID_PROTOCOL, "rx frames with invalid protocol"),
3535 IPW2100_ORD(SYS_BOOT_TIME, "Boot time"),
3536 IPW2100_ORD(STAT_RX_NO_BUFFER, "rx frames rejected due to no buffer"),
3537 IPW2100_ORD(STAT_RX_MISSING_FRAG, "rx frames dropped due to missing fragment"),
3538 IPW2100_ORD(STAT_RX_ORPHAN_FRAG, "rx frames dropped due to non-sequential fragment"),
3539 IPW2100_ORD(STAT_RX_ORPHAN_FRAME, "rx frames dropped due to unmatched 1st frame"),
3540 IPW2100_ORD(STAT_RX_FRAG_AGEOUT, "rx frames dropped due to uncompleted frame"),
3541 IPW2100_ORD(STAT_RX_ICV_ERRORS, "ICV errors during decryption"),
3542 IPW2100_ORD(STAT_PSP_SUSPENSION,"times adapter suspended"),
3543 IPW2100_ORD(STAT_PSP_BCN_TIMEOUT, "beacon timeout"),
3544 IPW2100_ORD(STAT_PSP_POLL_TIMEOUT, "poll response timeouts"),
3545 IPW2100_ORD(STAT_PSP_NONDIR_TIMEOUT, "timeouts waiting for last {broad,multi}cast pkt"),
3546 IPW2100_ORD(STAT_PSP_RX_DTIMS, "PSP DTIMs received"),
3547 IPW2100_ORD(STAT_PSP_RX_TIMS, "PSP TIMs received"),
3548 IPW2100_ORD(STAT_PSP_STATION_ID,"PSP Station ID"),
3549 IPW2100_ORD(LAST_ASSN_TIME, "RTC time of last association"),
3550 IPW2100_ORD(STAT_PERCENT_MISSED_BCNS,"current calculation of % missed beacons"),
3551 IPW2100_ORD(STAT_PERCENT_RETRIES,"current calculation of % missed tx retries"),
3552 IPW2100_ORD(ASSOCIATED_AP_PTR, "0 if not associated, else pointer to AP table entry"),
3553 IPW2100_ORD(AVAILABLE_AP_CNT, "AP's decsribed in the AP table"),
3554 IPW2100_ORD(AP_LIST_PTR, "Ptr to list of available APs"),
3555 IPW2100_ORD(STAT_AP_ASSNS, "associations"),
3556 IPW2100_ORD(STAT_ASSN_FAIL, "association failures"),
3557 IPW2100_ORD(STAT_ASSN_RESP_FAIL,"failures due to response fail"),
3558 IPW2100_ORD(STAT_FULL_SCANS, "full scans"),
3559 IPW2100_ORD(CARD_DISABLED, "Card Disabled"),
3560 IPW2100_ORD(STAT_ROAM_INHIBIT, "times roaming was inhibited due to activity"),
3561 IPW2100_ORD(RSSI_AT_ASSN, "RSSI of associated AP at time of association"),
3562 IPW2100_ORD(STAT_ASSN_CAUSE1, "reassociation: no probe response or TX on hop"),
3563 IPW2100_ORD(STAT_ASSN_CAUSE2, "reassociation: poor tx/rx quality"),
3564 IPW2100_ORD(STAT_ASSN_CAUSE3, "reassociation: tx/rx quality (excessive AP load"),
3565 IPW2100_ORD(STAT_ASSN_CAUSE4, "reassociation: AP RSSI level"),
3566 IPW2100_ORD(STAT_ASSN_CAUSE5, "reassociations due to load leveling"),
3567 IPW2100_ORD(STAT_AUTH_FAIL, "times authentication failed"),
3568 IPW2100_ORD(STAT_AUTH_RESP_FAIL,"times authentication response failed"),
3569 IPW2100_ORD(STATION_TABLE_CNT, "entries in association table"),
3570 IPW2100_ORD(RSSI_AVG_CURR, "Current avg RSSI"),
3571 IPW2100_ORD(POWER_MGMT_MODE, "Power mode - 0=CAM, 1=PSP"),
3572 IPW2100_ORD(COUNTRY_CODE, "IEEE country code as recv'd from beacon"),
3573 IPW2100_ORD(COUNTRY_CHANNELS, "channels suported by country"),
3574 IPW2100_ORD(RESET_CNT, "adapter resets (warm)"),
3575 IPW2100_ORD(BEACON_INTERVAL, "Beacon interval"),
3576 IPW2100_ORD(ANTENNA_DIVERSITY, "TRUE if antenna diversity is disabled"),
3577 IPW2100_ORD(DTIM_PERIOD, "beacon intervals between DTIMs"),
3578 IPW2100_ORD(OUR_FREQ, "current radio freq lower digits - channel ID"),
3579 IPW2100_ORD(RTC_TIME, "current RTC time"),
3580 IPW2100_ORD(PORT_TYPE, "operating mode"),
3581 IPW2100_ORD(CURRENT_TX_RATE, "current tx rate"),
3582 IPW2100_ORD(SUPPORTED_RATES, "supported tx rates"),
3583 IPW2100_ORD(ATIM_WINDOW, "current ATIM Window"),
3584 IPW2100_ORD(BASIC_RATES, "basic tx rates"),
3585 IPW2100_ORD(NIC_HIGHEST_RATE, "NIC highest tx rate"),
3586 IPW2100_ORD(AP_HIGHEST_RATE, "AP highest tx rate"),
3587 IPW2100_ORD(CAPABILITIES, "Management frame capability field"),
3588 IPW2100_ORD(AUTH_TYPE, "Type of authentication"),
3589 IPW2100_ORD(RADIO_TYPE, "Adapter card platform type"),
3590 IPW2100_ORD(RTS_THRESHOLD, "Min packet length for RTS handshaking"),
3591 IPW2100_ORD(INT_MODE, "International mode"),
3592 IPW2100_ORD(FRAGMENTATION_THRESHOLD, "protocol frag threshold"),
3593 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_START_ADDRESS, "EEPROM offset in SRAM"),
3594 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_SIZE, "EEPROM size in SRAM"),
3595 IPW2100_ORD(EEPROM_SKU_CAPABILITY, "EEPROM SKU Capability"),
3596 IPW2100_ORD(EEPROM_IBSS_11B_CHANNELS, "EEPROM IBSS 11b channel set"),
3597 IPW2100_ORD(MAC_VERSION, "MAC Version"),
3598 IPW2100_ORD(MAC_REVISION, "MAC Revision"),
3599 IPW2100_ORD(RADIO_VERSION, "Radio Version"),
3600 IPW2100_ORD(NIC_MANF_DATE_TIME, "MANF Date/Time STAMP"),
3601 IPW2100_ORD(UCODE_VERSION, "Ucode Version"),
3602};
3603
3604
3605static ssize_t show_registers(struct device *d, char *buf)
3606{
3607 int i;
3608 struct ipw2100_priv *priv = dev_get_drvdata(d);
3609 struct net_device *dev = priv->net_dev;
3610 char * out = buf;
3611 u32 val = 0;
3612
3613 out += sprintf(out, "%30s [Address ] : Hex\n", "Register");
3614
3615 for (i = 0; i < (sizeof(hw_data) / sizeof(*hw_data)); i++) {
3616 read_register(dev, hw_data[i].addr, &val);
3617 out += sprintf(out, "%30s [%08X] : %08X\n",
3618 hw_data[i].name, hw_data[i].addr, val);
3619 }
3620
3621 return out - buf;
3622}
3623static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
3624
3625
3626static ssize_t show_hardware(struct device *d, char *buf)
3627{
3628 struct ipw2100_priv *priv = dev_get_drvdata(d);
3629 struct net_device *dev = priv->net_dev;
3630 char * out = buf;
3631 int i;
3632
3633 out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry");
3634
3635 for (i = 0; i < (sizeof(nic_data) / sizeof(*nic_data)); i++) {
3636 u8 tmp8;
3637 u16 tmp16;
3638 u32 tmp32;
3639
3640 switch (nic_data[i].size) {
3641 case 1:
3642 read_nic_byte(dev, nic_data[i].addr, &tmp8);
3643 out += sprintf(out, "%30s [%08X] : %02X\n",
3644 nic_data[i].name, nic_data[i].addr,
3645 tmp8);
3646 break;
3647 case 2:
3648 read_nic_word(dev, nic_data[i].addr, &tmp16);
3649 out += sprintf(out, "%30s [%08X] : %04X\n",
3650 nic_data[i].name, nic_data[i].addr,
3651 tmp16);
3652 break;
3653 case 4:
3654 read_nic_dword(dev, nic_data[i].addr, &tmp32);
3655 out += sprintf(out, "%30s [%08X] : %08X\n",
3656 nic_data[i].name, nic_data[i].addr,
3657 tmp32);
3658 break;
3659 }
3660 }
3661 return out - buf;
3662}
3663static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
3664
3665
3666static ssize_t show_memory(struct device *d, char *buf)
3667{
3668 struct ipw2100_priv *priv = dev_get_drvdata(d);
3669 struct net_device *dev = priv->net_dev;
3670 static unsigned long loop = 0;
3671 int len = 0;
3672 u32 buffer[4];
3673 int i;
3674 char line[81];
3675
3676 if (loop >= 0x30000)
3677 loop = 0;
3678
3679 /* sysfs provides us PAGE_SIZE buffer */
3680 while (len < PAGE_SIZE - 128 && loop < 0x30000) {
3681
3682 if (priv->snapshot[0]) for (i = 0; i < 4; i++)
3683 buffer[i] = *(u32 *)SNAPSHOT_ADDR(loop + i * 4);
3684 else for (i = 0; i < 4; i++)
3685 read_nic_dword(dev, loop + i * 4, &buffer[i]);
3686
3687 if (priv->dump_raw)
3688 len += sprintf(buf + len,
3689 "%c%c%c%c"
3690 "%c%c%c%c"
3691 "%c%c%c%c"
3692 "%c%c%c%c",
3693 ((u8*)buffer)[0x0],
3694 ((u8*)buffer)[0x1],
3695 ((u8*)buffer)[0x2],
3696 ((u8*)buffer)[0x3],
3697 ((u8*)buffer)[0x4],
3698 ((u8*)buffer)[0x5],
3699 ((u8*)buffer)[0x6],
3700 ((u8*)buffer)[0x7],
3701 ((u8*)buffer)[0x8],
3702 ((u8*)buffer)[0x9],
3703 ((u8*)buffer)[0xa],
3704 ((u8*)buffer)[0xb],
3705 ((u8*)buffer)[0xc],
3706 ((u8*)buffer)[0xd],
3707 ((u8*)buffer)[0xe],
3708 ((u8*)buffer)[0xf]);
3709 else
3710 len += sprintf(buf + len, "%s\n",
3711 snprint_line(line, sizeof(line),
3712 (u8*)buffer, 16, loop));
3713 loop += 16;
3714 }
3715
3716 return len;
3717}
3718
3719static ssize_t store_memory(struct device *d, const char *buf, size_t count)
3720{
3721 struct ipw2100_priv *priv = dev_get_drvdata(d);
3722 struct net_device *dev = priv->net_dev;
3723 const char *p = buf;
3724
3725 if (count < 1)
3726 return count;
3727
3728 if (p[0] == '1' ||
3729 (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) {
3730 IPW_DEBUG_INFO("%s: Setting memory dump to RAW mode.\n",
3731 dev->name);
3732 priv->dump_raw = 1;
3733
3734 } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' &&
3735 tolower(p[1]) == 'f')) {
3736 IPW_DEBUG_INFO("%s: Setting memory dump to HEX mode.\n",
3737 dev->name);
3738 priv->dump_raw = 0;
3739
3740 } else if (tolower(p[0]) == 'r') {
3741 IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n",
3742 dev->name);
3743 ipw2100_snapshot_free(priv);
3744
3745 } else
3746 IPW_DEBUG_INFO("%s: Usage: 0|on = HEX, 1|off = RAW, "
3747 "reset = clear memory snapshot\n",
3748 dev->name);
3749
3750 return count;
3751}
3752static DEVICE_ATTR(memory, S_IWUSR|S_IRUGO, show_memory, store_memory);
3753
3754
3755static ssize_t show_ordinals(struct device *d, char *buf)
3756{
3757 struct ipw2100_priv *priv = dev_get_drvdata(d);
3758 u32 val = 0;
3759 int len = 0;
3760 u32 val_len;
3761 static int loop = 0;
3762
3763 if (loop >= sizeof(ord_data) / sizeof(*ord_data))
3764 loop = 0;
3765
3766 /* sysfs provides us PAGE_SIZE buffer */
3767 while (len < PAGE_SIZE - 128 &&
3768 loop < (sizeof(ord_data) / sizeof(*ord_data))) {
3769
3770 val_len = sizeof(u32);
3771
3772 if (ipw2100_get_ordinal(priv, ord_data[loop].index, &val,
3773 &val_len))
3774 len += sprintf(buf + len, "[0x%02X] = ERROR %s\n",
3775 ord_data[loop].index,
3776 ord_data[loop].desc);
3777 else
3778 len += sprintf(buf + len, "[0x%02X] = 0x%08X %s\n",
3779 ord_data[loop].index, val,
3780 ord_data[loop].desc);
3781 loop++;
3782 }
3783
3784 return len;
3785}
3786static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
3787
3788
3789static ssize_t show_stats(struct device *d, char *buf)
3790{
3791 struct ipw2100_priv *priv = dev_get_drvdata(d);
3792 char * out = buf;
3793
3794 out += sprintf(out, "interrupts: %d {tx: %d, rx: %d, other: %d}\n",
3795 priv->interrupts, priv->tx_interrupts,
3796 priv->rx_interrupts, priv->inta_other);
3797 out += sprintf(out, "firmware resets: %d\n", priv->resets);
3798 out += sprintf(out, "firmware hangs: %d\n", priv->hangs);
3799#ifdef CONFIG_IPW_DEBUG
3800 out += sprintf(out, "packet mismatch image: %s\n",
3801 priv->snapshot[0] ? "YES" : "NO");
3802#endif
3803
3804 return out - buf;
3805}
3806static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
3807
3808
3809int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3810{
3811 int err;
3812
3813 if (mode == priv->ieee->iw_mode)
3814 return 0;
3815
3816 err = ipw2100_disable_adapter(priv);
3817 if (err) {
3818 IPW_DEBUG_ERROR("%s: Could not disable adapter %d\n",
3819 priv->net_dev->name, err);
3820 return err;
3821 }
3822
3823 switch (mode) {
3824 case IW_MODE_INFRA:
3825 priv->net_dev->type = ARPHRD_ETHER;
3826 break;
3827 case IW_MODE_ADHOC:
3828 priv->net_dev->type = ARPHRD_ETHER;
3829 break;
3830#ifdef CONFIG_IPW2100_MONITOR
3831 case IW_MODE_MONITOR:
3832 priv->last_mode = priv->ieee->iw_mode;
3833 priv->net_dev->type = ARPHRD_IEEE80211;
3834 break;
3835#endif /* CONFIG_IPW2100_MONITOR */
3836 }
3837
3838 priv->ieee->iw_mode = mode;
3839
3840#ifdef CONFIG_PM
3841 /* Indicate ipw2100_download_firmware download firmware
3842 * from disk instead of memory. */
3843 ipw2100_firmware.version = 0;
3844#endif
3845
3846 printk(KERN_INFO "%s: Reseting on mode change.\n",
3847 priv->net_dev->name);
3848 priv->reset_backoff = 0;
3849 schedule_reset(priv);
3850
3851 return 0;
3852}
3853
3854static ssize_t show_internals(struct device *d, char *buf)
3855{
3856 struct ipw2100_priv *priv = dev_get_drvdata(d);
3857 int len = 0;
3858
3859#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" # y "\n", priv-> x)
3860
3861 if (priv->status & STATUS_ASSOCIATED)
3862 len += sprintf(buf + len, "connected: %lu\n",
3863 get_seconds() - priv->connect_start);
3864 else
3865 len += sprintf(buf + len, "not connected\n");
3866
3867 DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], p);
3868 DUMP_VAR(status, 08lx);
3869 DUMP_VAR(config, 08lx);
3870 DUMP_VAR(capability, 08lx);
3871
3872 len += sprintf(buf + len, "last_rtc: %lu\n", (unsigned long)priv->last_rtc);
3873
3874 DUMP_VAR(fatal_error, d);
3875 DUMP_VAR(stop_hang_check, d);
3876 DUMP_VAR(stop_rf_kill, d);
3877 DUMP_VAR(messages_sent, d);
3878
3879 DUMP_VAR(tx_pend_stat.value, d);
3880 DUMP_VAR(tx_pend_stat.hi, d);
3881
3882 DUMP_VAR(tx_free_stat.value, d);
3883 DUMP_VAR(tx_free_stat.lo, d);
3884
3885 DUMP_VAR(msg_free_stat.value, d);
3886 DUMP_VAR(msg_free_stat.lo, d);
3887
3888 DUMP_VAR(msg_pend_stat.value, d);
3889 DUMP_VAR(msg_pend_stat.hi, d);
3890
3891 DUMP_VAR(fw_pend_stat.value, d);
3892 DUMP_VAR(fw_pend_stat.hi, d);
3893
3894 DUMP_VAR(txq_stat.value, d);
3895 DUMP_VAR(txq_stat.lo, d);
3896
3897 DUMP_VAR(ieee->scans, d);
3898 DUMP_VAR(reset_backoff, d);
3899
3900 return len;
3901}
3902static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
3903
3904
3905static ssize_t show_bssinfo(struct device *d, char *buf)
3906{
3907 struct ipw2100_priv *priv = dev_get_drvdata(d);
3908 char essid[IW_ESSID_MAX_SIZE + 1];
3909 u8 bssid[ETH_ALEN];
3910 u32 chan = 0;
3911 char * out = buf;
3912 int length;
3913 int ret;
3914
3915 memset(essid, 0, sizeof(essid));
3916 memset(bssid, 0, sizeof(bssid));
3917
3918 length = IW_ESSID_MAX_SIZE;
3919 ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_SSID, essid, &length);
3920 if (ret)
3921 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
3922 __LINE__);
3923
3924 length = sizeof(bssid);
3925 ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID,
3926 bssid, &length);
3927 if (ret)
3928 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
3929 __LINE__);
3930
3931 length = sizeof(u32);
3932 ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &length);
3933 if (ret)
3934 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
3935 __LINE__);
3936
3937 out += sprintf(out, "ESSID: %s\n", essid);
3938 out += sprintf(out, "BSSID: %02x:%02x:%02x:%02x:%02x:%02x\n",
3939 bssid[0], bssid[1], bssid[2],
3940 bssid[3], bssid[4], bssid[5]);
3941 out += sprintf(out, "Channel: %d\n", chan);
3942
3943 return out - buf;
3944}
3945static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
3946
3947
3948
3949
3950#ifdef CONFIG_IPW_DEBUG
3951static ssize_t show_debug_level(struct device_driver *d, char *buf)
3952{
3953 return sprintf(buf, "0x%08X\n", ipw2100_debug_level);
3954}
3955
3956static ssize_t store_debug_level(struct device_driver *d, const char *buf,
3957 size_t count)
3958{
3959 char *p = (char *)buf;
3960 u32 val;
3961
3962 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
3963 p++;
3964 if (p[0] == 'x' || p[0] == 'X')
3965 p++;
3966 val = simple_strtoul(p, &p, 16);
3967 } else
3968 val = simple_strtoul(p, &p, 10);
3969 if (p == buf)
3970 IPW_DEBUG_INFO(DRV_NAME
3971 ": %s is not in hex or decimal form.\n", buf);
3972 else
3973 ipw2100_debug_level = val;
3974
3975 return strnlen(buf, count);
3976}
3977static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level,
3978 store_debug_level);
3979#endif /* CONFIG_IPW_DEBUG */
3980
3981
3982static ssize_t show_fatal_error(struct device *d, char *buf)
3983{
3984 struct ipw2100_priv *priv = dev_get_drvdata(d);
3985 char *out = buf;
3986 int i;
3987
3988 if (priv->fatal_error)
3989 out += sprintf(out, "0x%08X\n",
3990 priv->fatal_error);
3991 else
3992 out += sprintf(out, "0\n");
3993
3994 for (i = 1; i <= IPW2100_ERROR_QUEUE; i++) {
3995 if (!priv->fatal_errors[(priv->fatal_index - i) %
3996 IPW2100_ERROR_QUEUE])
3997 continue;
3998
3999 out += sprintf(out, "%d. 0x%08X\n", i,
4000 priv->fatal_errors[(priv->fatal_index - i) %
4001 IPW2100_ERROR_QUEUE]);
4002 }
4003
4004 return out - buf;
4005}
4006
4007static ssize_t store_fatal_error(struct device *d, const char *buf,
4008 size_t count)
4009{
4010 struct ipw2100_priv *priv = dev_get_drvdata(d);
4011 schedule_reset(priv);
4012 return count;
4013}
4014static DEVICE_ATTR(fatal_error, S_IWUSR|S_IRUGO, show_fatal_error, store_fatal_error);
4015
4016
4017static ssize_t show_scan_age(struct device *d, char *buf)
4018{
4019 struct ipw2100_priv *priv = dev_get_drvdata(d);
4020 return sprintf(buf, "%d\n", priv->ieee->scan_age);
4021}
4022
4023static ssize_t store_scan_age(struct device *d, const char *buf, size_t count)
4024{
4025 struct ipw2100_priv *priv = dev_get_drvdata(d);
4026 struct net_device *dev = priv->net_dev;
4027 char buffer[] = "00000000";
4028 unsigned long len =
4029 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
4030 unsigned long val;
4031 char *p = buffer;
4032
4033 IPW_DEBUG_INFO("enter\n");
4034
4035 strncpy(buffer, buf, len);
4036 buffer[len] = 0;
4037
4038 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
4039 p++;
4040 if (p[0] == 'x' || p[0] == 'X')
4041 p++;
4042 val = simple_strtoul(p, &p, 16);
4043 } else
4044 val = simple_strtoul(p, &p, 10);
4045 if (p == buffer) {
4046 IPW_DEBUG_INFO("%s: user supplied invalid value.\n",
4047 dev->name);
4048 } else {
4049 priv->ieee->scan_age = val;
4050 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
4051 }
4052
4053 IPW_DEBUG_INFO("exit\n");
4054 return len;
4055}
4056static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
4057
4058
4059static ssize_t show_rf_kill(struct device *d, char *buf)
4060{
4061 /* 0 - RF kill not enabled
4062 1 - SW based RF kill active (sysfs)
4063 2 - HW based RF kill active
4064 3 - Both HW and SW baed RF kill active */
4065 struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data;
4066 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
4067 (rf_kill_active(priv) ? 0x2 : 0x0);
4068 return sprintf(buf, "%i\n", val);
4069}
4070
4071static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4072{
4073 if ((disable_radio ? 1 : 0) ==
4074 (priv->status & STATUS_RF_KILL_SW ? 1 : 0))
4075 return 0 ;
4076
4077 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
4078 disable_radio ? "OFF" : "ON");
4079
4080 down(&priv->action_sem);
4081
4082 if (disable_radio) {
4083 priv->status |= STATUS_RF_KILL_SW;
4084 ipw2100_down(priv);
4085 } else {
4086 priv->status &= ~STATUS_RF_KILL_SW;
4087 if (rf_kill_active(priv)) {
4088 IPW_DEBUG_RF_KILL("Can not turn radio back on - "
4089 "disabled by HW switch\n");
4090 /* Make sure the RF_KILL check timer is running */
4091 priv->stop_rf_kill = 0;
4092 cancel_delayed_work(&priv->rf_kill);
4093 queue_delayed_work(priv->workqueue, &priv->rf_kill,
4094 HZ);
4095 } else
4096 schedule_reset(priv);
4097 }
4098
4099 up(&priv->action_sem);
4100 return 1;
4101}
4102
4103static ssize_t store_rf_kill(struct device *d, const char *buf, size_t count)
4104{
4105 struct ipw2100_priv *priv = dev_get_drvdata(d);
4106 ipw_radio_kill_sw(priv, buf[0] == '1');
4107 return count;
4108}
4109static DEVICE_ATTR(rf_kill, S_IWUSR|S_IRUGO, show_rf_kill, store_rf_kill);
4110
4111
4112static struct attribute *ipw2100_sysfs_entries[] = {
4113 &dev_attr_hardware.attr,
4114 &dev_attr_registers.attr,
4115 &dev_attr_ordinals.attr,
4116 &dev_attr_pci.attr,
4117 &dev_attr_stats.attr,
4118 &dev_attr_internals.attr,
4119 &dev_attr_bssinfo.attr,
4120 &dev_attr_memory.attr,
4121 &dev_attr_scan_age.attr,
4122 &dev_attr_fatal_error.attr,
4123 &dev_attr_rf_kill.attr,
4124 &dev_attr_cfg.attr,
4125 &dev_attr_status.attr,
4126 &dev_attr_capability.attr,
4127 NULL,
4128};
4129
4130static struct attribute_group ipw2100_attribute_group = {
4131 .attrs = ipw2100_sysfs_entries,
4132};
4133
4134
4135static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
4136{
4137 struct ipw2100_status_queue *q = &priv->status_queue;
4138
4139 IPW_DEBUG_INFO("enter\n");
4140
4141 q->size = entries * sizeof(struct ipw2100_status);
4142 q->drv = (struct ipw2100_status *)pci_alloc_consistent(
4143 priv->pci_dev, q->size, &q->nic);
4144 if (!q->drv) {
4145 IPW_DEBUG_WARNING(
4146 "Can not allocate status queue.\n");
4147 return -ENOMEM;
4148 }
4149
4150 memset(q->drv, 0, q->size);
4151
4152 IPW_DEBUG_INFO("exit\n");
4153
4154 return 0;
4155}
4156
4157static void status_queue_free(struct ipw2100_priv *priv)
4158{
4159 IPW_DEBUG_INFO("enter\n");
4160
4161 if (priv->status_queue.drv) {
4162 pci_free_consistent(
4163 priv->pci_dev, priv->status_queue.size,
4164 priv->status_queue.drv, priv->status_queue.nic);
4165 priv->status_queue.drv = NULL;
4166 }
4167
4168 IPW_DEBUG_INFO("exit\n");
4169}
4170
4171static int bd_queue_allocate(struct ipw2100_priv *priv,
4172 struct ipw2100_bd_queue *q, int entries)
4173{
4174 IPW_DEBUG_INFO("enter\n");
4175
4176 memset(q, 0, sizeof(struct ipw2100_bd_queue));
4177
4178 q->entries = entries;
4179 q->size = entries * sizeof(struct ipw2100_bd);
4180 q->drv = pci_alloc_consistent(priv->pci_dev, q->size, &q->nic);
4181 if (!q->drv) {
4182 IPW_DEBUG_INFO("can't allocate shared memory for buffer descriptors\n");
4183 return -ENOMEM;
4184 }
4185 memset(q->drv, 0, q->size);
4186
4187 IPW_DEBUG_INFO("exit\n");
4188
4189 return 0;
4190}
4191
4192static void bd_queue_free(struct ipw2100_priv *priv,
4193 struct ipw2100_bd_queue *q)
4194{
4195 IPW_DEBUG_INFO("enter\n");
4196
4197 if (!q)
4198 return;
4199
4200 if (q->drv) {
4201 pci_free_consistent(priv->pci_dev,
4202 q->size, q->drv, q->nic);
4203 q->drv = NULL;
4204 }
4205
4206 IPW_DEBUG_INFO("exit\n");
4207}
4208
4209static void bd_queue_initialize(
4210 struct ipw2100_priv *priv, struct ipw2100_bd_queue * q,
4211 u32 base, u32 size, u32 r, u32 w)
4212{
4213 IPW_DEBUG_INFO("enter\n");
4214
4215 IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv, q->nic);
4216
4217 write_register(priv->net_dev, base, q->nic);
4218 write_register(priv->net_dev, size, q->entries);
4219 write_register(priv->net_dev, r, q->oldest);
4220 write_register(priv->net_dev, w, q->next);
4221
4222 IPW_DEBUG_INFO("exit\n");
4223}
4224
4225static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
4226{
4227 if (priv->workqueue) {
4228 priv->stop_rf_kill = 1;
4229 priv->stop_hang_check = 1;
4230 cancel_delayed_work(&priv->reset_work);
4231 cancel_delayed_work(&priv->security_work);
4232 cancel_delayed_work(&priv->wx_event_work);
4233 cancel_delayed_work(&priv->hang_check);
4234 cancel_delayed_work(&priv->rf_kill);
4235 destroy_workqueue(priv->workqueue);
4236 priv->workqueue = NULL;
4237 }
4238}
4239
4240static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
4241{
4242 int i, j, err = -EINVAL;
4243 void *v;
4244 dma_addr_t p;
4245
4246 IPW_DEBUG_INFO("enter\n");
4247
4248 err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH);
4249 if (err) {
4250 IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n",
4251 priv->net_dev->name);
4252 return err;
4253 }
4254
4255 priv->tx_buffers = (struct ipw2100_tx_packet *)kmalloc(
4256 TX_PENDED_QUEUE_LENGTH * sizeof(struct ipw2100_tx_packet),
4257 GFP_ATOMIC);
4258 if (!priv->tx_buffers) {
4259 IPW_DEBUG_ERROR("%s: alloc failed form tx buffers.\n",
4260 priv->net_dev->name);
4261 bd_queue_free(priv, &priv->tx_queue);
4262 return -ENOMEM;
4263 }
4264
4265 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4266 v = pci_alloc_consistent(
4267 priv->pci_dev, sizeof(struct ipw2100_data_header), &p);
4268 if (!v) {
4269 IPW_DEBUG_ERROR("%s: PCI alloc failed for tx "
4270 "buffers.\n", priv->net_dev->name);
4271 err = -ENOMEM;
4272 break;
4273 }
4274
4275 priv->tx_buffers[i].type = DATA;
4276 priv->tx_buffers[i].info.d_struct.data = (struct ipw2100_data_header*)v;
4277 priv->tx_buffers[i].info.d_struct.data_phys = p;
4278 priv->tx_buffers[i].info.d_struct.txb = NULL;
4279 }
4280
4281 if (i == TX_PENDED_QUEUE_LENGTH)
4282 return 0;
4283
4284 for (j = 0; j < i; j++) {
4285 pci_free_consistent(
4286 priv->pci_dev,
4287 sizeof(struct ipw2100_data_header),
4288 priv->tx_buffers[j].info.d_struct.data,
4289 priv->tx_buffers[j].info.d_struct.data_phys);
4290 }
4291
4292 kfree(priv->tx_buffers);
4293 priv->tx_buffers = NULL;
4294
4295 return err;
4296}
4297
4298static void ipw2100_tx_initialize(struct ipw2100_priv *priv)
4299{
4300 int i;
4301
4302 IPW_DEBUG_INFO("enter\n");
4303
4304 /*
4305 * reinitialize packet info lists
4306 */
4307 INIT_LIST_HEAD(&priv->fw_pend_list);
4308 INIT_STAT(&priv->fw_pend_stat);
4309
4310 /*
4311 * reinitialize lists
4312 */
4313 INIT_LIST_HEAD(&priv->tx_pend_list);
4314 INIT_LIST_HEAD(&priv->tx_free_list);
4315 INIT_STAT(&priv->tx_pend_stat);
4316 INIT_STAT(&priv->tx_free_stat);
4317
4318 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4319 /* We simply drop any SKBs that have been queued for
4320 * transmit */
4321 if (priv->tx_buffers[i].info.d_struct.txb) {
4322 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb);
4323 priv->tx_buffers[i].info.d_struct.txb = NULL;
4324 }
4325
4326 list_add_tail(&priv->tx_buffers[i].list, &priv->tx_free_list);
4327 }
4328
4329 SET_STAT(&priv->tx_free_stat, i);
4330
4331 priv->tx_queue.oldest = 0;
4332 priv->tx_queue.available = priv->tx_queue.entries;
4333 priv->tx_queue.next = 0;
4334 INIT_STAT(&priv->txq_stat);
4335 SET_STAT(&priv->txq_stat, priv->tx_queue.available);
4336
4337 bd_queue_initialize(priv, &priv->tx_queue,
4338 IPW_MEM_HOST_SHARED_TX_QUEUE_BD_BASE,
4339 IPW_MEM_HOST_SHARED_TX_QUEUE_BD_SIZE,
4340 IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX,
4341 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX);
4342
4343 IPW_DEBUG_INFO("exit\n");
4344
4345}
4346
4347static void ipw2100_tx_free(struct ipw2100_priv *priv)
4348{
4349 int i;
4350
4351 IPW_DEBUG_INFO("enter\n");
4352
4353 bd_queue_free(priv, &priv->tx_queue);
4354
4355 if (!priv->tx_buffers)
4356 return;
4357
4358 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4359 if (priv->tx_buffers[i].info.d_struct.txb) {
4360 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb);
4361 priv->tx_buffers[i].info.d_struct.txb = NULL;
4362 }
4363 if (priv->tx_buffers[i].info.d_struct.data)
4364 pci_free_consistent(
4365 priv->pci_dev,
4366 sizeof(struct ipw2100_data_header),
4367 priv->tx_buffers[i].info.d_struct.data,
4368 priv->tx_buffers[i].info.d_struct.data_phys);
4369 }
4370
4371 kfree(priv->tx_buffers);
4372 priv->tx_buffers = NULL;
4373
4374 IPW_DEBUG_INFO("exit\n");
4375}
4376
4377
4378
4379static int ipw2100_rx_allocate(struct ipw2100_priv *priv)
4380{
4381 int i, j, err = -EINVAL;
4382
4383 IPW_DEBUG_INFO("enter\n");
4384
4385 err = bd_queue_allocate(priv, &priv->rx_queue, RX_QUEUE_LENGTH);
4386 if (err) {
4387 IPW_DEBUG_INFO("failed bd_queue_allocate\n");
4388 return err;
4389 }
4390
4391 err = status_queue_allocate(priv, RX_QUEUE_LENGTH);
4392 if (err) {
4393 IPW_DEBUG_INFO("failed status_queue_allocate\n");
4394 bd_queue_free(priv, &priv->rx_queue);
4395 return err;
4396 }
4397
4398 /*
4399 * allocate packets
4400 */
4401 priv->rx_buffers = (struct ipw2100_rx_packet *)
4402 kmalloc(RX_QUEUE_LENGTH * sizeof(struct ipw2100_rx_packet),
4403 GFP_KERNEL);
4404 if (!priv->rx_buffers) {
4405 IPW_DEBUG_INFO("can't allocate rx packet buffer table\n");
4406
4407 bd_queue_free(priv, &priv->rx_queue);
4408
4409 status_queue_free(priv);
4410
4411 return -ENOMEM;
4412 }
4413
4414 for (i = 0; i < RX_QUEUE_LENGTH; i++) {
4415 struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
4416
4417 err = ipw2100_alloc_skb(priv, packet);
4418 if (unlikely(err)) {
4419 err = -ENOMEM;
4420 break;
4421 }
4422
4423 /* The BD holds the cache aligned address */
4424 priv->rx_queue.drv[i].host_addr = packet->dma_addr;
4425 priv->rx_queue.drv[i].buf_length = IPW_RX_NIC_BUFFER_LENGTH;
4426 priv->status_queue.drv[i].status_fields = 0;
4427 }
4428
4429 if (i == RX_QUEUE_LENGTH)
4430 return 0;
4431
4432 for (j = 0; j < i; j++) {
4433 pci_unmap_single(priv->pci_dev, priv->rx_buffers[j].dma_addr,
4434 sizeof(struct ipw2100_rx_packet),
4435 PCI_DMA_FROMDEVICE);
4436 dev_kfree_skb(priv->rx_buffers[j].skb);
4437 }
4438
4439 kfree(priv->rx_buffers);
4440 priv->rx_buffers = NULL;
4441
4442 bd_queue_free(priv, &priv->rx_queue);
4443
4444 status_queue_free(priv);
4445
4446 return err;
4447}
4448
4449static void ipw2100_rx_initialize(struct ipw2100_priv *priv)
4450{
4451 IPW_DEBUG_INFO("enter\n");
4452
4453 priv->rx_queue.oldest = 0;
4454 priv->rx_queue.available = priv->rx_queue.entries - 1;
4455 priv->rx_queue.next = priv->rx_queue.entries - 1;
4456
4457 INIT_STAT(&priv->rxq_stat);
4458 SET_STAT(&priv->rxq_stat, priv->rx_queue.available);
4459
4460 bd_queue_initialize(priv, &priv->rx_queue,
4461 IPW_MEM_HOST_SHARED_RX_BD_BASE,
4462 IPW_MEM_HOST_SHARED_RX_BD_SIZE,
4463 IPW_MEM_HOST_SHARED_RX_READ_INDEX,
4464 IPW_MEM_HOST_SHARED_RX_WRITE_INDEX);
4465
4466 /* set up the status queue */
4467 write_register(priv->net_dev, IPW_MEM_HOST_SHARED_RX_STATUS_BASE,
4468 priv->status_queue.nic);
4469
4470 IPW_DEBUG_INFO("exit\n");
4471}
4472
4473static void ipw2100_rx_free(struct ipw2100_priv *priv)
4474{
4475 int i;
4476
4477 IPW_DEBUG_INFO("enter\n");
4478
4479 bd_queue_free(priv, &priv->rx_queue);
4480 status_queue_free(priv);
4481
4482 if (!priv->rx_buffers)
4483 return;
4484
4485 for (i = 0; i < RX_QUEUE_LENGTH; i++) {
4486 if (priv->rx_buffers[i].rxp) {
4487 pci_unmap_single(priv->pci_dev,
4488 priv->rx_buffers[i].dma_addr,
4489 sizeof(struct ipw2100_rx),
4490 PCI_DMA_FROMDEVICE);
4491 dev_kfree_skb(priv->rx_buffers[i].skb);
4492 }
4493 }
4494
4495 kfree(priv->rx_buffers);
4496 priv->rx_buffers = NULL;
4497
4498 IPW_DEBUG_INFO("exit\n");
4499}
4500
4501static int ipw2100_read_mac_address(struct ipw2100_priv *priv)
4502{
4503 u32 length = ETH_ALEN;
4504 u8 mac[ETH_ALEN];
4505
4506 int err;
4507
4508 err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC,
4509 mac, &length);
4510 if (err) {
4511 IPW_DEBUG_INFO("MAC address read failed\n");
4512 return -EIO;
4513 }
4514 IPW_DEBUG_INFO("card MAC is %02X:%02X:%02X:%02X:%02X:%02X\n",
4515 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4516
4517 memcpy(priv->net_dev->dev_addr, mac, ETH_ALEN);
4518
4519 return 0;
4520}
4521
4522/********************************************************************
4523 *
4524 * Firmware Commands
4525 *
4526 ********************************************************************/
4527
4528int ipw2100_set_mac_address(struct ipw2100_priv *priv, int batch_mode)
4529{
4530 struct host_command cmd = {
4531 .host_command = ADAPTER_ADDRESS,
4532 .host_command_sequence = 0,
4533 .host_command_length = ETH_ALEN
4534 };
4535 int err;
4536
4537 IPW_DEBUG_HC("SET_MAC_ADDRESS\n");
4538
4539 IPW_DEBUG_INFO("enter\n");
4540
4541 if (priv->config & CFG_CUSTOM_MAC) {
4542 memcpy(cmd.host_command_parameters, priv->mac_addr,
4543 ETH_ALEN);
4544 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
4545 } else
4546 memcpy(cmd.host_command_parameters, priv->net_dev->dev_addr,
4547 ETH_ALEN);
4548
4549 err = ipw2100_hw_send_command(priv, &cmd);
4550
4551 IPW_DEBUG_INFO("exit\n");
4552 return err;
4553}
4554
4555int ipw2100_set_port_type(struct ipw2100_priv *priv, u32 port_type,
4556 int batch_mode)
4557{
4558 struct host_command cmd = {
4559 .host_command = PORT_TYPE,
4560 .host_command_sequence = 0,
4561 .host_command_length = sizeof(u32)
4562 };
4563 int err;
4564
4565 switch (port_type) {
4566 case IW_MODE_INFRA:
4567 cmd.host_command_parameters[0] = IPW_BSS;
4568 break;
4569 case IW_MODE_ADHOC:
4570 cmd.host_command_parameters[0] = IPW_IBSS;
4571 break;
4572 }
4573
4574 IPW_DEBUG_HC("PORT_TYPE: %s\n",
4575 port_type == IPW_IBSS ? "Ad-Hoc" : "Managed");
4576
4577 if (!batch_mode) {
4578 err = ipw2100_disable_adapter(priv);
4579 if (err) {
4580 IPW_DEBUG_ERROR("%s: Could not disable adapter %d\n",
4581 priv->net_dev->name, err);
4582 return err;
4583 }
4584 }
4585
4586 /* send cmd to firmware */
4587 err = ipw2100_hw_send_command(priv, &cmd);
4588
4589 if (!batch_mode)
4590 ipw2100_enable_adapter(priv);
4591
4592 return err;
4593}
4594
4595
4596int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel, int batch_mode)
4597{
4598 struct host_command cmd = {
4599 .host_command = CHANNEL,
4600 .host_command_sequence = 0,
4601 .host_command_length = sizeof(u32)
4602 };
4603 int err;
4604
4605 cmd.host_command_parameters[0] = channel;
4606
4607 IPW_DEBUG_HC("CHANNEL: %d\n", channel);
4608
4609 /* If BSS then we don't support channel selection */
4610 if (priv->ieee->iw_mode == IW_MODE_INFRA)
4611 return 0;
4612
4613 if ((channel != 0) &&
4614 ((channel < REG_MIN_CHANNEL) || (channel > REG_MAX_CHANNEL)))
4615 return -EINVAL;
4616
4617 if (!batch_mode) {
4618 err = ipw2100_disable_adapter(priv);
4619 if (err)
4620 return err;
4621 }
4622
4623 err = ipw2100_hw_send_command(priv, &cmd);
4624 if (err) {
4625 IPW_DEBUG_INFO("Failed to set channel to %d",
4626 channel);
4627 return err;
4628 }
4629
4630 if (channel)
4631 priv->config |= CFG_STATIC_CHANNEL;
4632 else
4633 priv->config &= ~CFG_STATIC_CHANNEL;
4634
4635 priv->channel = channel;
4636
4637 if (!batch_mode) {
4638 err = ipw2100_enable_adapter(priv);
4639 if (err)
4640 return err;
4641 }
4642
4643 return 0;
4644}
4645
4646int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode)
4647{
4648 struct host_command cmd = {
4649 .host_command = SYSTEM_CONFIG,
4650 .host_command_sequence = 0,
4651 .host_command_length = 12,
4652 };
4653 u32 ibss_mask, len = sizeof(u32);
4654 int err;
4655
4656 /* Set system configuration */
4657
4658 if (!batch_mode) {
4659 err = ipw2100_disable_adapter(priv);
4660 if (err)
4661 return err;
4662 }
4663
4664 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
4665 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_AUTO_START;
4666
4667 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_MASK |
4668 IPW_CFG_BSS_MASK |
4669 IPW_CFG_802_1x_ENABLE;
4670
4671 if (!(priv->config & CFG_LONG_PREAMBLE))
4672 cmd.host_command_parameters[0] |= IPW_CFG_PREAMBLE_AUTO;
4673
4674 err = ipw2100_get_ordinal(priv,
4675 IPW_ORD_EEPROM_IBSS_11B_CHANNELS,
4676 &ibss_mask, &len);
4677 if (err)
4678 ibss_mask = IPW_IBSS_11B_DEFAULT_MASK;
4679
4680 cmd.host_command_parameters[1] = REG_CHANNEL_MASK;
4681 cmd.host_command_parameters[2] = REG_CHANNEL_MASK & ibss_mask;
4682
4683 /* 11b only */
4684 /*cmd.host_command_parameters[0] |= DIVERSITY_ANTENNA_A;*/
4685
4686 err = ipw2100_hw_send_command(priv, &cmd);
4687 if (err)
4688 return err;
4689
4690/* If IPv6 is configured in the kernel then we don't want to filter out all
4691 * of the multicast packets as IPv6 needs some. */
4692#if !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE)
4693 cmd.host_command = ADD_MULTICAST;
4694 cmd.host_command_sequence = 0;
4695 cmd.host_command_length = 0;
4696
4697 ipw2100_hw_send_command(priv, &cmd);
4698#endif
4699 if (!batch_mode) {
4700 err = ipw2100_enable_adapter(priv);
4701 if (err)
4702 return err;
4703 }
4704
4705 return 0;
4706}
4707
4708int ipw2100_set_tx_rates(struct ipw2100_priv *priv, u32 rate, int batch_mode)
4709{
4710 struct host_command cmd = {
4711 .host_command = BASIC_TX_RATES,
4712 .host_command_sequence = 0,
4713 .host_command_length = 4
4714 };
4715 int err;
4716
4717 cmd.host_command_parameters[0] = rate & TX_RATE_MASK;
4718
4719 if (!batch_mode) {
4720 err = ipw2100_disable_adapter(priv);
4721 if (err)
4722 return err;
4723 }
4724
4725 /* Set BASIC TX Rate first */
4726 ipw2100_hw_send_command(priv, &cmd);
4727
4728 /* Set TX Rate */
4729 cmd.host_command = TX_RATES;
4730 ipw2100_hw_send_command(priv, &cmd);
4731
4732 /* Set MSDU TX Rate */
4733 cmd.host_command = MSDU_TX_RATES;
4734 ipw2100_hw_send_command(priv, &cmd);
4735
4736 if (!batch_mode) {
4737 err = ipw2100_enable_adapter(priv);
4738 if (err)
4739 return err;
4740 }
4741
4742 priv->tx_rates = rate;
4743
4744 return 0;
4745}
4746
4747int ipw2100_set_power_mode(struct ipw2100_priv *priv,
4748 int power_level)
4749{
4750 struct host_command cmd = {
4751 .host_command = POWER_MODE,
4752 .host_command_sequence = 0,
4753 .host_command_length = 4
4754 };
4755 int err;
4756
4757 cmd.host_command_parameters[0] = power_level;
4758
4759 err = ipw2100_hw_send_command(priv, &cmd);
4760 if (err)
4761 return err;
4762
4763 if (power_level == IPW_POWER_MODE_CAM)
4764 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
4765 else
4766 priv->power_mode = IPW_POWER_ENABLED | power_level;
4767
4768#ifdef CONFIG_IPW2100_TX_POWER
4769 if (priv->port_type == IBSS &&
4770 priv->adhoc_power != DFTL_IBSS_TX_POWER) {
4771 /* Set beacon interval */
4772 cmd.host_command = TX_POWER_INDEX;
4773 cmd.host_command_parameters[0] = (u32)priv->adhoc_power;
4774
4775 err = ipw2100_hw_send_command(priv, &cmd);
4776 if (err)
4777 return err;
4778 }
4779#endif
4780
4781 return 0;
4782}
4783
4784
4785int ipw2100_set_rts_threshold(struct ipw2100_priv *priv, u32 threshold)
4786{
4787 struct host_command cmd = {
4788 .host_command = RTS_THRESHOLD,
4789 .host_command_sequence = 0,
4790 .host_command_length = 4
4791 };
4792 int err;
4793
4794 if (threshold & RTS_DISABLED)
4795 cmd.host_command_parameters[0] = MAX_RTS_THRESHOLD;
4796 else
4797 cmd.host_command_parameters[0] = threshold & ~RTS_DISABLED;
4798
4799 err = ipw2100_hw_send_command(priv, &cmd);
4800 if (err)
4801 return err;
4802
4803 priv->rts_threshold = threshold;
4804
4805 return 0;
4806}
4807
4808#if 0
4809int ipw2100_set_fragmentation_threshold(struct ipw2100_priv *priv,
4810 u32 threshold, int batch_mode)
4811{
4812 struct host_command cmd = {
4813 .host_command = FRAG_THRESHOLD,
4814 .host_command_sequence = 0,
4815 .host_command_length = 4,
4816 .host_command_parameters[0] = 0,
4817 };
4818 int err;
4819
4820 if (!batch_mode) {
4821 err = ipw2100_disable_adapter(priv);
4822 if (err)
4823 return err;
4824 }
4825
4826 if (threshold == 0)
4827 threshold = DEFAULT_FRAG_THRESHOLD;
4828 else {
4829 threshold = max(threshold, MIN_FRAG_THRESHOLD);
4830 threshold = min(threshold, MAX_FRAG_THRESHOLD);
4831 }
4832
4833 cmd.host_command_parameters[0] = threshold;
4834
4835 IPW_DEBUG_HC("FRAG_THRESHOLD: %u\n", threshold);
4836
4837 err = ipw2100_hw_send_command(priv, &cmd);
4838
4839 if (!batch_mode)
4840 ipw2100_enable_adapter(priv);
4841
4842 if (!err)
4843 priv->frag_threshold = threshold;
4844
4845 return err;
4846}
4847#endif
4848
4849int ipw2100_set_short_retry(struct ipw2100_priv *priv, u32 retry)
4850{
4851 struct host_command cmd = {
4852 .host_command = SHORT_RETRY_LIMIT,
4853 .host_command_sequence = 0,
4854 .host_command_length = 4
4855 };
4856 int err;
4857
4858 cmd.host_command_parameters[0] = retry;
4859
4860 err = ipw2100_hw_send_command(priv, &cmd);
4861 if (err)
4862 return err;
4863
4864 priv->short_retry_limit = retry;
4865
4866 return 0;
4867}
4868
4869int ipw2100_set_long_retry(struct ipw2100_priv *priv, u32 retry)
4870{
4871 struct host_command cmd = {
4872 .host_command = LONG_RETRY_LIMIT,
4873 .host_command_sequence = 0,
4874 .host_command_length = 4
4875 };
4876 int err;
4877
4878 cmd.host_command_parameters[0] = retry;
4879
4880 err = ipw2100_hw_send_command(priv, &cmd);
4881 if (err)
4882 return err;
4883
4884 priv->long_retry_limit = retry;
4885
4886 return 0;
4887}
4888
4889
4890int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4891 int batch_mode)
4892{
4893 struct host_command cmd = {
4894 .host_command = MANDATORY_BSSID,
4895 .host_command_sequence = 0,
4896 .host_command_length = (bssid == NULL) ? 0 : ETH_ALEN
4897 };
4898 int err;
4899
4900#ifdef CONFIG_IPW_DEBUG
4901 if (bssid != NULL)
4902 IPW_DEBUG_HC(
4903 "MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n",
4904 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4],
4905 bssid[5]);
4906 else
4907 IPW_DEBUG_HC("MANDATORY_BSSID: <clear>\n");
4908#endif
4909 /* if BSSID is empty then we disable mandatory bssid mode */
4910 if (bssid != NULL)
4911 memcpy((u8 *)cmd.host_command_parameters, bssid, ETH_ALEN);
4912
4913 if (!batch_mode) {
4914 err = ipw2100_disable_adapter(priv);
4915 if (err)
4916 return err;
4917 }
4918
4919 err = ipw2100_hw_send_command(priv, &cmd);
4920
4921 if (!batch_mode)
4922 ipw2100_enable_adapter(priv);
4923
4924 return err;
4925}
4926
4927#ifdef CONFIG_IEEE80211_WPA
4928static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
4929{
4930 struct host_command cmd = {
4931 .host_command = DISASSOCIATION_BSSID,
4932 .host_command_sequence = 0,
4933 .host_command_length = ETH_ALEN
4934 };
4935 int err;
4936 int len;
4937
4938 IPW_DEBUG_HC("DISASSOCIATION_BSSID\n");
4939
4940 len = ETH_ALEN;
4941 /* The Firmware currently ignores the BSSID and just disassociates from
4942 * the currently associated AP -- but in the off chance that a future
4943 * firmware does use the BSSID provided here, we go ahead and try and
4944 * set it to the currently associated AP's BSSID */
4945 memcpy(cmd.host_command_parameters, priv->bssid, ETH_ALEN);
4946
4947 err = ipw2100_hw_send_command(priv, &cmd);
4948
4949 return err;
4950}
4951#endif
4952
4953/*
4954 * Pseudo code for setting up wpa_frame:
4955 */
4956#if 0
4957void x(struct ieee80211_assoc_frame *wpa_assoc)
4958{
4959 struct ipw2100_wpa_assoc_frame frame;
4960 frame->fixed_ie_mask = IPW_WPA_CAPABILTIES |
4961 IPW_WPA_LISTENINTERVAL |
4962 IPW_WPA_AP_ADDRESS;
4963 frame->capab_info = wpa_assoc->capab_info;
4964 frame->lisen_interval = wpa_assoc->listent_interval;
4965 memcpy(frame->current_ap, wpa_assoc->current_ap, ETH_ALEN);
4966
4967 /* UNKNOWN -- I'm not postivive about this part; don't have any WPA
4968 * setup here to test it with.
4969 *
4970 * Walk the IEs in the wpa_assoc and figure out the total size of all
4971 * that data. Stick that into frame->var_ie_len. Then memcpy() all of
4972 * the IEs from wpa_frame into frame.
4973 */
4974 frame->var_ie_len = calculate_ie_len(wpa_assoc);
4975 memcpy(frame->var_ie, wpa_assoc->variable, frame->var_ie_len);
4976
4977 ipw2100_set_wpa_ie(priv, &frame, 0);
4978}
4979#endif
4980
4981
4982
4983
4984static int ipw2100_set_wpa_ie(struct ipw2100_priv *,
4985 struct ipw2100_wpa_assoc_frame *, int)
4986__attribute__ ((unused));
4987
4988static int ipw2100_set_wpa_ie(struct ipw2100_priv *priv,
4989 struct ipw2100_wpa_assoc_frame *wpa_frame,
4990 int batch_mode)
4991{
4992 struct host_command cmd = {
4993 .host_command = SET_WPA_IE,
4994 .host_command_sequence = 0,
4995 .host_command_length = sizeof(struct ipw2100_wpa_assoc_frame),
4996 };
4997 int err;
4998
4999 IPW_DEBUG_HC("SET_WPA_IE\n");
5000
5001 if (!batch_mode) {
5002 err = ipw2100_disable_adapter(priv);
5003 if (err)
5004 return err;
5005 }
5006
5007 memcpy(cmd.host_command_parameters, wpa_frame,
5008 sizeof(struct ipw2100_wpa_assoc_frame));
5009
5010 err = ipw2100_hw_send_command(priv, &cmd);
5011
5012 if (!batch_mode) {
5013 if (ipw2100_enable_adapter(priv))
5014 err = -EIO;
5015 }
5016
5017 return err;
5018}
5019
5020struct security_info_params {
5021 u32 allowed_ciphers;
5022 u16 version;
5023 u8 auth_mode;
5024 u8 replay_counters_number;
5025 u8 unicast_using_group;
5026} __attribute__ ((packed));
5027
5028int ipw2100_set_security_information(struct ipw2100_priv *priv,
5029 int auth_mode,
5030 int security_level,
5031 int unicast_using_group,
5032 int batch_mode)
5033{
5034 struct host_command cmd = {
5035 .host_command = SET_SECURITY_INFORMATION,
5036 .host_command_sequence = 0,
5037 .host_command_length = sizeof(struct security_info_params)
5038 };
5039 struct security_info_params *security =
5040 (struct security_info_params *)&cmd.host_command_parameters;
5041 int err;
5042 memset(security, 0, sizeof(*security));
5043
5044 /* If shared key AP authentication is turned on, then we need to
5045 * configure the firmware to try and use it.
5046 *
5047 * Actual data encryption/decryption is handled by the host. */
5048 security->auth_mode = auth_mode;
5049 security->unicast_using_group = unicast_using_group;
5050
5051 switch (security_level) {
5052 default:
5053 case SEC_LEVEL_0:
5054 security->allowed_ciphers = IPW_NONE_CIPHER;
5055 break;
5056 case SEC_LEVEL_1:
5057 security->allowed_ciphers = IPW_WEP40_CIPHER |
5058 IPW_WEP104_CIPHER;
5059 break;
5060 case SEC_LEVEL_2:
5061 security->allowed_ciphers = IPW_WEP40_CIPHER |
5062 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER;
5063 break;
5064 case SEC_LEVEL_2_CKIP:
5065 security->allowed_ciphers = IPW_WEP40_CIPHER |
5066 IPW_WEP104_CIPHER | IPW_CKIP_CIPHER;
5067 break;
5068 case SEC_LEVEL_3:
5069 security->allowed_ciphers = IPW_WEP40_CIPHER |
5070 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER | IPW_CCMP_CIPHER;
5071 break;
5072 }
5073
5074 IPW_DEBUG_HC(
5075 "SET_SECURITY_INFORMATION: auth:%d cipher:0x%02X (level %d)\n",
5076 security->auth_mode, security->allowed_ciphers, security_level);
5077
5078 security->replay_counters_number = 0;
5079
5080 if (!batch_mode) {
5081 err = ipw2100_disable_adapter(priv);
5082 if (err)
5083 return err;
5084 }
5085
5086 err = ipw2100_hw_send_command(priv, &cmd);
5087
5088 if (!batch_mode)
5089 ipw2100_enable_adapter(priv);
5090
5091 return err;
5092}
5093
5094int ipw2100_set_tx_power(struct ipw2100_priv *priv,
5095 u32 tx_power)
5096{
5097 struct host_command cmd = {
5098 .host_command = TX_POWER_INDEX,
5099 .host_command_sequence = 0,
5100 .host_command_length = 4
5101 };
5102 int err = 0;
5103
5104 cmd.host_command_parameters[0] = tx_power;
5105
5106 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
5107 err = ipw2100_hw_send_command(priv, &cmd);
5108 if (!err)
5109 priv->tx_power = tx_power;
5110
5111 return 0;
5112}
5113
5114int ipw2100_set_ibss_beacon_interval(struct ipw2100_priv *priv,
5115 u32 interval, int batch_mode)
5116{
5117 struct host_command cmd = {
5118 .host_command = BEACON_INTERVAL,
5119 .host_command_sequence = 0,
5120 .host_command_length = 4
5121 };
5122 int err;
5123
5124 cmd.host_command_parameters[0] = interval;
5125
5126 IPW_DEBUG_INFO("enter\n");
5127
5128 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5129 if (!batch_mode) {
5130 err = ipw2100_disable_adapter(priv);
5131 if (err)
5132 return err;
5133 }
5134
5135 ipw2100_hw_send_command(priv, &cmd);
5136
5137 if (!batch_mode) {
5138 err = ipw2100_enable_adapter(priv);
5139 if (err)
5140 return err;
5141 }
5142 }
5143
5144 IPW_DEBUG_INFO("exit\n");
5145
5146 return 0;
5147}
5148
5149
5150void ipw2100_queues_initialize(struct ipw2100_priv *priv)
5151{
5152 ipw2100_tx_initialize(priv);
5153 ipw2100_rx_initialize(priv);
5154 ipw2100_msg_initialize(priv);
5155}
5156
5157void ipw2100_queues_free(struct ipw2100_priv *priv)
5158{
5159 ipw2100_tx_free(priv);
5160 ipw2100_rx_free(priv);
5161 ipw2100_msg_free(priv);
5162}
5163
5164int ipw2100_queues_allocate(struct ipw2100_priv *priv)
5165{
5166 if (ipw2100_tx_allocate(priv) ||
5167 ipw2100_rx_allocate(priv) ||
5168 ipw2100_msg_allocate(priv))
5169 goto fail;
5170
5171 return 0;
5172
5173 fail:
5174 ipw2100_tx_free(priv);
5175 ipw2100_rx_free(priv);
5176 ipw2100_msg_free(priv);
5177 return -ENOMEM;
5178}
5179
5180#define IPW_PRIVACY_CAPABLE 0x0008
5181
5182static int ipw2100_set_wep_flags(struct ipw2100_priv *priv, u32 flags,
5183 int batch_mode)
5184{
5185 struct host_command cmd = {
5186 .host_command = WEP_FLAGS,
5187 .host_command_sequence = 0,
5188 .host_command_length = 4
5189 };
5190 int err;
5191
5192 cmd.host_command_parameters[0] = flags;
5193
5194 IPW_DEBUG_HC("WEP_FLAGS: flags = 0x%08X\n", flags);
5195
5196 if (!batch_mode) {
5197 err = ipw2100_disable_adapter(priv);
5198 if (err) {
5199 IPW_DEBUG_ERROR("%s: Could not disable adapter %d\n",
5200 priv->net_dev->name, err);
5201 return err;
5202 }
5203 }
5204
5205 /* send cmd to firmware */
5206 err = ipw2100_hw_send_command(priv, &cmd);
5207
5208 if (!batch_mode)
5209 ipw2100_enable_adapter(priv);
5210
5211 return err;
5212}
5213
5214struct ipw2100_wep_key {
5215 u8 idx;
5216 u8 len;
5217 u8 key[13];
5218};
5219
5220/* Macros to ease up priting WEP keys */
5221#define WEP_FMT_64 "%02X%02X%02X%02X-%02X"
5222#define WEP_FMT_128 "%02X%02X%02X%02X-%02X%02X%02X%02X-%02X%02X%02X"
5223#define WEP_STR_64(x) x[0],x[1],x[2],x[3],x[4]
5224#define WEP_STR_128(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10]
5225
5226
5227/**
5228 * Set a the wep key
5229 *
5230 * @priv: struct to work on
5231 * @idx: index of the key we want to set
5232 * @key: ptr to the key data to set
5233 * @len: length of the buffer at @key
5234 * @batch_mode: FIXME perform the operation in batch mode, not
5235 * disabling the device.
5236 *
5237 * @returns 0 if OK, < 0 errno code on error.
5238 *
5239 * Fill out a command structure with the new wep key, length an
5240 * index and send it down the wire.
5241 */
5242static int ipw2100_set_key(struct ipw2100_priv *priv,
5243 int idx, char *key, int len, int batch_mode)
5244{
5245 int keylen = len ? (len <= 5 ? 5 : 13) : 0;
5246 struct host_command cmd = {
5247 .host_command = WEP_KEY_INFO,
5248 .host_command_sequence = 0,
5249 .host_command_length = sizeof(struct ipw2100_wep_key),
5250 };
5251 struct ipw2100_wep_key *wep_key = (void*)cmd.host_command_parameters;
5252 int err;
5253
5254 IPW_DEBUG_HC("WEP_KEY_INFO: index = %d, len = %d/%d\n",
5255 idx, keylen, len);
5256
5257 /* NOTE: We don't check cached values in case the firmware was reset
5258 * or some other problem is occuring. If the user is setting the key,
5259 * then we push the change */
5260
5261 wep_key->idx = idx;
5262 wep_key->len = keylen;
5263
5264 if (keylen) {
5265 memcpy(wep_key->key, key, len);
5266 memset(wep_key->key + len, 0, keylen - len);
5267 }
5268
5269 /* Will be optimized out on debug not being configured in */
5270 if (keylen == 0)
5271 IPW_DEBUG_WEP("%s: Clearing key %d\n",
5272 priv->net_dev->name, wep_key->idx);
5273 else if (keylen == 5)
5274 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_64 "\n",
5275 priv->net_dev->name, wep_key->idx, wep_key->len,
5276 WEP_STR_64(wep_key->key));
5277 else
5278 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_128
5279 "\n",
5280 priv->net_dev->name, wep_key->idx, wep_key->len,
5281 WEP_STR_128(wep_key->key));
5282
5283 if (!batch_mode) {
5284 err = ipw2100_disable_adapter(priv);
5285 /* FIXME: IPG: shouldn't this prink be in _disable_adapter()? */
5286 if (err) {
5287 IPW_DEBUG_ERROR("%s: Could not disable adapter %d\n",
5288 priv->net_dev->name, err);
5289 return err;
5290 }
5291 }
5292
5293 /* send cmd to firmware */
5294 err = ipw2100_hw_send_command(priv, &cmd);
5295
5296 if (!batch_mode) {
5297 int err2 = ipw2100_enable_adapter(priv);
5298 if (err == 0)
5299 err = err2;
5300 }
5301 return err;
5302}
5303
5304static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5305 int idx, int batch_mode)
5306{
5307 struct host_command cmd = {
5308 .host_command = WEP_KEY_INDEX,
5309 .host_command_sequence = 0,
5310 .host_command_length = 4,
5311 .host_command_parameters[0] = idx,
5312 };
5313 int err;
5314
5315 IPW_DEBUG_HC("WEP_KEY_INDEX: index = %d\n", idx);
5316
5317 if (idx < 0 || idx > 3)
5318 return -EINVAL;
5319
5320 if (!batch_mode) {
5321 err = ipw2100_disable_adapter(priv);
5322 if (err) {
5323 IPW_DEBUG_ERROR("%s: Could not disable adapter %d\n",
5324 priv->net_dev->name, err);
5325 return err;
5326 }
5327 }
5328
5329 /* send cmd to firmware */
5330 err = ipw2100_hw_send_command(priv, &cmd);
5331
5332 if (!batch_mode)
5333 ipw2100_enable_adapter(priv);
5334
5335 return err;
5336}
5337
5338
5339static int ipw2100_configure_security(struct ipw2100_priv *priv,
5340 int batch_mode)
5341{
5342 int i, err, auth_mode, sec_level, use_group;
5343
5344 if (!(priv->status & STATUS_RUNNING))
5345 return 0;
5346
5347 if (!batch_mode) {
5348 err = ipw2100_disable_adapter(priv);
5349 if (err)
5350 return err;
5351 }
5352
5353 if (!priv->sec.enabled) {
5354 err = ipw2100_set_security_information(
5355 priv, IPW_AUTH_OPEN, SEC_LEVEL_0, 0, 1);
5356 } else {
5357 auth_mode = IPW_AUTH_OPEN;
5358 if ((priv->sec.flags & SEC_AUTH_MODE) &&
5359 (priv->sec.auth_mode == WLAN_AUTH_SHARED_KEY))
5360 auth_mode = IPW_AUTH_SHARED;
5361
5362 sec_level = SEC_LEVEL_0;
5363 if (priv->sec.flags & SEC_LEVEL)
5364 sec_level = priv->sec.level;
5365
5366 use_group = 0;
5367 if (priv->sec.flags & SEC_UNICAST_GROUP)
5368 use_group = priv->sec.unicast_uses_group;
5369
5370 err = ipw2100_set_security_information(
5371 priv, auth_mode, sec_level, use_group, 1);
5372 }
5373
5374 if (err)
5375 goto exit;
5376
5377 if (priv->sec.enabled) {
5378 for (i = 0; i < 4; i++) {
5379 if (!(priv->sec.flags & (1 << i))) {
5380 memset(priv->sec.keys[i], 0, WEP_KEY_LEN);
5381 priv->sec.key_sizes[i] = 0;
5382 } else {
5383 err = ipw2100_set_key(priv, i,
5384 priv->sec.keys[i],
5385 priv->sec.key_sizes[i],
5386 1);
5387 if (err)
5388 goto exit;
5389 }
5390 }
5391
5392 ipw2100_set_key_index(priv, priv->ieee->tx_keyidx, 1);
5393 }
5394
5395 /* Always enable privacy so the Host can filter WEP packets if
5396 * encrypted data is sent up */
5397 err = ipw2100_set_wep_flags(
5398 priv, priv->sec.enabled ? IPW_PRIVACY_CAPABLE : 0, 1);
5399 if (err)
5400 goto exit;
5401
5402 priv->status &= ~STATUS_SECURITY_UPDATED;
5403
5404 exit:
5405 if (!batch_mode)
5406 ipw2100_enable_adapter(priv);
5407
5408 return err;
5409}
5410
5411static void ipw2100_security_work(struct ipw2100_priv *priv)
5412{
5413 /* If we happen to have reconnected before we get a chance to
5414 * process this, then update the security settings--which causes
5415 * a disassociation to occur */
5416 if (!(priv->status & STATUS_ASSOCIATED) &&
5417 priv->status & STATUS_SECURITY_UPDATED)
5418 ipw2100_configure_security(priv, 0);
5419}
5420
5421static void shim__set_security(struct net_device *dev,
5422 struct ieee80211_security *sec)
5423{
5424 struct ipw2100_priv *priv = ieee80211_priv(dev);
5425 int i, force_update = 0;
5426
5427 down(&priv->action_sem);
5428 if (!(priv->status & STATUS_INITIALIZED))
5429 goto done;
5430
5431 for (i = 0; i < 4; i++) {
5432 if (sec->flags & (1 << i)) {
5433 priv->sec.key_sizes[i] = sec->key_sizes[i];
5434 if (sec->key_sizes[i] == 0)
5435 priv->sec.flags &= ~(1 << i);
5436 else
5437 memcpy(priv->sec.keys[i], sec->keys[i],
5438 sec->key_sizes[i]);
5439 priv->sec.flags |= (1 << i);
5440 priv->status |= STATUS_SECURITY_UPDATED;
5441 }
5442 }
5443
5444 if ((sec->flags & SEC_ACTIVE_KEY) &&
5445 priv->sec.active_key != sec->active_key) {
5446 if (sec->active_key <= 3) {
5447 priv->sec.active_key = sec->active_key;
5448 priv->sec.flags |= SEC_ACTIVE_KEY;
5449 } else
5450 priv->sec.flags &= ~SEC_ACTIVE_KEY;
5451
5452 priv->status |= STATUS_SECURITY_UPDATED;
5453 }
5454
5455 if ((sec->flags & SEC_AUTH_MODE) &&
5456 (priv->sec.auth_mode != sec->auth_mode)) {
5457 priv->sec.auth_mode = sec->auth_mode;
5458 priv->sec.flags |= SEC_AUTH_MODE;
5459 priv->status |= STATUS_SECURITY_UPDATED;
5460 }
5461
5462 if (sec->flags & SEC_ENABLED &&
5463 priv->sec.enabled != sec->enabled) {
5464 priv->sec.flags |= SEC_ENABLED;
5465 priv->sec.enabled = sec->enabled;
5466 priv->status |= STATUS_SECURITY_UPDATED;
5467 force_update = 1;
5468 }
5469
5470 if (sec->flags & SEC_LEVEL &&
5471 priv->sec.level != sec->level) {
5472 priv->sec.level = sec->level;
5473 priv->sec.flags |= SEC_LEVEL;
5474 priv->status |= STATUS_SECURITY_UPDATED;
5475 }
5476
5477 IPW_DEBUG_WEP("Security flags: %c %c%c%c%c %c%c%c%c\n",
5478 priv->sec.flags & (1<<8) ? '1' : '0',
5479 priv->sec.flags & (1<<7) ? '1' : '0',
5480 priv->sec.flags & (1<<6) ? '1' : '0',
5481 priv->sec.flags & (1<<5) ? '1' : '0',
5482 priv->sec.flags & (1<<4) ? '1' : '0',
5483 priv->sec.flags & (1<<3) ? '1' : '0',
5484 priv->sec.flags & (1<<2) ? '1' : '0',
5485 priv->sec.flags & (1<<1) ? '1' : '0',
5486 priv->sec.flags & (1<<0) ? '1' : '0');
5487
5488/* As a temporary work around to enable WPA until we figure out why
5489 * wpa_supplicant toggles the security capability of the driver, which
5490 * forces a disassocation with force_update...
5491 *
5492 * if (force_update || !(priv->status & STATUS_ASSOCIATED))*/
5493 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
5494 ipw2100_configure_security(priv, 0);
5495done:
5496 up(&priv->action_sem);
5497}
5498
5499static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5500{
5501 int err;
5502 int batch_mode = 1;
5503 u8 *bssid;
5504
5505 IPW_DEBUG_INFO("enter\n");
5506
5507 err = ipw2100_disable_adapter(priv);
5508 if (err)
5509 return err;
5510#ifdef CONFIG_IPW2100_MONITOR
5511 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
5512 err = ipw2100_set_channel(priv, priv->channel, batch_mode);
5513 if (err)
5514 return err;
5515
5516 IPW_DEBUG_INFO("exit\n");
5517
5518 return 0;
5519 }
5520#endif /* CONFIG_IPW2100_MONITOR */
5521
5522 err = ipw2100_read_mac_address(priv);
5523 if (err)
5524 return -EIO;
5525
5526 err = ipw2100_set_mac_address(priv, batch_mode);
5527 if (err)
5528 return err;
5529
5530 err = ipw2100_set_port_type(priv, priv->ieee->iw_mode, batch_mode);
5531 if (err)
5532 return err;
5533
5534 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5535 err = ipw2100_set_channel(priv, priv->channel, batch_mode);
5536 if (err)
5537 return err;
5538 }
5539
5540 err = ipw2100_system_config(priv, batch_mode);
5541 if (err)
5542 return err;
5543
5544 err = ipw2100_set_tx_rates(priv, priv->tx_rates, batch_mode);
5545 if (err)
5546 return err;
5547
5548 /* Default to power mode OFF */
5549 err = ipw2100_set_power_mode(priv, IPW_POWER_MODE_CAM);
5550 if (err)
5551 return err;
5552
5553 err = ipw2100_set_rts_threshold(priv, priv->rts_threshold);
5554 if (err)
5555 return err;
5556
5557 if (priv->config & CFG_STATIC_BSSID)
5558 bssid = priv->bssid;
5559 else
5560 bssid = NULL;
5561 err = ipw2100_set_mandatory_bssid(priv, bssid, batch_mode);
5562 if (err)
5563 return err;
5564
5565 if (priv->config & CFG_STATIC_ESSID)
5566 err = ipw2100_set_essid(priv, priv->essid, priv->essid_len,
5567 batch_mode);
5568 else
5569 err = ipw2100_set_essid(priv, NULL, 0, batch_mode);
5570 if (err)
5571 return err;
5572
5573 err = ipw2100_configure_security(priv, batch_mode);
5574 if (err)
5575 return err;
5576
5577 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5578 err = ipw2100_set_ibss_beacon_interval(
5579 priv, priv->beacon_interval, batch_mode);
5580 if (err)
5581 return err;
5582
5583 err = ipw2100_set_tx_power(priv, priv->tx_power);
5584 if (err)
5585 return err;
5586 }
5587
5588 /*
5589 err = ipw2100_set_fragmentation_threshold(
5590 priv, priv->frag_threshold, batch_mode);
5591 if (err)
5592 return err;
5593 */
5594
5595 IPW_DEBUG_INFO("exit\n");
5596
5597 return 0;
5598}
5599
5600
5601/*************************************************************************
5602 *
5603 * EXTERNALLY CALLED METHODS
5604 *
5605 *************************************************************************/
5606
5607/* This method is called by the network layer -- not to be confused with
5608 * ipw2100_set_mac_address() declared above called by this driver (and this
5609 * method as well) to talk to the firmware */
5610static int ipw2100_set_address(struct net_device *dev, void *p)
5611{
5612 struct ipw2100_priv *priv = ieee80211_priv(dev);
5613 struct sockaddr *addr = p;
5614 int err = 0;
5615
5616 if (!is_valid_ether_addr(addr->sa_data))
5617 return -EADDRNOTAVAIL;
5618
5619 down(&priv->action_sem);
5620
5621 priv->config |= CFG_CUSTOM_MAC;
5622 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
5623
5624 err = ipw2100_set_mac_address(priv, 0);
5625 if (err)
5626 goto done;
5627
5628 priv->reset_backoff = 0;
5629 up(&priv->action_sem);
5630 ipw2100_reset_adapter(priv);
5631 return 0;
5632
5633 done:
5634 up(&priv->action_sem);
5635 return err;
5636}
5637
5638static int ipw2100_open(struct net_device *dev)
5639{
5640 struct ipw2100_priv *priv = ieee80211_priv(dev);
5641 unsigned long flags;
5642 IPW_DEBUG_INFO("dev->open\n");
5643
5644 spin_lock_irqsave(&priv->low_lock, flags);
5645 if (priv->status & STATUS_ASSOCIATED)
5646 netif_start_queue(dev);
5647 spin_unlock_irqrestore(&priv->low_lock, flags);
5648
5649 return 0;
5650}
5651
5652static int ipw2100_close(struct net_device *dev)
5653{
5654 struct ipw2100_priv *priv = ieee80211_priv(dev);
5655 unsigned long flags;
5656 struct list_head *element;
5657 struct ipw2100_tx_packet *packet;
5658
5659 IPW_DEBUG_INFO("enter\n");
5660
5661 spin_lock_irqsave(&priv->low_lock, flags);
5662
5663 if (priv->status & STATUS_ASSOCIATED)
5664 netif_carrier_off(dev);
5665 netif_stop_queue(dev);
5666
5667 /* Flush the TX queue ... */
5668 while (!list_empty(&priv->tx_pend_list)) {
5669 element = priv->tx_pend_list.next;
5670 packet = list_entry(element, struct ipw2100_tx_packet, list);
5671
5672 list_del(element);
5673 DEC_STAT(&priv->tx_pend_stat);
5674
5675 ieee80211_txb_free(packet->info.d_struct.txb);
5676 packet->info.d_struct.txb = NULL;
5677
5678 list_add_tail(element, &priv->tx_free_list);
5679 INC_STAT(&priv->tx_free_stat);
5680 }
5681 spin_unlock_irqrestore(&priv->low_lock, flags);
5682
5683 IPW_DEBUG_INFO("exit\n");
5684
5685 return 0;
5686}
5687
5688
5689
5690/*
5691 * TODO: Fix this function... its just wrong
5692 */
5693static void ipw2100_tx_timeout(struct net_device *dev)
5694{
5695 struct ipw2100_priv *priv = ieee80211_priv(dev);
5696
5697 priv->ieee->stats.tx_errors++;
5698
5699#ifdef CONFIG_IPW2100_MONITOR
5700 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
5701 return;
5702#endif
5703
5704 IPW_DEBUG_INFO("%s: TX timed out. Scheduling firmware restart.\n",
5705 dev->name);
5706 schedule_reset(priv);
5707}
5708
5709
5710/*
5711 * TODO: reimplement it so that it reads statistics
5712 * from the adapter using ordinal tables
5713 * instead of/in addition to collecting them
5714 * in the driver
5715 */
5716static struct net_device_stats *ipw2100_stats(struct net_device *dev)
5717{
5718 struct ipw2100_priv *priv = ieee80211_priv(dev);
5719
5720 return &priv->ieee->stats;
5721}
5722
5723/* Support for wpa_supplicant. Will be replaced with WEXT once
5724 * they get WPA support. */
5725#ifdef CONFIG_IEEE80211_WPA
5726
5727/* following definitions must match definitions in driver_ipw2100.c */
5728
5729#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
5730
5731#define IPW2100_CMD_SET_WPA_PARAM 1
5732#define IPW2100_CMD_SET_WPA_IE 2
5733#define IPW2100_CMD_SET_ENCRYPTION 3
5734#define IPW2100_CMD_MLME 4
5735
5736#define IPW2100_PARAM_WPA_ENABLED 1
5737#define IPW2100_PARAM_TKIP_COUNTERMEASURES 2
5738#define IPW2100_PARAM_DROP_UNENCRYPTED 3
5739#define IPW2100_PARAM_PRIVACY_INVOKED 4
5740#define IPW2100_PARAM_AUTH_ALGS 5
5741#define IPW2100_PARAM_IEEE_802_1X 6
5742
5743#define IPW2100_MLME_STA_DEAUTH 1
5744#define IPW2100_MLME_STA_DISASSOC 2
5745
5746#define IPW2100_CRYPT_ERR_UNKNOWN_ALG 2
5747#define IPW2100_CRYPT_ERR_UNKNOWN_ADDR 3
5748#define IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED 4
5749#define IPW2100_CRYPT_ERR_KEY_SET_FAILED 5
5750#define IPW2100_CRYPT_ERR_TX_KEY_SET_FAILED 6
5751#define IPW2100_CRYPT_ERR_CARD_CONF_FAILED 7
5752
5753#define IPW2100_CRYPT_ALG_NAME_LEN 16
5754
5755struct ipw2100_param {
5756 u32 cmd;
5757 u8 sta_addr[ETH_ALEN];
5758 union {
5759 struct {
5760 u8 name;
5761 u32 value;
5762 } wpa_param;
5763 struct {
5764 u32 len;
5765 u8 *data;
5766 } wpa_ie;
5767 struct{
5768 int command;
5769 int reason_code;
5770 } mlme;
5771 struct {
5772 u8 alg[IPW2100_CRYPT_ALG_NAME_LEN];
5773 u8 set_tx;
5774 u32 err;
5775 u8 idx;
5776 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
5777 u16 key_len;
5778 u8 key[0];
5779 } crypt;
5780
5781 } u;
5782};
5783
5784/* end of driver_ipw2100.c code */
5785
5786static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value){
5787
5788 struct ieee80211_device *ieee = priv->ieee;
5789 struct ieee80211_security sec = {
5790 .flags = SEC_LEVEL | SEC_ENABLED,
5791 };
5792 int ret = 0;
5793
5794 ieee->wpa_enabled = value;
5795
5796 if (value){
5797 sec.level = SEC_LEVEL_3;
5798 sec.enabled = 1;
5799 } else {
5800 sec.level = SEC_LEVEL_0;
5801 sec.enabled = 0;
5802 }
5803
5804 if (ieee->set_security)
5805 ieee->set_security(ieee->dev, &sec);
5806 else
5807 ret = -EOPNOTSUPP;
5808
5809 return ret;
5810}
5811
5812#define AUTH_ALG_OPEN_SYSTEM 0x1
5813#define AUTH_ALG_SHARED_KEY 0x2
5814
5815static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){
5816
5817 struct ieee80211_device *ieee = priv->ieee;
5818 struct ieee80211_security sec = {
5819 .flags = SEC_AUTH_MODE,
5820 };
5821 int ret = 0;
5822
5823 if (value & AUTH_ALG_SHARED_KEY){
5824 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
5825 ieee->open_wep = 0;
5826 } else {
5827 sec.auth_mode = WLAN_AUTH_OPEN;
5828 ieee->open_wep = 1;
5829 }
5830
5831 if (ieee->set_security)
5832 ieee->set_security(ieee->dev, &sec);
5833 else
5834 ret = -EOPNOTSUPP;
5835
5836 return ret;
5837}
5838
5839
5840static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value){
5841
5842 struct ipw2100_priv *priv = ieee80211_priv(dev);
5843 int ret=0;
5844
5845 switch(name){
5846 case IPW2100_PARAM_WPA_ENABLED:
5847 ret = ipw2100_wpa_enable(priv, value);
5848 break;
5849
5850 case IPW2100_PARAM_TKIP_COUNTERMEASURES:
5851 priv->ieee->tkip_countermeasures=value;
5852 break;
5853
5854 case IPW2100_PARAM_DROP_UNENCRYPTED:
5855 priv->ieee->drop_unencrypted=value;
5856 break;
5857
5858 case IPW2100_PARAM_PRIVACY_INVOKED:
5859 priv->ieee->privacy_invoked=value;
5860 break;
5861
5862 case IPW2100_PARAM_AUTH_ALGS:
5863 ret = ipw2100_wpa_set_auth_algs(priv, value);
5864 break;
5865
5866 case IPW2100_PARAM_IEEE_802_1X:
5867 priv->ieee->ieee802_1x=value;
5868 break;
5869
5870 default:
5871 IPW_DEBUG_ERROR("%s: Unknown WPA param: %d\n",
5872 dev->name, name);
5873 ret = -EOPNOTSUPP;
5874 }
5875
5876 return ret;
5877}
5878
5879static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason){
5880
5881 struct ipw2100_priv *priv = ieee80211_priv(dev);
5882 int ret=0;
5883
5884 switch(command){
5885 case IPW2100_MLME_STA_DEAUTH:
5886 // silently ignore
5887 break;
5888
5889 case IPW2100_MLME_STA_DISASSOC:
5890 ipw2100_disassociate_bssid(priv);
5891 break;
5892
5893 default:
5894 IPW_DEBUG_ERROR("%s: Unknown MLME request: %d\n",
5895 dev->name, command);
5896 ret = -EOPNOTSUPP;
5897 }
5898
5899 return ret;
5900}
5901
5902
5903void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
5904 char *wpa_ie, int wpa_ie_len){
5905
5906 struct ipw2100_wpa_assoc_frame frame;
5907
5908 frame.fixed_ie_mask = 0;
5909
5910 /* copy WPA IE */
5911 memcpy(frame.var_ie, wpa_ie, wpa_ie_len);
5912 frame.var_ie_len = wpa_ie_len;
5913
5914 /* make sure WPA is enabled */
5915 ipw2100_wpa_enable(priv, 1);
5916 ipw2100_set_wpa_ie(priv, &frame, 0);
5917}
5918
5919
5920static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
5921 struct ipw2100_param *param, int plen){
5922
5923 struct ipw2100_priv *priv = ieee80211_priv(dev);
5924 struct ieee80211_device *ieee = priv->ieee;
5925 u8 *buf;
5926
5927 if (! ieee->wpa_enabled)
5928 return -EOPNOTSUPP;
5929
5930 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
5931 (param->u.wpa_ie.len &&
5932 param->u.wpa_ie.data==NULL))
5933 return -EINVAL;
5934
5935 if (param->u.wpa_ie.len){
5936 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
5937 if (buf == NULL)
5938 return -ENOMEM;
5939
5940 memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
5941
5942 kfree(ieee->wpa_ie);
5943 ieee->wpa_ie = buf;
5944 ieee->wpa_ie_len = param->u.wpa_ie.len;
5945
5946 } else {
5947 kfree(ieee->wpa_ie);
5948 ieee->wpa_ie = NULL;
5949 ieee->wpa_ie_len = 0;
5950 }
5951
5952 ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
5953
5954 return 0;
5955}
5956
5957/* implementation borrowed from hostap driver */
5958
5959static int ipw2100_wpa_set_encryption(struct net_device *dev,
5960 struct ipw2100_param *param, int param_len){
5961
5962 int ret = 0;
5963 struct ipw2100_priv *priv = ieee80211_priv(dev);
5964 struct ieee80211_device *ieee = priv->ieee;
5965 struct ieee80211_crypto_ops *ops;
5966 struct ieee80211_crypt_data **crypt;
5967
5968 struct ieee80211_security sec = {
5969 .flags = 0,
5970 };
5971
5972 param->u.crypt.err = 0;
5973 param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0';
5974
5975 if (param_len !=
5976 (int) ((char *) param->u.crypt.key - (char *) param) +
5977 param->u.crypt.key_len){
5978 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len, param->u.crypt.key_len);
5979 return -EINVAL;
5980 }
5981 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
5982 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
5983 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
5984 if (param->u.crypt.idx >= WEP_KEYS)
5985 return -EINVAL;
5986 crypt = &ieee->crypt[param->u.crypt.idx];
5987 } else {
5988 return -EINVAL;
5989 }
5990
5991 if (strcmp(param->u.crypt.alg, "none") == 0) {
5992 if (crypt){
5993 sec.enabled = 0;
5994 sec.level = SEC_LEVEL_0;
5995 sec.flags |= SEC_ENABLED | SEC_LEVEL;
5996 ieee80211_crypt_delayed_deinit(ieee, crypt);
5997 }
5998 goto done;
5999 }
6000 sec.enabled = 1;
6001 sec.flags |= SEC_ENABLED;
6002
6003 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6004 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
6005 request_module("ieee80211_crypt_wep");
6006 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6007 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
6008 request_module("ieee80211_crypt_tkip");
6009 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6010 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
6011 request_module("ieee80211_crypt_ccmp");
6012 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6013 }
6014 if (ops == NULL) {
6015 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
6016 dev->name, param->u.crypt.alg);
6017 param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG;
6018 ret = -EINVAL;
6019 goto done;
6020 }
6021
6022 if (*crypt == NULL || (*crypt)->ops != ops) {
6023 struct ieee80211_crypt_data *new_crypt;
6024
6025 ieee80211_crypt_delayed_deinit(ieee, crypt);
6026
6027 new_crypt = (struct ieee80211_crypt_data *)
6028 kmalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
6029 if (new_crypt == NULL) {
6030 ret = -ENOMEM;
6031 goto done;
6032 }
6033 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
6034 new_crypt->ops = ops;
6035 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
6036 new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx);
6037
6038 if (new_crypt->priv == NULL) {
6039 kfree(new_crypt);
6040 param->u.crypt.err =
6041 IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED;
6042 ret = -EINVAL;
6043 goto done;
6044 }
6045
6046 *crypt = new_crypt;
6047 }
6048
6049 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
6050 (*crypt)->ops->set_key(param->u.crypt.key,
6051 param->u.crypt.key_len, param->u.crypt.seq,
6052 (*crypt)->priv) < 0) {
6053 IPW_DEBUG_INFO("%s: key setting failed\n",
6054 dev->name);
6055 param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED;
6056 ret = -EINVAL;
6057 goto done;
6058 }
6059
6060 if (param->u.crypt.set_tx){
6061 ieee->tx_keyidx = param->u.crypt.idx;
6062 sec.active_key = param->u.crypt.idx;
6063 sec.flags |= SEC_ACTIVE_KEY;
6064 }
6065
6066 if (ops->name != NULL){
6067
6068 if (strcmp(ops->name, "WEP") == 0) {
6069 memcpy(sec.keys[param->u.crypt.idx], param->u.crypt.key, param->u.crypt.key_len);
6070 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
6071 sec.flags |= (1 << param->u.crypt.idx);
6072 sec.flags |= SEC_LEVEL;
6073 sec.level = SEC_LEVEL_1;
6074 } else if (strcmp(ops->name, "TKIP") == 0) {
6075 sec.flags |= SEC_LEVEL;
6076 sec.level = SEC_LEVEL_2;
6077 } else if (strcmp(ops->name, "CCMP") == 0) {
6078 sec.flags |= SEC_LEVEL;
6079 sec.level = SEC_LEVEL_3;
6080 }
6081 }
6082 done:
6083 if (ieee->set_security)
6084 ieee->set_security(ieee->dev, &sec);
6085
6086 /* Do not reset port if card is in Managed mode since resetting will
6087 * generate new IEEE 802.11 authentication which may end up in looping
6088 * with IEEE 802.1X. If your hardware requires a reset after WEP
6089 * configuration (for example... Prism2), implement the reset_port in
6090 * the callbacks structures used to initialize the 802.11 stack. */
6091 if (ieee->reset_on_keychange &&
6092 ieee->iw_mode != IW_MODE_INFRA &&
6093 ieee->reset_port &&
6094 ieee->reset_port(dev)) {
6095 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
6096 param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED;
6097 return -EINVAL;
6098 }
6099
6100 return ret;
6101}
6102
6103
6104static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6105
6106 struct ipw2100_param *param;
6107 int ret=0;
6108
6109 IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length);
6110
6111 if (p->length < sizeof(struct ipw2100_param) || !p->pointer)
6112 return -EINVAL;
6113
6114 param = (struct ipw2100_param *)kmalloc(p->length, GFP_KERNEL);
6115 if (param == NULL)
6116 return -ENOMEM;
6117
6118 if (copy_from_user(param, p->pointer, p->length)){
6119 kfree(param);
6120 return -EFAULT;
6121 }
6122
6123 switch (param->cmd){
6124
6125 case IPW2100_CMD_SET_WPA_PARAM:
6126 ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name,
6127 param->u.wpa_param.value);
6128 break;
6129
6130 case IPW2100_CMD_SET_WPA_IE:
6131 ret = ipw2100_wpa_set_wpa_ie(dev, param, p->length);
6132 break;
6133
6134 case IPW2100_CMD_SET_ENCRYPTION:
6135 ret = ipw2100_wpa_set_encryption(dev, param, p->length);
6136 break;
6137
6138 case IPW2100_CMD_MLME:
6139 ret = ipw2100_wpa_mlme(dev, param->u.mlme.command,
6140 param->u.mlme.reason_code);
6141 break;
6142
6143 default:
6144 IPW_DEBUG_ERROR("%s: Unknown WPA supplicant request: %d\n",
6145 dev->name, param->cmd);
6146 ret = -EOPNOTSUPP;
6147
6148 }
6149
6150 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
6151 ret = -EFAULT;
6152
6153 kfree(param);
6154 return ret;
6155}
6156#endif /* CONFIG_IEEE80211_WPA */
6157
6158static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6159{
6160#ifdef CONFIG_IEEE80211_WPA
6161 struct iwreq *wrq = (struct iwreq *) rq;
6162 int ret=-1;
6163 switch (cmd){
6164 case IPW2100_IOCTL_WPA_SUPPLICANT:
6165 ret = ipw2100_wpa_supplicant(dev, &wrq->u.data);
6166 return ret;
6167
6168 default:
6169 return -EOPNOTSUPP;
6170 }
6171
6172#endif /* CONFIG_IEEE80211_WPA */
6173
6174 return -EOPNOTSUPP;
6175}
6176
6177
6178static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6179 struct ethtool_drvinfo *info)
6180{
6181 struct ipw2100_priv *priv = ieee80211_priv(dev);
6182 char fw_ver[64], ucode_ver[64];
6183
6184 strcpy(info->driver, DRV_NAME);
6185 strcpy(info->version, DRV_VERSION);
6186
6187 ipw2100_get_fwversion(priv, fw_ver, sizeof(fw_ver));
6188 ipw2100_get_ucodeversion(priv, ucode_ver, sizeof(ucode_ver));
6189
6190 snprintf(info->fw_version, sizeof(info->fw_version), "%s:%d:%s",
6191 fw_ver, priv->eeprom_version, ucode_ver);
6192
6193 strcpy(info->bus_info, pci_name(priv->pci_dev));
6194}
6195
6196static u32 ipw2100_ethtool_get_link(struct net_device *dev)
6197{
6198 struct ipw2100_priv *priv = ieee80211_priv(dev);
6199 return (priv->status & STATUS_ASSOCIATED) ? 1 : 0;
6200}
6201
6202
6203static struct ethtool_ops ipw2100_ethtool_ops = {
6204 .get_link = ipw2100_ethtool_get_link,
6205 .get_drvinfo = ipw_ethtool_get_drvinfo,
6206};
6207
6208static void ipw2100_hang_check(void *adapter)
6209{
6210 struct ipw2100_priv *priv = adapter;
6211 unsigned long flags;
6212 u32 rtc = 0xa5a5a5a5;
6213 u32 len = sizeof(rtc);
6214 int restart = 0;
6215
6216 spin_lock_irqsave(&priv->low_lock, flags);
6217
6218 if (priv->fatal_error != 0) {
6219 /* If fatal_error is set then we need to restart */
6220 IPW_DEBUG_INFO("%s: Hardware fatal error detected.\n",
6221 priv->net_dev->name);
6222
6223 restart = 1;
6224 } else if (ipw2100_get_ordinal(priv, IPW_ORD_RTC_TIME, &rtc, &len) ||
6225 (rtc == priv->last_rtc)) {
6226 /* Check if firmware is hung */
6227 IPW_DEBUG_INFO("%s: Firmware RTC stalled.\n",
6228 priv->net_dev->name);
6229
6230 restart = 1;
6231 }
6232
6233 if (restart) {
6234 /* Kill timer */
6235 priv->stop_hang_check = 1;
6236 priv->hangs++;
6237
6238 /* Restart the NIC */
6239 schedule_reset(priv);
6240 }
6241
6242 priv->last_rtc = rtc;
6243
6244 if (!priv->stop_hang_check)
6245 queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
6246
6247 spin_unlock_irqrestore(&priv->low_lock, flags);
6248}
6249
6250
6251static void ipw2100_rf_kill(void *adapter)
6252{
6253 struct ipw2100_priv *priv = adapter;
6254 unsigned long flags;
6255
6256 spin_lock_irqsave(&priv->low_lock, flags);
6257
6258 if (rf_kill_active(priv)) {
6259 IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
6260 if (!priv->stop_rf_kill)
6261 queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
6262 goto exit_unlock;
6263 }
6264
6265 /* RF Kill is now disabled, so bring the device back up */
6266
6267 if (!(priv->status & STATUS_RF_KILL_MASK)) {
6268 IPW_DEBUG_RF_KILL("HW RF Kill no longer active, restarting "
6269 "device\n");
6270 schedule_reset(priv);
6271 } else
6272 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
6273 "enabled\n");
6274
6275 exit_unlock:
6276 spin_unlock_irqrestore(&priv->low_lock, flags);
6277}
6278
6279static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
6280
6281/* Look into using netdev destructor to shutdown ieee80211? */
6282
6283static struct net_device *ipw2100_alloc_device(
6284 struct pci_dev *pci_dev,
6285 char *base_addr,
6286 unsigned long mem_start,
6287 unsigned long mem_len)
6288{
6289 struct ipw2100_priv *priv;
6290 struct net_device *dev;
6291
6292 dev = alloc_ieee80211(sizeof(struct ipw2100_priv));
6293 if (!dev)
6294 return NULL;
6295 priv = ieee80211_priv(dev);
6296 priv->ieee = netdev_priv(dev);
6297 priv->pci_dev = pci_dev;
6298 priv->net_dev = dev;
6299
6300 priv->ieee->hard_start_xmit = ipw2100_tx;
6301 priv->ieee->set_security = shim__set_security;
6302
6303 dev->open = ipw2100_open;
6304 dev->stop = ipw2100_close;
6305 dev->init = ipw2100_net_init;
6306 dev->do_ioctl = ipw2100_ioctl;
6307 dev->get_stats = ipw2100_stats;
6308 dev->ethtool_ops = &ipw2100_ethtool_ops;
6309 dev->tx_timeout = ipw2100_tx_timeout;
6310 dev->wireless_handlers = &ipw2100_wx_handler_def;
6311 dev->get_wireless_stats = ipw2100_wx_wireless_stats;
6312 dev->set_mac_address = ipw2100_set_address;
6313 dev->watchdog_timeo = 3*HZ;
6314 dev->irq = 0;
6315
6316 dev->base_addr = (unsigned long)base_addr;
6317 dev->mem_start = mem_start;
6318 dev->mem_end = dev->mem_start + mem_len - 1;
6319
6320 /* NOTE: We don't use the wireless_handlers hook
6321 * in dev as the system will start throwing WX requests
6322 * to us before we're actually initialized and it just
6323 * ends up causing problems. So, we just handle
6324 * the WX extensions through the ipw2100_ioctl interface */
6325
6326
6327 /* memset() puts everything to 0, so we only have explicitely set
6328 * those values that need to be something else */
6329
6330 /* If power management is turned on, default to AUTO mode */
6331 priv->power_mode = IPW_POWER_AUTO;
6332
6333
6334
6335#ifdef CONFIG_IEEE80211_WPA
6336 priv->ieee->wpa_enabled = 0;
6337 priv->ieee->tkip_countermeasures = 0;
6338 priv->ieee->drop_unencrypted = 0;
6339 priv->ieee->privacy_invoked = 0;
6340 priv->ieee->ieee802_1x = 1;
6341#endif /* CONFIG_IEEE80211_WPA */
6342
6343 /* Set module parameters */
6344 switch (mode) {
6345 case 1:
6346 priv->ieee->iw_mode = IW_MODE_ADHOC;
6347 break;
6348#ifdef CONFIG_IPW2100_MONITOR
6349 case 2:
6350 priv->ieee->iw_mode = IW_MODE_MONITOR;
6351 break;
6352#endif
6353 default:
6354 case 0:
6355 priv->ieee->iw_mode = IW_MODE_INFRA;
6356 break;
6357 }
6358
6359 if (disable == 1)
6360 priv->status |= STATUS_RF_KILL_SW;
6361
6362 if (channel != 0 &&
6363 ((channel >= REG_MIN_CHANNEL) &&
6364 (channel <= REG_MAX_CHANNEL))) {
6365 priv->config |= CFG_STATIC_CHANNEL;
6366 priv->channel = channel;
6367 }
6368
6369 if (associate)
6370 priv->config |= CFG_ASSOCIATE;
6371
6372 priv->beacon_interval = DEFAULT_BEACON_INTERVAL;
6373 priv->short_retry_limit = DEFAULT_SHORT_RETRY_LIMIT;
6374 priv->long_retry_limit = DEFAULT_LONG_RETRY_LIMIT;
6375 priv->rts_threshold = DEFAULT_RTS_THRESHOLD | RTS_DISABLED;
6376 priv->frag_threshold = DEFAULT_FTS | FRAG_DISABLED;
6377 priv->tx_power = IPW_TX_POWER_DEFAULT;
6378 priv->tx_rates = DEFAULT_TX_RATES;
6379
6380 strcpy(priv->nick, "ipw2100");
6381
6382 spin_lock_init(&priv->low_lock);
6383 sema_init(&priv->action_sem, 1);
6384 sema_init(&priv->adapter_sem, 1);
6385
6386 init_waitqueue_head(&priv->wait_command_queue);
6387
6388 netif_carrier_off(dev);
6389
6390 INIT_LIST_HEAD(&priv->msg_free_list);
6391 INIT_LIST_HEAD(&priv->msg_pend_list);
6392 INIT_STAT(&priv->msg_free_stat);
6393 INIT_STAT(&priv->msg_pend_stat);
6394
6395 INIT_LIST_HEAD(&priv->tx_free_list);
6396 INIT_LIST_HEAD(&priv->tx_pend_list);
6397 INIT_STAT(&priv->tx_free_stat);
6398 INIT_STAT(&priv->tx_pend_stat);
6399
6400 INIT_LIST_HEAD(&priv->fw_pend_list);
6401 INIT_STAT(&priv->fw_pend_stat);
6402
6403
6404#ifdef CONFIG_SOFTWARE_SUSPEND2
6405 priv->workqueue = create_workqueue(DRV_NAME, 0);
6406#else
6407 priv->workqueue = create_workqueue(DRV_NAME);
6408#endif
6409 INIT_WORK(&priv->reset_work,
6410 (void (*)(void *))ipw2100_reset_adapter, priv);
6411 INIT_WORK(&priv->security_work,
6412 (void (*)(void *))ipw2100_security_work, priv);
6413 INIT_WORK(&priv->wx_event_work,
6414 (void (*)(void *))ipw2100_wx_event_work, priv);
6415 INIT_WORK(&priv->hang_check, ipw2100_hang_check, priv);
6416 INIT_WORK(&priv->rf_kill, ipw2100_rf_kill, priv);
6417
6418 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
6419 ipw2100_irq_tasklet, (unsigned long)priv);
6420
6421 /* NOTE: We do not start the deferred work for status checks yet */
6422 priv->stop_rf_kill = 1;
6423 priv->stop_hang_check = 1;
6424
6425 return dev;
6426}
6427
6428
6429
6430#define PCI_DMA_32BIT 0x00000000ffffffffULL
6431
6432static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6433 const struct pci_device_id *ent)
6434{
6435 unsigned long mem_start, mem_len, mem_flags;
6436 char *base_addr = NULL;
6437 struct net_device *dev = NULL;
6438 struct ipw2100_priv *priv = NULL;
6439 int err = 0;
6440 int registered = 0;
6441 u32 val;
6442
6443 IPW_DEBUG_INFO("enter\n");
6444
6445 mem_start = pci_resource_start(pci_dev, 0);
6446 mem_len = pci_resource_len(pci_dev, 0);
6447 mem_flags = pci_resource_flags(pci_dev, 0);
6448
6449 if ((mem_flags & IORESOURCE_MEM) != IORESOURCE_MEM) {
6450 IPW_DEBUG_INFO("weird - resource type is not memory\n");
6451 err = -ENODEV;
6452 goto fail;
6453 }
6454
6455 base_addr = ioremap_nocache(mem_start, mem_len);
6456 if (!base_addr) {
6457 printk(KERN_WARNING DRV_NAME
6458 "Error calling ioremap_nocache.\n");
6459 err = -EIO;
6460 goto fail;
6461 }
6462
6463 /* allocate and initialize our net_device */
6464 dev = ipw2100_alloc_device(pci_dev, base_addr, mem_start, mem_len);
6465 if (!dev) {
6466 printk(KERN_WARNING DRV_NAME
6467 "Error calling ipw2100_alloc_device.\n");
6468 err = -ENOMEM;
6469 goto fail;
6470 }
6471
6472 /* set up PCI mappings for device */
6473 err = pci_enable_device(pci_dev);
6474 if (err) {
6475 printk(KERN_WARNING DRV_NAME
6476 "Error calling pci_enable_device.\n");
6477 return err;
6478 }
6479
6480 priv = ieee80211_priv(dev);
6481
6482 pci_set_master(pci_dev);
6483 pci_set_drvdata(pci_dev, priv);
6484
6485 err = pci_set_dma_mask(pci_dev, PCI_DMA_32BIT);
6486 if (err) {
6487 printk(KERN_WARNING DRV_NAME
6488 "Error calling pci_set_dma_mask.\n");
6489 pci_disable_device(pci_dev);
6490 return err;
6491 }
6492
6493 err = pci_request_regions(pci_dev, DRV_NAME);
6494 if (err) {
6495 printk(KERN_WARNING DRV_NAME
6496 "Error calling pci_request_regions.\n");
6497 pci_disable_device(pci_dev);
6498 return err;
6499 }
6500
6501 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6502 * PCI Tx retries from interfering with C3 CPU state */
6503 pci_read_config_dword(pci_dev, 0x40, &val);
6504 if ((val & 0x0000ff00) != 0)
6505 pci_write_config_dword(pci_dev, 0x40, val & 0xffff00ff);
6506
6507 pci_set_power_state(pci_dev, 0);
6508
6509 if (!ipw2100_hw_is_adapter_in_system(dev)) {
6510 printk(KERN_WARNING DRV_NAME
6511 "Device not found via register read.\n");
6512 err = -ENODEV;
6513 goto fail;
6514 }
6515
6516 SET_NETDEV_DEV(dev, &pci_dev->dev);
6517
6518 /* Force interrupts to be shut off on the device */
6519 priv->status |= STATUS_INT_ENABLED;
6520 ipw2100_disable_interrupts(priv);
6521
6522 /* Allocate and initialize the Tx/Rx queues and lists */
6523 if (ipw2100_queues_allocate(priv)) {
6524 printk(KERN_WARNING DRV_NAME
6525 "Error calilng ipw2100_queues_allocate.\n");
6526 err = -ENOMEM;
6527 goto fail;
6528 }
6529 ipw2100_queues_initialize(priv);
6530
6531 err = request_irq(pci_dev->irq,
6532 ipw2100_interrupt, SA_SHIRQ,
6533 dev->name, priv);
6534 if (err) {
6535 printk(KERN_WARNING DRV_NAME
6536 "Error calling request_irq: %d.\n",
6537 pci_dev->irq);
6538 goto fail;
6539 }
6540 dev->irq = pci_dev->irq;
6541
6542 IPW_DEBUG_INFO("Attempting to register device...\n");
6543
6544 SET_MODULE_OWNER(dev);
6545
6546 printk(KERN_INFO DRV_NAME
6547 ": Detected Intel PRO/Wireless 2100 Network Connection\n");
6548
6549 /* Bring up the interface. Pre 0.46, after we registered the
6550 * network device we would call ipw2100_up. This introduced a race
6551 * condition with newer hotplug configurations (network was coming
6552 * up and making calls before the device was initialized).
6553 *
6554 * If we called ipw2100_up before we registered the device, then the
6555 * device name wasn't registered. So, we instead use the net_dev->init
6556 * member to call a function that then just turns and calls ipw2100_up.
6557 * net_dev->init is called after name allocation but before the
6558 * notifier chain is called */
6559 down(&priv->action_sem);
6560 err = register_netdev(dev);
6561 if (err) {
6562 printk(KERN_WARNING DRV_NAME
6563 "Error calling register_netdev.\n");
6564 goto fail_unlock;
6565 }
6566 registered = 1;
6567
6568 IPW_DEBUG_INFO("%s: Bound to %s\n", dev->name, pci_name(pci_dev));
6569
6570 /* perform this after register_netdev so that dev->name is set */
6571 sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
6572 netif_carrier_off(dev);
6573
6574 /* If the RF Kill switch is disabled, go ahead and complete the
6575 * startup sequence */
6576 if (!(priv->status & STATUS_RF_KILL_MASK)) {
6577 /* Enable the adapter - sends HOST_COMPLETE */
6578 if (ipw2100_enable_adapter(priv)) {
6579 printk(KERN_WARNING DRV_NAME
6580 ": %s: failed in call to enable adapter.\n",
6581 priv->net_dev->name);
6582 ipw2100_hw_stop_adapter(priv);
6583 err = -EIO;
6584 goto fail_unlock;
6585 }
6586
6587 /* Start a scan . . . */
6588 ipw2100_set_scan_options(priv);
6589 ipw2100_start_scan(priv);
6590 }
6591
6592 IPW_DEBUG_INFO("exit\n");
6593
6594 priv->status |= STATUS_INITIALIZED;
6595
6596 up(&priv->action_sem);
6597
6598 return 0;
6599
6600 fail_unlock:
6601 up(&priv->action_sem);
6602
6603 fail:
6604 if (dev) {
6605 if (registered)
6606 unregister_netdev(dev);
6607
6608 ipw2100_hw_stop_adapter(priv);
6609
6610 ipw2100_disable_interrupts(priv);
6611
6612 if (dev->irq)
6613 free_irq(dev->irq, priv);
6614
6615 ipw2100_kill_workqueue(priv);
6616
6617 /* These are safe to call even if they weren't allocated */
6618 ipw2100_queues_free(priv);
6619 sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
6620
6621 free_ieee80211(dev);
6622 pci_set_drvdata(pci_dev, NULL);
6623 }
6624
6625 if (base_addr)
6626 iounmap((char*)base_addr);
6627
6628 pci_release_regions(pci_dev);
6629 pci_disable_device(pci_dev);
6630
6631 return err;
6632}
6633
6634static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6635{
6636 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6637 struct net_device *dev;
6638
6639 if (priv) {
6640 down(&priv->action_sem);
6641
6642 priv->status &= ~STATUS_INITIALIZED;
6643
6644 dev = priv->net_dev;
6645 sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
6646
6647#ifdef CONFIG_PM
6648 if (ipw2100_firmware.version)
6649 ipw2100_release_firmware(priv, &ipw2100_firmware);
6650#endif
6651 /* Take down the hardware */
6652 ipw2100_down(priv);
6653
6654 /* Release the semaphore so that the network subsystem can
6655 * complete any needed calls into the driver... */
6656 up(&priv->action_sem);
6657
6658 /* Unregister the device first - this results in close()
6659 * being called if the device is open. If we free storage
6660 * first, then close() will crash. */
6661 unregister_netdev(dev);
6662
6663 /* ipw2100_down will ensure that there is no more pending work
6664 * in the workqueue's, so we can safely remove them now. */
6665 ipw2100_kill_workqueue(priv);
6666
6667 ipw2100_queues_free(priv);
6668
6669 /* Free potential debugging firmware snapshot */
6670 ipw2100_snapshot_free(priv);
6671
6672 if (dev->irq)
6673 free_irq(dev->irq, priv);
6674
6675 if (dev->base_addr)
6676 iounmap((unsigned char *)dev->base_addr);
6677
6678 free_ieee80211(dev);
6679 }
6680
6681 pci_release_regions(pci_dev);
6682 pci_disable_device(pci_dev);
6683
6684 IPW_DEBUG_INFO("exit\n");
6685}
6686
6687
6688#ifdef CONFIG_PM
6689#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
6690static int ipw2100_suspend(struct pci_dev *pci_dev, u32 state)
6691#else
6692static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
6693#endif
6694{
6695 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6696 struct net_device *dev = priv->net_dev;
6697
6698 IPW_DEBUG_INFO("%s: Going into suspend...\n",
6699 dev->name);
6700
6701 down(&priv->action_sem);
6702 if (priv->status & STATUS_INITIALIZED) {
6703 /* Take down the device; powers it off, etc. */
6704 ipw2100_down(priv);
6705 }
6706
6707 /* Remove the PRESENT state of the device */
6708 netif_device_detach(dev);
6709
6710#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
6711 pci_save_state(pci_dev, priv->pm_state);
6712#else
6713 pci_save_state(pci_dev);
6714#endif
6715 pci_disable_device (pci_dev);
6716#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
6717 pci_set_power_state(pci_dev, state);
6718#else
6719 pci_set_power_state(pci_dev, PCI_D3hot);
6720#endif
6721
6722 up(&priv->action_sem);
6723
6724 return 0;
6725}
6726
6727static int ipw2100_resume(struct pci_dev *pci_dev)
6728{
6729 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6730 struct net_device *dev = priv->net_dev;
6731 u32 val;
6732
6733 if (IPW2100_PM_DISABLED)
6734 return 0;
6735
6736 down(&priv->action_sem);
6737
6738 IPW_DEBUG_INFO("%s: Coming out of suspend...\n",
6739 dev->name);
6740
6741#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
6742 pci_set_power_state(pci_dev, 0);
6743#else
6744 pci_set_power_state(pci_dev, PCI_D0);
6745#endif
6746 pci_enable_device(pci_dev);
6747#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
6748 pci_restore_state(pci_dev, priv->pm_state);
6749#else
6750 pci_restore_state(pci_dev);
6751#endif
6752
6753 /*
6754 * Suspend/Resume resets the PCI configuration space, so we have to
6755 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
6756 * from interfering with C3 CPU state. pci_restore_state won't help
6757 * here since it only restores the first 64 bytes pci config header.
6758 */
6759 pci_read_config_dword(pci_dev, 0x40, &val);
6760 if ((val & 0x0000ff00) != 0)
6761 pci_write_config_dword(pci_dev, 0x40, val & 0xffff00ff);
6762
6763 /* Set the device back into the PRESENT state; this will also wake
6764 * the queue of needed */
6765 netif_device_attach(dev);
6766
6767 /* Bring the device back up */
6768 if (!(priv->status & STATUS_RF_KILL_SW))
6769 ipw2100_up(priv, 0);
6770
6771 up(&priv->action_sem);
6772
6773 return 0;
6774}
6775#endif
6776
6777
6778#define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x }
6779
6780static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = {
6781 IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */
6782 IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */
6783 IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */
6784 IPW2100_DEV_ID(0x2525), /* IN 2100A mPCI 3B */
6785 IPW2100_DEV_ID(0x2526), /* IN 2100A mPCI Gen A3 */
6786 IPW2100_DEV_ID(0x2522), /* IN 2100 mPCI 3B */
6787 IPW2100_DEV_ID(0x2523), /* IN 2100 mPCI 3A */
6788 IPW2100_DEV_ID(0x2527), /* IN 2100 mPCI 3B */
6789 IPW2100_DEV_ID(0x2528), /* IN 2100 mPCI 3B */
6790 IPW2100_DEV_ID(0x2529), /* IN 2100 mPCI 3B */
6791 IPW2100_DEV_ID(0x252B), /* IN 2100 mPCI 3A */
6792 IPW2100_DEV_ID(0x252C), /* IN 2100 mPCI 3A */
6793 IPW2100_DEV_ID(0x252D), /* IN 2100 mPCI 3A */
6794
6795 IPW2100_DEV_ID(0x2550), /* IB 2100A mPCI 3B */
6796 IPW2100_DEV_ID(0x2551), /* IB 2100 mPCI 3B */
6797 IPW2100_DEV_ID(0x2553), /* IB 2100 mPCI 3B */
6798 IPW2100_DEV_ID(0x2554), /* IB 2100 mPCI 3B */
6799 IPW2100_DEV_ID(0x2555), /* IB 2100 mPCI 3B */
6800
6801 IPW2100_DEV_ID(0x2560), /* DE 2100A mPCI 3A */
6802 IPW2100_DEV_ID(0x2562), /* DE 2100A mPCI 3A */
6803 IPW2100_DEV_ID(0x2563), /* DE 2100A mPCI 3A */
6804 IPW2100_DEV_ID(0x2561), /* DE 2100 mPCI 3A */
6805 IPW2100_DEV_ID(0x2565), /* DE 2100 mPCI 3A */
6806 IPW2100_DEV_ID(0x2566), /* DE 2100 mPCI 3A */
6807 IPW2100_DEV_ID(0x2567), /* DE 2100 mPCI 3A */
6808
6809 IPW2100_DEV_ID(0x2570), /* GA 2100 mPCI 3B */
6810
6811 IPW2100_DEV_ID(0x2580), /* TO 2100A mPCI 3B */
6812 IPW2100_DEV_ID(0x2582), /* TO 2100A mPCI 3B */
6813 IPW2100_DEV_ID(0x2583), /* TO 2100A mPCI 3B */
6814 IPW2100_DEV_ID(0x2581), /* TO 2100 mPCI 3B */
6815 IPW2100_DEV_ID(0x2585), /* TO 2100 mPCI 3B */
6816 IPW2100_DEV_ID(0x2586), /* TO 2100 mPCI 3B */
6817 IPW2100_DEV_ID(0x2587), /* TO 2100 mPCI 3B */
6818
6819 IPW2100_DEV_ID(0x2590), /* SO 2100A mPCI 3B */
6820 IPW2100_DEV_ID(0x2592), /* SO 2100A mPCI 3B */
6821 IPW2100_DEV_ID(0x2591), /* SO 2100 mPCI 3B */
6822 IPW2100_DEV_ID(0x2593), /* SO 2100 mPCI 3B */
6823 IPW2100_DEV_ID(0x2596), /* SO 2100 mPCI 3B */
6824 IPW2100_DEV_ID(0x2598), /* SO 2100 mPCI 3B */
6825
6826 IPW2100_DEV_ID(0x25A0), /* HP 2100 mPCI 3B */
6827 {0,},
6828};
6829
6830MODULE_DEVICE_TABLE(pci, ipw2100_pci_id_table);
6831
6832static struct pci_driver ipw2100_pci_driver = {
6833 .name = DRV_NAME,
6834 .id_table = ipw2100_pci_id_table,
6835 .probe = ipw2100_pci_init_one,
6836 .remove = __devexit_p(ipw2100_pci_remove_one),
6837#ifdef CONFIG_PM
6838 .suspend = ipw2100_suspend,
6839 .resume = ipw2100_resume,
6840#endif
6841};
6842
6843
6844/**
6845 * Initialize the ipw2100 driver/module
6846 *
6847 * @returns 0 if ok, < 0 errno node con error.
6848 *
6849 * Note: we cannot init the /proc stuff until the PCI driver is there,
6850 * or we risk an unlikely race condition on someone accessing
6851 * uninitialized data in the PCI dev struct through /proc.
6852 */
6853static int __init ipw2100_init(void)
6854{
6855 int ret;
6856
6857 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
6858 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
6859
6860#ifdef CONFIG_IEEE80211_NOWEP
6861 IPW_DEBUG_INFO(DRV_NAME ": Compiled with WEP disabled.\n");
6862#endif
6863
6864 ret = pci_module_init(&ipw2100_pci_driver);
6865
6866#ifdef CONFIG_IPW_DEBUG
6867 ipw2100_debug_level = debug;
6868 driver_create_file(&ipw2100_pci_driver.driver,
6869 &driver_attr_debug_level);
6870#endif
6871
6872 return ret;
6873}
6874
6875
6876/**
6877 * Cleanup ipw2100 driver registration
6878 */
6879static void __exit ipw2100_exit(void)
6880{
6881 /* FIXME: IPG: check that we have no instances of the devices open */
6882#ifdef CONFIG_IPW_DEBUG
6883 driver_remove_file(&ipw2100_pci_driver.driver,
6884 &driver_attr_debug_level);
6885#endif
6886 pci_unregister_driver(&ipw2100_pci_driver);
6887}
6888
6889module_init(ipw2100_init);
6890module_exit(ipw2100_exit);
6891
6892#define WEXT_USECHANNELS 1
6893
6894const long ipw2100_frequencies[] = {
6895 2412, 2417, 2422, 2427,
6896 2432, 2437, 2442, 2447,
6897 2452, 2457, 2462, 2467,
6898 2472, 2484
6899};
6900
6901#define FREQ_COUNT (sizeof(ipw2100_frequencies) / \
6902 sizeof(ipw2100_frequencies[0]))
6903
6904const long ipw2100_rates_11b[] = {
6905 1000000,
6906 2000000,
6907 5500000,
6908 11000000
6909};
6910
6911#define RATE_COUNT (sizeof(ipw2100_rates_11b) / sizeof(ipw2100_rates_11b[0]))
6912
6913static int ipw2100_wx_get_name(struct net_device *dev,
6914 struct iw_request_info *info,
6915 union iwreq_data *wrqu, char *extra)
6916{
6917 /*
6918 * This can be called at any time. No action lock required
6919 */
6920
6921 struct ipw2100_priv *priv = ieee80211_priv(dev);
6922 if (!(priv->status & STATUS_ASSOCIATED))
6923 strcpy(wrqu->name, "unassociated");
6924 else
6925 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
6926
6927 IPW_DEBUG_WX("Name: %s\n", wrqu->name);
6928 return 0;
6929}
6930
6931
6932static int ipw2100_wx_set_freq(struct net_device *dev,
6933 struct iw_request_info *info,
6934 union iwreq_data *wrqu, char *extra)
6935{
6936 struct ipw2100_priv *priv = ieee80211_priv(dev);
6937 struct iw_freq *fwrq = &wrqu->freq;
6938 int err = 0;
6939
6940 if (priv->ieee->iw_mode == IW_MODE_INFRA)
6941 return -EOPNOTSUPP;
6942
6943 down(&priv->action_sem);
6944 if (!(priv->status & STATUS_INITIALIZED)) {
6945 err = -EIO;
6946 goto done;
6947 }
6948
6949 /* if setting by freq convert to channel */
6950 if (fwrq->e == 1) {
6951 if ((fwrq->m >= (int) 2.412e8 &&
6952 fwrq->m <= (int) 2.487e8)) {
6953 int f = fwrq->m / 100000;
6954 int c = 0;
6955
6956 while ((c < REG_MAX_CHANNEL) &&
6957 (f != ipw2100_frequencies[c]))
6958 c++;
6959
6960 /* hack to fall through */
6961 fwrq->e = 0;
6962 fwrq->m = c + 1;
6963 }
6964 }
6965
6966 if (fwrq->e > 0 || fwrq->m > 1000)
6967 return -EOPNOTSUPP;
6968 else { /* Set the channel */
6969 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
6970 err = ipw2100_set_channel(priv, fwrq->m, 0);
6971 }
6972
6973 done:
6974 up(&priv->action_sem);
6975 return err;
6976}
6977
6978
6979static int ipw2100_wx_get_freq(struct net_device *dev,
6980 struct iw_request_info *info,
6981 union iwreq_data *wrqu, char *extra)
6982{
6983 /*
6984 * This can be called at any time. No action lock required
6985 */
6986
6987 struct ipw2100_priv *priv = ieee80211_priv(dev);
6988
6989 wrqu->freq.e = 0;
6990
6991 /* If we are associated, trying to associate, or have a statically
6992 * configured CHANNEL then return that; otherwise return ANY */
6993 if (priv->config & CFG_STATIC_CHANNEL ||
6994 priv->status & STATUS_ASSOCIATED)
6995 wrqu->freq.m = priv->channel;
6996 else
6997 wrqu->freq.m = 0;
6998
6999 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
7000 return 0;
7001
7002}
7003
7004static int ipw2100_wx_set_mode(struct net_device *dev,
7005 struct iw_request_info *info,
7006 union iwreq_data *wrqu, char *extra)
7007{
7008 struct ipw2100_priv *priv = ieee80211_priv(dev);
7009 int err = 0;
7010
7011 IPW_DEBUG_WX("SET Mode -> %d \n", wrqu->mode);
7012
7013 if (wrqu->mode == priv->ieee->iw_mode)
7014 return 0;
7015
7016 down(&priv->action_sem);
7017 if (!(priv->status & STATUS_INITIALIZED)) {
7018 err = -EIO;
7019 goto done;
7020 }
7021
7022 switch (wrqu->mode) {
7023#ifdef CONFIG_IPW2100_MONITOR
7024 case IW_MODE_MONITOR:
7025 err = ipw2100_switch_mode(priv, IW_MODE_MONITOR);
7026 break;
7027#endif /* CONFIG_IPW2100_MONITOR */
7028 case IW_MODE_ADHOC:
7029 err = ipw2100_switch_mode(priv, IW_MODE_ADHOC);
7030 break;
7031 case IW_MODE_INFRA:
7032 case IW_MODE_AUTO:
7033 default:
7034 err = ipw2100_switch_mode(priv, IW_MODE_INFRA);
7035 break;
7036 }
7037
7038done:
7039 up(&priv->action_sem);
7040 return err;
7041}
7042
7043static int ipw2100_wx_get_mode(struct net_device *dev,
7044 struct iw_request_info *info,
7045 union iwreq_data *wrqu, char *extra)
7046{
7047 /*
7048 * This can be called at any time. No action lock required
7049 */
7050
7051 struct ipw2100_priv *priv = ieee80211_priv(dev);
7052
7053 wrqu->mode = priv->ieee->iw_mode;
7054 IPW_DEBUG_WX("GET Mode -> %d\n", wrqu->mode);
7055
7056 return 0;
7057}
7058
7059
7060#define POWER_MODES 5
7061
7062/* Values are in microsecond */
7063const s32 timeout_duration[POWER_MODES] = {
7064 350000,
7065 250000,
7066 75000,
7067 37000,
7068 25000,
7069};
7070
7071const s32 period_duration[POWER_MODES] = {
7072 400000,
7073 700000,
7074 1000000,
7075 1000000,
7076 1000000
7077};
7078
7079static int ipw2100_wx_get_range(struct net_device *dev,
7080 struct iw_request_info *info,
7081 union iwreq_data *wrqu, char *extra)
7082{
7083 /*
7084 * This can be called at any time. No action lock required
7085 */
7086
7087 struct ipw2100_priv *priv = ieee80211_priv(dev);
7088 struct iw_range *range = (struct iw_range *)extra;
7089 u16 val;
7090 int i, level;
7091
7092 wrqu->data.length = sizeof(*range);
7093 memset(range, 0, sizeof(*range));
7094
7095 /* Let's try to keep this struct in the same order as in
7096 * linux/include/wireless.h
7097 */
7098
7099 /* TODO: See what values we can set, and remove the ones we can't
7100 * set, or fill them with some default data.
7101 */
7102
7103 /* ~5 Mb/s real (802.11b) */
7104 range->throughput = 5 * 1000 * 1000;
7105
7106// range->sensitivity; /* signal level threshold range */
7107
7108 range->max_qual.qual = 100;
7109 /* TODO: Find real max RSSI and stick here */
7110 range->max_qual.level = 0;
7111 range->max_qual.noise = 0;
7112 range->max_qual.updated = 7; /* Updated all three */
7113
7114 range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */
7115 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
7116 range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM;
7117 range->avg_qual.noise = 0;
7118 range->avg_qual.updated = 7; /* Updated all three */
7119
7120 range->num_bitrates = RATE_COUNT;
7121
7122 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
7123 range->bitrate[i] = ipw2100_rates_11b[i];
7124 }
7125
7126 range->min_rts = MIN_RTS_THRESHOLD;
7127 range->max_rts = MAX_RTS_THRESHOLD;
7128 range->min_frag = MIN_FRAG_THRESHOLD;
7129 range->max_frag = MAX_FRAG_THRESHOLD;
7130
7131 range->min_pmp = period_duration[0]; /* Minimal PM period */
7132 range->max_pmp = period_duration[POWER_MODES-1];/* Maximal PM period */
7133 range->min_pmt = timeout_duration[POWER_MODES-1]; /* Minimal PM timeout */
7134 range->max_pmt = timeout_duration[0];/* Maximal PM timeout */
7135
7136 /* How to decode max/min PM period */
7137 range->pmp_flags = IW_POWER_PERIOD;
7138 /* How to decode max/min PM period */
7139 range->pmt_flags = IW_POWER_TIMEOUT;
7140 /* What PM options are supported */
7141 range->pm_capa = IW_POWER_TIMEOUT | IW_POWER_PERIOD;
7142
7143 range->encoding_size[0] = 5;
7144 range->encoding_size[1] = 13; /* Different token sizes */
7145 range->num_encoding_sizes = 2; /* Number of entry in the list */
7146 range->max_encoding_tokens = WEP_KEYS; /* Max number of tokens */
7147// range->encoding_login_index; /* token index for login token */
7148
7149 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
7150 range->txpower_capa = IW_TXPOW_DBM;
7151 range->num_txpower = IW_MAX_TXPOWER;
7152 for (i = 0, level = (IPW_TX_POWER_MAX_DBM * 16); i < IW_MAX_TXPOWER;
7153 i++, level -= ((IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM) * 16) /
7154 (IW_MAX_TXPOWER - 1))
7155 range->txpower[i] = level / 16;
7156 } else {
7157 range->txpower_capa = 0;
7158 range->num_txpower = 0;
7159 }
7160
7161
7162 /* Set the Wireless Extension versions */
7163 range->we_version_compiled = WIRELESS_EXT;
7164 range->we_version_source = 16;
7165
7166// range->retry_capa; /* What retry options are supported */
7167// range->retry_flags; /* How to decode max/min retry limit */
7168// range->r_time_flags; /* How to decode max/min retry life */
7169// range->min_retry; /* Minimal number of retries */
7170// range->max_retry; /* Maximal number of retries */
7171// range->min_r_time; /* Minimal retry lifetime */
7172// range->max_r_time; /* Maximal retry lifetime */
7173
7174 range->num_channels = FREQ_COUNT;
7175
7176 val = 0;
7177 for (i = 0; i < FREQ_COUNT; i++) {
7178 // TODO: Include only legal frequencies for some countries
7179// if (local->channel_mask & (1 << i)) {
7180 range->freq[val].i = i + 1;
7181 range->freq[val].m = ipw2100_frequencies[i] * 100000;
7182 range->freq[val].e = 1;
7183 val++;
7184// }
7185 if (val == IW_MAX_FREQUENCIES)
7186 break;
7187 }
7188 range->num_frequency = val;
7189
7190 IPW_DEBUG_WX("GET Range\n");
7191
7192 return 0;
7193}
7194
7195static int ipw2100_wx_set_wap(struct net_device *dev,
7196 struct iw_request_info *info,
7197 union iwreq_data *wrqu, char *extra)
7198{
7199 struct ipw2100_priv *priv = ieee80211_priv(dev);
7200 int err = 0;
7201
7202 static const unsigned char any[] = {
7203 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7204 };
7205 static const unsigned char off[] = {
7206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
7207 };
7208
7209 // sanity checks
7210 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
7211 return -EINVAL;
7212
7213 down(&priv->action_sem);
7214 if (!(priv->status & STATUS_INITIALIZED)) {
7215 err = -EIO;
7216 goto done;
7217 }
7218
7219 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
7220 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
7221 /* we disable mandatory BSSID association */
7222 IPW_DEBUG_WX("exit - disable mandatory BSSID\n");
7223 priv->config &= ~CFG_STATIC_BSSID;
7224 err = ipw2100_set_mandatory_bssid(priv, NULL, 0);
7225 goto done;
7226 }
7227
7228 priv->config |= CFG_STATIC_BSSID;
7229 memcpy(priv->mandatory_bssid_mac, wrqu->ap_addr.sa_data, ETH_ALEN);
7230
7231 err = ipw2100_set_mandatory_bssid(priv, wrqu->ap_addr.sa_data, 0);
7232
7233 IPW_DEBUG_WX("SET BSSID -> %02X:%02X:%02X:%02X:%02X:%02X\n",
7234 wrqu->ap_addr.sa_data[0] & 0xff,
7235 wrqu->ap_addr.sa_data[1] & 0xff,
7236 wrqu->ap_addr.sa_data[2] & 0xff,
7237 wrqu->ap_addr.sa_data[3] & 0xff,
7238 wrqu->ap_addr.sa_data[4] & 0xff,
7239 wrqu->ap_addr.sa_data[5] & 0xff);
7240
7241 done:
7242 up(&priv->action_sem);
7243 return err;
7244}
7245
7246static int ipw2100_wx_get_wap(struct net_device *dev,
7247 struct iw_request_info *info,
7248 union iwreq_data *wrqu, char *extra)
7249{
7250 /*
7251 * This can be called at any time. No action lock required
7252 */
7253
7254 struct ipw2100_priv *priv = ieee80211_priv(dev);
7255
7256 /* If we are associated, trying to associate, or have a statically
7257 * configured BSSID then return that; otherwise return ANY */
7258 if (priv->config & CFG_STATIC_BSSID ||
7259 priv->status & STATUS_ASSOCIATED) {
7260 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
7261 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN);
7262 } else
7263 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
7264
7265 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
7266 MAC_ARG(wrqu->ap_addr.sa_data));
7267 return 0;
7268}
7269
7270static int ipw2100_wx_set_essid(struct net_device *dev,
7271 struct iw_request_info *info,
7272 union iwreq_data *wrqu, char *extra)
7273{
7274 struct ipw2100_priv *priv = ieee80211_priv(dev);
7275 char *essid = ""; /* ANY */
7276 int length = 0;
7277 int err = 0;
7278
7279 down(&priv->action_sem);
7280 if (!(priv->status & STATUS_INITIALIZED)) {
7281 err = -EIO;
7282 goto done;
7283 }
7284
7285 if (wrqu->essid.flags && wrqu->essid.length) {
7286 length = wrqu->essid.length - 1;
7287 essid = extra;
7288 }
7289
7290 if (length == 0) {
7291 IPW_DEBUG_WX("Setting ESSID to ANY\n");
7292 priv->config &= ~CFG_STATIC_ESSID;
7293 err = ipw2100_set_essid(priv, NULL, 0, 0);
7294 goto done;
7295 }
7296
7297 length = min(length, IW_ESSID_MAX_SIZE);
7298
7299 priv->config |= CFG_STATIC_ESSID;
7300
7301 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
7302 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
7303 err = 0;
7304 goto done;
7305 }
7306
7307 IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(essid, length),
7308 length);
7309
7310 priv->essid_len = length;
7311 memcpy(priv->essid, essid, priv->essid_len);
7312
7313 err = ipw2100_set_essid(priv, essid, length, 0);
7314
7315 done:
7316 up(&priv->action_sem);
7317 return err;
7318}
7319
7320static int ipw2100_wx_get_essid(struct net_device *dev,
7321 struct iw_request_info *info,
7322 union iwreq_data *wrqu, char *extra)
7323{
7324 /*
7325 * This can be called at any time. No action lock required
7326 */
7327
7328 struct ipw2100_priv *priv = ieee80211_priv(dev);
7329
7330 /* If we are associated, trying to associate, or have a statically
7331 * configured ESSID then return that; otherwise return ANY */
7332 if (priv->config & CFG_STATIC_ESSID ||
7333 priv->status & STATUS_ASSOCIATED) {
7334 IPW_DEBUG_WX("Getting essid: '%s'\n",
7335 escape_essid(priv->essid, priv->essid_len));
7336 memcpy(extra, priv->essid, priv->essid_len);
7337 wrqu->essid.length = priv->essid_len;
7338 wrqu->essid.flags = 1; /* active */
7339 } else {
7340 IPW_DEBUG_WX("Getting essid: ANY\n");
7341 wrqu->essid.length = 0;
7342 wrqu->essid.flags = 0; /* active */
7343 }
7344
7345 return 0;
7346}
7347
7348static int ipw2100_wx_set_nick(struct net_device *dev,
7349 struct iw_request_info *info,
7350 union iwreq_data *wrqu, char *extra)
7351{
7352 /*
7353 * This can be called at any time. No action lock required
7354 */
7355
7356 struct ipw2100_priv *priv = ieee80211_priv(dev);
7357
7358 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
7359 return -E2BIG;
7360
7361 wrqu->data.length = min((size_t)wrqu->data.length, sizeof(priv->nick));
7362 memset(priv->nick, 0, sizeof(priv->nick));
7363 memcpy(priv->nick, extra, wrqu->data.length);
7364
7365 IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick);
7366
7367 return 0;
7368}
7369
7370static int ipw2100_wx_get_nick(struct net_device *dev,
7371 struct iw_request_info *info,
7372 union iwreq_data *wrqu, char *extra)
7373{
7374 /*
7375 * This can be called at any time. No action lock required
7376 */
7377
7378 struct ipw2100_priv *priv = ieee80211_priv(dev);
7379
7380 wrqu->data.length = strlen(priv->nick) + 1;
7381 memcpy(extra, priv->nick, wrqu->data.length);
7382 wrqu->data.flags = 1; /* active */
7383
7384 IPW_DEBUG_WX("GET Nickname -> %s \n", extra);
7385
7386 return 0;
7387}
7388
7389static int ipw2100_wx_set_rate(struct net_device *dev,
7390 struct iw_request_info *info,
7391 union iwreq_data *wrqu, char *extra)
7392{
7393 struct ipw2100_priv *priv = ieee80211_priv(dev);
7394 u32 target_rate = wrqu->bitrate.value;
7395 u32 rate;
7396 int err = 0;
7397
7398 down(&priv->action_sem);
7399 if (!(priv->status & STATUS_INITIALIZED)) {
7400 err = -EIO;
7401 goto done;
7402 }
7403
7404 rate = 0;
7405
7406 if (target_rate == 1000000 ||
7407 (!wrqu->bitrate.fixed && target_rate > 1000000))
7408 rate |= TX_RATE_1_MBIT;
7409 if (target_rate == 2000000 ||
7410 (!wrqu->bitrate.fixed && target_rate > 2000000))
7411 rate |= TX_RATE_2_MBIT;
7412 if (target_rate == 5500000 ||
7413 (!wrqu->bitrate.fixed && target_rate > 5500000))
7414 rate |= TX_RATE_5_5_MBIT;
7415 if (target_rate == 11000000 ||
7416 (!wrqu->bitrate.fixed && target_rate > 11000000))
7417 rate |= TX_RATE_11_MBIT;
7418 if (rate == 0)
7419 rate = DEFAULT_TX_RATES;
7420
7421 err = ipw2100_set_tx_rates(priv, rate, 0);
7422
7423 IPW_DEBUG_WX("SET Rate -> %04X \n", rate);
7424 done:
7425 up(&priv->action_sem);
7426 return err;
7427}
7428
7429
7430static int ipw2100_wx_get_rate(struct net_device *dev,
7431 struct iw_request_info *info,
7432 union iwreq_data *wrqu, char *extra)
7433{
7434 struct ipw2100_priv *priv = ieee80211_priv(dev);
7435 int val;
7436 int len = sizeof(val);
7437 int err = 0;
7438
7439 if (!(priv->status & STATUS_ENABLED) ||
7440 priv->status & STATUS_RF_KILL_MASK ||
7441 !(priv->status & STATUS_ASSOCIATED)) {
7442 wrqu->bitrate.value = 0;
7443 return 0;
7444 }
7445
7446 down(&priv->action_sem);
7447 if (!(priv->status & STATUS_INITIALIZED)) {
7448 err = -EIO;
7449 goto done;
7450 }
7451
7452 err = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE, &val, &len);
7453 if (err) {
7454 IPW_DEBUG_WX("failed querying ordinals.\n");
7455 return err;
7456 }
7457
7458 switch (val & TX_RATE_MASK) {
7459 case TX_RATE_1_MBIT:
7460 wrqu->bitrate.value = 1000000;
7461 break;
7462 case TX_RATE_2_MBIT:
7463 wrqu->bitrate.value = 2000000;
7464 break;
7465 case TX_RATE_5_5_MBIT:
7466 wrqu->bitrate.value = 5500000;
7467 break;
7468 case TX_RATE_11_MBIT:
7469 wrqu->bitrate.value = 11000000;
7470 break;
7471 default:
7472 wrqu->bitrate.value = 0;
7473 }
7474
7475 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
7476
7477 done:
7478 up(&priv->action_sem);
7479 return err;
7480}
7481
7482static int ipw2100_wx_set_rts(struct net_device *dev,
7483 struct iw_request_info *info,
7484 union iwreq_data *wrqu, char *extra)
7485{
7486 struct ipw2100_priv *priv = ieee80211_priv(dev);
7487 int value, err;
7488
7489 /* Auto RTS not yet supported */
7490 if (wrqu->rts.fixed == 0)
7491 return -EINVAL;
7492
7493 down(&priv->action_sem);
7494 if (!(priv->status & STATUS_INITIALIZED)) {
7495 err = -EIO;
7496 goto done;
7497 }
7498
7499 if (wrqu->rts.disabled)
7500 value = priv->rts_threshold | RTS_DISABLED;
7501 else {
7502 if (wrqu->rts.value < 1 ||
7503 wrqu->rts.value > 2304) {
7504 err = -EINVAL;
7505 goto done;
7506 }
7507 value = wrqu->rts.value;
7508 }
7509
7510 err = ipw2100_set_rts_threshold(priv, value);
7511
7512 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value);
7513 done:
7514 up(&priv->action_sem);
7515 return err;
7516}
7517
7518static int ipw2100_wx_get_rts(struct net_device *dev,
7519 struct iw_request_info *info,
7520 union iwreq_data *wrqu, char *extra)
7521{
7522 /*
7523 * This can be called at any time. No action lock required
7524 */
7525
7526 struct ipw2100_priv *priv = ieee80211_priv(dev);
7527
7528 wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED;
7529 wrqu->rts.fixed = 1; /* no auto select */
7530
7531 /* If RTS is set to the default value, then it is disabled */
7532 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0;
7533
7534 IPW_DEBUG_WX("GET RTS Threshold -> 0x%08X \n", wrqu->rts.value);
7535
7536 return 0;
7537}
7538
7539static int ipw2100_wx_set_txpow(struct net_device *dev,
7540 struct iw_request_info *info,
7541 union iwreq_data *wrqu, char *extra)
7542{
7543 struct ipw2100_priv *priv = ieee80211_priv(dev);
7544 int err = 0, value;
7545
7546 if (priv->ieee->iw_mode != IW_MODE_ADHOC)
7547 return -EINVAL;
7548
7549 if (wrqu->txpower.disabled == 1 || wrqu->txpower.fixed == 0)
7550 value = IPW_TX_POWER_DEFAULT;
7551 else {
7552 if (wrqu->txpower.value < IPW_TX_POWER_MIN_DBM ||
7553 wrqu->txpower.value > IPW_TX_POWER_MAX_DBM)
7554 return -EINVAL;
7555
7556 value = (wrqu->txpower.value - IPW_TX_POWER_MIN_DBM) * 16 /
7557 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
7558 }
7559
7560 down(&priv->action_sem);
7561 if (!(priv->status & STATUS_INITIALIZED)) {
7562 err = -EIO;
7563 goto done;
7564 }
7565
7566 err = ipw2100_set_tx_power(priv, value);
7567
7568 IPW_DEBUG_WX("SET TX Power -> %d \n", value);
7569
7570 done:
7571 up(&priv->action_sem);
7572 return err;
7573}
7574
7575static int ipw2100_wx_get_txpow(struct net_device *dev,
7576 struct iw_request_info *info,
7577 union iwreq_data *wrqu, char *extra)
7578{
7579 /*
7580 * This can be called at any time. No action lock required
7581 */
7582
7583 struct ipw2100_priv *priv = ieee80211_priv(dev);
7584
7585 if (priv->ieee->iw_mode != IW_MODE_ADHOC) {
7586 wrqu->power.disabled = 1;
7587 return 0;
7588 }
7589
7590 if (priv->tx_power == IPW_TX_POWER_DEFAULT) {
7591 wrqu->power.fixed = 0;
7592 wrqu->power.value = IPW_TX_POWER_MAX_DBM;
7593 wrqu->power.disabled = 1;
7594 } else {
7595 wrqu->power.disabled = 0;
7596 wrqu->power.fixed = 1;
7597 wrqu->power.value =
7598 (priv->tx_power *
7599 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM)) /
7600 (IPW_TX_POWER_MAX - IPW_TX_POWER_MIN) +
7601 IPW_TX_POWER_MIN_DBM;
7602 }
7603
7604 wrqu->power.flags = IW_TXPOW_DBM;
7605
7606 IPW_DEBUG_WX("GET TX Power -> %d \n", wrqu->power.value);
7607
7608 return 0;
7609}
7610
7611static int ipw2100_wx_set_frag(struct net_device *dev,
7612 struct iw_request_info *info,
7613 union iwreq_data *wrqu, char *extra)
7614{
7615 /*
7616 * This can be called at any time. No action lock required
7617 */
7618
7619 struct ipw2100_priv *priv = ieee80211_priv(dev);
7620
7621 if (!wrqu->frag.fixed)
7622 return -EINVAL;
7623
7624 if (wrqu->frag.disabled) {
7625 priv->frag_threshold |= FRAG_DISABLED;
7626 priv->ieee->fts = DEFAULT_FTS;
7627 } else {
7628 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
7629 wrqu->frag.value > MAX_FRAG_THRESHOLD)
7630 return -EINVAL;
7631
7632 priv->ieee->fts = wrqu->frag.value & ~0x1;
7633 priv->frag_threshold = priv->ieee->fts;
7634 }
7635
7636 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", priv->ieee->fts);
7637
7638 return 0;
7639}
7640
7641static int ipw2100_wx_get_frag(struct net_device *dev,
7642 struct iw_request_info *info,
7643 union iwreq_data *wrqu, char *extra)
7644{
7645 /*
7646 * This can be called at any time. No action lock required
7647 */
7648
7649 struct ipw2100_priv *priv = ieee80211_priv(dev);
7650 wrqu->frag.value = priv->frag_threshold & ~FRAG_DISABLED;
7651 wrqu->frag.fixed = 0; /* no auto select */
7652 wrqu->frag.disabled = (priv->frag_threshold & FRAG_DISABLED) ? 1 : 0;
7653
7654 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
7655
7656 return 0;
7657}
7658
7659static int ipw2100_wx_set_retry(struct net_device *dev,
7660 struct iw_request_info *info,
7661 union iwreq_data *wrqu, char *extra)
7662{
7663 struct ipw2100_priv *priv = ieee80211_priv(dev);
7664 int err = 0;
7665
7666 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
7667 wrqu->retry.disabled)
7668 return -EINVAL;
7669
7670 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
7671 return 0;
7672
7673 down(&priv->action_sem);
7674 if (!(priv->status & STATUS_INITIALIZED)) {
7675 err = -EIO;
7676 goto done;
7677 }
7678
7679 if (wrqu->retry.flags & IW_RETRY_MIN) {
7680 err = ipw2100_set_short_retry(priv, wrqu->retry.value);
7681 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n",
7682 wrqu->retry.value);
7683 goto done;
7684 }
7685
7686 if (wrqu->retry.flags & IW_RETRY_MAX) {
7687 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7688 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n",
7689 wrqu->retry.value);
7690 goto done;
7691 }
7692
7693 err = ipw2100_set_short_retry(priv, wrqu->retry.value);
7694 if (!err)
7695 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7696
7697 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value);
7698
7699 done:
7700 up(&priv->action_sem);
7701 return err;
7702}
7703
7704static int ipw2100_wx_get_retry(struct net_device *dev,
7705 struct iw_request_info *info,
7706 union iwreq_data *wrqu, char *extra)
7707{
7708 /*
7709 * This can be called at any time. No action lock required
7710 */
7711
7712 struct ipw2100_priv *priv = ieee80211_priv(dev);
7713
7714 wrqu->retry.disabled = 0; /* can't be disabled */
7715
7716 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
7717 IW_RETRY_LIFETIME)
7718 return -EINVAL;
7719
7720 if (wrqu->retry.flags & IW_RETRY_MAX) {
7721 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
7722 wrqu->retry.value = priv->long_retry_limit;
7723 } else {
7724 wrqu->retry.flags =
7725 (priv->short_retry_limit !=
7726 priv->long_retry_limit) ?
7727 IW_RETRY_LIMIT & IW_RETRY_MIN : IW_RETRY_LIMIT;
7728
7729 wrqu->retry.value = priv->short_retry_limit;
7730 }
7731
7732 IPW_DEBUG_WX("GET Retry -> %d \n", wrqu->retry.value);
7733
7734 return 0;
7735}
7736
7737static int ipw2100_wx_set_scan(struct net_device *dev,
7738 struct iw_request_info *info,
7739 union iwreq_data *wrqu, char *extra)
7740{
7741 struct ipw2100_priv *priv = ieee80211_priv(dev);
7742 int err = 0;
7743
7744 down(&priv->action_sem);
7745 if (!(priv->status & STATUS_INITIALIZED)) {
7746 err = -EIO;
7747 goto done;
7748 }
7749
7750 IPW_DEBUG_WX("Initiating scan...\n");
7751 if (ipw2100_set_scan_options(priv) ||
7752 ipw2100_start_scan(priv)) {
7753 IPW_DEBUG_WX("Start scan failed.\n");
7754
7755 /* TODO: Mark a scan as pending so when hardware initialized
7756 * a scan starts */
7757 }
7758
7759 done:
7760 up(&priv->action_sem);
7761 return err;
7762}
7763
7764static int ipw2100_wx_get_scan(struct net_device *dev,
7765 struct iw_request_info *info,
7766 union iwreq_data *wrqu, char *extra)
7767{
7768 /*
7769 * This can be called at any time. No action lock required
7770 */
7771
7772 struct ipw2100_priv *priv = ieee80211_priv(dev);
7773 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
7774}
7775
7776
7777/*
7778 * Implementation based on code in hostap-driver v0.1.3 hostap_ioctl.c
7779 */
7780static int ipw2100_wx_set_encode(struct net_device *dev,
7781 struct iw_request_info *info,
7782 union iwreq_data *wrqu, char *key)
7783{
7784 /*
7785 * No check of STATUS_INITIALIZED required
7786 */
7787
7788 struct ipw2100_priv *priv = ieee80211_priv(dev);
7789 return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
7790}
7791
7792static int ipw2100_wx_get_encode(struct net_device *dev,
7793 struct iw_request_info *info,
7794 union iwreq_data *wrqu, char *key)
7795{
7796 /*
7797 * This can be called at any time. No action lock required
7798 */
7799
7800 struct ipw2100_priv *priv = ieee80211_priv(dev);
7801 return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key);
7802}
7803
7804static int ipw2100_wx_set_power(struct net_device *dev,
7805 struct iw_request_info *info,
7806 union iwreq_data *wrqu, char *extra)
7807{
7808 struct ipw2100_priv *priv = ieee80211_priv(dev);
7809 int err = 0;
7810
7811 down(&priv->action_sem);
7812 if (!(priv->status & STATUS_INITIALIZED)) {
7813 err = -EIO;
7814 goto done;
7815 }
7816
7817 if (wrqu->power.disabled) {
7818 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
7819 err = ipw2100_set_power_mode(priv, IPW_POWER_MODE_CAM);
7820 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
7821 goto done;
7822 }
7823
7824 switch (wrqu->power.flags & IW_POWER_MODE) {
7825 case IW_POWER_ON: /* If not specified */
7826 case IW_POWER_MODE: /* If set all mask */
7827 case IW_POWER_ALL_R: /* If explicitely state all */
7828 break;
7829 default: /* Otherwise we don't support it */
7830 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
7831 wrqu->power.flags);
7832 err = -EOPNOTSUPP;
7833 goto done;
7834 }
7835
7836 /* If the user hasn't specified a power management mode yet, default
7837 * to BATTERY */
7838 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
7839 err = ipw2100_set_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
7840
7841 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n",
7842 priv->power_mode);
7843
7844 done:
7845 up(&priv->action_sem);
7846 return err;
7847
7848}
7849
7850static int ipw2100_wx_get_power(struct net_device *dev,
7851 struct iw_request_info *info,
7852 union iwreq_data *wrqu, char *extra)
7853{
7854 /*
7855 * This can be called at any time. No action lock required
7856 */
7857
7858 struct ipw2100_priv *priv = ieee80211_priv(dev);
7859
7860 if (!(priv->power_mode & IPW_POWER_ENABLED)) {
7861 wrqu->power.disabled = 1;
7862 } else {
7863 wrqu->power.disabled = 0;
7864 wrqu->power.flags = 0;
7865 }
7866
7867 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
7868
7869 return 0;
7870}
7871
7872
7873/*
7874 *
7875 * IWPRIV handlers
7876 *
7877 */
7878#ifdef CONFIG_IPW2100_MONITOR
7879static int ipw2100_wx_set_promisc(struct net_device *dev,
7880 struct iw_request_info *info,
7881 union iwreq_data *wrqu, char *extra)
7882{
7883 struct ipw2100_priv *priv = ieee80211_priv(dev);
7884 int *parms = (int *)extra;
7885 int enable = (parms[0] > 0);
7886 int err = 0;
7887
7888 down(&priv->action_sem);
7889 if (!(priv->status & STATUS_INITIALIZED)) {
7890 err = -EIO;
7891 goto done;
7892 }
7893
7894 if (enable) {
7895 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7896 err = ipw2100_set_channel(priv, parms[1], 0);
7897 goto done;
7898 }
7899 priv->channel = parms[1];
7900 err = ipw2100_switch_mode(priv, IW_MODE_MONITOR);
7901 } else {
7902 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
7903 err = ipw2100_switch_mode(priv, priv->last_mode);
7904 }
7905 done:
7906 up(&priv->action_sem);
7907 return err;
7908}
7909
7910static int ipw2100_wx_reset(struct net_device *dev,
7911 struct iw_request_info *info,
7912 union iwreq_data *wrqu, char *extra)
7913{
7914 struct ipw2100_priv *priv = ieee80211_priv(dev);
7915 if (priv->status & STATUS_INITIALIZED)
7916 schedule_reset(priv);
7917 return 0;
7918}
7919
7920#endif
7921
7922static int ipw2100_wx_set_powermode(struct net_device *dev,
7923 struct iw_request_info *info,
7924 union iwreq_data *wrqu, char *extra)
7925{
7926 struct ipw2100_priv *priv = ieee80211_priv(dev);
7927 int err = 0, mode = *(int *)extra;
7928
7929 down(&priv->action_sem);
7930 if (!(priv->status & STATUS_INITIALIZED)) {
7931 err = -EIO;
7932 goto done;
7933 }
7934
7935 if ((mode < 1) || (mode > POWER_MODES))
7936 mode = IPW_POWER_AUTO;
7937
7938 if (priv->power_mode != mode)
7939 err = ipw2100_set_power_mode(priv, mode);
7940 done:
7941 up(&priv->action_sem);
7942 return err;
7943}
7944
7945#define MAX_POWER_STRING 80
7946static int ipw2100_wx_get_powermode(struct net_device *dev,
7947 struct iw_request_info *info,
7948 union iwreq_data *wrqu, char *extra)
7949{
7950 /*
7951 * This can be called at any time. No action lock required
7952 */
7953
7954 struct ipw2100_priv *priv = ieee80211_priv(dev);
7955 int level = IPW_POWER_LEVEL(priv->power_mode);
7956 s32 timeout, period;
7957
7958 if (!(priv->power_mode & IPW_POWER_ENABLED)) {
7959 snprintf(extra, MAX_POWER_STRING,
7960 "Power save level: %d (Off)", level);
7961 } else {
7962 switch (level) {
7963 case IPW_POWER_MODE_CAM:
7964 snprintf(extra, MAX_POWER_STRING,
7965 "Power save level: %d (None)", level);
7966 break;
7967 case IPW_POWER_AUTO:
7968 snprintf(extra, MAX_POWER_STRING,
7969 "Power save level: %d (Auto)", 0);
7970 break;
7971 default:
7972 timeout = timeout_duration[level - 1] / 1000;
7973 period = period_duration[level - 1] / 1000;
7974 snprintf(extra, MAX_POWER_STRING,
7975 "Power save level: %d "
7976 "(Timeout %dms, Period %dms)",
7977 level, timeout, period);
7978 }
7979 }
7980
7981 wrqu->data.length = strlen(extra) + 1;
7982
7983 return 0;
7984}
7985
7986
7987static int ipw2100_wx_set_preamble(struct net_device *dev,
7988 struct iw_request_info *info,
7989 union iwreq_data *wrqu, char *extra)
7990{
7991 struct ipw2100_priv *priv = ieee80211_priv(dev);
7992 int err, mode = *(int *)extra;
7993
7994 down(&priv->action_sem);
7995 if (!(priv->status & STATUS_INITIALIZED)) {
7996 err = -EIO;
7997 goto done;
7998 }
7999
8000 if (mode == 1)
8001 priv->config |= CFG_LONG_PREAMBLE;
8002 else if (mode == 0)
8003 priv->config &= ~CFG_LONG_PREAMBLE;
8004 else {
8005 err = -EINVAL;
8006 goto done;
8007 }
8008
8009 err = ipw2100_system_config(priv, 0);
8010
8011done:
8012 up(&priv->action_sem);
8013 return err;
8014}
8015
8016static int ipw2100_wx_get_preamble(struct net_device *dev,
8017 struct iw_request_info *info,
8018 union iwreq_data *wrqu, char *extra)
8019{
8020 /*
8021 * This can be called at any time. No action lock required
8022 */
8023
8024 struct ipw2100_priv *priv = ieee80211_priv(dev);
8025
8026 if (priv->config & CFG_LONG_PREAMBLE)
8027 snprintf(wrqu->name, IFNAMSIZ, "long (1)");
8028 else
8029 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
8030
8031 return 0;
8032}
8033
8034static iw_handler ipw2100_wx_handlers[] =
8035{
8036 NULL, /* SIOCSIWCOMMIT */
8037 ipw2100_wx_get_name, /* SIOCGIWNAME */
8038 NULL, /* SIOCSIWNWID */
8039 NULL, /* SIOCGIWNWID */
8040 ipw2100_wx_set_freq, /* SIOCSIWFREQ */
8041 ipw2100_wx_get_freq, /* SIOCGIWFREQ */
8042 ipw2100_wx_set_mode, /* SIOCSIWMODE */
8043 ipw2100_wx_get_mode, /* SIOCGIWMODE */
8044 NULL, /* SIOCSIWSENS */
8045 NULL, /* SIOCGIWSENS */
8046 NULL, /* SIOCSIWRANGE */
8047 ipw2100_wx_get_range, /* SIOCGIWRANGE */
8048 NULL, /* SIOCSIWPRIV */
8049 NULL, /* SIOCGIWPRIV */
8050 NULL, /* SIOCSIWSTATS */
8051 NULL, /* SIOCGIWSTATS */
8052 NULL, /* SIOCSIWSPY */
8053 NULL, /* SIOCGIWSPY */
8054 NULL, /* SIOCGIWTHRSPY */
8055 NULL, /* SIOCWIWTHRSPY */
8056 ipw2100_wx_set_wap, /* SIOCSIWAP */
8057 ipw2100_wx_get_wap, /* SIOCGIWAP */
8058 NULL, /* -- hole -- */
8059 NULL, /* SIOCGIWAPLIST -- depricated */
8060 ipw2100_wx_set_scan, /* SIOCSIWSCAN */
8061 ipw2100_wx_get_scan, /* SIOCGIWSCAN */
8062 ipw2100_wx_set_essid, /* SIOCSIWESSID */
8063 ipw2100_wx_get_essid, /* SIOCGIWESSID */
8064 ipw2100_wx_set_nick, /* SIOCSIWNICKN */
8065 ipw2100_wx_get_nick, /* SIOCGIWNICKN */
8066 NULL, /* -- hole -- */
8067 NULL, /* -- hole -- */
8068 ipw2100_wx_set_rate, /* SIOCSIWRATE */
8069 ipw2100_wx_get_rate, /* SIOCGIWRATE */
8070 ipw2100_wx_set_rts, /* SIOCSIWRTS */
8071 ipw2100_wx_get_rts, /* SIOCGIWRTS */
8072 ipw2100_wx_set_frag, /* SIOCSIWFRAG */
8073 ipw2100_wx_get_frag, /* SIOCGIWFRAG */
8074 ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */
8075 ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */
8076 ipw2100_wx_set_retry, /* SIOCSIWRETRY */
8077 ipw2100_wx_get_retry, /* SIOCGIWRETRY */
8078 ipw2100_wx_set_encode, /* SIOCSIWENCODE */
8079 ipw2100_wx_get_encode, /* SIOCGIWENCODE */
8080 ipw2100_wx_set_power, /* SIOCSIWPOWER */
8081 ipw2100_wx_get_power, /* SIOCGIWPOWER */
8082};
8083
8084#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV
8085#define IPW2100_PRIV_RESET SIOCIWFIRSTPRIV+1
8086#define IPW2100_PRIV_SET_POWER SIOCIWFIRSTPRIV+2
8087#define IPW2100_PRIV_GET_POWER SIOCIWFIRSTPRIV+3
8088#define IPW2100_PRIV_SET_LONGPREAMBLE SIOCIWFIRSTPRIV+4
8089#define IPW2100_PRIV_GET_LONGPREAMBLE SIOCIWFIRSTPRIV+5
8090
8091static const struct iw_priv_args ipw2100_private_args[] = {
8092
8093#ifdef CONFIG_IPW2100_MONITOR
8094 {
8095 IPW2100_PRIV_SET_MONITOR,
8096 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"
8097 },
8098 {
8099 IPW2100_PRIV_RESET,
8100 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"
8101 },
8102#endif /* CONFIG_IPW2100_MONITOR */
8103
8104 {
8105 IPW2100_PRIV_SET_POWER,
8106 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power"
8107 },
8108 {
8109 IPW2100_PRIV_GET_POWER,
8110 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_POWER_STRING, "get_power"
8111 },
8112 {
8113 IPW2100_PRIV_SET_LONGPREAMBLE,
8114 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"
8115 },
8116 {
8117 IPW2100_PRIV_GET_LONGPREAMBLE,
8118 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble"
8119 },
8120};
8121
8122static iw_handler ipw2100_private_handler[] = {
8123#ifdef CONFIG_IPW2100_MONITOR
8124 ipw2100_wx_set_promisc,
8125 ipw2100_wx_reset,
8126#else /* CONFIG_IPW2100_MONITOR */
8127 NULL,
8128 NULL,
8129#endif /* CONFIG_IPW2100_MONITOR */
8130 ipw2100_wx_set_powermode,
8131 ipw2100_wx_get_powermode,
8132 ipw2100_wx_set_preamble,
8133 ipw2100_wx_get_preamble,
8134};
8135
8136struct iw_handler_def ipw2100_wx_handler_def =
8137{
8138 .standard = ipw2100_wx_handlers,
8139 .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
8140 .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
8141 .num_private_args = sizeof(ipw2100_private_args) /
8142 sizeof(struct iw_priv_args),
8143 .private = (iw_handler *)ipw2100_private_handler,
8144 .private_args = (struct iw_priv_args *)ipw2100_private_args,
8145};
8146
8147/*
8148 * Get wireless statistics.
8149 * Called by /proc/net/wireless
8150 * Also called by SIOCGIWSTATS
8151 */
8152struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8153{
8154 enum {
8155 POOR = 30,
8156 FAIR = 60,
8157 GOOD = 80,
8158 VERY_GOOD = 90,
8159 EXCELLENT = 95,
8160 PERFECT = 100
8161 };
8162 int rssi_qual;
8163 int tx_qual;
8164 int beacon_qual;
8165
8166 struct ipw2100_priv *priv = ieee80211_priv(dev);
8167 struct iw_statistics *wstats;
8168 u32 rssi, quality, tx_retries, missed_beacons, tx_failures;
8169 u32 ord_len = sizeof(u32);
8170
8171 if (!priv)
8172 return (struct iw_statistics *) NULL;
8173
8174 wstats = &priv->wstats;
8175
8176 /* if hw is disabled, then ipw2100_get_ordinal() can't be called.
8177 * ipw2100_wx_wireless_stats seems to be called before fw is
8178 * initialized. STATUS_ASSOCIATED will only be set if the hw is up
8179 * and associated; if not associcated, the values are all meaningless
8180 * anyway, so set them all to NULL and INVALID */
8181 if (!(priv->status & STATUS_ASSOCIATED)) {
8182 wstats->miss.beacon = 0;
8183 wstats->discard.retries = 0;
8184 wstats->qual.qual = 0;
8185 wstats->qual.level = 0;
8186 wstats->qual.noise = 0;
8187 wstats->qual.updated = 7;
8188 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
8189 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
8190 return wstats;
8191 }
8192
8193 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_MISSED_BCNS,
8194 &missed_beacons, &ord_len))
8195 goto fail_get_ordinal;
8196
8197 /* If we don't have a connection the quality and level is 0*/
8198 if (!(priv->status & STATUS_ASSOCIATED)) {
8199 wstats->qual.qual = 0;
8200 wstats->qual.level = 0;
8201 } else {
8202 if (ipw2100_get_ordinal(priv, IPW_ORD_RSSI_AVG_CURR,
8203 &rssi, &ord_len))
8204 goto fail_get_ordinal;
8205 wstats->qual.level = rssi + IPW2100_RSSI_TO_DBM;
8206 if (rssi < 10)
8207 rssi_qual = rssi * POOR / 10;
8208 else if (rssi < 15)
8209 rssi_qual = (rssi - 10) * (FAIR - POOR) / 5 + POOR;
8210 else if (rssi < 20)
8211 rssi_qual = (rssi - 15) * (GOOD - FAIR) / 5 + FAIR;
8212 else if (rssi < 30)
8213 rssi_qual = (rssi - 20) * (VERY_GOOD - GOOD) /
8214 10 + GOOD;
8215 else
8216 rssi_qual = (rssi - 30) * (PERFECT - VERY_GOOD) /
8217 10 + VERY_GOOD;
8218
8219 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_RETRIES,
8220 &tx_retries, &ord_len))
8221 goto fail_get_ordinal;
8222
8223 if (tx_retries > 75)
8224 tx_qual = (90 - tx_retries) * POOR / 15;
8225 else if (tx_retries > 70)
8226 tx_qual = (75 - tx_retries) * (FAIR - POOR) / 5 + POOR;
8227 else if (tx_retries > 65)
8228 tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR;
8229 else if (tx_retries > 50)
8230 tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) /
8231 15 + GOOD;
8232 else
8233 tx_qual = (50 - tx_retries) *
8234 (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
8235
8236 if (missed_beacons > 50)
8237 beacon_qual = (60 - missed_beacons) * POOR / 10;
8238 else if (missed_beacons > 40)
8239 beacon_qual = (50 - missed_beacons) * (FAIR - POOR) /
8240 10 + POOR;
8241 else if (missed_beacons > 32)
8242 beacon_qual = (40 - missed_beacons) * (GOOD - FAIR) /
8243 18 + FAIR;
8244 else if (missed_beacons > 20)
8245 beacon_qual = (32 - missed_beacons) *
8246 (VERY_GOOD - GOOD) / 20 + GOOD;
8247 else
8248 beacon_qual = (20 - missed_beacons) *
8249 (PERFECT - VERY_GOOD) / 20 + VERY_GOOD;
8250
8251 quality = min(beacon_qual, min(tx_qual, rssi_qual));
8252
8253#ifdef CONFIG_IPW_DEBUG
8254 if (beacon_qual == quality)
8255 IPW_DEBUG_WX("Quality clamped by Missed Beacons\n");
8256 else if (tx_qual == quality)
8257 IPW_DEBUG_WX("Quality clamped by Tx Retries\n");
8258 else if (quality != 100)
8259 IPW_DEBUG_WX("Quality clamped by Signal Strength\n");
8260 else
8261 IPW_DEBUG_WX("Quality not clamped.\n");
8262#endif
8263
8264 wstats->qual.qual = quality;
8265 wstats->qual.level = rssi + IPW2100_RSSI_TO_DBM;
8266 }
8267
8268 wstats->qual.noise = 0;
8269 wstats->qual.updated = 7;
8270 wstats->qual.updated |= IW_QUAL_NOISE_INVALID;
8271
8272 /* FIXME: this is percent and not a # */
8273 wstats->miss.beacon = missed_beacons;
8274
8275 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURES,
8276 &tx_failures, &ord_len))
8277 goto fail_get_ordinal;
8278 wstats->discard.retries = tx_failures;
8279
8280 return wstats;
8281
8282 fail_get_ordinal:
8283 IPW_DEBUG_WX("failed querying ordinals.\n");
8284
8285 return (struct iw_statistics *) NULL;
8286}
8287
8288void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8289{
8290 union iwreq_data wrqu;
8291 int len = ETH_ALEN;
8292
8293 if (priv->status & STATUS_STOPPING)
8294 return;
8295
8296 down(&priv->action_sem);
8297
8298 IPW_DEBUG_WX("enter\n");
8299
8300 up(&priv->action_sem);
8301
8302 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
8303
8304 /* Fetch BSSID from the hardware */
8305 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) ||
8306 priv->status & STATUS_RF_KILL_MASK ||
8307 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID,
8308 &priv->bssid, &len)) {
8309 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
8310 } else {
8311 /* We now have the BSSID, so can finish setting to the full
8312 * associated state */
8313 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
8314 memcpy(&priv->ieee->bssid, priv->bssid, ETH_ALEN);
8315 priv->status &= ~STATUS_ASSOCIATING;
8316 priv->status |= STATUS_ASSOCIATED;
8317 netif_carrier_on(priv->net_dev);
8318 if (netif_queue_stopped(priv->net_dev)) {
8319 IPW_DEBUG_INFO("Waking net queue.\n");
8320 netif_wake_queue(priv->net_dev);
8321 } else {
8322 IPW_DEBUG_INFO("Starting net queue.\n");
8323 netif_start_queue(priv->net_dev);
8324 }
8325 }
8326
8327 if (!(priv->status & STATUS_ASSOCIATED)) {
8328 IPW_DEBUG_WX("Configuring ESSID\n");
8329 down(&priv->action_sem);
8330 /* This is a disassociation event, so kick the firmware to
8331 * look for another AP */
8332 if (priv->config & CFG_STATIC_ESSID)
8333 ipw2100_set_essid(priv, priv->essid, priv->essid_len, 0);
8334 else
8335 ipw2100_set_essid(priv, NULL, 0, 0);
8336 up(&priv->action_sem);
8337 }
8338
8339 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
8340}
8341
8342#define IPW2100_FW_MAJOR_VERSION 1
8343#define IPW2100_FW_MINOR_VERSION 3
8344
8345#define IPW2100_FW_MINOR(x) ((x & 0xff) >> 8)
8346#define IPW2100_FW_MAJOR(x) (x & 0xff)
8347
8348#define IPW2100_FW_VERSION ((IPW2100_FW_MINOR_VERSION << 8) | \
8349 IPW2100_FW_MAJOR_VERSION)
8350
8351#define IPW2100_FW_PREFIX "ipw2100-" __stringify(IPW2100_FW_MAJOR_VERSION) \
8352"." __stringify(IPW2100_FW_MINOR_VERSION)
8353
8354#define IPW2100_FW_NAME(x) IPW2100_FW_PREFIX "" x ".fw"
8355
8356
8357/*
8358
8359BINARY FIRMWARE HEADER FORMAT
8360
8361offset length desc
83620 2 version
83632 2 mode == 0:BSS,1:IBSS,2:MONITOR
83644 4 fw_len
83658 4 uc_len
8366C fw_len firmware data
836712 + fw_len uc_len microcode data
8368
8369*/
8370
8371struct ipw2100_fw_header {
8372 short version;
8373 short mode;
8374 unsigned int fw_size;
8375 unsigned int uc_size;
8376} __attribute__ ((packed));
8377
8378
8379
8380static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
8381{
8382 struct ipw2100_fw_header *h =
8383 (struct ipw2100_fw_header *)fw->fw_entry->data;
8384
8385 if (IPW2100_FW_MAJOR(h->version) != IPW2100_FW_MAJOR_VERSION) {
8386 IPW_DEBUG_WARNING("Firmware image not compatible "
8387 "(detected version id of %u). "
8388 "See Documentation/networking/README.ipw2100\n",
8389 h->version);
8390 return 1;
8391 }
8392
8393 fw->version = h->version;
8394 fw->fw.data = fw->fw_entry->data + sizeof(struct ipw2100_fw_header);
8395 fw->fw.size = h->fw_size;
8396 fw->uc.data = fw->fw.data + h->fw_size;
8397 fw->uc.size = h->uc_size;
8398
8399 return 0;
8400}
8401
8402
8403int ipw2100_get_firmware(struct ipw2100_priv *priv, struct ipw2100_fw *fw)
8404{
8405 char *fw_name;
8406 int rc;
8407
8408 IPW_DEBUG_INFO("%s: Using hotplug firmware load.\n",
8409 priv->net_dev->name);
8410
8411 switch (priv->ieee->iw_mode) {
8412 case IW_MODE_ADHOC:
8413 fw_name = IPW2100_FW_NAME("-i");
8414 break;
8415#ifdef CONFIG_IPW2100_MONITOR
8416 case IW_MODE_MONITOR:
8417 fw_name = IPW2100_FW_NAME("-p");
8418 break;
8419#endif
8420 case IW_MODE_INFRA:
8421 default:
8422 fw_name = IPW2100_FW_NAME("");
8423 break;
8424 }
8425
8426 rc = request_firmware(&fw->fw_entry, fw_name, &priv->pci_dev->dev);
8427
8428 if (rc < 0) {
8429 IPW_DEBUG_ERROR(
8430 "%s: Firmware '%s' not available or load failed.\n",
8431 priv->net_dev->name, fw_name);
8432 return rc;
8433 }
8434 IPW_DEBUG_INFO("firmware data %p size %d\n", fw->fw_entry->data,
8435 fw->fw_entry->size);
8436
8437 ipw2100_mod_firmware_load(fw);
8438
8439 return 0;
8440}
8441
8442void ipw2100_release_firmware(struct ipw2100_priv *priv,
8443 struct ipw2100_fw *fw)
8444{
8445 fw->version = 0;
8446 if (fw->fw_entry)
8447 release_firmware(fw->fw_entry);
8448 fw->fw_entry = NULL;
8449}
8450
8451
8452int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf, size_t max)
8453{
8454 char ver[MAX_FW_VERSION_LEN];
8455 u32 len = MAX_FW_VERSION_LEN;
8456 u32 tmp;
8457 int i;
8458 /* firmware version is an ascii string (max len of 14) */
8459 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_FW_VER_NUM,
8460 ver, &len))
8461 return -EIO;
8462 tmp = max;
8463 if (len >= max)
8464 len = max - 1;
8465 for (i = 0; i < len; i++)
8466 buf[i] = ver[i];
8467 buf[i] = '\0';
8468 return tmp;
8469}
8470
8471int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf, size_t max)
8472{
8473 u32 ver;
8474 u32 len = sizeof(ver);
8475 /* microcode version is a 32 bit integer */
8476 if (ipw2100_get_ordinal(priv, IPW_ORD_UCODE_VERSION,
8477 &ver, &len))
8478 return -EIO;
8479 return snprintf(buf, max, "%08X", ver);
8480}
8481
8482/*
8483 * On exit, the firmware will have been freed from the fw list
8484 */
8485int ipw2100_fw_download(struct ipw2100_priv *priv, struct ipw2100_fw *fw)
8486{
8487 /* firmware is constructed of N contiguous entries, each entry is
8488 * structured as:
8489 *
8490 * offset sie desc
8491 * 0 4 address to write to
8492 * 4 2 length of data run
8493 * 6 length data
8494 */
8495 unsigned int addr;
8496 unsigned short len;
8497
8498 const unsigned char *firmware_data = fw->fw.data;
8499 unsigned int firmware_data_left = fw->fw.size;
8500
8501 while (firmware_data_left > 0) {
8502 addr = *(u32 *)(firmware_data);
8503 firmware_data += 4;
8504 firmware_data_left -= 4;
8505
8506 len = *(u16 *)(firmware_data);
8507 firmware_data += 2;
8508 firmware_data_left -= 2;
8509
8510 if (len > 32) {
8511 IPW_DEBUG_ERROR(
8512 "Invalid firmware run-length of %d bytes\n",
8513 len);
8514 return -EINVAL;
8515 }
8516
8517 write_nic_memory(priv->net_dev, addr, len, firmware_data);
8518 firmware_data += len;
8519 firmware_data_left -= len;
8520 }
8521
8522 return 0;
8523}
8524
8525struct symbol_alive_response {
8526 u8 cmd_id;
8527 u8 seq_num;
8528 u8 ucode_rev;
8529 u8 eeprom_valid;
8530 u16 valid_flags;
8531 u8 IEEE_addr[6];
8532 u16 flags;
8533 u16 pcb_rev;
8534 u16 clock_settle_time; // 1us LSB
8535 u16 powerup_settle_time; // 1us LSB
8536 u16 hop_settle_time; // 1us LSB
8537 u8 date[3]; // month, day, year
8538 u8 time[2]; // hours, minutes
8539 u8 ucode_valid;
8540};
8541
8542int ipw2100_ucode_download(struct ipw2100_priv *priv, struct ipw2100_fw *fw)
8543{
8544 struct net_device *dev = priv->net_dev;
8545 const unsigned char *microcode_data = fw->uc.data;
8546 unsigned int microcode_data_left = fw->uc.size;
8547
8548 struct symbol_alive_response response;
8549 int i, j;
8550 u8 data;
8551
8552 /* Symbol control */
8553 write_nic_word(dev, IPW2100_CONTROL_REG, 0x703);
8554 readl((void *)(dev->base_addr));
8555 write_nic_word(dev, IPW2100_CONTROL_REG, 0x707);
8556 readl((void *)(dev->base_addr));
8557
8558 /* HW config */
8559 write_nic_byte(dev, 0x210014, 0x72); /* fifo width =16 */
8560 readl((void *)(dev->base_addr));
8561 write_nic_byte(dev, 0x210014, 0x72); /* fifo width =16 */
8562 readl((void *)(dev->base_addr));
8563
8564 /* EN_CS_ACCESS bit to reset control store pointer */
8565 write_nic_byte(dev, 0x210000, 0x40);
8566 readl((void *)(dev->base_addr));
8567 write_nic_byte(dev, 0x210000, 0x0);
8568 readl((void *)(dev->base_addr));
8569 write_nic_byte(dev, 0x210000, 0x40);
8570 readl((void *)(dev->base_addr));
8571
8572 /* copy microcode from buffer into Symbol */
8573
8574 while (microcode_data_left > 0) {
8575 write_nic_byte(dev, 0x210010, *microcode_data++);
8576 write_nic_byte(dev, 0x210010, *microcode_data++);
8577 microcode_data_left -= 2;
8578 }
8579
8580 /* EN_CS_ACCESS bit to reset the control store pointer */
8581 write_nic_byte(dev, 0x210000, 0x0);
8582 readl((void *)(dev->base_addr));
8583
8584 /* Enable System (Reg 0)
8585 * first enable causes garbage in RX FIFO */
8586 write_nic_byte(dev, 0x210000, 0x0);
8587 readl((void *)(dev->base_addr));
8588 write_nic_byte(dev, 0x210000, 0x80);
8589 readl((void *)(dev->base_addr));
8590
8591 /* Reset External Baseband Reg */
8592 write_nic_word(dev, IPW2100_CONTROL_REG, 0x703);
8593 readl((void *)(dev->base_addr));
8594 write_nic_word(dev, IPW2100_CONTROL_REG, 0x707);
8595 readl((void *)(dev->base_addr));
8596
8597 /* HW Config (Reg 5) */
8598 write_nic_byte(dev, 0x210014, 0x72); // fifo width =16
8599 readl((void *)(dev->base_addr));
8600 write_nic_byte(dev, 0x210014, 0x72); // fifo width =16
8601 readl((void *)(dev->base_addr));
8602
8603 /* Enable System (Reg 0)
8604 * second enable should be OK */
8605 write_nic_byte(dev, 0x210000, 0x00); // clear enable system
8606 readl((void *)(dev->base_addr));
8607 write_nic_byte(dev, 0x210000, 0x80); // set enable system
8608
8609 /* check Symbol is enabled - upped this from 5 as it wasn't always
8610 * catching the update */
8611 for (i = 0; i < 10; i++) {
8612 udelay(10);
8613
8614 /* check Dino is enabled bit */
8615 read_nic_byte(dev, 0x210000, &data);
8616 if (data & 0x1)
8617 break;
8618 }
8619
8620 if (i == 10) {
8621 IPW_DEBUG_ERROR("%s: Error initializing Symbol\n",
8622 dev->name);
8623 return -EIO;
8624 }
8625
8626 /* Get Symbol alive response */
8627 for (i = 0; i < 30; i++) {
8628 /* Read alive response structure */
8629 for (j = 0;
8630 j < (sizeof(struct symbol_alive_response) >> 1);
8631 j++)
8632 read_nic_word(dev, 0x210004,
8633 ((u16 *)&response) + j);
8634
8635 if ((response.cmd_id == 1) &&
8636 (response.ucode_valid == 0x1))
8637 break;
8638 udelay(10);
8639 }
8640
8641 if (i == 30) {
8642 IPW_DEBUG_ERROR("%s: No response from Symbol - hw not alive\n",
8643 dev->name);
8644 printk_buf(IPW_DL_ERROR, (u8*)&response, sizeof(response));
8645 return -EIO;
8646 }
8647
8648 return 0;
8649}
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
new file mode 100644
index 000000000000..0cc5746dd4f1
--- /dev/null
+++ b/drivers/net/wireless/ipw2100.h
@@ -0,0 +1,1278 @@
1/******************************************************************************
2
3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as
7 published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 The full GNU General Public License is included in this distribution in the
19 file called LICENSE.
20
21 Contact Information:
22 James P. Ketrenos <ipw2100-admin@linux.intel.com>
23 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
25******************************************************************************/
26#ifndef _IPW2100_H
27#define _IPW2100_H
28
29#include <linux/sched.h>
30#include <linux/interrupt.h>
31#include <linux/netdevice.h>
32#include <linux/etherdevice.h>
33#include <linux/list.h>
34#include <linux/delay.h>
35#include <linux/skbuff.h>
36#include <asm/io.h>
37#include <linux/socket.h>
38#include <linux/if_arp.h>
39#include <linux/wireless.h>
40#include <linux/version.h>
41#include <net/iw_handler.h> // new driver API
42
43#include <net/ieee80211.h>
44
45#include <linux/workqueue.h>
46
47#ifndef IRQ_NONE
48typedef void irqreturn_t;
49#define IRQ_NONE
50#define IRQ_HANDLED
51#define IRQ_RETVAL(x)
52#endif
53
54#if WIRELESS_EXT < 17
55#define IW_QUAL_QUAL_INVALID 0x10
56#define IW_QUAL_LEVEL_INVALID 0x20
57#define IW_QUAL_NOISE_INVALID 0x40
58#endif
59
60#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) )
61#define pci_dma_sync_single_for_cpu pci_dma_sync_single
62#define pci_dma_sync_single_for_device pci_dma_sync_single
63#endif
64
65#ifndef HAVE_FREE_NETDEV
66#define free_netdev(x) kfree(x)
67#endif
68
69
70
71struct ipw2100_priv;
72struct ipw2100_tx_packet;
73struct ipw2100_rx_packet;
74
75#ifdef CONFIG_IPW_DEBUG
76enum { IPW_DEBUG_ENABLED = 1 };
77extern u32 ipw2100_debug_level;
78#define IPW_DEBUG(level, message...) \
79do { \
80 if (ipw2100_debug_level & (level)) { \
81 printk(KERN_DEBUG "ipw2100: %c %s ", \
82 in_interrupt() ? 'I' : 'U', __FUNCTION__); \
83 printk(message); \
84 } \
85} while (0)
86#else
87enum { IPW_DEBUG_ENABLED = 0 };
88#define IPW_DEBUG(level, message...) do {} while (0)
89#endif /* CONFIG_IPW_DEBUG */
90
91#define IPW_DL_UNINIT 0x80000000
92#define IPW_DL_NONE 0x00000000
93#define IPW_DL_ALL 0x7FFFFFFF
94
95/*
96 * To use the debug system;
97 *
98 * If you are defining a new debug classification, simply add it to the #define
99 * list here in the form of:
100 *
101 * #define IPW_DL_xxxx VALUE
102 *
103 * shifting value to the left one bit from the previous entry. xxxx should be
104 * the name of the classification (for example, WEP)
105 *
106 * You then need to either add a IPW2100_xxxx_DEBUG() macro definition for your
107 * classification, or use IPW_DEBUG(IPW_DL_xxxx, ...) whenever you want
108 * to send output to that classification.
109 *
110 * To add your debug level to the list of levels seen when you perform
111 *
112 * % cat /proc/net/ipw2100/debug_level
113 *
114 * you simply need to add your entry to the ipw2100_debug_levels array.
115 *
116 * If you do not see debug_level in /proc/net/ipw2100 then you do not have
117 * CONFIG_IPW_DEBUG defined in your kernel configuration
118 *
119 */
120
121#define IPW_DL_ERROR (1<<0)
122#define IPW_DL_WARNING (1<<1)
123#define IPW_DL_INFO (1<<2)
124#define IPW_DL_WX (1<<3)
125#define IPW_DL_HC (1<<5)
126#define IPW_DL_STATE (1<<6)
127
128#define IPW_DL_NOTIF (1<<10)
129#define IPW_DL_SCAN (1<<11)
130#define IPW_DL_ASSOC (1<<12)
131#define IPW_DL_DROP (1<<13)
132
133#define IPW_DL_IOCTL (1<<14)
134#define IPW_DL_RF_KILL (1<<17)
135
136
137#define IPW_DL_MANAGE (1<<15)
138#define IPW_DL_FW (1<<16)
139
140#define IPW_DL_FRAG (1<<21)
141#define IPW_DL_WEP (1<<22)
142#define IPW_DL_TX (1<<23)
143#define IPW_DL_RX (1<<24)
144#define IPW_DL_ISR (1<<25)
145#define IPW_DL_IO (1<<26)
146#define IPW_DL_TRACE (1<<28)
147
148#define IPW_DEBUG_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
149#define IPW_DEBUG_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
150#define IPW_DEBUG_INFO(f...) IPW_DEBUG(IPW_DL_INFO, ## f)
151#define IPW_DEBUG_WX(f...) IPW_DEBUG(IPW_DL_WX, ## f)
152#define IPW_DEBUG_SCAN(f...) IPW_DEBUG(IPW_DL_SCAN, ## f)
153#define IPW_DEBUG_NOTIF(f...) IPW_DEBUG(IPW_DL_NOTIF, ## f)
154#define IPW_DEBUG_TRACE(f...) IPW_DEBUG(IPW_DL_TRACE, ## f)
155#define IPW_DEBUG_RX(f...) IPW_DEBUG(IPW_DL_RX, ## f)
156#define IPW_DEBUG_TX(f...) IPW_DEBUG(IPW_DL_TX, ## f)
157#define IPW_DEBUG_ISR(f...) IPW_DEBUG(IPW_DL_ISR, ## f)
158#define IPW_DEBUG_MANAGEMENT(f...) IPW_DEBUG(IPW_DL_MANAGE, ## f)
159#define IPW_DEBUG_WEP(f...) IPW_DEBUG(IPW_DL_WEP, ## f)
160#define IPW_DEBUG_HC(f...) IPW_DEBUG(IPW_DL_HC, ## f)
161#define IPW_DEBUG_FRAG(f...) IPW_DEBUG(IPW_DL_FRAG, ## f)
162#define IPW_DEBUG_FW(f...) IPW_DEBUG(IPW_DL_FW, ## f)
163#define IPW_DEBUG_RF_KILL(f...) IPW_DEBUG(IPW_DL_RF_KILL, ## f)
164#define IPW_DEBUG_DROP(f...) IPW_DEBUG(IPW_DL_DROP, ## f)
165#define IPW_DEBUG_IO(f...) IPW_DEBUG(IPW_DL_IO, ## f)
166#define IPW_DEBUG_IOCTL(f...) IPW_DEBUG(IPW_DL_IOCTL, ## f)
167#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
168#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
169
170
171#define VERIFY(f) \
172{ \
173 int status = 0; \
174 status = f; \
175 if(status) \
176 return status; \
177}
178
179enum {
180 IPW_HW_STATE_DISABLED = 1,
181 IPW_HW_STATE_ENABLED = 0
182};
183
184struct ssid_context {
185 char ssid[IW_ESSID_MAX_SIZE + 1];
186 int ssid_len;
187 unsigned char bssid[ETH_ALEN];
188 int port_type;
189 int channel;
190
191};
192
193extern const char *port_type_str[];
194extern const char *band_str[];
195
196#define NUMBER_OF_BD_PER_COMMAND_PACKET 1
197#define NUMBER_OF_BD_PER_DATA_PACKET 2
198
199#define IPW_MAX_BDS 6
200#define NUMBER_OF_OVERHEAD_BDS_PER_PACKETR 2
201#define NUMBER_OF_BDS_TO_LEAVE_FOR_COMMANDS 1
202
203#define REQUIRED_SPACE_IN_RING_FOR_COMMAND_PACKET \
204 (IPW_BD_QUEUE_W_R_MIN_SPARE + NUMBER_OF_BD_PER_COMMAND_PACKET)
205
206struct bd_status {
207 union {
208 struct { u8 nlf:1, txType:2, intEnabled:1, reserved:4;} fields;
209 u8 field;
210 } info;
211} __attribute__ ((packed));
212
213#define IPW_BUFDESC_LAST_FRAG 0
214
215struct ipw2100_bd {
216 u32 host_addr;
217 u32 buf_length;
218 struct bd_status status;
219 /* number of fragments for frame (should be set only for
220 * 1st TBD) */
221 u8 num_fragments;
222 u8 reserved[6];
223} __attribute__ ((packed));
224
225#define IPW_BD_QUEUE_LENGTH(n) (1<<n)
226#define IPW_BD_ALIGNMENT(L) (L*sizeof(struct ipw2100_bd))
227
228#define IPW_BD_STATUS_TX_FRAME_802_3 0x00
229#define IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT 0x01
230#define IPW_BD_STATUS_TX_FRAME_COMMAND 0x02
231#define IPW_BD_STATUS_TX_FRAME_802_11 0x04
232#define IPW_BD_STATUS_TX_INTERRUPT_ENABLE 0x08
233
234struct ipw2100_bd_queue {
235 /* driver (virtual) pointer to queue */
236 struct ipw2100_bd *drv;
237
238 /* firmware (physical) pointer to queue */
239 dma_addr_t nic;
240
241 /* Length of phy memory allocated for BDs */
242 u32 size;
243
244 /* Number of BDs in queue (and in array) */
245 u32 entries;
246
247 /* Number of available BDs (invalid for NIC BDs) */
248 u32 available;
249
250 /* Offset of oldest used BD in array (next one to
251 * check for completion) */
252 u32 oldest;
253
254 /* Offset of next available (unused) BD */
255 u32 next;
256};
257
258#define RX_QUEUE_LENGTH 256
259#define TX_QUEUE_LENGTH 256
260#define HW_QUEUE_LENGTH 256
261
262#define TX_PENDED_QUEUE_LENGTH (TX_QUEUE_LENGTH / NUMBER_OF_BD_PER_DATA_PACKET)
263
264#define STATUS_TYPE_MASK 0x0000000f
265#define COMMAND_STATUS_VAL 0
266#define STATUS_CHANGE_VAL 1
267#define P80211_DATA_VAL 2
268#define P8023_DATA_VAL 3
269#define HOST_NOTIFICATION_VAL 4
270
271#define IPW2100_RSSI_TO_DBM (-98)
272
273struct ipw2100_status {
274 u32 frame_size;
275 u16 status_fields;
276 u8 flags;
277#define IPW_STATUS_FLAG_DECRYPTED (1<<0)
278#define IPW_STATUS_FLAG_WEP_ENCRYPTED (1<<1)
279#define IPW_STATUS_FLAG_CRC_ERROR (1<<2)
280 u8 rssi;
281} __attribute__ ((packed));
282
283struct ipw2100_status_queue {
284 /* driver (virtual) pointer to queue */
285 struct ipw2100_status *drv;
286
287 /* firmware (physical) pointer to queue */
288 dma_addr_t nic;
289
290 /* Length of phy memory allocated for BDs */
291 u32 size;
292};
293
294#define HOST_COMMAND_PARAMS_REG_LEN 100
295#define CMD_STATUS_PARAMS_REG_LEN 3
296
297#define IPW_WPA_CAPABILITIES 0x1
298#define IPW_WPA_LISTENINTERVAL 0x2
299#define IPW_WPA_AP_ADDRESS 0x4
300
301#define IPW_MAX_VAR_IE_LEN ((HOST_COMMAND_PARAMS_REG_LEN - 4) * sizeof(u32))
302
303struct ipw2100_wpa_assoc_frame {
304 u16 fixed_ie_mask;
305 struct {
306 u16 capab_info;
307 u16 listen_interval;
308 u8 current_ap[ETH_ALEN];
309 } fixed_ies;
310 u32 var_ie_len;
311 u8 var_ie[IPW_MAX_VAR_IE_LEN];
312};
313
314#define IPW_BSS 1
315#define IPW_MONITOR 2
316#define IPW_IBSS 3
317
318/**
319 * @struct _tx_cmd - HWCommand
320 * @brief H/W command structure.
321 */
322struct ipw2100_cmd_header {
323 u32 host_command_reg;
324 u32 host_command_reg1;
325 u32 sequence;
326 u32 host_command_len_reg;
327 u32 host_command_params_reg[HOST_COMMAND_PARAMS_REG_LEN];
328 u32 cmd_status_reg;
329 u32 cmd_status_params_reg[CMD_STATUS_PARAMS_REG_LEN];
330 u32 rxq_base_ptr;
331 u32 rxq_next_ptr;
332 u32 rxq_host_ptr;
333 u32 txq_base_ptr;
334 u32 txq_next_ptr;
335 u32 txq_host_ptr;
336 u32 tx_status_reg;
337 u32 reserved;
338 u32 status_change_reg;
339 u32 reserved1[3];
340 u32 *ordinal1_ptr;
341 u32 *ordinal2_ptr;
342} __attribute__ ((packed));
343
344struct ipw2100_data_header {
345 u32 host_command_reg;
346 u32 host_command_reg1;
347 u8 encrypted; // BOOLEAN in win! TRUE if frame is enc by driver
348 u8 needs_encryption; // BOOLEAN in win! TRUE if frma need to be enc in NIC
349 u8 wep_index; // 0 no key, 1-4 key index, 0xff immediate key
350 u8 key_size; // 0 no imm key, 0x5 64bit encr, 0xd 128bit encr, 0x10 128bit encr and 128bit IV
351 u8 key[16];
352 u8 reserved[10]; // f/w reserved
353 u8 src_addr[ETH_ALEN];
354 u8 dst_addr[ETH_ALEN];
355 u16 fragment_size;
356} __attribute__ ((packed));
357
358// Host command data structure
359struct host_command {
360 u32 host_command; // COMMAND ID
361 u32 host_command1; // COMMAND ID
362 u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID)
363 u32 host_command_length; // LENGTH
364 u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS
365} __attribute__ ((packed));
366
367
368typedef enum {
369 POWER_ON_RESET,
370 EXIT_POWER_DOWN_RESET,
371 SW_RESET,
372 EEPROM_RW,
373 SW_RE_INIT
374} ipw2100_reset_event;
375
376enum {
377 COMMAND = 0xCAFE,
378 DATA,
379 RX
380};
381
382
383struct ipw2100_tx_packet {
384 int type;
385 int index;
386 union {
387 struct { /* COMMAND */
388 struct ipw2100_cmd_header* cmd;
389 dma_addr_t cmd_phys;
390 } c_struct;
391 struct { /* DATA */
392 struct ipw2100_data_header* data;
393 dma_addr_t data_phys;
394 struct ieee80211_txb *txb;
395 } d_struct;
396 } info;
397 int jiffy_start;
398
399 struct list_head list;
400};
401
402
403struct ipw2100_rx_packet {
404 struct ipw2100_rx *rxp;
405 dma_addr_t dma_addr;
406 int jiffy_start;
407 struct sk_buff *skb;
408 struct list_head list;
409};
410
411#define FRAG_DISABLED (1<<31)
412#define RTS_DISABLED (1<<31)
413#define MAX_RTS_THRESHOLD 2304U
414#define MIN_RTS_THRESHOLD 1U
415#define DEFAULT_RTS_THRESHOLD 1000U
416
417#define DEFAULT_BEACON_INTERVAL 100U
418#define DEFAULT_SHORT_RETRY_LIMIT 7U
419#define DEFAULT_LONG_RETRY_LIMIT 4U
420
421struct ipw2100_ordinals {
422 u32 table1_addr;
423 u32 table2_addr;
424 u32 table1_size;
425 u32 table2_size;
426};
427
428/* Host Notification header */
429struct ipw2100_notification {
430 u32 hnhdr_subtype; /* type of host notification */
431 u32 hnhdr_size; /* size in bytes of data
432 or number of entries, if table.
433 Does NOT include header */
434} __attribute__ ((packed));
435
436#define MAX_KEY_SIZE 16
437#define MAX_KEYS 8
438
439#define IPW2100_WEP_ENABLE (1<<1)
440#define IPW2100_WEP_DROP_CLEAR (1<<2)
441
442#define IPW_NONE_CIPHER (1<<0)
443#define IPW_WEP40_CIPHER (1<<1)
444#define IPW_TKIP_CIPHER (1<<2)
445#define IPW_CCMP_CIPHER (1<<4)
446#define IPW_WEP104_CIPHER (1<<5)
447#define IPW_CKIP_CIPHER (1<<6)
448
449#define IPW_AUTH_OPEN 0
450#define IPW_AUTH_SHARED 1
451
452struct statistic {
453 int value;
454 int hi;
455 int lo;
456};
457
458#define INIT_STAT(x) do { \
459 (x)->value = (x)->hi = 0; \
460 (x)->lo = 0x7fffffff; \
461} while (0)
462#define SET_STAT(x,y) do { \
463 (x)->value = y; \
464 if ((x)->value > (x)->hi) (x)->hi = (x)->value; \
465 if ((x)->value < (x)->lo) (x)->lo = (x)->value; \
466} while (0)
467#define INC_STAT(x) do { if (++(x)->value > (x)->hi) (x)->hi = (x)->value; } \
468while (0)
469#define DEC_STAT(x) do { if (--(x)->value < (x)->lo) (x)->lo = (x)->value; } \
470while (0)
471
472#define IPW2100_ERROR_QUEUE 5
473
474/* Power management code: enable or disable? */
475enum {
476#ifdef CONFIG_PM
477 IPW2100_PM_DISABLED = 0,
478 PM_STATE_SIZE = 16,
479#else
480 IPW2100_PM_DISABLED = 1,
481 PM_STATE_SIZE = 0,
482#endif
483};
484
485#define STATUS_POWERED (1<<0)
486#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */
487#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */
488#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */
489#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */
490#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */
491#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */
492#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */
493#define STATUS_INT_ENABLED (1<<11)
494#define STATUS_RF_KILL_HW (1<<12)
495#define STATUS_RF_KILL_SW (1<<13)
496#define STATUS_RF_KILL_MASK (STATUS_RF_KILL_HW | STATUS_RF_KILL_SW)
497#define STATUS_EXIT_PENDING (1<<14)
498
499#define STATUS_SCAN_PENDING (1<<23)
500#define STATUS_SCANNING (1<<24)
501#define STATUS_SCAN_ABORTING (1<<25)
502#define STATUS_SCAN_COMPLETE (1<<26)
503#define STATUS_WX_EVENT_PENDING (1<<27)
504#define STATUS_RESET_PENDING (1<<29)
505#define STATUS_SECURITY_UPDATED (1<<30) /* Security sync needed */
506
507
508
509/* Internal NIC states */
510#define IPW_STATE_INITIALIZED (1<<0)
511#define IPW_STATE_COUNTRY_FOUND (1<<1)
512#define IPW_STATE_ASSOCIATED (1<<2)
513#define IPW_STATE_ASSN_LOST (1<<3)
514#define IPW_STATE_ASSN_CHANGED (1<<4)
515#define IPW_STATE_SCAN_COMPLETE (1<<5)
516#define IPW_STATE_ENTERED_PSP (1<<6)
517#define IPW_STATE_LEFT_PSP (1<<7)
518#define IPW_STATE_RF_KILL (1<<8)
519#define IPW_STATE_DISABLED (1<<9)
520#define IPW_STATE_POWER_DOWN (1<<10)
521#define IPW_STATE_SCANNING (1<<11)
522
523
524
525#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */
526#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
527#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
528#define CFG_CUSTOM_MAC (1<<3)
529#define CFG_LONG_PREAMBLE (1<<4)
530#define CFG_ASSOCIATE (1<<6)
531#define CFG_FIXED_RATE (1<<7)
532#define CFG_ADHOC_CREATE (1<<8)
533#define CFG_C3_DISABLED (1<<9)
534#define CFG_PASSIVE_SCAN (1<<10)
535
536#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
537#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
538
539struct ipw2100_priv {
540
541 int stop_hang_check; /* Set 1 when shutting down to kill hang_check */
542 int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */
543
544 struct ieee80211_device *ieee;
545 unsigned long status;
546 unsigned long config;
547 unsigned long capability;
548
549 /* Statistics */
550 int resets;
551 int reset_backoff;
552
553 /* Context */
554 u8 essid[IW_ESSID_MAX_SIZE];
555 u8 essid_len;
556 u8 bssid[ETH_ALEN];
557 u8 channel;
558 int last_mode;
559 int cstate_limit;
560
561 unsigned long connect_start;
562 unsigned long last_reset;
563
564 u32 channel_mask;
565 u32 fatal_error;
566 u32 fatal_errors[IPW2100_ERROR_QUEUE];
567 u32 fatal_index;
568 int eeprom_version;
569 int firmware_version;
570 unsigned long hw_features;
571 int hangs;
572 u32 last_rtc;
573 int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */
574 u8* snapshot[0x30];
575
576 u8 mandatory_bssid_mac[ETH_ALEN];
577 u8 mac_addr[ETH_ALEN];
578
579 int power_mode;
580
581 /* WEP data */
582 struct ieee80211_security sec;
583 int messages_sent;
584
585
586 int short_retry_limit;
587 int long_retry_limit;
588
589 u32 rts_threshold;
590 u32 frag_threshold;
591
592 int in_isr;
593
594 u32 tx_rates;
595 int tx_power;
596 u32 beacon_interval;
597
598 char nick[IW_ESSID_MAX_SIZE + 1];
599
600 struct ipw2100_status_queue status_queue;
601
602 struct statistic txq_stat;
603 struct statistic rxq_stat;
604 struct ipw2100_bd_queue rx_queue;
605 struct ipw2100_bd_queue tx_queue;
606 struct ipw2100_rx_packet *rx_buffers;
607
608 struct statistic fw_pend_stat;
609 struct list_head fw_pend_list;
610
611 struct statistic msg_free_stat;
612 struct statistic msg_pend_stat;
613 struct list_head msg_free_list;
614 struct list_head msg_pend_list;
615 struct ipw2100_tx_packet *msg_buffers;
616
617 struct statistic tx_free_stat;
618 struct statistic tx_pend_stat;
619 struct list_head tx_free_list;
620 struct list_head tx_pend_list;
621 struct ipw2100_tx_packet *tx_buffers;
622
623 struct ipw2100_ordinals ordinals;
624
625 struct pci_dev *pci_dev;
626
627 struct proc_dir_entry *dir_dev;
628
629 struct net_device *net_dev;
630 struct iw_statistics wstats;
631
632 struct tasklet_struct irq_tasklet;
633
634 struct workqueue_struct *workqueue;
635 struct work_struct reset_work;
636 struct work_struct security_work;
637 struct work_struct wx_event_work;
638 struct work_struct hang_check;
639 struct work_struct rf_kill;
640
641 u32 interrupts;
642 int tx_interrupts;
643 int rx_interrupts;
644 int inta_other;
645
646 spinlock_t low_lock;
647 struct semaphore action_sem;
648 struct semaphore adapter_sem;
649
650 wait_queue_head_t wait_command_queue;
651#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
652 u32 pm_state[PM_STATE_SIZE];
653#endif
654};
655
656
657/*********************************************************
658 * Host Command -> From Driver to FW
659 *********************************************************/
660
661/**
662 * Host command identifiers
663 */
664#define HOST_COMPLETE 2
665#define SYSTEM_CONFIG 6
666#define SSID 8
667#define MANDATORY_BSSID 9
668#define AUTHENTICATION_TYPE 10
669#define ADAPTER_ADDRESS 11
670#define PORT_TYPE 12
671#define INTERNATIONAL_MODE 13
672#define CHANNEL 14
673#define RTS_THRESHOLD 15
674#define FRAG_THRESHOLD 16
675#define POWER_MODE 17
676#define TX_RATES 18
677#define BASIC_TX_RATES 19
678#define WEP_KEY_INFO 20
679#define WEP_KEY_INDEX 25
680#define WEP_FLAGS 26
681#define ADD_MULTICAST 27
682#define CLEAR_ALL_MULTICAST 28
683#define BEACON_INTERVAL 29
684#define ATIM_WINDOW 30
685#define CLEAR_STATISTICS 31
686#define SEND 33
687#define TX_POWER_INDEX 36
688#define BROADCAST_SCAN 43
689#define CARD_DISABLE 44
690#define PREFERRED_BSSID 45
691#define SET_SCAN_OPTIONS 46
692#define SCAN_DWELL_TIME 47
693#define SWEEP_TABLE 48
694#define AP_OR_STATION_TABLE 49
695#define GROUP_ORDINALS 50
696#define SHORT_RETRY_LIMIT 51
697#define LONG_RETRY_LIMIT 52
698
699#define HOST_PRE_POWER_DOWN 58
700#define CARD_DISABLE_PHY_OFF 61
701#define MSDU_TX_RATES 62
702
703
704// Rogue AP Detection
705#define SET_STATION_STAT_BITS 64
706#define CLEAR_STATIONS_STAT_BITS 65
707#define LEAP_ROGUE_MODE 66 //TODO tbw replaced by CFG_LEAP_ROGUE_AP
708#define SET_SECURITY_INFORMATION 67
709#define DISASSOCIATION_BSSID 68
710#define SET_WPA_IE 69
711
712
713
714// system configuration bit mask:
715//#define IPW_CFG_ANTENNA_SETTING 0x03
716//#define IPW_CFG_ANTENNA_A 0x01
717//#define IPW_CFG_ANTENNA_B 0x02
718#define IPW_CFG_MONITOR 0x00004
719//#define IPW_CFG_TX_STATUS_ENABLE 0x00008
720#define IPW_CFG_PREAMBLE_AUTO 0x00010
721#define IPW_CFG_IBSS_AUTO_START 0x00020
722//#define IPW_CFG_KERBEROS_ENABLE 0x00040
723#define IPW_CFG_LOOPBACK 0x00100
724//#define IPW_CFG_WNMP_PING_PASS 0x00200
725//#define IPW_CFG_DEBUG_ENABLE 0x00400
726#define IPW_CFG_ANSWER_BCSSID_PROBE 0x00800
727//#define IPW_CFG_BT_PRIORITY 0x01000
728#define IPW_CFG_BT_SIDEBAND_SIGNAL 0x02000
729#define IPW_CFG_802_1x_ENABLE 0x04000
730#define IPW_CFG_BSS_MASK 0x08000
731#define IPW_CFG_IBSS_MASK 0x10000
732//#define IPW_CFG_DYNAMIC_CW 0x10000
733
734#define IPW_SCAN_NOASSOCIATE (1<<0)
735#define IPW_SCAN_MIXED_CELL (1<<1)
736/* RESERVED (1<<2) */
737#define IPW_SCAN_PASSIVE (1<<3)
738
739#define IPW_NIC_FATAL_ERROR 0x2A7F0
740#define IPW_ERROR_ADDR(x) (x & 0x3FFFF)
741#define IPW_ERROR_CODE(x) ((x & 0xFF000000) >> 24)
742#define IPW2100_ERR_C3_CORRUPTION (0x10 << 24)
743#define IPW2100_ERR_MSG_TIMEOUT (0x11 << 24)
744#define IPW2100_ERR_FW_LOAD (0x12 << 24)
745
746#define IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND 0x200
747#define IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x0D80
748
749#define IPW_MEM_HOST_SHARED_RX_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x40)
750#define IPW_MEM_HOST_SHARED_RX_STATUS_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x44)
751#define IPW_MEM_HOST_SHARED_RX_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x48)
752#define IPW_MEM_HOST_SHARED_RX_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0xa0)
753
754#define IPW_MEM_HOST_SHARED_TX_QUEUE_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x00)
755#define IPW_MEM_HOST_SHARED_TX_QUEUE_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x04)
756#define IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x80)
757
758#define IPW_MEM_HOST_SHARED_RX_WRITE_INDEX \
759 (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x20)
760
761#define IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX \
762 (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND)
763
764
765#if 0
766#define IPW_MEM_HOST_SHARED_TX_QUEUE_0_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x00)
767#define IPW_MEM_HOST_SHARED_TX_QUEUE_0_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x04)
768#define IPW_MEM_HOST_SHARED_TX_QUEUE_1_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x08)
769#define IPW_MEM_HOST_SHARED_TX_QUEUE_1_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x0c)
770#define IPW_MEM_HOST_SHARED_TX_QUEUE_2_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x10)
771#define IPW_MEM_HOST_SHARED_TX_QUEUE_2_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x14)
772#define IPW_MEM_HOST_SHARED_TX_QUEUE_3_BD_BASE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x18)
773#define IPW_MEM_HOST_SHARED_TX_QUEUE_3_BD_SIZE (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x1c)
774#define IPW_MEM_HOST_SHARED_TX_QUEUE_0_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x80)
775#define IPW_MEM_HOST_SHARED_TX_QUEUE_1_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x84)
776#define IPW_MEM_HOST_SHARED_TX_QUEUE_2_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x88)
777#define IPW_MEM_HOST_SHARED_TX_QUEUE_3_READ_INDEX (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x8c)
778
779#define IPW_MEM_HOST_SHARED_TX_QUEUE_BD_BASE(QueueNum) \
780 (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + (QueueNum<<3))
781#define IPW_MEM_HOST_SHARED_TX_QUEUE_BD_SIZE(QueueNum) \
782 (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x0004+(QueueNum<<3))
783#define IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX(QueueNum) \
784 (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x0080+(QueueNum<<2))
785
786#define IPW_MEM_HOST_SHARED_TX_QUEUE_0_WRITE_INDEX \
787 (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x00)
788#define IPW_MEM_HOST_SHARED_TX_QUEUE_1_WRITE_INDEX \
789 (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x04)
790#define IPW_MEM_HOST_SHARED_TX_QUEUE_2_WRITE_INDEX \
791 (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x08)
792#define IPW_MEM_HOST_SHARED_TX_QUEUE_3_WRITE_INDEX \
793 (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x0c)
794#define IPW_MEM_HOST_SHARED_SLAVE_MODE_INT_REGISTER \
795 (IPW_MEM_SRAM_HOST_INTERRUPT_AREA_LOWER_BOUND + 0x78)
796
797#endif
798
799#define IPW_MEM_HOST_SHARED_ORDINALS_TABLE_1 (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x180)
800#define IPW_MEM_HOST_SHARED_ORDINALS_TABLE_2 (IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND + 0x184)
801
802#define IPW2100_INTA_TX_TRANSFER (0x00000001) // Bit 0 (LSB)
803#define IPW2100_INTA_RX_TRANSFER (0x00000002) // Bit 1
804#define IPW2100_INTA_TX_COMPLETE (0x00000004) // Bit 2
805#define IPW2100_INTA_EVENT_INTERRUPT (0x00000008) // Bit 3
806#define IPW2100_INTA_STATUS_CHANGE (0x00000010) // Bit 4
807#define IPW2100_INTA_BEACON_PERIOD_EXPIRED (0x00000020) // Bit 5
808#define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE (0x00010000) // Bit 16
809#define IPW2100_INTA_FW_INIT_DONE (0x01000000) // Bit 24
810#define IPW2100_INTA_FW_CALIBRATION_CALC (0x02000000) // Bit 25
811#define IPW2100_INTA_FATAL_ERROR (0x40000000) // Bit 30
812#define IPW2100_INTA_PARITY_ERROR (0x80000000) // Bit 31 (MSB)
813
814#define IPW_AUX_HOST_RESET_REG_PRINCETON_RESET (0x00000001)
815#define IPW_AUX_HOST_RESET_REG_FORCE_NMI (0x00000002)
816#define IPW_AUX_HOST_RESET_REG_PCI_HOST_CLUSTER_FATAL_NMI (0x00000004)
817#define IPW_AUX_HOST_RESET_REG_CORE_FATAL_NMI (0x00000008)
818#define IPW_AUX_HOST_RESET_REG_SW_RESET (0x00000080)
819#define IPW_AUX_HOST_RESET_REG_MASTER_DISABLED (0x00000100)
820#define IPW_AUX_HOST_RESET_REG_STOP_MASTER (0x00000200)
821
822#define IPW_AUX_HOST_GP_CNTRL_BIT_CLOCK_READY (0x00000001) // Bit 0 (LSB)
823#define IPW_AUX_HOST_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY (0x00000002) // Bit 1
824#define IPW_AUX_HOST_GP_CNTRL_BIT_INIT_DONE (0x00000004) // Bit 2
825#define IPW_AUX_HOST_GP_CNTRL_BITS_SYS_CONFIG (0x000007c0) // Bits 6-10
826#define IPW_AUX_HOST_GP_CNTRL_BIT_BUS_TYPE (0x00000200) // Bit 9
827#define IPW_AUX_HOST_GP_CNTRL_BIT_BAR0_BLOCK_SIZE (0x00000400) // Bit 10
828#define IPW_AUX_HOST_GP_CNTRL_BIT_USB_MODE (0x20000000) // Bit 29
829#define IPW_AUX_HOST_GP_CNTRL_BIT_HOST_FORCES_SYS_CLK (0x40000000) // Bit 30
830#define IPW_AUX_HOST_GP_CNTRL_BIT_FW_FORCES_SYS_CLK (0x80000000) // Bit 31 (MSB)
831
832#define IPW_BIT_GPIO_GPIO1_MASK 0x0000000C
833#define IPW_BIT_GPIO_GPIO3_MASK 0x000000C0
834#define IPW_BIT_GPIO_GPIO1_ENABLE 0x00000008
835#define IPW_BIT_GPIO_RF_KILL 0x00010000
836
837#define IPW_BIT_GPIO_LED_OFF 0x00002000 // Bit 13 = 1
838
839#define IPW_REG_DOMAIN_0_OFFSET 0x0000
840#define IPW_REG_DOMAIN_1_OFFSET IPW_MEM_SRAM_HOST_SHARED_LOWER_BOUND
841
842#define IPW_REG_INTA IPW_REG_DOMAIN_0_OFFSET + 0x0008
843#define IPW_REG_INTA_MASK IPW_REG_DOMAIN_0_OFFSET + 0x000C
844#define IPW_REG_INDIRECT_ACCESS_ADDRESS IPW_REG_DOMAIN_0_OFFSET + 0x0010
845#define IPW_REG_INDIRECT_ACCESS_DATA IPW_REG_DOMAIN_0_OFFSET + 0x0014
846#define IPW_REG_AUTOINCREMENT_ADDRESS IPW_REG_DOMAIN_0_OFFSET + 0x0018
847#define IPW_REG_AUTOINCREMENT_DATA IPW_REG_DOMAIN_0_OFFSET + 0x001C
848#define IPW_REG_RESET_REG IPW_REG_DOMAIN_0_OFFSET + 0x0020
849#define IPW_REG_GP_CNTRL IPW_REG_DOMAIN_0_OFFSET + 0x0024
850#define IPW_REG_GPIO IPW_REG_DOMAIN_0_OFFSET + 0x0030
851#define IPW_REG_FW_TYPE IPW_REG_DOMAIN_1_OFFSET + 0x0188
852#define IPW_REG_FW_VERSION IPW_REG_DOMAIN_1_OFFSET + 0x018C
853#define IPW_REG_FW_COMPATABILITY_VERSION IPW_REG_DOMAIN_1_OFFSET + 0x0190
854
855#define IPW_REG_INDIRECT_ADDR_MASK 0x00FFFFFC
856
857#define IPW_INTERRUPT_MASK 0xC1010013
858
859#define IPW2100_CONTROL_REG 0x220000
860#define IPW2100_CONTROL_PHY_OFF 0x8
861
862#define IPW2100_COMMAND 0x00300004
863#define IPW2100_COMMAND_PHY_ON 0x0
864#define IPW2100_COMMAND_PHY_OFF 0x1
865
866/* in DEBUG_AREA, values of memory always 0xd55555d5 */
867#define IPW_REG_DOA_DEBUG_AREA_START IPW_REG_DOMAIN_0_OFFSET + 0x0090
868#define IPW_REG_DOA_DEBUG_AREA_END IPW_REG_DOMAIN_0_OFFSET + 0x00FF
869#define IPW_DATA_DOA_DEBUG_VALUE 0xd55555d5
870
871#define IPW_INTERNAL_REGISTER_HALT_AND_RESET 0x003000e0
872
873#define IPW_WAIT_CLOCK_STABILIZATION_DELAY 50 // micro seconds
874#define IPW_WAIT_RESET_ARC_COMPLETE_DELAY 10 // micro seconds
875#define IPW_WAIT_RESET_MASTER_ASSERT_COMPLETE_DELAY 10 // micro seconds
876
877// BD ring queue read/write difference
878#define IPW_BD_QUEUE_W_R_MIN_SPARE 2
879
880#define IPW_CACHE_LINE_LENGTH_DEFAULT 0x80
881
882#define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT 100 // 100 milli
883#define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT 100 // 100 milli
884
885
886
887
888#define IPW_HEADER_802_11_SIZE sizeof(struct ieee80211_header_data)
889#define IPW_MAX_80211_PAYLOAD_SIZE 2304U
890#define IPW_MAX_802_11_PAYLOAD_LENGTH 2312
891#define IPW_MAX_ACCEPTABLE_TX_FRAME_LENGTH 1536
892#define IPW_MIN_ACCEPTABLE_RX_FRAME_LENGTH 60
893#define IPW_MAX_ACCEPTABLE_RX_FRAME_LENGTH \
894 (IPW_MAX_ACCEPTABLE_TX_FRAME_LENGTH + IPW_HEADER_802_11_SIZE - \
895 sizeof(struct ethhdr))
896
897#define IPW_802_11_FCS_LENGTH 4
898#define IPW_RX_NIC_BUFFER_LENGTH \
899 (IPW_MAX_802_11_PAYLOAD_LENGTH + IPW_HEADER_802_11_SIZE + \
900 IPW_802_11_FCS_LENGTH)
901
902#define IPW_802_11_PAYLOAD_OFFSET \
903 (sizeof(struct ieee80211_header_data) + \
904 sizeof(struct ieee80211_snap_hdr))
905
906struct ipw2100_rx {
907 union {
908 unsigned char payload[IPW_RX_NIC_BUFFER_LENGTH];
909 struct ieee80211_hdr header;
910 u32 status;
911 struct ipw2100_notification notification;
912 struct ipw2100_cmd_header command;
913 } rx_data;
914} __attribute__ ((packed));
915
916// Bit 0-7 are for 802.11b tx rates - . Bit 5-7 are reserved
917#define TX_RATE_1_MBIT 0x0001
918#define TX_RATE_2_MBIT 0x0002
919#define TX_RATE_5_5_MBIT 0x0004
920#define TX_RATE_11_MBIT 0x0008
921#define TX_RATE_MASK 0x000F
922#define DEFAULT_TX_RATES 0x000F
923
924#define IPW_POWER_MODE_CAM 0x00 //(always on)
925#define IPW_POWER_INDEX_1 0x01
926#define IPW_POWER_INDEX_2 0x02
927#define IPW_POWER_INDEX_3 0x03
928#define IPW_POWER_INDEX_4 0x04
929#define IPW_POWER_INDEX_5 0x05
930#define IPW_POWER_AUTO 0x06
931#define IPW_POWER_MASK 0x0F
932#define IPW_POWER_ENABLED 0x10
933#define IPW_POWER_LEVEL(x) ((x) & IPW_POWER_MASK)
934
935#define IPW_TX_POWER_AUTO 0
936#define IPW_TX_POWER_ENHANCED 1
937
938#define IPW_TX_POWER_DEFAULT 32
939#define IPW_TX_POWER_MIN 0
940#define IPW_TX_POWER_MAX 16
941#define IPW_TX_POWER_MIN_DBM (-12)
942#define IPW_TX_POWER_MAX_DBM 16
943
944#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan
945#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan
946
947#define REG_MIN_CHANNEL 0
948#define REG_MAX_CHANNEL 14
949
950#define REG_CHANNEL_MASK 0x00003FFF
951#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff
952
953#define DIVERSITY_EITHER 0 // Use both antennas
954#define DIVERSITY_ANTENNA_A 1 // Use antenna A
955#define DIVERSITY_ANTENNA_B 2 // Use antenna B
956
957
958#define HOST_COMMAND_WAIT 0
959#define HOST_COMMAND_NO_WAIT 1
960
961#define LOCK_NONE 0
962#define LOCK_DRIVER 1
963#define LOCK_FW 2
964
965#define TYPE_SWEEP_ORD 0x000D
966#define TYPE_IBSS_STTN_ORD 0x000E
967#define TYPE_BSS_AP_ORD 0x000F
968#define TYPE_RAW_BEACON_ENTRY 0x0010
969#define TYPE_CALIBRATION_DATA 0x0011
970#define TYPE_ROGUE_AP_DATA 0x0012
971#define TYPE_ASSOCIATION_REQUEST 0x0013
972#define TYPE_REASSOCIATION_REQUEST 0x0014
973
974
975#define HW_FEATURE_RFKILL (0x0001)
976#define RF_KILLSWITCH_OFF (1)
977#define RF_KILLSWITCH_ON (0)
978
979#define IPW_COMMAND_POOL_SIZE 40
980
981#define IPW_START_ORD_TAB_1 1
982#define IPW_START_ORD_TAB_2 1000
983
984#define IPW_ORD_TAB_1_ENTRY_SIZE sizeof(u32)
985
986#define IS_ORDINAL_TABLE_ONE(mgr,id) \
987 ((id >= IPW_START_ORD_TAB_1) && (id < mgr->table1_size))
988#define IS_ORDINAL_TABLE_TWO(mgr,id) \
989 ((id >= IPW_START_ORD_TAB_2) && (id < (mgr->table2_size + IPW_START_ORD_TAB_2)))
990
991#define BSS_ID_LENGTH 6
992
993// Fixed size data: Ordinal Table 1
994typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
995// Transmit statistics
996 IPW_ORD_STAT_TX_HOST_REQUESTS = 1,// # of requested Host Tx's (MSDU)
997 IPW_ORD_STAT_TX_HOST_COMPLETE, // # of successful Host Tx's (MSDU)
998 IPW_ORD_STAT_TX_DIR_DATA, // # of successful Directed Tx's (MSDU)
999
1000 IPW_ORD_STAT_TX_DIR_DATA1 = 4, // # of successful Directed Tx's (MSDU) @ 1MB
1001 IPW_ORD_STAT_TX_DIR_DATA2, // # of successful Directed Tx's (MSDU) @ 2MB
1002 IPW_ORD_STAT_TX_DIR_DATA5_5, // # of successful Directed Tx's (MSDU) @ 5_5MB
1003 IPW_ORD_STAT_TX_DIR_DATA11, // # of successful Directed Tx's (MSDU) @ 11MB
1004 IPW_ORD_STAT_TX_DIR_DATA22, // # of successful Directed Tx's (MSDU) @ 22MB
1005
1006 IPW_ORD_STAT_TX_NODIR_DATA1 = 13,// # of successful Non_Directed Tx's (MSDU) @ 1MB
1007 IPW_ORD_STAT_TX_NODIR_DATA2, // # of successful Non_Directed Tx's (MSDU) @ 2MB
1008 IPW_ORD_STAT_TX_NODIR_DATA5_5, // # of successful Non_Directed Tx's (MSDU) @ 5.5MB
1009 IPW_ORD_STAT_TX_NODIR_DATA11, // # of successful Non_Directed Tx's (MSDU) @ 11MB
1010
1011 IPW_ORD_STAT_NULL_DATA = 21, // # of successful NULL data Tx's
1012 IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS
1013 IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS
1014 IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK
1015 IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's
1016 IPW_ORD_STAT_TX_ASSN_RESP, // # of successful Association response Tx's
1017 IPW_ORD_STAT_TX_REASSN, // # of successful Reassociation Tx's
1018 IPW_ORD_STAT_TX_REASSN_RESP, // # of successful Reassociation response Tx's
1019 IPW_ORD_STAT_TX_PROBE, // # of probes successfully transmitted
1020 IPW_ORD_STAT_TX_PROBE_RESP, // # of probe responses successfully transmitted
1021 IPW_ORD_STAT_TX_BEACON, // # of tx beacon
1022 IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM
1023 IPW_ORD_STAT_TX_DISASSN, // # of successful Disassociation TX
1024 IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx
1025 IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX
1026
1027 IPW_ORD_STAT_TX_TOTAL_BYTES = 41,// Total successful Tx data bytes
1028 IPW_ORD_STAT_TX_RETRIES, // # of Tx retries
1029 IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS
1030 IPW_ORD_STAT_TX_RETRY2, // # of Tx retries at 2MBPS
1031 IPW_ORD_STAT_TX_RETRY5_5, // # of Tx retries at 5.5MBPS
1032 IPW_ORD_STAT_TX_RETRY11, // # of Tx retries at 11MBPS
1033
1034 IPW_ORD_STAT_TX_FAILURES = 51, // # of Tx Failures
1035 IPW_ORD_STAT_TX_ABORT_AT_HOP, //NS // # of Tx's aborted at hop time
1036 IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP,// # of times max tries in a hop failed
1037 IPW_ORD_STAT_TX_ABORT_LATE_DMA, //NS // # of times tx aborted due to late dma setup
1038 IPW_ORD_STAT_TX_ABORT_STX, //NS // # of times backoff aborted
1039 IPW_ORD_STAT_TX_DISASSN_FAIL, // # of times disassociation failed
1040 IPW_ORD_STAT_TX_ERR_CTS, // # of missed/bad CTS frames
1041 IPW_ORD_STAT_TX_BPDU, //NS // # of spanning tree BPDUs sent
1042 IPW_ORD_STAT_TX_ERR_ACK, // # of tx err due to acks
1043
1044 // Receive statistics
1045 IPW_ORD_STAT_RX_HOST = 61, // # of packets passed to host
1046 IPW_ORD_STAT_RX_DIR_DATA, // # of directed packets
1047 IPW_ORD_STAT_RX_DIR_DATA1, // # of directed packets at 1MB
1048 IPW_ORD_STAT_RX_DIR_DATA2, // # of directed packets at 2MB
1049 IPW_ORD_STAT_RX_DIR_DATA5_5, // # of directed packets at 5.5MB
1050 IPW_ORD_STAT_RX_DIR_DATA11, // # of directed packets at 11MB
1051 IPW_ORD_STAT_RX_DIR_DATA22, // # of directed packets at 22MB
1052
1053 IPW_ORD_STAT_RX_NODIR_DATA = 71,// # of nondirected packets
1054 IPW_ORD_STAT_RX_NODIR_DATA1, // # of nondirected packets at 1MB
1055 IPW_ORD_STAT_RX_NODIR_DATA2, // # of nondirected packets at 2MB
1056 IPW_ORD_STAT_RX_NODIR_DATA5_5, // # of nondirected packets at 5.5MB
1057 IPW_ORD_STAT_RX_NODIR_DATA11, // # of nondirected packets at 11MB
1058
1059 IPW_ORD_STAT_RX_NULL_DATA = 80, // # of null data rx's
1060 IPW_ORD_STAT_RX_POLL, //NS // # of poll rx
1061 IPW_ORD_STAT_RX_RTS, // # of Rx RTS
1062 IPW_ORD_STAT_RX_CTS, // # of Rx CTS
1063 IPW_ORD_STAT_RX_ACK, // # of Rx ACK
1064 IPW_ORD_STAT_RX_CFEND, // # of Rx CF End
1065 IPW_ORD_STAT_RX_CFEND_ACK, // # of Rx CF End + CF Ack
1066 IPW_ORD_STAT_RX_ASSN, // # of Association Rx's
1067 IPW_ORD_STAT_RX_ASSN_RESP, // # of Association response Rx's
1068 IPW_ORD_STAT_RX_REASSN, // # of Reassociation Rx's
1069 IPW_ORD_STAT_RX_REASSN_RESP, // # of Reassociation response Rx's
1070 IPW_ORD_STAT_RX_PROBE, // # of probe Rx's
1071 IPW_ORD_STAT_RX_PROBE_RESP, // # of probe response Rx's
1072 IPW_ORD_STAT_RX_BEACON, // # of Rx beacon
1073 IPW_ORD_STAT_RX_ATIM, // # of Rx ATIM
1074 IPW_ORD_STAT_RX_DISASSN, // # of disassociation Rx
1075 IPW_ORD_STAT_RX_AUTH, // # of authentication Rx
1076 IPW_ORD_STAT_RX_DEAUTH, // # of deauthentication Rx
1077
1078 IPW_ORD_STAT_RX_TOTAL_BYTES = 101,// Total rx data bytes received
1079 IPW_ORD_STAT_RX_ERR_CRC, // # of packets with Rx CRC error
1080 IPW_ORD_STAT_RX_ERR_CRC1, // # of Rx CRC errors at 1MB
1081 IPW_ORD_STAT_RX_ERR_CRC2, // # of Rx CRC errors at 2MB
1082 IPW_ORD_STAT_RX_ERR_CRC5_5, // # of Rx CRC errors at 5.5MB
1083 IPW_ORD_STAT_RX_ERR_CRC11, // # of Rx CRC errors at 11MB
1084
1085 IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB
1086 IPW_ORD_STAT_RX_DUPLICATE2, // # of duplicate rx packets at 2MB
1087 IPW_ORD_STAT_RX_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB
1088 IPW_ORD_STAT_RX_DUPLICATE11, // # of duplicate rx packets at 11MB
1089 IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets
1090
1091 IPW_ORD_PERS_DB_LOCK = 120, // # locking fw permanent db
1092 IPW_ORD_PERS_DB_SIZE, // # size of fw permanent db
1093 IPW_ORD_PERS_DB_ADDR, // # address of fw permanent db
1094 IPW_ORD_STAT_RX_INVALID_PROTOCOL, // # of rx frames with invalid protocol
1095 IPW_ORD_SYS_BOOT_TIME, // # Boot time
1096 IPW_ORD_STAT_RX_NO_BUFFER, // # of rx frames rejected due to no buffer
1097 IPW_ORD_STAT_RX_ABORT_LATE_DMA, //NS // # of rx frames rejected due to dma setup too late
1098 IPW_ORD_STAT_RX_ABORT_AT_HOP, //NS // # of rx frames aborted due to hop
1099 IPW_ORD_STAT_RX_MISSING_FRAG, // # of rx frames dropped due to missing fragment
1100 IPW_ORD_STAT_RX_ORPHAN_FRAG, // # of rx frames dropped due to non-sequential fragment
1101 IPW_ORD_STAT_RX_ORPHAN_FRAME, // # of rx frames dropped due to unmatched 1st frame
1102 IPW_ORD_STAT_RX_FRAG_AGEOUT, // # of rx frames dropped due to uncompleted frame
1103 IPW_ORD_STAT_RX_BAD_SSID, //NS // Bad SSID (unused)
1104 IPW_ORD_STAT_RX_ICV_ERRORS, // # of ICV errors during decryption
1105
1106// PSP Statistics
1107 IPW_ORD_STAT_PSP_SUSPENSION = 137,// # of times adapter suspended
1108 IPW_ORD_STAT_PSP_BCN_TIMEOUT, // # of beacon timeout
1109 IPW_ORD_STAT_PSP_POLL_TIMEOUT, // # of poll response timeouts
1110 IPW_ORD_STAT_PSP_NONDIR_TIMEOUT,// # of timeouts waiting for last broadcast/muticast pkt
1111 IPW_ORD_STAT_PSP_RX_DTIMS, // # of PSP DTIMs received
1112 IPW_ORD_STAT_PSP_RX_TIMS, // # of PSP TIMs received
1113 IPW_ORD_STAT_PSP_STATION_ID, // PSP Station ID
1114
1115// Association and roaming
1116 IPW_ORD_LAST_ASSN_TIME = 147, // RTC time of last association
1117 IPW_ORD_STAT_PERCENT_MISSED_BCNS,// current calculation of % missed beacons
1118 IPW_ORD_STAT_PERCENT_RETRIES, // current calculation of % missed tx retries
1119 IPW_ORD_ASSOCIATED_AP_PTR, // If associated, this is ptr to the associated
1120 // AP table entry. set to 0 if not associated
1121 IPW_ORD_AVAILABLE_AP_CNT, // # of AP's decsribed in the AP table
1122 IPW_ORD_AP_LIST_PTR, // Ptr to list of available APs
1123 IPW_ORD_STAT_AP_ASSNS, // # of associations
1124 IPW_ORD_STAT_ASSN_FAIL, // # of association failures
1125 IPW_ORD_STAT_ASSN_RESP_FAIL, // # of failuresdue to response fail
1126 IPW_ORD_STAT_FULL_SCANS, // # of full scans
1127
1128 IPW_ORD_CARD_DISABLED, // # Card Disabled
1129 IPW_ORD_STAT_ROAM_INHIBIT, // # of times roaming was inhibited due to ongoing activity
1130 IPW_FILLER_40,
1131 IPW_ORD_RSSI_AT_ASSN = 160, // RSSI of associated AP at time of association
1132 IPW_ORD_STAT_ASSN_CAUSE1, // # of reassociations due to no tx from AP in last N
1133 // hops or no prob_ responses in last 3 minutes
1134 IPW_ORD_STAT_ASSN_CAUSE2, // # of reassociations due to poor tx/rx quality
1135 IPW_ORD_STAT_ASSN_CAUSE3, // # of reassociations due to tx/rx quality with excessive
1136 // load at the AP
1137 IPW_ORD_STAT_ASSN_CAUSE4, // # of reassociations due to AP RSSI level fell below
1138 // eligible group
1139 IPW_ORD_STAT_ASSN_CAUSE5, // # of reassociations due to load leveling
1140 IPW_ORD_STAT_ASSN_CAUSE6, //NS // # of reassociations due to dropped by Ap
1141 IPW_FILLER_41,
1142 IPW_FILLER_42,
1143 IPW_FILLER_43,
1144 IPW_ORD_STAT_AUTH_FAIL, // # of times authentication failed
1145 IPW_ORD_STAT_AUTH_RESP_FAIL, // # of times authentication response failed
1146 IPW_ORD_STATION_TABLE_CNT, // # of entries in association table
1147
1148// Other statistics
1149 IPW_ORD_RSSI_AVG_CURR = 173, // Current avg RSSI
1150 IPW_ORD_STEST_RESULTS_CURR, //NS // Current self test results word
1151 IPW_ORD_STEST_RESULTS_CUM, //NS // Cummulative self test results word
1152 IPW_ORD_SELF_TEST_STATUS, //NS //
1153 IPW_ORD_POWER_MGMT_MODE, // Power mode - 0=CAM, 1=PSP
1154 IPW_ORD_POWER_MGMT_INDEX, //NS //
1155 IPW_ORD_COUNTRY_CODE, // IEEE country code as recv'd from beacon
1156 IPW_ORD_COUNTRY_CHANNELS, // channels suported by country
1157// IPW_ORD_COUNTRY_CHANNELS:
1158// For 11b the lower 2-byte are used for channels from 1-14
1159// and the higher 2-byte are not used.
1160 IPW_ORD_RESET_CNT, // # of adapter resets (warm)
1161 IPW_ORD_BEACON_INTERVAL, // Beacon interval
1162
1163 IPW_ORD_PRINCETON_VERSION = 184, //NS // Princeton Version
1164 IPW_ORD_ANTENNA_DIVERSITY, // TRUE if antenna diversity is disabled
1165 IPW_ORD_CCA_RSSI, //NS // CCA RSSI value (factory programmed)
1166 IPW_ORD_STAT_EEPROM_UPDATE, //NS // # of times config EEPROM updated
1167 IPW_ORD_DTIM_PERIOD, // # of beacon intervals between DTIMs
1168 IPW_ORD_OUR_FREQ, // current radio freq lower digits - channel ID
1169
1170 IPW_ORD_RTC_TIME = 190, // current RTC time
1171 IPW_ORD_PORT_TYPE, // operating mode
1172 IPW_ORD_CURRENT_TX_RATE, // current tx rate
1173 IPW_ORD_SUPPORTED_RATES, // Bitmap of supported tx rates
1174 IPW_ORD_ATIM_WINDOW, // current ATIM Window
1175 IPW_ORD_BASIC_RATES, // bitmap of basic tx rates
1176 IPW_ORD_NIC_HIGHEST_RATE, // bitmap of basic tx rates
1177 IPW_ORD_AP_HIGHEST_RATE, // bitmap of basic tx rates
1178 IPW_ORD_CAPABILITIES, // Management frame capability field
1179 IPW_ORD_AUTH_TYPE, // Type of authentication
1180 IPW_ORD_RADIO_TYPE, // Adapter card platform type
1181 IPW_ORD_RTS_THRESHOLD = 201, // Min length of packet after which RTS handshaking is used
1182 IPW_ORD_INT_MODE, // International mode
1183 IPW_ORD_FRAGMENTATION_THRESHOLD, // protocol frag threshold
1184 IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS, // EEPROM offset in SRAM
1185 IPW_ORD_EEPROM_SRAM_DB_BLOCK_SIZE, // EEPROM size in SRAM
1186 IPW_ORD_EEPROM_SKU_CAPABILITY, // EEPROM SKU Capability 206 =
1187 IPW_ORD_EEPROM_IBSS_11B_CHANNELS, // EEPROM IBSS 11b channel set
1188
1189 IPW_ORD_MAC_VERSION = 209, // MAC Version
1190 IPW_ORD_MAC_REVISION, // MAC Revision
1191 IPW_ORD_RADIO_VERSION, // Radio Version
1192 IPW_ORD_NIC_MANF_DATE_TIME, // MANF Date/Time STAMP
1193 IPW_ORD_UCODE_VERSION, // Ucode Version
1194 IPW_ORD_HW_RF_SWITCH_STATE = 214, // HW RF Kill Switch State
1195} ORDINALTABLE1;
1196//ENDOF TABLE1
1197
1198// ordinal table 2
1199// Variable length data:
1200#define IPW_FIRST_VARIABLE_LENGTH_ORDINAL 1001
1201
1202typedef enum _ORDINAL_TABLE_2 { // NS - means Not Supported by FW
1203 IPW_ORD_STAT_BASE = 1000, // contains number of variable ORDs
1204 IPW_ORD_STAT_ADAPTER_MAC = 1001, // 6 bytes: our adapter MAC address
1205 IPW_ORD_STAT_PREFERRED_BSSID = 1002, // 6 bytes: BSSID of the preferred AP
1206 IPW_ORD_STAT_MANDATORY_BSSID = 1003, // 6 bytes: BSSID of the mandatory AP
1207 IPW_FILL_1, //NS //
1208 IPW_ORD_STAT_COUNTRY_TEXT = 1005, // 36 bytes: Country name text, First two bytes are Country code
1209 IPW_ORD_STAT_ASSN_SSID = 1006, // 32 bytes: ESSID String
1210 IPW_ORD_STATION_TABLE = 1007, // ? bytes: Station/AP table (via Direct SSID Scans)
1211 IPW_ORD_STAT_SWEEP_TABLE = 1008, // ? bytes: Sweep/Host Table table (via Broadcast Scans)
1212 IPW_ORD_STAT_ROAM_LOG = 1009, // ? bytes: Roaming log
1213 IPW_ORD_STAT_RATE_LOG = 1010, //NS // 0 bytes: Rate log
1214 IPW_ORD_STAT_FIFO = 1011, //NS // 0 bytes: Fifo buffer data structures
1215 IPW_ORD_STAT_FW_VER_NUM = 1012, // 14 bytes: fw version ID string as in (a.bb.ccc; "0.08.011")
1216 IPW_ORD_STAT_FW_DATE = 1013, // 14 bytes: fw date string (mmm dd yyyy; "Mar 13 2002")
1217 IPW_ORD_STAT_ASSN_AP_BSSID = 1014, // 6 bytes: MAC address of associated AP
1218 IPW_ORD_STAT_DEBUG = 1015, //NS // ? bytes:
1219 IPW_ORD_STAT_NIC_BPA_NUM = 1016, // 11 bytes: NIC BPA number in ASCII
1220 IPW_ORD_STAT_UCODE_DATE = 1017, // 5 bytes: uCode date
1221 IPW_ORD_SECURITY_NGOTIATION_RESULT = 1018,
1222} ORDINALTABLE2; // NS - means Not Supported by FW
1223
1224#define IPW_LAST_VARIABLE_LENGTH_ORDINAL 1018
1225
1226#ifndef WIRELESS_SPY
1227#define WIRELESS_SPY // enable iwspy support
1228#endif
1229
1230extern struct iw_handler_def ipw2100_wx_handler_def;
1231extern struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev);
1232extern void ipw2100_wx_event_work(struct ipw2100_priv *priv);
1233
1234#define IPW_HOST_FW_SHARED_AREA0 0x0002f200
1235#define IPW_HOST_FW_SHARED_AREA0_END 0x0002f510 // 0x310 bytes
1236
1237#define IPW_HOST_FW_SHARED_AREA1 0x0002f610
1238#define IPW_HOST_FW_SHARED_AREA1_END 0x0002f630 // 0x20 bytes
1239
1240#define IPW_HOST_FW_SHARED_AREA2 0x0002fa00
1241#define IPW_HOST_FW_SHARED_AREA2_END 0x0002fa20 // 0x20 bytes
1242
1243#define IPW_HOST_FW_SHARED_AREA3 0x0002fc00
1244#define IPW_HOST_FW_SHARED_AREA3_END 0x0002fc10 // 0x10 bytes
1245
1246#define IPW_HOST_FW_INTERRUPT_AREA 0x0002ff80
1247#define IPW_HOST_FW_INTERRUPT_AREA_END 0x00030000 // 0x80 bytes
1248
1249struct ipw2100_fw_chunk {
1250 unsigned char *buf;
1251 long len;
1252 long pos;
1253 struct list_head list;
1254};
1255
1256struct ipw2100_fw_chunk_set {
1257 const void *data;
1258 unsigned long size;
1259};
1260
1261struct ipw2100_fw {
1262 int version;
1263 struct ipw2100_fw_chunk_set fw;
1264 struct ipw2100_fw_chunk_set uc;
1265 const struct firmware *fw_entry;
1266};
1267
1268int ipw2100_get_firmware(struct ipw2100_priv *priv, struct ipw2100_fw *fw);
1269void ipw2100_release_firmware(struct ipw2100_priv *priv, struct ipw2100_fw *fw);
1270int ipw2100_fw_download(struct ipw2100_priv *priv, struct ipw2100_fw *fw);
1271int ipw2100_ucode_download(struct ipw2100_priv *priv, struct ipw2100_fw *fw);
1272
1273#define MAX_FW_VERSION_LEN 14
1274
1275int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf, size_t max);
1276int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf, size_t max);
1277
1278#endif /* _IPW2100_H */