]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/net/wireless/ipw2200.c
Move code from ipw2100_wpa_enable to IPW2100_PARAM_DROP_UNENCRYPTED to
[mirror_ubuntu-bionic-kernel.git] / drivers / net / wireless / ipw2200.c
CommitLineData
43f66a6c 1/******************************************************************************
bf79451e 2
43f66a6c
JK
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4
5 802.11 status code portion of this file from ethereal-0.10.6:
6 Copyright 2000, Axis Communications AB
7 Ethereal - Network traffic analyzer
8 By Gerald Combs <gerald@ethereal.com>
9 Copyright 1998 Gerald Combs
10
bf79451e
JG
11 This program is free software; you can redistribute it and/or modify it
12 under the terms of version 2 of the GNU General Public License as
43f66a6c 13 published by the Free Software Foundation.
bf79451e
JG
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
43f66a6c 18 more details.
bf79451e 19
43f66a6c 20 You should have received a copy of the GNU General Public License along with
bf79451e 21 this program; if not, write to the Free Software Foundation, Inc., 59
43f66a6c 22 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
bf79451e 23
43f66a6c
JK
24 The full GNU General Public License is included in this distribution in the
25 file called LICENSE.
bf79451e 26
43f66a6c
JK
27 Contact Information:
28 James P. Ketrenos <ipw2100-admin@linux.intel.com>
29 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30
31******************************************************************************/
32
33#include "ipw2200.h"
34
b095c381 35#define IPW2200_VERSION "1.0.4"
43f66a6c
JK
36#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
37#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation"
38#define DRV_VERSION IPW2200_VERSION
39
b095c381
JK
40#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)
41
43f66a6c
JK
42MODULE_DESCRIPTION(DRV_DESCRIPTION);
43MODULE_VERSION(DRV_VERSION);
44MODULE_AUTHOR(DRV_COPYRIGHT);
45MODULE_LICENSE("GPL");
46
47static int debug = 0;
48static int channel = 0;
43f66a6c
JK
49static int mode = 0;
50
51static u32 ipw_debug_level;
52static int associate = 1;
53static int auto_create = 1;
a613bffd 54static int led = 0;
43f66a6c 55static int disable = 0;
b095c381 56static int hwcrypto = 1;
43f66a6c
JK
57static const char ipw_modes[] = {
58 'a', 'b', 'g', '?'
59};
60
b095c381
JK
61#ifdef CONFIG_IPW_QOS
62static int qos_enable = 0;
63static int qos_burst_enable = 0;
64static int qos_no_ack_mask = 0;
65static int burst_duration_CCK = 0;
66static int burst_duration_OFDM = 0;
67
68static struct ieee80211_qos_parameters def_qos_parameters_OFDM = {
69 {QOS_TX0_CW_MIN_OFDM, QOS_TX1_CW_MIN_OFDM, QOS_TX2_CW_MIN_OFDM,
70 QOS_TX3_CW_MIN_OFDM},
71 {QOS_TX0_CW_MAX_OFDM, QOS_TX1_CW_MAX_OFDM, QOS_TX2_CW_MAX_OFDM,
72 QOS_TX3_CW_MAX_OFDM},
73 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
74 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
75 {QOS_TX0_TXOP_LIMIT_OFDM, QOS_TX1_TXOP_LIMIT_OFDM,
76 QOS_TX2_TXOP_LIMIT_OFDM, QOS_TX3_TXOP_LIMIT_OFDM}
77};
78
79static struct ieee80211_qos_parameters def_qos_parameters_CCK = {
80 {QOS_TX0_CW_MIN_CCK, QOS_TX1_CW_MIN_CCK, QOS_TX2_CW_MIN_CCK,
81 QOS_TX3_CW_MIN_CCK},
82 {QOS_TX0_CW_MAX_CCK, QOS_TX1_CW_MAX_CCK, QOS_TX2_CW_MAX_CCK,
83 QOS_TX3_CW_MAX_CCK},
84 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
85 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
86 {QOS_TX0_TXOP_LIMIT_CCK, QOS_TX1_TXOP_LIMIT_CCK, QOS_TX2_TXOP_LIMIT_CCK,
87 QOS_TX3_TXOP_LIMIT_CCK}
88};
89
90static struct ieee80211_qos_parameters def_parameters_OFDM = {
91 {DEF_TX0_CW_MIN_OFDM, DEF_TX1_CW_MIN_OFDM, DEF_TX2_CW_MIN_OFDM,
92 DEF_TX3_CW_MIN_OFDM},
93 {DEF_TX0_CW_MAX_OFDM, DEF_TX1_CW_MAX_OFDM, DEF_TX2_CW_MAX_OFDM,
94 DEF_TX3_CW_MAX_OFDM},
95 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
96 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
97 {DEF_TX0_TXOP_LIMIT_OFDM, DEF_TX1_TXOP_LIMIT_OFDM,
98 DEF_TX2_TXOP_LIMIT_OFDM, DEF_TX3_TXOP_LIMIT_OFDM}
99};
100
101static struct ieee80211_qos_parameters def_parameters_CCK = {
102 {DEF_TX0_CW_MIN_CCK, DEF_TX1_CW_MIN_CCK, DEF_TX2_CW_MIN_CCK,
103 DEF_TX3_CW_MIN_CCK},
104 {DEF_TX0_CW_MAX_CCK, DEF_TX1_CW_MAX_CCK, DEF_TX2_CW_MAX_CCK,
105 DEF_TX3_CW_MAX_CCK},
106 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
107 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
108 {DEF_TX0_TXOP_LIMIT_CCK, DEF_TX1_TXOP_LIMIT_CCK, DEF_TX2_TXOP_LIMIT_CCK,
109 DEF_TX3_TXOP_LIMIT_CCK}
110};
111
112static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
113
114static int from_priority_to_tx_queue[] = {
115 IPW_TX_QUEUE_1, IPW_TX_QUEUE_2, IPW_TX_QUEUE_2, IPW_TX_QUEUE_1,
116 IPW_TX_QUEUE_3, IPW_TX_QUEUE_3, IPW_TX_QUEUE_4, IPW_TX_QUEUE_4
117};
118
119static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv);
120
121static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
122 *qos_param);
123static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
124 *qos_param);
125#endif /* CONFIG_IPW_QOS */
126
127static void ipw_remove_current_network(struct ipw_priv *priv);
43f66a6c 128static void ipw_rx(struct ipw_priv *priv);
bf79451e 129static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
43f66a6c
JK
130 struct clx2_tx_queue *txq, int qindex);
131static int ipw_queue_reset(struct ipw_priv *priv);
132
133static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
134 int len, int sync);
135
136static void ipw_tx_queue_free(struct ipw_priv *);
137
138static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *);
139static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);
140static void ipw_rx_queue_replenish(void *);
43f66a6c 141static int ipw_up(struct ipw_priv *);
c848d0af 142static void ipw_bg_up(void *);
43f66a6c 143static void ipw_down(struct ipw_priv *);
c848d0af 144static void ipw_bg_down(void *);
43f66a6c 145static int ipw_config(struct ipw_priv *);
0edd5b44
JG
146static int init_supported_rates(struct ipw_priv *priv,
147 struct ipw_supported_rates *prates);
b095c381
JK
148static void ipw_set_hwcrypto_keys(struct ipw_priv *);
149static void ipw_send_wep_keys(struct ipw_priv *, int);
43f66a6c 150
bf79451e 151static char *snprint_line(char *buf, size_t count,
0edd5b44 152 const u8 * data, u32 len, u32 ofs)
43f66a6c
JK
153{
154 int out, i, j, l;
155 char c;
bf79451e 156
43f66a6c
JK
157 out = snprintf(buf, count, "%08X", ofs);
158
159 for (l = 0, i = 0; i < 2; i++) {
160 out += snprintf(buf + out, count - out, " ");
bf79451e
JG
161 for (j = 0; j < 8 && l < len; j++, l++)
162 out += snprintf(buf + out, count - out, "%02X ",
43f66a6c
JK
163 data[(i * 8 + j)]);
164 for (; j < 8; j++)
165 out += snprintf(buf + out, count - out, " ");
166 }
bf79451e 167
43f66a6c
JK
168 out += snprintf(buf + out, count - out, " ");
169 for (l = 0, i = 0; i < 2; i++) {
170 out += snprintf(buf + out, count - out, " ");
171 for (j = 0; j < 8 && l < len; j++, l++) {
172 c = data[(i * 8 + j)];
173 if (!isascii(c) || !isprint(c))
174 c = '.';
bf79451e 175
43f66a6c
JK
176 out += snprintf(buf + out, count - out, "%c", c);
177 }
178
179 for (; j < 8; j++)
180 out += snprintf(buf + out, count - out, " ");
181 }
bf79451e 182
43f66a6c
JK
183 return buf;
184}
185
0edd5b44 186static void printk_buf(int level, const u8 * data, u32 len)
43f66a6c
JK
187{
188 char line[81];
189 u32 ofs = 0;
190 if (!(ipw_debug_level & level))
191 return;
192
193 while (len) {
194 printk(KERN_DEBUG "%s\n",
bf79451e 195 snprint_line(line, sizeof(line), &data[ofs],
43f66a6c
JK
196 min(len, 16U), ofs));
197 ofs += 16;
198 len -= min(len, 16U);
199 }
200}
201
202static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
203#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
204
205static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg);
206#define ipw_read_reg8(a, b) _ipw_read_reg8(a, b)
207
208static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value);
209static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c)
210{
0edd5b44
JG
211 IPW_DEBUG_IO("%s %d: write_indirect8(0x%08X, 0x%08X)\n", __FILE__,
212 __LINE__, (u32) (b), (u32) (c));
43f66a6c
JK
213 _ipw_write_reg8(a, b, c);
214}
215
216static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value);
217static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c)
218{
0edd5b44
JG
219 IPW_DEBUG_IO("%s %d: write_indirect16(0x%08X, 0x%08X)\n", __FILE__,
220 __LINE__, (u32) (b), (u32) (c));
43f66a6c
JK
221 _ipw_write_reg16(a, b, c);
222}
223
224static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value);
225static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
226{
0edd5b44
JG
227 IPW_DEBUG_IO("%s %d: write_indirect32(0x%08X, 0x%08X)\n", __FILE__,
228 __LINE__, (u32) (b), (u32) (c));
43f66a6c
JK
229 _ipw_write_reg32(a, b, c);
230}
231
232#define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
233#define ipw_write8(ipw, ofs, val) \
234 IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
235 _ipw_write8(ipw, ofs, val)
236
237#define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))
238#define ipw_write16(ipw, ofs, val) \
239 IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
240 _ipw_write16(ipw, ofs, val)
241
242#define _ipw_write32(ipw, ofs, val) writel((val), (ipw)->hw_base + (ofs))
243#define ipw_write32(ipw, ofs, val) \
244 IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
245 _ipw_write32(ipw, ofs, val)
246
247#define _ipw_read8(ipw, ofs) readb((ipw)->hw_base + (ofs))
0edd5b44
JG
248static inline u8 __ipw_read8(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
249{
250 IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", f, l, (u32) (ofs));
43f66a6c
JK
251 return _ipw_read8(ipw, ofs);
252}
0edd5b44 253
43f66a6c
JK
254#define ipw_read8(ipw, ofs) __ipw_read8(__FILE__, __LINE__, ipw, ofs)
255
256#define _ipw_read16(ipw, ofs) readw((ipw)->hw_base + (ofs))
0edd5b44
JG
257static inline u16 __ipw_read16(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
258{
259 IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", f, l, (u32) (ofs));
43f66a6c
JK
260 return _ipw_read16(ipw, ofs);
261}
0edd5b44 262
43f66a6c
JK
263#define ipw_read16(ipw, ofs) __ipw_read16(__FILE__, __LINE__, ipw, ofs)
264
265#define _ipw_read32(ipw, ofs) readl((ipw)->hw_base + (ofs))
0edd5b44
JG
266static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
267{
268 IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", f, l, (u32) (ofs));
43f66a6c
JK
269 return _ipw_read32(ipw, ofs);
270}
0edd5b44 271
43f66a6c
JK
272#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
273
274static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
275#define ipw_read_indirect(a, b, c, d) \
276 IPW_DEBUG_IO("%s %d: read_inddirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
277 _ipw_read_indirect(a, b, c, d)
278
0edd5b44
JG
279static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
280 int num);
43f66a6c
JK
281#define ipw_write_indirect(a, b, c, d) \
282 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
283 _ipw_write_indirect(a, b, c, d)
284
285/* indirect write s */
0edd5b44 286static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
43f66a6c 287{
0edd5b44 288 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
b095c381
JK
289 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
290 _ipw_write32(priv, IPW_INDIRECT_DATA, value);
43f66a6c
JK
291}
292
43f66a6c
JK
293static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
294{
295 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
b095c381
JK
296 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
297 _ipw_write8(priv, IPW_INDIRECT_DATA, value);
bf79451e 298 IPW_DEBUG_IO(" reg = 0x%8lX : value = 0x%8X\n",
b095c381 299 (unsigned long)(priv->hw_base + IPW_INDIRECT_DATA), value);
43f66a6c
JK
300}
301
0edd5b44 302static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
43f66a6c
JK
303{
304 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
b095c381
JK
305 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
306 _ipw_write16(priv, IPW_INDIRECT_DATA, value);
43f66a6c
JK
307}
308
309/* indirect read s */
310
311static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
312{
313 u32 word;
b095c381 314 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
43f66a6c 315 IPW_DEBUG_IO(" reg = 0x%8X : \n", reg);
b095c381 316 word = _ipw_read32(priv, IPW_INDIRECT_DATA);
0edd5b44 317 return (word >> ((reg & 0x3) * 8)) & 0xff;
43f66a6c
JK
318}
319
320static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
321{
322 u32 value;
323
324 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg);
325
b095c381
JK
326 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
327 value = _ipw_read32(priv, IPW_INDIRECT_DATA);
43f66a6c
JK
328 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value);
329 return value;
330}
331
332/* iterative/auto-increment 32 bit reads and writes */
333static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
334 int num)
335{
b095c381 336 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
43f66a6c 337 u32 dif_len = addr - aligned_addr;
43f66a6c 338 u32 i;
bf79451e 339
43f66a6c
JK
340 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
341
ea2b26e0
JK
342 if (num <= 0) {
343 return;
344 }
345
43f66a6c
JK
346 /* Read the first nibble byte by byte */
347 if (unlikely(dif_len)) {
b095c381 348 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
ea2b26e0
JK
349 /* Start reading at aligned_addr + dif_len */
350 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--)
b095c381 351 *buf++ = _ipw_read8(priv, IPW_INDIRECT_DATA + i);
43f66a6c
JK
352 aligned_addr += 4;
353 }
354
b095c381 355 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
ea2b26e0 356 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
b095c381 357 *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA);
bf79451e 358
43f66a6c 359 /* Copy the last nibble */
ea2b26e0 360 if (unlikely(num)) {
b095c381 361 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
ea2b26e0 362 for (i = 0; num > 0; i++, num--)
b095c381 363 *buf++ = ipw_read8(priv, IPW_INDIRECT_DATA + i);
ea2b26e0 364 }
43f66a6c
JK
365}
366
0edd5b44 367static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
43f66a6c
JK
368 int num)
369{
b095c381 370 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
43f66a6c 371 u32 dif_len = addr - aligned_addr;
43f66a6c 372 u32 i;
bf79451e 373
43f66a6c 374 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
bf79451e 375
ea2b26e0
JK
376 if (num <= 0) {
377 return;
378 }
379
43f66a6c
JK
380 /* Write the first nibble byte by byte */
381 if (unlikely(dif_len)) {
b095c381 382 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
ea2b26e0
JK
383 /* Start reading at aligned_addr + dif_len */
384 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
b095c381 385 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
43f66a6c
JK
386 aligned_addr += 4;
387 }
bf79451e 388
b095c381 389 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
ea2b26e0 390 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
b095c381 391 _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);
bf79451e 392
43f66a6c 393 /* Copy the last nibble */
ea2b26e0 394 if (unlikely(num)) {
b095c381 395 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
ea2b26e0 396 for (i = 0; num > 0; i++, num--, buf++)
b095c381 397 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
ea2b26e0 398 }
43f66a6c
JK
399}
400
bf79451e 401static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
43f66a6c
JK
402 int num)
403{
404 memcpy_toio((priv->hw_base + addr), buf, num);
405}
406
407static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask)
408{
409 ipw_write32(priv, reg, ipw_read32(priv, reg) | mask);
410}
411
412static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask)
413{
414 ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask);
415}
416
417static inline void ipw_enable_interrupts(struct ipw_priv *priv)
418{
419 if (priv->status & STATUS_INT_ENABLED)
420 return;
421 priv->status |= STATUS_INT_ENABLED;
b095c381 422 ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL);
43f66a6c
JK
423}
424
425static inline void ipw_disable_interrupts(struct ipw_priv *priv)
426{
427 if (!(priv->status & STATUS_INT_ENABLED))
428 return;
429 priv->status &= ~STATUS_INT_ENABLED;
b095c381 430 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
43f66a6c
JK
431}
432
433static char *ipw_error_desc(u32 val)
434{
435 switch (val) {
bf79451e 436 case IPW_FW_ERROR_OK:
43f66a6c 437 return "ERROR_OK";
bf79451e 438 case IPW_FW_ERROR_FAIL:
43f66a6c 439 return "ERROR_FAIL";
bf79451e 440 case IPW_FW_ERROR_MEMORY_UNDERFLOW:
43f66a6c 441 return "MEMORY_UNDERFLOW";
bf79451e 442 case IPW_FW_ERROR_MEMORY_OVERFLOW:
43f66a6c 443 return "MEMORY_OVERFLOW";
bf79451e 444 case IPW_FW_ERROR_BAD_PARAM:
b095c381 445 return "BAD_PARAM";
bf79451e 446 case IPW_FW_ERROR_BAD_CHECKSUM:
b095c381 447 return "BAD_CHECKSUM";
bf79451e 448 case IPW_FW_ERROR_NMI_INTERRUPT:
b095c381 449 return "NMI_INTERRUPT";
bf79451e 450 case IPW_FW_ERROR_BAD_DATABASE:
b095c381 451 return "BAD_DATABASE";
bf79451e 452 case IPW_FW_ERROR_ALLOC_FAIL:
b095c381 453 return "ALLOC_FAIL";
bf79451e 454 case IPW_FW_ERROR_DMA_UNDERRUN:
b095c381 455 return "DMA_UNDERRUN";
bf79451e 456 case IPW_FW_ERROR_DMA_STATUS:
b095c381
JK
457 return "DMA_STATUS";
458 case IPW_FW_ERROR_DINO_ERROR:
459 return "DINO_ERROR";
460 case IPW_FW_ERROR_EEPROM_ERROR:
461 return "EEPROM_ERROR";
bf79451e 462 case IPW_FW_ERROR_SYSASSERT:
b095c381 463 return "SYSASSERT";
bf79451e 464 case IPW_FW_ERROR_FATAL_ERROR:
b095c381 465 return "FATAL_ERROR";
bf79451e 466 default:
b095c381 467 return "UNKNOWN_ERROR";
43f66a6c
JK
468 }
469}
470
471static void ipw_dump_nic_error_log(struct ipw_priv *priv)
472{
473 u32 desc, time, blink1, blink2, ilink1, ilink2, idata, i, count, base;
474
475 base = ipw_read32(priv, IPWSTATUS_ERROR_LOG);
476 count = ipw_read_reg32(priv, base);
bf79451e 477
43f66a6c
JK
478 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
479 IPW_ERROR("Start IPW Error Log Dump:\n");
480 IPW_ERROR("Status: 0x%08X, Config: %08X\n",
481 priv->status, priv->config);
482 }
483
bf79451e 484 for (i = ERROR_START_OFFSET;
0edd5b44
JG
485 i <= count * ERROR_ELEM_SIZE; i += ERROR_ELEM_SIZE) {
486 desc = ipw_read_reg32(priv, base + i);
487 time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
488 blink1 = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
489 blink2 = ipw_read_reg32(priv, base + i + 3 * sizeof(u32));
490 ilink1 = ipw_read_reg32(priv, base + i + 4 * sizeof(u32));
491 ilink2 = ipw_read_reg32(priv, base + i + 5 * sizeof(u32));
492 idata = ipw_read_reg32(priv, base + i + 6 * sizeof(u32));
43f66a6c 493
0edd5b44
JG
494 IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
495 ipw_error_desc(desc), time, blink1, blink2,
496 ilink1, ilink2, idata);
43f66a6c
JK
497 }
498}
499
500static void ipw_dump_nic_event_log(struct ipw_priv *priv)
501{
502 u32 ev, time, data, i, count, base;
503
504 base = ipw_read32(priv, IPW_EVENT_LOG);
505 count = ipw_read_reg32(priv, base);
bf79451e 506
43f66a6c
JK
507 if (EVENT_START_OFFSET <= count * EVENT_ELEM_SIZE)
508 IPW_ERROR("Start IPW Event Log Dump:\n");
509
bf79451e 510 for (i = EVENT_START_OFFSET;
0edd5b44 511 i <= count * EVENT_ELEM_SIZE; i += EVENT_ELEM_SIZE) {
43f66a6c 512 ev = ipw_read_reg32(priv, base + i);
0edd5b44
JG
513 time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
514 data = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
43f66a6c
JK
515
516#ifdef CONFIG_IPW_DEBUG
517 IPW_ERROR("%i\t0x%08x\t%i\n", time, data, ev);
518#endif
519 }
520}
521
c848d0af
JK
522static inline int ipw_is_init(struct ipw_priv *priv)
523{
524 return (priv->status & STATUS_INIT) ? 1 : 0;
525}
526
0edd5b44 527static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)
43f66a6c
JK
528{
529 u32 addr, field_info, field_len, field_count, total_len;
530
531 IPW_DEBUG_ORD("ordinal = %i\n", ord);
532
533 if (!priv || !val || !len) {
534 IPW_DEBUG_ORD("Invalid argument\n");
535 return -EINVAL;
536 }
bf79451e 537
43f66a6c
JK
538 /* verify device ordinal tables have been initialized */
539 if (!priv->table0_addr || !priv->table1_addr || !priv->table2_addr) {
540 IPW_DEBUG_ORD("Access ordinals before initialization\n");
541 return -EINVAL;
542 }
543
544 switch (IPW_ORD_TABLE_ID_MASK & ord) {
545 case IPW_ORD_TABLE_0_MASK:
546 /*
547 * TABLE 0: Direct access to a table of 32 bit values
548 *
bf79451e 549 * This is a very simple table with the data directly
43f66a6c
JK
550 * read from the table
551 */
552
553 /* remove the table id from the ordinal */
554 ord &= IPW_ORD_TABLE_VALUE_MASK;
555
556 /* boundary check */
557 if (ord > priv->table0_len) {
558 IPW_DEBUG_ORD("ordinal value (%i) longer then "
559 "max (%i)\n", ord, priv->table0_len);
560 return -EINVAL;
561 }
562
563 /* verify we have enough room to store the value */
564 if (*len < sizeof(u32)) {
565 IPW_DEBUG_ORD("ordinal buffer length too small, "
aaa4d308 566 "need %zd\n", sizeof(u32));
43f66a6c
JK
567 return -EINVAL;
568 }
569
570 IPW_DEBUG_ORD("Reading TABLE0[%i] from offset 0x%08x\n",
0edd5b44 571 ord, priv->table0_addr + (ord << 2));
43f66a6c
JK
572
573 *len = sizeof(u32);
574 ord <<= 2;
0edd5b44 575 *((u32 *) val) = ipw_read32(priv, priv->table0_addr + ord);
43f66a6c
JK
576 break;
577
578 case IPW_ORD_TABLE_1_MASK:
579 /*
580 * TABLE 1: Indirect access to a table of 32 bit values
bf79451e
JG
581 *
582 * This is a fairly large table of u32 values each
43f66a6c
JK
583 * representing starting addr for the data (which is
584 * also a u32)
585 */
586
587 /* remove the table id from the ordinal */
588 ord &= IPW_ORD_TABLE_VALUE_MASK;
bf79451e 589
43f66a6c
JK
590 /* boundary check */
591 if (ord > priv->table1_len) {
592 IPW_DEBUG_ORD("ordinal value too long\n");
593 return -EINVAL;
594 }
595
596 /* verify we have enough room to store the value */
597 if (*len < sizeof(u32)) {
598 IPW_DEBUG_ORD("ordinal buffer length too small, "
aaa4d308 599 "need %zd\n", sizeof(u32));
43f66a6c
JK
600 return -EINVAL;
601 }
602
0edd5b44
JG
603 *((u32 *) val) =
604 ipw_read_reg32(priv, (priv->table1_addr + (ord << 2)));
43f66a6c
JK
605 *len = sizeof(u32);
606 break;
607
608 case IPW_ORD_TABLE_2_MASK:
609 /*
610 * TABLE 2: Indirect access to a table of variable sized values
611 *
612 * This table consist of six values, each containing
613 * - dword containing the starting offset of the data
614 * - dword containing the lengh in the first 16bits
615 * and the count in the second 16bits
616 */
617
618 /* remove the table id from the ordinal */
619 ord &= IPW_ORD_TABLE_VALUE_MASK;
620
621 /* boundary check */
622 if (ord > priv->table2_len) {
623 IPW_DEBUG_ORD("ordinal value too long\n");
624 return -EINVAL;
625 }
626
627 /* get the address of statistic */
628 addr = ipw_read_reg32(priv, priv->table2_addr + (ord << 3));
bf79451e
JG
629
630 /* get the second DW of statistics ;
43f66a6c 631 * two 16-bit words - first is length, second is count */
0edd5b44
JG
632 field_info =
633 ipw_read_reg32(priv,
634 priv->table2_addr + (ord << 3) +
635 sizeof(u32));
bf79451e 636
43f66a6c 637 /* get each entry length */
0edd5b44 638 field_len = *((u16 *) & field_info);
bf79451e 639
43f66a6c 640 /* get number of entries */
0edd5b44 641 field_count = *(((u16 *) & field_info) + 1);
bf79451e 642
43f66a6c
JK
643 /* abort if not enought memory */
644 total_len = field_len * field_count;
645 if (total_len > *len) {
646 *len = total_len;
647 return -EINVAL;
648 }
bf79451e 649
43f66a6c
JK
650 *len = total_len;
651 if (!total_len)
652 return 0;
653
654 IPW_DEBUG_ORD("addr = 0x%08x, total_len = %i, "
bf79451e 655 "field_info = 0x%08x\n",
43f66a6c
JK
656 addr, total_len, field_info);
657 ipw_read_indirect(priv, addr, val, total_len);
658 break;
659
660 default:
661 IPW_DEBUG_ORD("Invalid ordinal!\n");
662 return -EINVAL;
663
664 }
665
43f66a6c
JK
666 return 0;
667}
668
669static void ipw_init_ordinals(struct ipw_priv *priv)
670{
671 priv->table0_addr = IPW_ORDINALS_TABLE_LOWER;
bf79451e 672 priv->table0_len = ipw_read32(priv, priv->table0_addr);
43f66a6c
JK
673
674 IPW_DEBUG_ORD("table 0 offset at 0x%08x, len = %i\n",
675 priv->table0_addr, priv->table0_len);
676
677 priv->table1_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_1);
678 priv->table1_len = ipw_read_reg32(priv, priv->table1_addr);
679
680 IPW_DEBUG_ORD("table 1 offset at 0x%08x, len = %i\n",
681 priv->table1_addr, priv->table1_len);
682
683 priv->table2_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_2);
684 priv->table2_len = ipw_read_reg32(priv, priv->table2_addr);
0edd5b44 685 priv->table2_len &= 0x0000ffff; /* use first two bytes */
43f66a6c
JK
686
687 IPW_DEBUG_ORD("table 2 offset at 0x%08x, len = %i\n",
688 priv->table2_addr, priv->table2_len);
689
690}
691
a613bffd
JK
692u32 ipw_register_toggle(u32 reg)
693{
b095c381
JK
694 reg &= ~IPW_START_STANDBY;
695 if (reg & IPW_GATE_ODMA)
696 reg &= ~IPW_GATE_ODMA;
697 if (reg & IPW_GATE_IDMA)
698 reg &= ~IPW_GATE_IDMA;
699 if (reg & IPW_GATE_ADMA)
700 reg &= ~IPW_GATE_ADMA;
a613bffd
JK
701 return reg;
702}
703
704/*
705 * LED behavior:
706 * - On radio ON, turn on any LEDs that require to be on during start
707 * - On initialization, start unassociated blink
708 * - On association, disable unassociated blink
709 * - On disassociation, start unassociated blink
710 * - On radio OFF, turn off any LEDs started during radio on
711 *
712 */
713#define LD_TIME_LINK_ON 300
714#define LD_TIME_LINK_OFF 2700
715#define LD_TIME_ACT_ON 250
716
717void ipw_led_link_on(struct ipw_priv *priv)
718{
719 unsigned long flags;
720 u32 led;
721
722 /* If configured to not use LEDs, or nic_type is 1,
723 * then we don't toggle a LINK led */
724 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
725 return;
726
727 spin_lock_irqsave(&priv->lock, flags);
728
729 if (!(priv->status & STATUS_RF_KILL_MASK) &&
730 !(priv->status & STATUS_LED_LINK_ON)) {
731 IPW_DEBUG_LED("Link LED On\n");
b095c381 732 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
733 led |= priv->led_association_on;
734
735 led = ipw_register_toggle(led);
736
737 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 738 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
739
740 priv->status |= STATUS_LED_LINK_ON;
741
742 /* If we aren't associated, schedule turning the LED off */
743 if (!(priv->status & STATUS_ASSOCIATED))
744 queue_delayed_work(priv->workqueue,
745 &priv->led_link_off,
746 LD_TIME_LINK_ON);
747 }
748
749 spin_unlock_irqrestore(&priv->lock, flags);
750}
751
c848d0af
JK
752static void ipw_bg_led_link_on(void *data)
753{
754 struct ipw_priv *priv = data;
755 down(&priv->sem);
756 ipw_led_link_on(data);
757 up(&priv->sem);
758}
759
a613bffd
JK
760void ipw_led_link_off(struct ipw_priv *priv)
761{
762 unsigned long flags;
763 u32 led;
764
765 /* If configured not to use LEDs, or nic type is 1,
766 * then we don't goggle the LINK led. */
767 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
768 return;
769
770 spin_lock_irqsave(&priv->lock, flags);
771
772 if (priv->status & STATUS_LED_LINK_ON) {
b095c381 773 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
774 led &= priv->led_association_off;
775 led = ipw_register_toggle(led);
776
777 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 778 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
779
780 IPW_DEBUG_LED("Link LED Off\n");
781
782 priv->status &= ~STATUS_LED_LINK_ON;
783
784 /* If we aren't associated and the radio is on, schedule
785 * turning the LED on (blink while unassociated) */
786 if (!(priv->status & STATUS_RF_KILL_MASK) &&
787 !(priv->status & STATUS_ASSOCIATED))
788 queue_delayed_work(priv->workqueue, &priv->led_link_on,
789 LD_TIME_LINK_OFF);
790
791 }
792
793 spin_unlock_irqrestore(&priv->lock, flags);
794}
795
c848d0af
JK
796static void ipw_bg_led_link_off(void *data)
797{
798 struct ipw_priv *priv = data;
799 down(&priv->sem);
800 ipw_led_link_off(data);
801 up(&priv->sem);
802}
803
b095c381 804static inline void __ipw_led_activity_on(struct ipw_priv *priv)
a613bffd 805{
a613bffd
JK
806 u32 led;
807
808 if (priv->config & CFG_NO_LED)
809 return;
810
b095c381 811 if (priv->status & STATUS_RF_KILL_MASK)
a613bffd 812 return;
a613bffd
JK
813
814 if (!(priv->status & STATUS_LED_ACT_ON)) {
b095c381 815 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
816 led |= priv->led_activity_on;
817
818 led = ipw_register_toggle(led);
819
820 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 821 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
822
823 IPW_DEBUG_LED("Activity LED On\n");
824
825 priv->status |= STATUS_LED_ACT_ON;
826
c848d0af 827 cancel_delayed_work(&priv->led_act_off);
a613bffd
JK
828 queue_delayed_work(priv->workqueue, &priv->led_act_off,
829 LD_TIME_ACT_ON);
830 } else {
831 /* Reschedule LED off for full time period */
832 cancel_delayed_work(&priv->led_act_off);
833 queue_delayed_work(priv->workqueue, &priv->led_act_off,
834 LD_TIME_ACT_ON);
835 }
b095c381 836}
a613bffd 837
b095c381
JK
838void ipw_led_activity_on(struct ipw_priv *priv)
839{
840 unsigned long flags;
841 spin_lock_irqsave(&priv->lock, flags);
842 __ipw_led_activity_on(priv);
a613bffd
JK
843 spin_unlock_irqrestore(&priv->lock, flags);
844}
845
846void ipw_led_activity_off(struct ipw_priv *priv)
847{
848 unsigned long flags;
849 u32 led;
850
851 if (priv->config & CFG_NO_LED)
852 return;
853
854 spin_lock_irqsave(&priv->lock, flags);
855
856 if (priv->status & STATUS_LED_ACT_ON) {
b095c381 857 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
858 led &= priv->led_activity_off;
859
860 led = ipw_register_toggle(led);
861
862 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 863 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
864
865 IPW_DEBUG_LED("Activity LED Off\n");
866
867 priv->status &= ~STATUS_LED_ACT_ON;
868 }
869
870 spin_unlock_irqrestore(&priv->lock, flags);
871}
872
c848d0af
JK
873static void ipw_bg_led_activity_off(void *data)
874{
875 struct ipw_priv *priv = data;
876 down(&priv->sem);
877 ipw_led_activity_off(data);
878 up(&priv->sem);
879}
880
a613bffd
JK
881void ipw_led_band_on(struct ipw_priv *priv)
882{
883 unsigned long flags;
884 u32 led;
885
886 /* Only nic type 1 supports mode LEDs */
c848d0af
JK
887 if (priv->config & CFG_NO_LED ||
888 priv->nic_type != EEPROM_NIC_TYPE_1 || !priv->assoc_network)
a613bffd
JK
889 return;
890
891 spin_lock_irqsave(&priv->lock, flags);
892
b095c381 893 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
894 if (priv->assoc_network->mode == IEEE_A) {
895 led |= priv->led_ofdm_on;
896 led &= priv->led_association_off;
897 IPW_DEBUG_LED("Mode LED On: 802.11a\n");
898 } else if (priv->assoc_network->mode == IEEE_G) {
899 led |= priv->led_ofdm_on;
900 led |= priv->led_association_on;
901 IPW_DEBUG_LED("Mode LED On: 802.11g\n");
902 } else {
903 led &= priv->led_ofdm_off;
904 led |= priv->led_association_on;
905 IPW_DEBUG_LED("Mode LED On: 802.11b\n");
906 }
907
908 led = ipw_register_toggle(led);
909
910 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 911 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
912
913 spin_unlock_irqrestore(&priv->lock, flags);
914}
915
916void ipw_led_band_off(struct ipw_priv *priv)
917{
918 unsigned long flags;
919 u32 led;
920
921 /* Only nic type 1 supports mode LEDs */
922 if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
923 return;
924
925 spin_lock_irqsave(&priv->lock, flags);
926
b095c381 927 led = ipw_read_reg32(priv, IPW_EVENT_REG);
a613bffd
JK
928 led &= priv->led_ofdm_off;
929 led &= priv->led_association_off;
930
931 led = ipw_register_toggle(led);
932
933 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
b095c381 934 ipw_write_reg32(priv, IPW_EVENT_REG, led);
a613bffd
JK
935
936 spin_unlock_irqrestore(&priv->lock, flags);
937}
938
939void ipw_led_radio_on(struct ipw_priv *priv)
940{
941 ipw_led_link_on(priv);
942}
943
944void ipw_led_radio_off(struct ipw_priv *priv)
945{
946 ipw_led_activity_off(priv);
947 ipw_led_link_off(priv);
948}
949
950void ipw_led_link_up(struct ipw_priv *priv)
951{
952 /* Set the Link Led on for all nic types */
953 ipw_led_link_on(priv);
954}
955
956void ipw_led_link_down(struct ipw_priv *priv)
957{
958 ipw_led_activity_off(priv);
959 ipw_led_link_off(priv);
960
961 if (priv->status & STATUS_RF_KILL_MASK)
962 ipw_led_radio_off(priv);
963}
964
965void ipw_led_init(struct ipw_priv *priv)
966{
967 priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
968
969 /* Set the default PINs for the link and activity leds */
b095c381
JK
970 priv->led_activity_on = IPW_ACTIVITY_LED;
971 priv->led_activity_off = ~(IPW_ACTIVITY_LED);
a613bffd 972
b095c381
JK
973 priv->led_association_on = IPW_ASSOCIATED_LED;
974 priv->led_association_off = ~(IPW_ASSOCIATED_LED);
a613bffd
JK
975
976 /* Set the default PINs for the OFDM leds */
b095c381
JK
977 priv->led_ofdm_on = IPW_OFDM_LED;
978 priv->led_ofdm_off = ~(IPW_OFDM_LED);
a613bffd
JK
979
980 switch (priv->nic_type) {
981 case EEPROM_NIC_TYPE_1:
982 /* In this NIC type, the LEDs are reversed.... */
b095c381
JK
983 priv->led_activity_on = IPW_ASSOCIATED_LED;
984 priv->led_activity_off = ~(IPW_ASSOCIATED_LED);
985 priv->led_association_on = IPW_ACTIVITY_LED;
986 priv->led_association_off = ~(IPW_ACTIVITY_LED);
a613bffd
JK
987
988 if (!(priv->config & CFG_NO_LED))
989 ipw_led_band_on(priv);
990
991 /* And we don't blink link LEDs for this nic, so
992 * just return here */
993 return;
994
995 case EEPROM_NIC_TYPE_3:
996 case EEPROM_NIC_TYPE_2:
997 case EEPROM_NIC_TYPE_4:
998 case EEPROM_NIC_TYPE_0:
999 break;
1000
1001 default:
1002 IPW_DEBUG_INFO("Unknown NIC type from EEPROM: %d\n",
1003 priv->nic_type);
1004 priv->nic_type = EEPROM_NIC_TYPE_0;
1005 break;
1006 }
1007
1008 if (!(priv->config & CFG_NO_LED)) {
1009 if (priv->status & STATUS_ASSOCIATED)
1010 ipw_led_link_on(priv);
1011 else
1012 ipw_led_link_off(priv);
1013 }
1014}
1015
1016void ipw_led_shutdown(struct ipw_priv *priv)
1017{
1018 cancel_delayed_work(&priv->led_link_on);
1019 cancel_delayed_work(&priv->led_link_off);
1020 cancel_delayed_work(&priv->led_act_off);
1021 ipw_led_activity_off(priv);
1022 ipw_led_link_off(priv);
1023 ipw_led_band_off(priv);
1024}
1025
43f66a6c
JK
1026/*
1027 * The following adds a new attribute to the sysfs representation
1028 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
1029 * used for controling the debug level.
bf79451e 1030 *
43f66a6c
JK
1031 * See the level definitions in ipw for details.
1032 */
1033static ssize_t show_debug_level(struct device_driver *d, char *buf)
1034{
1035 return sprintf(buf, "0x%08X\n", ipw_debug_level);
1036}
a613bffd
JK
1037
1038static ssize_t store_debug_level(struct device_driver *d, const char *buf,
1039 size_t count)
43f66a6c
JK
1040{
1041 char *p = (char *)buf;
1042 u32 val;
1043
1044 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
1045 p++;
1046 if (p[0] == 'x' || p[0] == 'X')
1047 p++;
1048 val = simple_strtoul(p, &p, 16);
1049 } else
1050 val = simple_strtoul(p, &p, 10);
bf79451e
JG
1051 if (p == buf)
1052 printk(KERN_INFO DRV_NAME
43f66a6c
JK
1053 ": %s is not in hex or decimal form.\n", buf);
1054 else
1055 ipw_debug_level = val;
1056
1057 return strnlen(buf, count);
1058}
1059
bf79451e 1060static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
43f66a6c
JK
1061 show_debug_level, store_debug_level);
1062
a613bffd
JK
1063static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
1064 char *buf)
1065{
1066 struct ipw_priv *priv = dev_get_drvdata(d);
1067 return sprintf(buf, "%d\n", priv->ieee->scan_age);
1068}
1069
1070static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
1071 const char *buf, size_t count)
1072{
1073 struct ipw_priv *priv = dev_get_drvdata(d);
c848d0af 1074#ifdef CONFIG_IPW_DEBUG
a613bffd 1075 struct net_device *dev = priv->net_dev;
c848d0af 1076#endif
a613bffd
JK
1077 char buffer[] = "00000000";
1078 unsigned long len =
1079 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
1080 unsigned long val;
1081 char *p = buffer;
1082
1083 IPW_DEBUG_INFO("enter\n");
1084
1085 strncpy(buffer, buf, len);
1086 buffer[len] = 0;
1087
1088 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
1089 p++;
1090 if (p[0] == 'x' || p[0] == 'X')
1091 p++;
1092 val = simple_strtoul(p, &p, 16);
1093 } else
1094 val = simple_strtoul(p, &p, 10);
1095 if (p == buffer) {
1096 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
1097 } else {
1098 priv->ieee->scan_age = val;
1099 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
1100 }
1101
1102 IPW_DEBUG_INFO("exit\n");
1103 return len;
1104}
1105
1106static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
1107
1108static ssize_t show_led(struct device *d, struct device_attribute *attr,
1109 char *buf)
1110{
1111 struct ipw_priv *priv = dev_get_drvdata(d);
1112 return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);
1113}
1114
1115static ssize_t store_led(struct device *d, struct device_attribute *attr,
1116 const char *buf, size_t count)
1117{
1118 struct ipw_priv *priv = dev_get_drvdata(d);
1119
1120 IPW_DEBUG_INFO("enter\n");
1121
1122 if (count == 0)
1123 return 0;
1124
1125 if (*buf == 0) {
1126 IPW_DEBUG_LED("Disabling LED control.\n");
1127 priv->config |= CFG_NO_LED;
1128 ipw_led_shutdown(priv);
1129 } else {
1130 IPW_DEBUG_LED("Enabling LED control.\n");
1131 priv->config &= ~CFG_NO_LED;
1132 ipw_led_init(priv);
1133 }
1134
1135 IPW_DEBUG_INFO("exit\n");
1136 return count;
1137}
1138
1139static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
1140
ad3fee56 1141static ssize_t show_status(struct device *d,
0edd5b44 1142 struct device_attribute *attr, char *buf)
43f66a6c 1143{
ad3fee56 1144 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1145 return sprintf(buf, "0x%08x\n", (int)p->status);
1146}
0edd5b44 1147
43f66a6c
JK
1148static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
1149
ad3fee56
AM
1150static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
1151 char *buf)
43f66a6c 1152{
ad3fee56 1153 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1154 return sprintf(buf, "0x%08x\n", (int)p->config);
1155}
0edd5b44 1156
43f66a6c
JK
1157static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
1158
ad3fee56 1159static ssize_t show_nic_type(struct device *d,
0edd5b44 1160 struct device_attribute *attr, char *buf)
43f66a6c 1161{
a613bffd
JK
1162 struct ipw_priv *priv = d->driver_data;
1163 return sprintf(buf, "TYPE: %d\n", priv->nic_type);
43f66a6c 1164}
0edd5b44 1165
43f66a6c
JK
1166static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
1167
ad3fee56 1168static ssize_t dump_error_log(struct device *d,
0edd5b44
JG
1169 struct device_attribute *attr, const char *buf,
1170 size_t count)
43f66a6c
JK
1171{
1172 char *p = (char *)buf;
1173
bf79451e 1174 if (p[0] == '1')
0edd5b44 1175 ipw_dump_nic_error_log((struct ipw_priv *)d->driver_data);
43f66a6c
JK
1176
1177 return strnlen(buf, count);
1178}
0edd5b44 1179
43f66a6c
JK
1180static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log);
1181
ad3fee56 1182static ssize_t dump_event_log(struct device *d,
0edd5b44
JG
1183 struct device_attribute *attr, const char *buf,
1184 size_t count)
43f66a6c
JK
1185{
1186 char *p = (char *)buf;
1187
bf79451e 1188 if (p[0] == '1')
0edd5b44 1189 ipw_dump_nic_event_log((struct ipw_priv *)d->driver_data);
43f66a6c
JK
1190
1191 return strnlen(buf, count);
1192}
0edd5b44 1193
43f66a6c
JK
1194static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
1195
ad3fee56 1196static ssize_t show_ucode_version(struct device *d,
0edd5b44 1197 struct device_attribute *attr, char *buf)
43f66a6c
JK
1198{
1199 u32 len = sizeof(u32), tmp = 0;
ad3fee56 1200 struct ipw_priv *p = d->driver_data;
43f66a6c 1201
0edd5b44 1202 if (ipw_get_ordinal(p, IPW_ORD_STAT_UCODE_VERSION, &tmp, &len))
43f66a6c
JK
1203 return 0;
1204
1205 return sprintf(buf, "0x%08x\n", tmp);
1206}
0edd5b44
JG
1207
1208static DEVICE_ATTR(ucode_version, S_IWUSR | S_IRUGO, show_ucode_version, NULL);
43f66a6c 1209
ad3fee56
AM
1210static ssize_t show_rtc(struct device *d, struct device_attribute *attr,
1211 char *buf)
43f66a6c
JK
1212{
1213 u32 len = sizeof(u32), tmp = 0;
ad3fee56 1214 struct ipw_priv *p = d->driver_data;
43f66a6c 1215
0edd5b44 1216 if (ipw_get_ordinal(p, IPW_ORD_STAT_RTC, &tmp, &len))
43f66a6c
JK
1217 return 0;
1218
1219 return sprintf(buf, "0x%08x\n", tmp);
1220}
0edd5b44
JG
1221
1222static DEVICE_ATTR(rtc, S_IWUSR | S_IRUGO, show_rtc, NULL);
43f66a6c
JK
1223
1224/*
1225 * Add a device attribute to view/control the delay between eeprom
1226 * operations.
1227 */
ad3fee56 1228static ssize_t show_eeprom_delay(struct device *d,
0edd5b44 1229 struct device_attribute *attr, char *buf)
43f66a6c 1230{
0edd5b44 1231 int n = ((struct ipw_priv *)d->driver_data)->eeprom_delay;
43f66a6c
JK
1232 return sprintf(buf, "%i\n", n);
1233}
ad3fee56 1234static ssize_t store_eeprom_delay(struct device *d,
0edd5b44
JG
1235 struct device_attribute *attr,
1236 const char *buf, size_t count)
43f66a6c 1237{
ad3fee56 1238 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1239 sscanf(buf, "%i", &p->eeprom_delay);
1240 return strnlen(buf, count);
1241}
0edd5b44
JG
1242
1243static DEVICE_ATTR(eeprom_delay, S_IWUSR | S_IRUGO,
1244 show_eeprom_delay, store_eeprom_delay);
43f66a6c 1245
ad3fee56 1246static ssize_t show_command_event_reg(struct device *d,
0edd5b44 1247 struct device_attribute *attr, char *buf)
43f66a6c
JK
1248{
1249 u32 reg = 0;
ad3fee56 1250 struct ipw_priv *p = d->driver_data;
43f66a6c 1251
b095c381 1252 reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT);
43f66a6c
JK
1253 return sprintf(buf, "0x%08x\n", reg);
1254}
ad3fee56 1255static ssize_t store_command_event_reg(struct device *d,
0edd5b44
JG
1256 struct device_attribute *attr,
1257 const char *buf, size_t count)
43f66a6c
JK
1258{
1259 u32 reg;
ad3fee56 1260 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1261
1262 sscanf(buf, "%x", &reg);
b095c381 1263 ipw_write_reg32(p, IPW_INTERNAL_CMD_EVENT, reg);
43f66a6c
JK
1264 return strnlen(buf, count);
1265}
0edd5b44
JG
1266
1267static DEVICE_ATTR(command_event_reg, S_IWUSR | S_IRUGO,
1268 show_command_event_reg, store_command_event_reg);
43f66a6c 1269
ad3fee56 1270static ssize_t show_mem_gpio_reg(struct device *d,
0edd5b44 1271 struct device_attribute *attr, char *buf)
43f66a6c
JK
1272{
1273 u32 reg = 0;
ad3fee56 1274 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1275
1276 reg = ipw_read_reg32(p, 0x301100);
1277 return sprintf(buf, "0x%08x\n", reg);
1278}
ad3fee56 1279static ssize_t store_mem_gpio_reg(struct device *d,
0edd5b44
JG
1280 struct device_attribute *attr,
1281 const char *buf, size_t count)
43f66a6c
JK
1282{
1283 u32 reg;
ad3fee56 1284 struct ipw_priv *p = d->driver_data;
43f66a6c
JK
1285
1286 sscanf(buf, "%x", &reg);
1287 ipw_write_reg32(p, 0x301100, reg);
1288 return strnlen(buf, count);
1289}
0edd5b44
JG
1290
1291static DEVICE_ATTR(mem_gpio_reg, S_IWUSR | S_IRUGO,
1292 show_mem_gpio_reg, store_mem_gpio_reg);
43f66a6c 1293
ad3fee56 1294static ssize_t show_indirect_dword(struct device *d,
0edd5b44 1295 struct device_attribute *attr, char *buf)
43f66a6c
JK
1296{
1297 u32 reg = 0;
ad3fee56 1298 struct ipw_priv *priv = d->driver_data;
bf79451e 1299 if (priv->status & STATUS_INDIRECT_DWORD)
43f66a6c 1300 reg = ipw_read_reg32(priv, priv->indirect_dword);
bf79451e 1301 else
43f66a6c 1302 reg = 0;
bf79451e 1303
43f66a6c
JK
1304 return sprintf(buf, "0x%08x\n", reg);
1305}
ad3fee56 1306static ssize_t store_indirect_dword(struct device *d,
0edd5b44
JG
1307 struct device_attribute *attr,
1308 const char *buf, size_t count)
43f66a6c 1309{
ad3fee56 1310 struct ipw_priv *priv = d->driver_data;
43f66a6c
JK
1311
1312 sscanf(buf, "%x", &priv->indirect_dword);
1313 priv->status |= STATUS_INDIRECT_DWORD;
1314 return strnlen(buf, count);
1315}
0edd5b44
JG
1316
1317static DEVICE_ATTR(indirect_dword, S_IWUSR | S_IRUGO,
1318 show_indirect_dword, store_indirect_dword);
43f66a6c 1319
ad3fee56 1320static ssize_t show_indirect_byte(struct device *d,
0edd5b44 1321 struct device_attribute *attr, char *buf)
43f66a6c
JK
1322{
1323 u8 reg = 0;
ad3fee56 1324 struct ipw_priv *priv = d->driver_data;
bf79451e 1325 if (priv->status & STATUS_INDIRECT_BYTE)
43f66a6c 1326 reg = ipw_read_reg8(priv, priv->indirect_byte);
bf79451e 1327 else
43f66a6c
JK
1328 reg = 0;
1329
1330 return sprintf(buf, "0x%02x\n", reg);
1331}
ad3fee56 1332static ssize_t store_indirect_byte(struct device *d,
0edd5b44
JG
1333 struct device_attribute *attr,
1334 const char *buf, size_t count)
43f66a6c 1335{
ad3fee56 1336 struct ipw_priv *priv = d->driver_data;
43f66a6c
JK
1337
1338 sscanf(buf, "%x", &priv->indirect_byte);
1339 priv->status |= STATUS_INDIRECT_BYTE;
1340 return strnlen(buf, count);
1341}
0edd5b44
JG
1342
1343static DEVICE_ATTR(indirect_byte, S_IWUSR | S_IRUGO,
43f66a6c
JK
1344 show_indirect_byte, store_indirect_byte);
1345
ad3fee56 1346static ssize_t show_direct_dword(struct device *d,
0edd5b44 1347 struct device_attribute *attr, char *buf)
43f66a6c
JK
1348{
1349 u32 reg = 0;
ad3fee56 1350 struct ipw_priv *priv = d->driver_data;
43f66a6c 1351
bf79451e 1352 if (priv->status & STATUS_DIRECT_DWORD)
43f66a6c 1353 reg = ipw_read32(priv, priv->direct_dword);
bf79451e 1354 else
43f66a6c
JK
1355 reg = 0;
1356
1357 return sprintf(buf, "0x%08x\n", reg);
1358}
ad3fee56 1359static ssize_t store_direct_dword(struct device *d,
0edd5b44
JG
1360 struct device_attribute *attr,
1361 const char *buf, size_t count)
43f66a6c 1362{
ad3fee56 1363 struct ipw_priv *priv = d->driver_data;
43f66a6c
JK
1364
1365 sscanf(buf, "%x", &priv->direct_dword);
1366 priv->status |= STATUS_DIRECT_DWORD;
1367 return strnlen(buf, count);
1368}
43f66a6c 1369
0edd5b44
JG
1370static DEVICE_ATTR(direct_dword, S_IWUSR | S_IRUGO,
1371 show_direct_dword, store_direct_dword);
43f66a6c
JK
1372
1373static inline int rf_kill_active(struct ipw_priv *priv)
1374{
1375 if (0 == (ipw_read32(priv, 0x30) & 0x10000))
1376 priv->status |= STATUS_RF_KILL_HW;
1377 else
1378 priv->status &= ~STATUS_RF_KILL_HW;
1379
1380 return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0;
1381}
1382
ad3fee56 1383static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
0edd5b44 1384 char *buf)
43f66a6c
JK
1385{
1386 /* 0 - RF kill not enabled
bf79451e 1387 1 - SW based RF kill active (sysfs)
43f66a6c
JK
1388 2 - HW based RF kill active
1389 3 - Both HW and SW baed RF kill active */
ad3fee56 1390 struct ipw_priv *priv = d->driver_data;
43f66a6c 1391 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
0edd5b44 1392 (rf_kill_active(priv) ? 0x2 : 0x0);
43f66a6c
JK
1393 return sprintf(buf, "%i\n", val);
1394}
1395
1396static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
1397{
bf79451e 1398 if ((disable_radio ? 1 : 0) ==
ea2b26e0 1399 ((priv->status & STATUS_RF_KILL_SW) ? 1 : 0))
0edd5b44 1400 return 0;
43f66a6c
JK
1401
1402 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
1403 disable_radio ? "OFF" : "ON");
1404
1405 if (disable_radio) {
1406 priv->status |= STATUS_RF_KILL_SW;
1407
a613bffd 1408 if (priv->workqueue)
43f66a6c 1409 cancel_delayed_work(&priv->request_scan);
43f66a6c
JK
1410 queue_work(priv->workqueue, &priv->down);
1411 } else {
1412 priv->status &= ~STATUS_RF_KILL_SW;
1413 if (rf_kill_active(priv)) {
1414 IPW_DEBUG_RF_KILL("Can not turn radio back on - "
1415 "disabled by HW switch\n");
1416 /* Make sure the RF_KILL check timer is running */
1417 cancel_delayed_work(&priv->rf_kill);
bf79451e 1418 queue_delayed_work(priv->workqueue, &priv->rf_kill,
43f66a6c 1419 2 * HZ);
bf79451e 1420 } else
43f66a6c
JK
1421 queue_work(priv->workqueue, &priv->up);
1422 }
1423
1424 return 1;
1425}
1426
0edd5b44
JG
1427static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
1428 const char *buf, size_t count)
43f66a6c 1429{
ad3fee56 1430 struct ipw_priv *priv = d->driver_data;
bf79451e 1431
43f66a6c
JK
1432 ipw_radio_kill_sw(priv, buf[0] == '1');
1433
1434 return count;
1435}
0edd5b44
JG
1436
1437static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
43f66a6c 1438
b095c381
JK
1439static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
1440 char *buf)
1441{
1442 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1443 int pos = 0, len = 0;
1444 if (priv->config & CFG_SPEED_SCAN) {
1445 while (priv->speed_scan[pos] != 0)
1446 len += sprintf(&buf[len], "%d ",
1447 priv->speed_scan[pos++]);
1448 return len + sprintf(&buf[len], "\n");
1449 }
1450
1451 return sprintf(buf, "0\n");
1452}
1453
1454static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
1455 const char *buf, size_t count)
1456{
1457 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1458 int channel, pos = 0;
1459 const char *p = buf;
1460
1461 /* list of space separated channels to scan, optionally ending with 0 */
1462 while ((channel = simple_strtol(p, NULL, 0))) {
1463 if (pos == MAX_SPEED_SCAN - 1) {
1464 priv->speed_scan[pos] = 0;
1465 break;
1466 }
1467
1468 if (ieee80211_is_valid_channel(priv->ieee, channel))
1469 priv->speed_scan[pos++] = channel;
1470 else
1471 IPW_WARNING("Skipping invalid channel request: %d\n",
1472 channel);
1473 p = strchr(p, ' ');
1474 if (!p)
1475 break;
1476 while (*p == ' ' || *p == '\t')
1477 p++;
1478 }
1479
1480 if (pos == 0)
1481 priv->config &= ~CFG_SPEED_SCAN;
1482 else {
1483 priv->speed_scan_pos = 0;
1484 priv->config |= CFG_SPEED_SCAN;
1485 }
1486
1487 return count;
1488}
1489
1490static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan,
1491 store_speed_scan);
1492
1493static ssize_t show_net_stats(struct device *d, struct device_attribute *attr,
1494 char *buf)
1495{
1496 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1497 return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0');
1498}
1499
1500static ssize_t store_net_stats(struct device *d, struct device_attribute *attr,
1501 const char *buf, size_t count)
1502{
1503 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1504 if (buf[0] == '1')
1505 priv->config |= CFG_NET_STATS;
1506 else
1507 priv->config &= ~CFG_NET_STATS;
1508
1509 return count;
1510}
1511
1512static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO, show_net_stats,
1513 store_net_stats);
1514
ea2b26e0
JK
1515static void notify_wx_assoc_event(struct ipw_priv *priv)
1516{
1517 union iwreq_data wrqu;
1518 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1519 if (priv->status & STATUS_ASSOCIATED)
1520 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
1521 else
1522 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1523 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1524}
1525
43f66a6c
JK
1526static void ipw_irq_tasklet(struct ipw_priv *priv)
1527{
1528 u32 inta, inta_mask, handled = 0;
1529 unsigned long flags;
1530 int rc = 0;
1531
1532 spin_lock_irqsave(&priv->lock, flags);
1533
b095c381
JK
1534 inta = ipw_read32(priv, IPW_INTA_RW);
1535 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
1536 inta &= (IPW_INTA_MASK_ALL & inta_mask);
43f66a6c
JK
1537
1538 /* Add any cached INTA values that need to be handled */
1539 inta |= priv->isr_inta;
1540
1541 /* handle all the justifications for the interrupt */
b095c381 1542 if (inta & IPW_INTA_BIT_RX_TRANSFER) {
43f66a6c 1543 ipw_rx(priv);
b095c381 1544 handled |= IPW_INTA_BIT_RX_TRANSFER;
43f66a6c
JK
1545 }
1546
b095c381 1547 if (inta & IPW_INTA_BIT_TX_CMD_QUEUE) {
43f66a6c 1548 IPW_DEBUG_HC("Command completed.\n");
0edd5b44 1549 rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1);
43f66a6c
JK
1550 priv->status &= ~STATUS_HCMD_ACTIVE;
1551 wake_up_interruptible(&priv->wait_command_queue);
b095c381 1552 handled |= IPW_INTA_BIT_TX_CMD_QUEUE;
43f66a6c
JK
1553 }
1554
b095c381 1555 if (inta & IPW_INTA_BIT_TX_QUEUE_1) {
43f66a6c 1556 IPW_DEBUG_TX("TX_QUEUE_1\n");
0edd5b44 1557 rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0);
b095c381 1558 handled |= IPW_INTA_BIT_TX_QUEUE_1;
43f66a6c
JK
1559 }
1560
b095c381 1561 if (inta & IPW_INTA_BIT_TX_QUEUE_2) {
43f66a6c 1562 IPW_DEBUG_TX("TX_QUEUE_2\n");
0edd5b44 1563 rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1);
b095c381 1564 handled |= IPW_INTA_BIT_TX_QUEUE_2;
43f66a6c
JK
1565 }
1566
b095c381 1567 if (inta & IPW_INTA_BIT_TX_QUEUE_3) {
43f66a6c 1568 IPW_DEBUG_TX("TX_QUEUE_3\n");
0edd5b44 1569 rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2);
b095c381 1570 handled |= IPW_INTA_BIT_TX_QUEUE_3;
43f66a6c
JK
1571 }
1572
b095c381 1573 if (inta & IPW_INTA_BIT_TX_QUEUE_4) {
43f66a6c 1574 IPW_DEBUG_TX("TX_QUEUE_4\n");
0edd5b44 1575 rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3);
b095c381 1576 handled |= IPW_INTA_BIT_TX_QUEUE_4;
43f66a6c
JK
1577 }
1578
b095c381 1579 if (inta & IPW_INTA_BIT_STATUS_CHANGE) {
43f66a6c 1580 IPW_WARNING("STATUS_CHANGE\n");
b095c381 1581 handled |= IPW_INTA_BIT_STATUS_CHANGE;
43f66a6c
JK
1582 }
1583
b095c381 1584 if (inta & IPW_INTA_BIT_BEACON_PERIOD_EXPIRED) {
43f66a6c 1585 IPW_WARNING("TX_PERIOD_EXPIRED\n");
b095c381 1586 handled |= IPW_INTA_BIT_BEACON_PERIOD_EXPIRED;
43f66a6c
JK
1587 }
1588
b095c381 1589 if (inta & IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) {
43f66a6c 1590 IPW_WARNING("HOST_CMD_DONE\n");
b095c381 1591 handled |= IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE;
43f66a6c
JK
1592 }
1593
b095c381 1594 if (inta & IPW_INTA_BIT_FW_INITIALIZATION_DONE) {
43f66a6c 1595 IPW_WARNING("FW_INITIALIZATION_DONE\n");
b095c381 1596 handled |= IPW_INTA_BIT_FW_INITIALIZATION_DONE;
43f66a6c
JK
1597 }
1598
b095c381 1599 if (inta & IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) {
43f66a6c 1600 IPW_WARNING("PHY_OFF_DONE\n");
b095c381 1601 handled |= IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE;
43f66a6c
JK
1602 }
1603
b095c381 1604 if (inta & IPW_INTA_BIT_RF_KILL_DONE) {
43f66a6c
JK
1605 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
1606 priv->status |= STATUS_RF_KILL_HW;
1607 wake_up_interruptible(&priv->wait_command_queue);
ea2b26e0 1608 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
43f66a6c 1609 cancel_delayed_work(&priv->request_scan);
a613bffd 1610 schedule_work(&priv->link_down);
43f66a6c 1611 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
b095c381 1612 handled |= IPW_INTA_BIT_RF_KILL_DONE;
43f66a6c 1613 }
bf79451e 1614
b095c381 1615 if (inta & IPW_INTA_BIT_FATAL_ERROR) {
43f66a6c
JK
1616 IPW_ERROR("Firmware error detected. Restarting.\n");
1617#ifdef CONFIG_IPW_DEBUG
1618 if (ipw_debug_level & IPW_DL_FW_ERRORS) {
1619 ipw_dump_nic_error_log(priv);
1620 ipw_dump_nic_event_log(priv);
1621 }
1622#endif
b095c381
JK
1623 /* XXX: If hardware encryption is for WPA/WPA2,
1624 * we have to notify the supplicant. */
1625 if (priv->ieee->sec.encrypt) {
1626 priv->status &= ~STATUS_ASSOCIATED;
1627 notify_wx_assoc_event(priv);
1628 }
1629
1630 /* Keep the restart process from trying to send host
1631 * commands by clearing the INIT status bit */
1632 priv->status &= ~STATUS_INIT;
43f66a6c 1633 queue_work(priv->workqueue, &priv->adapter_restart);
b095c381 1634 handled |= IPW_INTA_BIT_FATAL_ERROR;
43f66a6c
JK
1635 }
1636
b095c381 1637 if (inta & IPW_INTA_BIT_PARITY_ERROR) {
43f66a6c 1638 IPW_ERROR("Parity error\n");
b095c381 1639 handled |= IPW_INTA_BIT_PARITY_ERROR;
43f66a6c
JK
1640 }
1641
1642 if (handled != inta) {
0edd5b44 1643 IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
43f66a6c
JK
1644 }
1645
1646 /* enable all interrupts */
1647 ipw_enable_interrupts(priv);
1648
1649 spin_unlock_irqrestore(&priv->lock, flags);
1650}
bf79451e 1651
43f66a6c
JK
1652#ifdef CONFIG_IPW_DEBUG
1653#define IPW_CMD(x) case IPW_CMD_ ## x : return #x
1654static char *get_cmd_string(u8 cmd)
1655{
1656 switch (cmd) {
1657 IPW_CMD(HOST_COMPLETE);
bf79451e
JG
1658 IPW_CMD(POWER_DOWN);
1659 IPW_CMD(SYSTEM_CONFIG);
1660 IPW_CMD(MULTICAST_ADDRESS);
1661 IPW_CMD(SSID);
1662 IPW_CMD(ADAPTER_ADDRESS);
1663 IPW_CMD(PORT_TYPE);
1664 IPW_CMD(RTS_THRESHOLD);
1665 IPW_CMD(FRAG_THRESHOLD);
1666 IPW_CMD(POWER_MODE);
1667 IPW_CMD(WEP_KEY);
1668 IPW_CMD(TGI_TX_KEY);
1669 IPW_CMD(SCAN_REQUEST);
1670 IPW_CMD(SCAN_REQUEST_EXT);
1671 IPW_CMD(ASSOCIATE);
1672 IPW_CMD(SUPPORTED_RATES);
1673 IPW_CMD(SCAN_ABORT);
1674 IPW_CMD(TX_FLUSH);
1675 IPW_CMD(QOS_PARAMETERS);
1676 IPW_CMD(DINO_CONFIG);
1677 IPW_CMD(RSN_CAPABILITIES);
1678 IPW_CMD(RX_KEY);
1679 IPW_CMD(CARD_DISABLE);
1680 IPW_CMD(SEED_NUMBER);
1681 IPW_CMD(TX_POWER);
1682 IPW_CMD(COUNTRY_INFO);
1683 IPW_CMD(AIRONET_INFO);
1684 IPW_CMD(AP_TX_POWER);
1685 IPW_CMD(CCKM_INFO);
1686 IPW_CMD(CCX_VER_INFO);
1687 IPW_CMD(SET_CALIBRATION);
1688 IPW_CMD(SENSITIVITY_CALIB);
1689 IPW_CMD(RETRY_LIMIT);
1690 IPW_CMD(IPW_PRE_POWER_DOWN);
1691 IPW_CMD(VAP_BEACON_TEMPLATE);
1692 IPW_CMD(VAP_DTIM_PERIOD);
1693 IPW_CMD(EXT_SUPPORTED_RATES);
1694 IPW_CMD(VAP_LOCAL_TX_PWR_CONSTRAINT);
1695 IPW_CMD(VAP_QUIET_INTERVALS);
1696 IPW_CMD(VAP_CHANNEL_SWITCH);
1697 IPW_CMD(VAP_MANDATORY_CHANNELS);
1698 IPW_CMD(VAP_CELL_PWR_LIMIT);
1699 IPW_CMD(VAP_CF_PARAM_SET);
1700 IPW_CMD(VAP_SET_BEACONING_STATE);
1701 IPW_CMD(MEASUREMENT);
1702 IPW_CMD(POWER_CAPABILITY);
1703 IPW_CMD(SUPPORTED_CHANNELS);
1704 IPW_CMD(TPC_REPORT);
1705 IPW_CMD(WME_INFO);
1706 IPW_CMD(PRODUCTION_COMMAND);
1707 default:
43f66a6c
JK
1708 return "UNKNOWN";
1709 }
1710}
ea2b26e0 1711#endif
43f66a6c
JK
1712
1713#define HOST_COMPLETE_TIMEOUT HZ
1714static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
1715{
1716 int rc = 0;
a613bffd 1717 unsigned long flags;
43f66a6c 1718
a613bffd 1719 spin_lock_irqsave(&priv->lock, flags);
43f66a6c
JK
1720 if (priv->status & STATUS_HCMD_ACTIVE) {
1721 IPW_ERROR("Already sending a command\n");
a613bffd 1722 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c
JK
1723 return -1;
1724 }
1725
1726 priv->status |= STATUS_HCMD_ACTIVE;
bf79451e 1727
b095c381
JK
1728 IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",
1729 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,
1730 priv->status);
0edd5b44 1731 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
43f66a6c
JK
1732
1733 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0);
a613bffd
JK
1734 if (rc) {
1735 priv->status &= ~STATUS_HCMD_ACTIVE;
1736 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c 1737 return rc;
a613bffd
JK
1738 }
1739 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c 1740
0edd5b44
JG
1741 rc = wait_event_interruptible_timeout(priv->wait_command_queue,
1742 !(priv->
1743 status & STATUS_HCMD_ACTIVE),
1744 HOST_COMPLETE_TIMEOUT);
43f66a6c 1745 if (rc == 0) {
a613bffd
JK
1746 spin_lock_irqsave(&priv->lock, flags);
1747 if (priv->status & STATUS_HCMD_ACTIVE) {
1748 IPW_DEBUG_INFO("Command completion failed out after "
1749 "%dms.\n",
1750 1000 * (HOST_COMPLETE_TIMEOUT / HZ));
1751 priv->status &= ~STATUS_HCMD_ACTIVE;
1752 spin_unlock_irqrestore(&priv->lock, flags);
1753 return -EIO;
1754 }
1755 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c 1756 }
a613bffd 1757
b095c381 1758 if (priv->status & STATUS_RF_KILL_HW) {
43f66a6c
JK
1759 IPW_DEBUG_INFO("Command aborted due to RF Kill Switch\n");
1760 return -EIO;
1761 }
1762
1763 return 0;
1764}
1765
1766static int ipw_send_host_complete(struct ipw_priv *priv)
1767{
1768 struct host_cmd cmd = {
1769 .cmd = IPW_CMD_HOST_COMPLETE,
1770 .len = 0
1771 };
1772
1773 if (!priv) {
1774 IPW_ERROR("Invalid args\n");
1775 return -1;
1776 }
1777
1778 if (ipw_send_cmd(priv, &cmd)) {
1779 IPW_ERROR("failed to send HOST_COMPLETE command\n");
1780 return -1;
1781 }
bf79451e 1782
43f66a6c
JK
1783 return 0;
1784}
1785
bf79451e 1786static int ipw_send_system_config(struct ipw_priv *priv,
43f66a6c
JK
1787 struct ipw_sys_config *config)
1788{
1789 struct host_cmd cmd = {
1790 .cmd = IPW_CMD_SYSTEM_CONFIG,
1791 .len = sizeof(*config)
1792 };
1793
1794 if (!priv || !config) {
1795 IPW_ERROR("Invalid args\n");
1796 return -1;
1797 }
1798
0edd5b44 1799 memcpy(&cmd.param, config, sizeof(*config));
43f66a6c
JK
1800 if (ipw_send_cmd(priv, &cmd)) {
1801 IPW_ERROR("failed to send SYSTEM_CONFIG command\n");
1802 return -1;
1803 }
1804
1805 return 0;
1806}
1807
0edd5b44 1808static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
43f66a6c
JK
1809{
1810 struct host_cmd cmd = {
1811 .cmd = IPW_CMD_SSID,
1812 .len = min(len, IW_ESSID_MAX_SIZE)
1813 };
1814
1815 if (!priv || !ssid) {
1816 IPW_ERROR("Invalid args\n");
1817 return -1;
1818 }
1819
1820 memcpy(&cmd.param, ssid, cmd.len);
1821 if (ipw_send_cmd(priv, &cmd)) {
1822 IPW_ERROR("failed to send SSID command\n");
1823 return -1;
1824 }
bf79451e 1825
43f66a6c
JK
1826 return 0;
1827}
1828
0edd5b44 1829static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
43f66a6c
JK
1830{
1831 struct host_cmd cmd = {
1832 .cmd = IPW_CMD_ADAPTER_ADDRESS,
1833 .len = ETH_ALEN
1834 };
1835
1836 if (!priv || !mac) {
1837 IPW_ERROR("Invalid args\n");
1838 return -1;
1839 }
1840
1841 IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",
1842 priv->net_dev->name, MAC_ARG(mac));
1843
1844 memcpy(&cmd.param, mac, ETH_ALEN);
1845
1846 if (ipw_send_cmd(priv, &cmd)) {
1847 IPW_ERROR("failed to send ADAPTER_ADDRESS command\n");
1848 return -1;
1849 }
bf79451e 1850
43f66a6c
JK
1851 return 0;
1852}
1853
a613bffd
JK
1854/*
1855 * NOTE: This must be executed from our workqueue as it results in udelay
1856 * being called which may corrupt the keyboard if executed on default
1857 * workqueue
1858 */
43f66a6c
JK
1859static void ipw_adapter_restart(void *adapter)
1860{
1861 struct ipw_priv *priv = adapter;
1862
1863 if (priv->status & STATUS_RF_KILL_MASK)
1864 return;
1865
1866 ipw_down(priv);
b095c381
JK
1867
1868 if (priv->assoc_network &&
1869 (priv->assoc_network->capability & WLAN_CAPABILITY_IBSS))
1870 ipw_remove_current_network(priv);
1871
43f66a6c
JK
1872 if (ipw_up(priv)) {
1873 IPW_ERROR("Failed to up device\n");
1874 return;
1875 }
b095c381
JK
1876
1877 if ((priv->capability & CAP_PRIVACY_ON) &&
1878 (priv->ieee->sec.level == SEC_LEVEL_1) &&
1879 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
1880 ipw_set_hwcrypto_keys(priv);
43f66a6c
JK
1881}
1882
c848d0af
JK
1883static void ipw_bg_adapter_restart(void *data)
1884{
1885 struct ipw_priv *priv = data;
1886 down(&priv->sem);
1887 ipw_adapter_restart(data);
1888 up(&priv->sem);
1889}
1890
43f66a6c
JK
1891#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
1892
1893static void ipw_scan_check(void *data)
1894{
1895 struct ipw_priv *priv = data;
1896 if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
1897 IPW_DEBUG_SCAN("Scan completion watchdog resetting "
bf79451e 1898 "adapter (%dms).\n",
43f66a6c 1899 IPW_SCAN_CHECK_WATCHDOG / 100);
a613bffd 1900 queue_work(priv->workqueue, &priv->adapter_restart);
43f66a6c
JK
1901 }
1902}
1903
c848d0af
JK
1904static void ipw_bg_scan_check(void *data)
1905{
1906 struct ipw_priv *priv = data;
1907 down(&priv->sem);
1908 ipw_scan_check(data);
1909 up(&priv->sem);
1910}
1911
43f66a6c
JK
1912static int ipw_send_scan_request_ext(struct ipw_priv *priv,
1913 struct ipw_scan_request_ext *request)
1914{
1915 struct host_cmd cmd = {
1916 .cmd = IPW_CMD_SCAN_REQUEST_EXT,
1917 .len = sizeof(*request)
1918 };
1919
0edd5b44 1920 memcpy(&cmd.param, request, sizeof(*request));
43f66a6c
JK
1921 if (ipw_send_cmd(priv, &cmd)) {
1922 IPW_ERROR("failed to send SCAN_REQUEST_EXT command\n");
1923 return -1;
1924 }
bf79451e
JG
1925
1926 queue_delayed_work(priv->workqueue, &priv->scan_check,
43f66a6c
JK
1927 IPW_SCAN_CHECK_WATCHDOG);
1928 return 0;
1929}
1930
1931static int ipw_send_scan_abort(struct ipw_priv *priv)
1932{
1933 struct host_cmd cmd = {
1934 .cmd = IPW_CMD_SCAN_ABORT,
1935 .len = 0
1936 };
1937
1938 if (!priv) {
1939 IPW_ERROR("Invalid args\n");
1940 return -1;
1941 }
1942
1943 if (ipw_send_cmd(priv, &cmd)) {
1944 IPW_ERROR("failed to send SCAN_ABORT command\n");
1945 return -1;
1946 }
bf79451e 1947
43f66a6c
JK
1948 return 0;
1949}
1950
1951static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
1952{
1953 struct host_cmd cmd = {
1954 .cmd = IPW_CMD_SENSITIVITY_CALIB,
1955 .len = sizeof(struct ipw_sensitivity_calib)
1956 };
1957 struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *)
0edd5b44 1958 &cmd.param;
43f66a6c
JK
1959 calib->beacon_rssi_raw = sens;
1960 if (ipw_send_cmd(priv, &cmd)) {
1961 IPW_ERROR("failed to send SENSITIVITY CALIB command\n");
1962 return -1;
1963 }
1964
1965 return 0;
1966}
1967
1968static int ipw_send_associate(struct ipw_priv *priv,
1969 struct ipw_associate *associate)
1970{
1971 struct host_cmd cmd = {
1972 .cmd = IPW_CMD_ASSOCIATE,
1973 .len = sizeof(*associate)
1974 };
1975
a613bffd
JK
1976 struct ipw_associate tmp_associate;
1977 memcpy(&tmp_associate, associate, sizeof(*associate));
1978 tmp_associate.policy_support =
1979 cpu_to_le16(tmp_associate.policy_support);
1980 tmp_associate.assoc_tsf_msw = cpu_to_le32(tmp_associate.assoc_tsf_msw);
1981 tmp_associate.assoc_tsf_lsw = cpu_to_le32(tmp_associate.assoc_tsf_lsw);
1982 tmp_associate.capability = cpu_to_le16(tmp_associate.capability);
1983 tmp_associate.listen_interval =
1984 cpu_to_le16(tmp_associate.listen_interval);
1985 tmp_associate.beacon_interval =
1986 cpu_to_le16(tmp_associate.beacon_interval);
1987 tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
1988
43f66a6c
JK
1989 if (!priv || !associate) {
1990 IPW_ERROR("Invalid args\n");
1991 return -1;
1992 }
1993
a613bffd 1994 memcpy(&cmd.param, &tmp_associate, sizeof(*associate));
43f66a6c
JK
1995 if (ipw_send_cmd(priv, &cmd)) {
1996 IPW_ERROR("failed to send ASSOCIATE command\n");
1997 return -1;
1998 }
bf79451e 1999
43f66a6c
JK
2000 return 0;
2001}
2002
2003static int ipw_send_supported_rates(struct ipw_priv *priv,
2004 struct ipw_supported_rates *rates)
2005{
2006 struct host_cmd cmd = {
2007 .cmd = IPW_CMD_SUPPORTED_RATES,
2008 .len = sizeof(*rates)
2009 };
2010
2011 if (!priv || !rates) {
2012 IPW_ERROR("Invalid args\n");
2013 return -1;
2014 }
2015
0edd5b44 2016 memcpy(&cmd.param, rates, sizeof(*rates));
43f66a6c
JK
2017 if (ipw_send_cmd(priv, &cmd)) {
2018 IPW_ERROR("failed to send SUPPORTED_RATES command\n");
2019 return -1;
2020 }
bf79451e 2021
43f66a6c
JK
2022 return 0;
2023}
2024
2025static int ipw_set_random_seed(struct ipw_priv *priv)
2026{
2027 struct host_cmd cmd = {
2028 .cmd = IPW_CMD_SEED_NUMBER,
2029 .len = sizeof(u32)
2030 };
2031
2032 if (!priv) {
2033 IPW_ERROR("Invalid args\n");
2034 return -1;
2035 }
2036
2037 get_random_bytes(&cmd.param, sizeof(u32));
2038
2039 if (ipw_send_cmd(priv, &cmd)) {
2040 IPW_ERROR("failed to send SEED_NUMBER command\n");
2041 return -1;
2042 }
bf79451e 2043
43f66a6c
JK
2044 return 0;
2045}
2046
43f66a6c
JK
2047static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
2048{
2049 struct host_cmd cmd = {
2050 .cmd = IPW_CMD_CARD_DISABLE,
2051 .len = sizeof(u32)
2052 };
2053
2054 if (!priv) {
2055 IPW_ERROR("Invalid args\n");
2056 return -1;
2057 }
2058
0edd5b44 2059 *((u32 *) & cmd.param) = phy_off;
43f66a6c
JK
2060
2061 if (ipw_send_cmd(priv, &cmd)) {
2062 IPW_ERROR("failed to send CARD_DISABLE command\n");
2063 return -1;
2064 }
bf79451e 2065
43f66a6c
JK
2066 return 0;
2067}
43f66a6c 2068
0edd5b44 2069static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
43f66a6c
JK
2070{
2071 struct host_cmd cmd = {
2072 .cmd = IPW_CMD_TX_POWER,
2073 .len = sizeof(*power)
2074 };
2075
2076 if (!priv || !power) {
2077 IPW_ERROR("Invalid args\n");
2078 return -1;
2079 }
2080
0edd5b44 2081 memcpy(&cmd.param, power, sizeof(*power));
43f66a6c
JK
2082 if (ipw_send_cmd(priv, &cmd)) {
2083 IPW_ERROR("failed to send TX_POWER command\n");
2084 return -1;
2085 }
bf79451e 2086
43f66a6c
JK
2087 return 0;
2088}
2089
2090static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
2091{
2092 struct ipw_rts_threshold rts_threshold = {
2093 .rts_threshold = rts,
2094 };
2095 struct host_cmd cmd = {
2096 .cmd = IPW_CMD_RTS_THRESHOLD,
2097 .len = sizeof(rts_threshold)
2098 };
2099
2100 if (!priv) {
2101 IPW_ERROR("Invalid args\n");
2102 return -1;
2103 }
2104
2105 memcpy(&cmd.param, &rts_threshold, sizeof(rts_threshold));
2106 if (ipw_send_cmd(priv, &cmd)) {
2107 IPW_ERROR("failed to send RTS_THRESHOLD command\n");
2108 return -1;
2109 }
2110
2111 return 0;
2112}
2113
2114static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
2115{
2116 struct ipw_frag_threshold frag_threshold = {
2117 .frag_threshold = frag,
2118 };
2119 struct host_cmd cmd = {
2120 .cmd = IPW_CMD_FRAG_THRESHOLD,
2121 .len = sizeof(frag_threshold)
2122 };
2123
2124 if (!priv) {
2125 IPW_ERROR("Invalid args\n");
2126 return -1;
2127 }
2128
2129 memcpy(&cmd.param, &frag_threshold, sizeof(frag_threshold));
2130 if (ipw_send_cmd(priv, &cmd)) {
2131 IPW_ERROR("failed to send FRAG_THRESHOLD command\n");
2132 return -1;
2133 }
2134
2135 return 0;
2136}
2137
2138static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
2139{
2140 struct host_cmd cmd = {
2141 .cmd = IPW_CMD_POWER_MODE,
2142 .len = sizeof(u32)
2143 };
0edd5b44 2144 u32 *param = (u32 *) (&cmd.param);
43f66a6c
JK
2145
2146 if (!priv) {
2147 IPW_ERROR("Invalid args\n");
2148 return -1;
2149 }
bf79451e 2150
43f66a6c
JK
2151 /* If on battery, set to 3, if AC set to CAM, else user
2152 * level */
2153 switch (mode) {
2154 case IPW_POWER_BATTERY:
2155 *param = IPW_POWER_INDEX_3;
2156 break;
2157 case IPW_POWER_AC:
2158 *param = IPW_POWER_MODE_CAM;
2159 break;
2160 default:
2161 *param = mode;
2162 break;
2163 }
2164
2165 if (ipw_send_cmd(priv, &cmd)) {
2166 IPW_ERROR("failed to send POWER_MODE command\n");
2167 return -1;
2168 }
2169
2170 return 0;
2171}
2172
2173/*
2174 * The IPW device contains a Microwire compatible EEPROM that stores
2175 * various data like the MAC address. Usually the firmware has exclusive
2176 * access to the eeprom, but during device initialization (before the
2177 * device driver has sent the HostComplete command to the firmware) the
2178 * device driver has read access to the EEPROM by way of indirect addressing
2179 * through a couple of memory mapped registers.
2180 *
2181 * The following is a simplified implementation for pulling data out of the
2182 * the eeprom, along with some helper functions to find information in
2183 * the per device private data's copy of the eeprom.
2184 *
2185 * NOTE: To better understand how these functions work (i.e what is a chip
2186 * select and why do have to keep driving the eeprom clock?), read
2187 * just about any data sheet for a Microwire compatible EEPROM.
2188 */
2189
2190/* write a 32 bit value into the indirect accessor register */
2191static inline void eeprom_write_reg(struct ipw_priv *p, u32 data)
2192{
2193 ipw_write_reg32(p, FW_MEM_REG_EEPROM_ACCESS, data);
bf79451e 2194
43f66a6c
JK
2195 /* the eeprom requires some time to complete the operation */
2196 udelay(p->eeprom_delay);
2197
2198 return;
2199}
2200
2201/* perform a chip select operation */
0edd5b44 2202static inline void eeprom_cs(struct ipw_priv *priv)
43f66a6c 2203{
0edd5b44
JG
2204 eeprom_write_reg(priv, 0);
2205 eeprom_write_reg(priv, EEPROM_BIT_CS);
2206 eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK);
2207 eeprom_write_reg(priv, EEPROM_BIT_CS);
43f66a6c
JK
2208}
2209
2210/* perform a chip select operation */
0edd5b44 2211static inline void eeprom_disable_cs(struct ipw_priv *priv)
43f66a6c 2212{
0edd5b44
JG
2213 eeprom_write_reg(priv, EEPROM_BIT_CS);
2214 eeprom_write_reg(priv, 0);
2215 eeprom_write_reg(priv, EEPROM_BIT_SK);
43f66a6c
JK
2216}
2217
2218/* push a single bit down to the eeprom */
0edd5b44 2219static inline void eeprom_write_bit(struct ipw_priv *p, u8 bit)
43f66a6c 2220{
0edd5b44
JG
2221 int d = (bit ? EEPROM_BIT_DI : 0);
2222 eeprom_write_reg(p, EEPROM_BIT_CS | d);
2223 eeprom_write_reg(p, EEPROM_BIT_CS | d | EEPROM_BIT_SK);
43f66a6c
JK
2224}
2225
2226/* push an opcode followed by an address down to the eeprom */
0edd5b44 2227static void eeprom_op(struct ipw_priv *priv, u8 op, u8 addr)
43f66a6c
JK
2228{
2229 int i;
2230
2231 eeprom_cs(priv);
0edd5b44
JG
2232 eeprom_write_bit(priv, 1);
2233 eeprom_write_bit(priv, op & 2);
2234 eeprom_write_bit(priv, op & 1);
2235 for (i = 7; i >= 0; i--) {
2236 eeprom_write_bit(priv, addr & (1 << i));
43f66a6c
JK
2237 }
2238}
2239
2240/* pull 16 bits off the eeprom, one bit at a time */
0edd5b44 2241static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr)
43f66a6c
JK
2242{
2243 int i;
0edd5b44 2244 u16 r = 0;
bf79451e 2245
43f66a6c 2246 /* Send READ Opcode */
0edd5b44 2247 eeprom_op(priv, EEPROM_CMD_READ, addr);
43f66a6c
JK
2248
2249 /* Send dummy bit */
0edd5b44 2250 eeprom_write_reg(priv, EEPROM_BIT_CS);
43f66a6c
JK
2251
2252 /* Read the byte off the eeprom one bit at a time */
0edd5b44 2253 for (i = 0; i < 16; i++) {
43f66a6c 2254 u32 data = 0;
0edd5b44
JG
2255 eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK);
2256 eeprom_write_reg(priv, EEPROM_BIT_CS);
2257 data = ipw_read_reg32(priv, FW_MEM_REG_EEPROM_ACCESS);
2258 r = (r << 1) | ((data & EEPROM_BIT_DO) ? 1 : 0);
43f66a6c 2259 }
bf79451e 2260
43f66a6c 2261 /* Send another dummy bit */
0edd5b44 2262 eeprom_write_reg(priv, 0);
43f66a6c 2263 eeprom_disable_cs(priv);
bf79451e 2264
43f66a6c
JK
2265 return r;
2266}
2267
2268/* helper function for pulling the mac address out of the private */
2269/* data's copy of the eeprom data */
0edd5b44 2270static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac)
43f66a6c 2271{
0edd5b44 2272 u8 *ee = (u8 *) priv->eeprom;
43f66a6c
JK
2273 memcpy(mac, &ee[EEPROM_MAC_ADDRESS], 6);
2274}
2275
2276/*
2277 * Either the device driver (i.e. the host) or the firmware can
2278 * load eeprom data into the designated region in SRAM. If neither
2279 * happens then the FW will shutdown with a fatal error.
2280 *
2281 * In order to signal the FW to load the EEPROM, the EEPROM_LOAD_DISABLE
2282 * bit needs region of shared SRAM needs to be non-zero.
2283 */
2284static void ipw_eeprom_init_sram(struct ipw_priv *priv)
2285{
2286 int i;
0edd5b44 2287 u16 *eeprom = (u16 *) priv->eeprom;
bf79451e 2288
43f66a6c
JK
2289 IPW_DEBUG_TRACE(">>\n");
2290
2291 /* read entire contents of eeprom into private buffer */
0edd5b44 2292 for (i = 0; i < 128; i++)
a613bffd 2293 eeprom[i] = le16_to_cpu(eeprom_read_u16(priv, (u8) i));
43f66a6c 2294
bf79451e
JG
2295 /*
2296 If the data looks correct, then copy it to our private
43f66a6c
JK
2297 copy. Otherwise let the firmware know to perform the operation
2298 on it's own
0edd5b44 2299 */
43f66a6c
JK
2300 if ((priv->eeprom + EEPROM_VERSION) != 0) {
2301 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
2302
2303 /* write the eeprom data to sram */
b095c381 2304 for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
0edd5b44 2305 ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]);
43f66a6c
JK
2306
2307 /* Do not load eeprom data on fatal error or suspend */
2308 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
2309 } else {
2310 IPW_DEBUG_INFO("Enabling FW initializationg of SRAM\n");
2311
2312 /* Load eeprom data on fatal error or suspend */
2313 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 1);
2314 }
2315
2316 IPW_DEBUG_TRACE("<<\n");
2317}
2318
43f66a6c
JK
2319static inline void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count)
2320{
2321 count >>= 2;
0edd5b44
JG
2322 if (!count)
2323 return;
b095c381 2324 _ipw_write32(priv, IPW_AUTOINC_ADDR, start);
bf79451e 2325 while (count--)
b095c381 2326 _ipw_write32(priv, IPW_AUTOINC_DATA, 0);
43f66a6c
JK
2327}
2328
2329static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)
2330{
b095c381 2331 ipw_zero_memory(priv, IPW_SHARED_SRAM_DMA_CONTROL,
bf79451e 2332 CB_NUMBER_OF_ELEMENTS_SMALL *
43f66a6c
JK
2333 sizeof(struct command_block));
2334}
2335
2336static int ipw_fw_dma_enable(struct ipw_priv *priv)
0edd5b44 2337{ /* start dma engine but no transfers yet */
43f66a6c
JK
2338
2339 IPW_DEBUG_FW(">> : \n");
bf79451e 2340
43f66a6c
JK
2341 /* Start the dma */
2342 ipw_fw_dma_reset_command_blocks(priv);
bf79451e 2343
43f66a6c 2344 /* Write CB base address */
b095c381 2345 ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL);
43f66a6c
JK
2346
2347 IPW_DEBUG_FW("<< : \n");
2348 return 0;
2349}
2350
2351static void ipw_fw_dma_abort(struct ipw_priv *priv)
2352{
2353 u32 control = 0;
2354
2355 IPW_DEBUG_FW(">> :\n");
bf79451e
JG
2356
2357 //set the Stop and Abort bit
43f66a6c 2358 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT;
b095c381 2359 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
43f66a6c 2360 priv->sram_desc.last_cb_index = 0;
bf79451e 2361
43f66a6c
JK
2362 IPW_DEBUG_FW("<< \n");
2363}
2364
0edd5b44
JG
2365static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index,
2366 struct command_block *cb)
43f66a6c 2367{
0edd5b44 2368 u32 address =
b095c381 2369 IPW_SHARED_SRAM_DMA_CONTROL +
0edd5b44 2370 (sizeof(struct command_block) * index);
43f66a6c
JK
2371 IPW_DEBUG_FW(">> :\n");
2372
0edd5b44
JG
2373 ipw_write_indirect(priv, address, (u8 *) cb,
2374 (int)sizeof(struct command_block));
43f66a6c
JK
2375
2376 IPW_DEBUG_FW("<< :\n");
2377 return 0;
2378
2379}
2380
2381static int ipw_fw_dma_kick(struct ipw_priv *priv)
2382{
2383 u32 control = 0;
0edd5b44 2384 u32 index = 0;
43f66a6c
JK
2385
2386 IPW_DEBUG_FW(">> :\n");
bf79451e 2387
43f66a6c 2388 for (index = 0; index < priv->sram_desc.last_cb_index; index++)
0edd5b44
JG
2389 ipw_fw_dma_write_command_block(priv, index,
2390 &priv->sram_desc.cb_list[index]);
43f66a6c
JK
2391
2392 /* Enable the DMA in the CSR register */
b095c381
JK
2393 ipw_clear_bit(priv, IPW_RESET_REG,
2394 IPW_RESET_REG_MASTER_DISABLED |
2395 IPW_RESET_REG_STOP_MASTER);
bf79451e 2396
0edd5b44 2397 /* Set the Start bit. */
43f66a6c 2398 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START;
b095c381 2399 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
43f66a6c
JK
2400
2401 IPW_DEBUG_FW("<< :\n");
2402 return 0;
2403}
2404
2405static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)
2406{
2407 u32 address;
0edd5b44
JG
2408 u32 register_value = 0;
2409 u32 cb_fields_address = 0;
43f66a6c
JK
2410
2411 IPW_DEBUG_FW(">> :\n");
b095c381 2412 address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
0edd5b44 2413 IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address);
43f66a6c
JK
2414
2415 /* Read the DMA Controlor register */
b095c381
JK
2416 register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL);
2417 IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x \n", register_value);
43f66a6c 2418
0edd5b44 2419 /* Print the CB values */
43f66a6c
JK
2420 cb_fields_address = address;
2421 register_value = ipw_read_reg32(priv, cb_fields_address);
0edd5b44 2422 IPW_DEBUG_FW_INFO("Current CB ControlField is 0x%x \n", register_value);
43f66a6c
JK
2423
2424 cb_fields_address += sizeof(u32);
2425 register_value = ipw_read_reg32(priv, cb_fields_address);
0edd5b44 2426 IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x \n", register_value);
43f66a6c
JK
2427
2428 cb_fields_address += sizeof(u32);
2429 register_value = ipw_read_reg32(priv, cb_fields_address);
2430 IPW_DEBUG_FW_INFO("Current CB Destination Field is 0x%x \n",
2431 register_value);
2432
2433 cb_fields_address += sizeof(u32);
2434 register_value = ipw_read_reg32(priv, cb_fields_address);
0edd5b44 2435 IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x \n", register_value);
43f66a6c
JK
2436
2437 IPW_DEBUG_FW(">> :\n");
2438}
2439
2440static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)
2441{
2442 u32 current_cb_address = 0;
2443 u32 current_cb_index = 0;
2444
2445 IPW_DEBUG_FW("<< :\n");
b095c381 2446 current_cb_address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
bf79451e 2447
b095c381 2448 current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) /
0edd5b44 2449 sizeof(struct command_block);
bf79451e 2450
43f66a6c 2451 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n",
0edd5b44 2452 current_cb_index, current_cb_address);
43f66a6c
JK
2453
2454 IPW_DEBUG_FW(">> :\n");
2455 return current_cb_index;
2456
2457}
2458
2459static int ipw_fw_dma_add_command_block(struct ipw_priv *priv,
2460 u32 src_address,
2461 u32 dest_address,
2462 u32 length,
0edd5b44 2463 int interrupt_enabled, int is_last)
43f66a6c
JK
2464{
2465
bf79451e 2466 u32 control = CB_VALID | CB_SRC_LE | CB_DEST_LE | CB_SRC_AUTOINC |
0edd5b44
JG
2467 CB_SRC_IO_GATED | CB_DEST_AUTOINC | CB_SRC_SIZE_LONG |
2468 CB_DEST_SIZE_LONG;
43f66a6c 2469 struct command_block *cb;
0edd5b44 2470 u32 last_cb_element = 0;
43f66a6c
JK
2471
2472 IPW_DEBUG_FW_INFO("src_address=0x%x dest_address=0x%x length=0x%x\n",
2473 src_address, dest_address, length);
2474
2475 if (priv->sram_desc.last_cb_index >= CB_NUMBER_OF_ELEMENTS_SMALL)
2476 return -1;
2477
2478 last_cb_element = priv->sram_desc.last_cb_index;
2479 cb = &priv->sram_desc.cb_list[last_cb_element];
2480 priv->sram_desc.last_cb_index++;
2481
2482 /* Calculate the new CB control word */
0edd5b44 2483 if (interrupt_enabled)
43f66a6c
JK
2484 control |= CB_INT_ENABLED;
2485
2486 if (is_last)
2487 control |= CB_LAST_VALID;
bf79451e 2488
43f66a6c
JK
2489 control |= length;
2490
2491 /* Calculate the CB Element's checksum value */
0edd5b44 2492 cb->status = control ^ src_address ^ dest_address;
43f66a6c
JK
2493
2494 /* Copy the Source and Destination addresses */
2495 cb->dest_addr = dest_address;
2496 cb->source_addr = src_address;
2497
2498 /* Copy the Control Word last */
2499 cb->control = control;
2500
2501 return 0;
2502}
2503
2504static int ipw_fw_dma_add_buffer(struct ipw_priv *priv,
0edd5b44 2505 u32 src_phys, u32 dest_address, u32 length)
43f66a6c
JK
2506{
2507 u32 bytes_left = length;
0edd5b44
JG
2508 u32 src_offset = 0;
2509 u32 dest_offset = 0;
43f66a6c
JK
2510 int status = 0;
2511 IPW_DEBUG_FW(">> \n");
2512 IPW_DEBUG_FW_INFO("src_phys=0x%x dest_address=0x%x length=0x%x\n",
2513 src_phys, dest_address, length);
2514 while (bytes_left > CB_MAX_LENGTH) {
0edd5b44
JG
2515 status = ipw_fw_dma_add_command_block(priv,
2516 src_phys + src_offset,
2517 dest_address +
2518 dest_offset,
2519 CB_MAX_LENGTH, 0, 0);
43f66a6c
JK
2520 if (status) {
2521 IPW_DEBUG_FW_INFO(": Failed\n");
2522 return -1;
bf79451e 2523 } else
43f66a6c
JK
2524 IPW_DEBUG_FW_INFO(": Added new cb\n");
2525
2526 src_offset += CB_MAX_LENGTH;
2527 dest_offset += CB_MAX_LENGTH;
2528 bytes_left -= CB_MAX_LENGTH;
2529 }
2530
2531 /* add the buffer tail */
2532 if (bytes_left > 0) {
0edd5b44
JG
2533 status =
2534 ipw_fw_dma_add_command_block(priv, src_phys + src_offset,
2535 dest_address + dest_offset,
2536 bytes_left, 0, 0);
43f66a6c
JK
2537 if (status) {
2538 IPW_DEBUG_FW_INFO(": Failed on the buffer tail\n");
2539 return -1;
bf79451e 2540 } else
0edd5b44
JG
2541 IPW_DEBUG_FW_INFO
2542 (": Adding new cb - the buffer tail\n");
43f66a6c 2543 }
bf79451e 2544
43f66a6c
JK
2545 IPW_DEBUG_FW("<< \n");
2546 return 0;
2547}
2548
2549static int ipw_fw_dma_wait(struct ipw_priv *priv)
2550{
2551 u32 current_index = 0;
2552 u32 watchdog = 0;
2553
2554 IPW_DEBUG_FW(">> : \n");
2555
2556 current_index = ipw_fw_dma_command_block_index(priv);
bf79451e 2557 IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%8X\n",
0edd5b44 2558 (int)priv->sram_desc.last_cb_index);
43f66a6c
JK
2559
2560 while (current_index < priv->sram_desc.last_cb_index) {
2561 udelay(50);
2562 current_index = ipw_fw_dma_command_block_index(priv);
2563
2564 watchdog++;
2565
2566 if (watchdog > 400) {
2567 IPW_DEBUG_FW_INFO("Timeout\n");
2568 ipw_fw_dma_dump_command_block(priv);
2569 ipw_fw_dma_abort(priv);
2570 return -1;
2571 }
2572 }
2573
2574 ipw_fw_dma_abort(priv);
2575
0edd5b44 2576 /*Disable the DMA in the CSR register */
b095c381
JK
2577 ipw_set_bit(priv, IPW_RESET_REG,
2578 IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER);
43f66a6c
JK
2579
2580 IPW_DEBUG_FW("<< dmaWaitSync \n");
2581 return 0;
2582}
2583
bf79451e 2584static void ipw_remove_current_network(struct ipw_priv *priv)
43f66a6c
JK
2585{
2586 struct list_head *element, *safe;
bf79451e 2587 struct ieee80211_network *network = NULL;
a613bffd
JK
2588 unsigned long flags;
2589
2590 spin_lock_irqsave(&priv->ieee->lock, flags);
43f66a6c
JK
2591 list_for_each_safe(element, safe, &priv->ieee->network_list) {
2592 network = list_entry(element, struct ieee80211_network, list);
2593 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
2594 list_del(element);
bf79451e 2595 list_add_tail(&network->list,
43f66a6c
JK
2596 &priv->ieee->network_free_list);
2597 }
2598 }
a613bffd 2599 spin_unlock_irqrestore(&priv->ieee->lock, flags);
43f66a6c
JK
2600}
2601
2602/**
bf79451e 2603 * Check that card is still alive.
43f66a6c
JK
2604 * Reads debug register from domain0.
2605 * If card is present, pre-defined value should
2606 * be found there.
bf79451e 2607 *
43f66a6c
JK
2608 * @param priv
2609 * @return 1 if card is present, 0 otherwise
2610 */
2611static inline int ipw_alive(struct ipw_priv *priv)
2612{
2613 return ipw_read32(priv, 0x90) == 0xd55555d5;
2614}
2615
2616static inline int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask,
2617 int timeout)
2618{
2619 int i = 0;
2620
2621 do {
bf79451e 2622 if ((ipw_read32(priv, addr) & mask) == mask)
43f66a6c
JK
2623 return i;
2624 mdelay(10);
2625 i += 10;
2626 } while (i < timeout);
bf79451e 2627
43f66a6c
JK
2628 return -ETIME;
2629}
2630
bf79451e 2631/* These functions load the firmware and micro code for the operation of
43f66a6c
JK
2632 * the ipw hardware. It assumes the buffer has all the bits for the
2633 * image and the caller is handling the memory allocation and clean up.
2634 */
2635
0edd5b44 2636static int ipw_stop_master(struct ipw_priv *priv)
43f66a6c
JK
2637{
2638 int rc;
bf79451e 2639
43f66a6c
JK
2640 IPW_DEBUG_TRACE(">> \n");
2641 /* stop master. typical delay - 0 */
b095c381 2642 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
43f66a6c 2643
b095c381
JK
2644 rc = ipw_poll_bit(priv, IPW_RESET_REG,
2645 IPW_RESET_REG_MASTER_DISABLED, 100);
43f66a6c
JK
2646 if (rc < 0) {
2647 IPW_ERROR("stop master failed in 10ms\n");
2648 return -1;
2649 }
2650
2651 IPW_DEBUG_INFO("stop master %dms\n", rc);
2652
2653 return rc;
2654}
2655
2656static void ipw_arc_release(struct ipw_priv *priv)
2657{
2658 IPW_DEBUG_TRACE(">> \n");
2659 mdelay(5);
2660
b095c381 2661 ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
43f66a6c
JK
2662
2663 /* no one knows timing, for safety add some delay */
2664 mdelay(5);
2665}
2666
2667struct fw_header {
2668 u32 version;
2669 u32 mode;
2670};
2671
2672struct fw_chunk {
2673 u32 address;
2674 u32 length;
2675};
2676
2677#define IPW_FW_MAJOR_VERSION 2
b095c381 2678#define IPW_FW_MINOR_VERSION 3
43f66a6c
JK
2679
2680#define IPW_FW_MINOR(x) ((x & 0xff) >> 8)
2681#define IPW_FW_MAJOR(x) (x & 0xff)
2682
2683#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | \
2684 IPW_FW_MAJOR_VERSION)
2685
2686#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \
2687"." __stringify(IPW_FW_MINOR_VERSION) "-"
2688
2689#if IPW_FW_MAJOR_VERSION >= 2 && IPW_FW_MINOR_VERSION > 0
2690#define IPW_FW_NAME(x) IPW_FW_PREFIX "" x ".fw"
2691#else
2692#define IPW_FW_NAME(x) "ipw2200_" x ".fw"
2693#endif
2694
0edd5b44 2695static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
43f66a6c
JK
2696{
2697 int rc = 0, i, addr;
2698 u8 cr = 0;
2699 u16 *image;
2700
0edd5b44 2701 image = (u16 *) data;
bf79451e 2702
43f66a6c
JK
2703 IPW_DEBUG_TRACE(">> \n");
2704
2705 rc = ipw_stop_master(priv);
2706
2707 if (rc < 0)
2708 return rc;
bf79451e 2709
0edd5b44 2710// spin_lock_irqsave(&priv->lock, flags);
bf79451e 2711
b095c381
JK
2712 for (addr = IPW_SHARED_LOWER_BOUND;
2713 addr < IPW_REGISTER_DOMAIN1_END; addr += 4) {
43f66a6c
JK
2714 ipw_write32(priv, addr, 0);
2715 }
2716
2717 /* no ucode (yet) */
2718 memset(&priv->dino_alive, 0, sizeof(priv->dino_alive));
2719 /* destroy DMA queues */
2720 /* reset sequence */
2721
b095c381 2722 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_ON);
43f66a6c 2723 ipw_arc_release(priv);
b095c381 2724 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_OFF);
43f66a6c
JK
2725 mdelay(1);
2726
2727 /* reset PHY */
b095c381 2728 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, IPW_BASEBAND_POWER_DOWN);
43f66a6c 2729 mdelay(1);
bf79451e 2730
b095c381 2731 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, 0);
43f66a6c 2732 mdelay(1);
bf79451e 2733
43f66a6c
JK
2734 /* enable ucode store */
2735 ipw_write_reg8(priv, DINO_CONTROL_REG, 0x0);
2736 ipw_write_reg8(priv, DINO_CONTROL_REG, DINO_ENABLE_CS);
2737 mdelay(1);
2738
2739 /* write ucode */
2740 /**
2741 * @bug
2742 * Do NOT set indirect address register once and then
2743 * store data to indirect data register in the loop.
2744 * It seems very reasonable, but in this case DINO do not
2745 * accept ucode. It is essential to set address each time.
2746 */
2747 /* load new ipw uCode */
2748 for (i = 0; i < len / 2; i++)
b095c381 2749 ipw_write_reg16(priv, IPW_BASEBAND_CONTROL_STORE,
a613bffd 2750 cpu_to_le16(image[i]));
43f66a6c 2751
43f66a6c 2752 /* enable DINO */
b095c381
JK
2753 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
2754 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM);
43f66a6c 2755
0edd5b44 2756 /* this is where the igx / win driver deveates from the VAP driver. */
43f66a6c
JK
2757
2758 /* wait for alive response */
2759 for (i = 0; i < 100; i++) {
2760 /* poll for incoming data */
b095c381 2761 cr = ipw_read_reg8(priv, IPW_BASEBAND_CONTROL_STATUS);
43f66a6c
JK
2762 if (cr & DINO_RXFIFO_DATA)
2763 break;
2764 mdelay(1);
2765 }
2766
2767 if (cr & DINO_RXFIFO_DATA) {
2768 /* alive_command_responce size is NOT multiple of 4 */
2769 u32 response_buffer[(sizeof(priv->dino_alive) + 3) / 4];
bf79451e
JG
2770
2771 for (i = 0; i < ARRAY_SIZE(response_buffer); i++)
43f66a6c 2772 response_buffer[i] =
a613bffd 2773 le32_to_cpu(ipw_read_reg32(priv,
b095c381 2774 IPW_BASEBAND_RX_FIFO_READ));
43f66a6c
JK
2775 memcpy(&priv->dino_alive, response_buffer,
2776 sizeof(priv->dino_alive));
2777 if (priv->dino_alive.alive_command == 1
2778 && priv->dino_alive.ucode_valid == 1) {
2779 rc = 0;
0edd5b44
JG
2780 IPW_DEBUG_INFO
2781 ("Microcode OK, rev. %d (0x%x) dev. %d (0x%x) "
2782 "of %02d/%02d/%02d %02d:%02d\n",
2783 priv->dino_alive.software_revision,
2784 priv->dino_alive.software_revision,
2785 priv->dino_alive.device_identifier,
2786 priv->dino_alive.device_identifier,
2787 priv->dino_alive.time_stamp[0],
2788 priv->dino_alive.time_stamp[1],
2789 priv->dino_alive.time_stamp[2],
2790 priv->dino_alive.time_stamp[3],
2791 priv->dino_alive.time_stamp[4]);
43f66a6c
JK
2792 } else {
2793 IPW_DEBUG_INFO("Microcode is not alive\n");
2794 rc = -EINVAL;
2795 }
2796 } else {
2797 IPW_DEBUG_INFO("No alive response from DINO\n");
2798 rc = -ETIME;
2799 }
2800
2801 /* disable DINO, otherwise for some reason
2802 firmware have problem getting alive resp. */
b095c381 2803 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
43f66a6c 2804
0edd5b44 2805// spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c
JK
2806
2807 return rc;
2808}
2809
0edd5b44 2810static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
43f66a6c
JK
2811{
2812 int rc = -1;
2813 int offset = 0;
2814 struct fw_chunk *chunk;
2815 dma_addr_t shared_phys;
2816 u8 *shared_virt;
2817
2818 IPW_DEBUG_TRACE("<< : \n");
2819 shared_virt = pci_alloc_consistent(priv->pci_dev, len, &shared_phys);
2820
2821 if (!shared_virt)
2822 return -ENOMEM;
2823
2824 memmove(shared_virt, data, len);
2825
2826 /* Start the Dma */
2827 rc = ipw_fw_dma_enable(priv);
2828
2829 if (priv->sram_desc.last_cb_index > 0) {
2830 /* the DMA is already ready this would be a bug. */
2831 BUG();
2832 goto out;
2833 }
2834
2835 do {
2836 chunk = (struct fw_chunk *)(data + offset);
2837 offset += sizeof(struct fw_chunk);
2838 /* build DMA packet and queue up for sending */
bf79451e 2839 /* dma to chunk->address, the chunk->length bytes from data +
43f66a6c
JK
2840 * offeset*/
2841 /* Dma loading */
2842 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset,
a613bffd
JK
2843 le32_to_cpu(chunk->address),
2844 le32_to_cpu(chunk->length));
43f66a6c
JK
2845 if (rc) {
2846 IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
2847 goto out;
2848 }
bf79451e 2849
a613bffd 2850 offset += le32_to_cpu(chunk->length);
43f66a6c
JK
2851 } while (offset < len);
2852
0edd5b44 2853 /* Run the DMA and wait for the answer */
43f66a6c
JK
2854 rc = ipw_fw_dma_kick(priv);
2855 if (rc) {
2856 IPW_ERROR("dmaKick Failed\n");
2857 goto out;
2858 }
2859
2860 rc = ipw_fw_dma_wait(priv);
2861 if (rc) {
2862 IPW_ERROR("dmaWaitSync Failed\n");
2863 goto out;
2864 }
0edd5b44
JG
2865 out:
2866 pci_free_consistent(priv->pci_dev, len, shared_virt, shared_phys);
43f66a6c
JK
2867 return rc;
2868}
2869
2870/* stop nic */
2871static int ipw_stop_nic(struct ipw_priv *priv)
2872{
2873 int rc = 0;
2874
0edd5b44 2875 /* stop */
b095c381 2876 ipw_write32(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
bf79451e 2877
b095c381
JK
2878 rc = ipw_poll_bit(priv, IPW_RESET_REG,
2879 IPW_RESET_REG_MASTER_DISABLED, 500);
43f66a6c
JK
2880 if (rc < 0) {
2881 IPW_ERROR("wait for reg master disabled failed\n");
2882 return rc;
bf79451e 2883 }
43f66a6c 2884
b095c381 2885 ipw_set_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
bf79451e 2886
43f66a6c
JK
2887 return rc;
2888}
2889
2890static void ipw_start_nic(struct ipw_priv *priv)
2891{
2892 IPW_DEBUG_TRACE(">>\n");
2893
0edd5b44 2894 /* prvHwStartNic release ARC */
b095c381
JK
2895 ipw_clear_bit(priv, IPW_RESET_REG,
2896 IPW_RESET_REG_MASTER_DISABLED |
2897 IPW_RESET_REG_STOP_MASTER |
43f66a6c 2898 CBD_RESET_REG_PRINCETON_RESET);
bf79451e 2899
43f66a6c 2900 /* enable power management */
b095c381
JK
2901 ipw_set_bit(priv, IPW_GP_CNTRL_RW,
2902 IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
43f66a6c
JK
2903
2904 IPW_DEBUG_TRACE("<<\n");
2905}
bf79451e 2906
43f66a6c
JK
2907static int ipw_init_nic(struct ipw_priv *priv)
2908{
2909 int rc;
2910
2911 IPW_DEBUG_TRACE(">>\n");
bf79451e 2912 /* reset */
43f66a6c
JK
2913 /*prvHwInitNic */
2914 /* set "initialization complete" bit to move adapter to D0 state */
b095c381 2915 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
43f66a6c
JK
2916
2917 /* low-level PLL activation */
b095c381
JK
2918 ipw_write32(priv, IPW_READ_INT_REGISTER,
2919 IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER);
43f66a6c
JK
2920
2921 /* wait for clock stabilization */
b095c381
JK
2922 rc = ipw_poll_bit(priv, IPW_GP_CNTRL_RW,
2923 IPW_GP_CNTRL_BIT_CLOCK_READY, 250);
0edd5b44 2924 if (rc < 0)
43f66a6c
JK
2925 IPW_DEBUG_INFO("FAILED wait for clock stablization\n");
2926
2927 /* assert SW reset */
b095c381 2928 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_SW_RESET);
43f66a6c
JK
2929
2930 udelay(10);
2931
2932 /* set "initialization complete" bit to move adapter to D0 state */
b095c381 2933 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
43f66a6c
JK
2934
2935 IPW_DEBUG_TRACE(">>\n");
2936 return 0;
2937}
2938
bf79451e 2939/* Call this function from process context, it will sleep in request_firmware.
43f66a6c
JK
2940 * Probe is an ok place to call this from.
2941 */
2942static int ipw_reset_nic(struct ipw_priv *priv)
2943{
2944 int rc = 0;
a613bffd 2945 unsigned long flags;
43f66a6c
JK
2946
2947 IPW_DEBUG_TRACE(">>\n");
bf79451e 2948
43f66a6c 2949 rc = ipw_init_nic(priv);
bf79451e 2950
a613bffd 2951 spin_lock_irqsave(&priv->lock, flags);
43f66a6c
JK
2952 /* Clear the 'host command active' bit... */
2953 priv->status &= ~STATUS_HCMD_ACTIVE;
2954 wake_up_interruptible(&priv->wait_command_queue);
a613bffd 2955 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c
JK
2956
2957 IPW_DEBUG_TRACE("<<\n");
2958 return rc;
bf79451e 2959}
43f66a6c 2960
bf79451e 2961static int ipw_get_fw(struct ipw_priv *priv,
43f66a6c
JK
2962 const struct firmware **fw, const char *name)
2963{
2964 struct fw_header *header;
2965 int rc;
2966
2967 /* ask firmware_class module to get the boot firmware off disk */
2968 rc = request_firmware(fw, name, &priv->pci_dev->dev);
2969 if (rc < 0) {
2970 IPW_ERROR("%s load failed: Reason %d\n", name, rc);
2971 return rc;
bf79451e 2972 }
43f66a6c
JK
2973
2974 header = (struct fw_header *)(*fw)->data;
a613bffd 2975 if (IPW_FW_MAJOR(le32_to_cpu(header->version)) != IPW_FW_MAJOR_VERSION) {
43f66a6c
JK
2976 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n",
2977 name,
a613bffd
JK
2978 IPW_FW_MAJOR(le32_to_cpu(header->version)),
2979 IPW_FW_MAJOR_VERSION);
43f66a6c
JK
2980 return -EINVAL;
2981 }
2982
aaa4d308 2983 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n",
43f66a6c 2984 name,
a613bffd
JK
2985 IPW_FW_MAJOR(le32_to_cpu(header->version)),
2986 IPW_FW_MINOR(le32_to_cpu(header->version)),
43f66a6c
JK
2987 (*fw)->size - sizeof(struct fw_header));
2988 return 0;
2989}
2990
b095c381 2991#define IPW_RX_BUF_SIZE (3000)
43f66a6c
JK
2992
2993static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
2994 struct ipw_rx_queue *rxq)
2995{
2996 unsigned long flags;
2997 int i;
2998
2999 spin_lock_irqsave(&rxq->lock, flags);
3000
3001 INIT_LIST_HEAD(&rxq->rx_free);
3002 INIT_LIST_HEAD(&rxq->rx_used);
3003
3004 /* Fill the rx_used queue with _all_ of the Rx buffers */
3005 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
3006 /* In the reset function, these buffers may have been allocated
3007 * to an SKB, so we need to unmap and free potential storage */
3008 if (rxq->pool[i].skb != NULL) {
3009 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
b095c381 3010 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
43f66a6c 3011 dev_kfree_skb(rxq->pool[i].skb);
a613bffd 3012 rxq->pool[i].skb = NULL;
43f66a6c
JK
3013 }
3014 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
3015 }
bf79451e 3016
43f66a6c
JK
3017 /* Set us so that we have processed and used all buffers, but have
3018 * not restocked the Rx queue with fresh buffers */
3019 rxq->read = rxq->write = 0;
3020 rxq->processed = RX_QUEUE_SIZE - 1;
3021 rxq->free_count = 0;
3022 spin_unlock_irqrestore(&rxq->lock, flags);
3023}
3024
3025#ifdef CONFIG_PM
3026static int fw_loaded = 0;
3027static const struct firmware *bootfw = NULL;
3028static const struct firmware *firmware = NULL;
3029static const struct firmware *ucode = NULL;
3030#endif
3031
3032static int ipw_load(struct ipw_priv *priv)
3033{
3034#ifndef CONFIG_PM
3035 const struct firmware *bootfw = NULL;
3036 const struct firmware *firmware = NULL;
3037 const struct firmware *ucode = NULL;
3038#endif
3039 int rc = 0, retries = 3;
3040
3041#ifdef CONFIG_PM
3042 if (!fw_loaded) {
3043#endif
3044 rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot"));
bf79451e 3045 if (rc)
43f66a6c 3046 goto error;
bf79451e 3047
43f66a6c
JK
3048 switch (priv->ieee->iw_mode) {
3049 case IW_MODE_ADHOC:
bf79451e 3050 rc = ipw_get_fw(priv, &ucode,
43f66a6c 3051 IPW_FW_NAME("ibss_ucode"));
bf79451e 3052 if (rc)
43f66a6c 3053 goto error;
bf79451e 3054
43f66a6c
JK
3055 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss"));
3056 break;
bf79451e 3057
b095c381 3058#ifdef CONFIG_IPW2200_MONITOR
43f66a6c 3059 case IW_MODE_MONITOR:
bf79451e 3060 rc = ipw_get_fw(priv, &ucode,
ea2b26e0 3061 IPW_FW_NAME("sniffer_ucode"));
bf79451e 3062 if (rc)
43f66a6c 3063 goto error;
bf79451e 3064
0edd5b44
JG
3065 rc = ipw_get_fw(priv, &firmware,
3066 IPW_FW_NAME("sniffer"));
43f66a6c
JK
3067 break;
3068#endif
3069 case IW_MODE_INFRA:
0edd5b44 3070 rc = ipw_get_fw(priv, &ucode, IPW_FW_NAME("bss_ucode"));
bf79451e 3071 if (rc)
43f66a6c 3072 goto error;
bf79451e 3073
43f66a6c
JK
3074 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("bss"));
3075 break;
bf79451e 3076
43f66a6c
JK
3077 default:
3078 rc = -EINVAL;
3079 }
3080
bf79451e 3081 if (rc)
43f66a6c
JK
3082 goto error;
3083
3084#ifdef CONFIG_PM
3085 fw_loaded = 1;
3086 }
3087#endif
3088
3089 if (!priv->rxq)
3090 priv->rxq = ipw_rx_queue_alloc(priv);
3091 else
3092 ipw_rx_queue_reset(priv, priv->rxq);
3093 if (!priv->rxq) {
3094 IPW_ERROR("Unable to initialize Rx queue\n");
3095 goto error;
3096 }
3097
0edd5b44 3098 retry:
43f66a6c 3099 /* Ensure interrupts are disabled */
b095c381 3100 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
43f66a6c
JK
3101 priv->status &= ~STATUS_INT_ENABLED;
3102
3103 /* ack pending interrupts */
b095c381 3104 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
bf79451e 3105
43f66a6c
JK
3106 ipw_stop_nic(priv);
3107
3108 rc = ipw_reset_nic(priv);
3109 if (rc) {
3110 IPW_ERROR("Unable to reset NIC\n");
3111 goto error;
3112 }
3113
b095c381
JK
3114 ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
3115 IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
43f66a6c
JK
3116
3117 /* DMA the initial boot firmware into the device */
bf79451e 3118 rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header),
43f66a6c
JK
3119 bootfw->size - sizeof(struct fw_header));
3120 if (rc < 0) {
3121 IPW_ERROR("Unable to load boot firmware\n");
3122 goto error;
3123 }
3124
3125 /* kick start the device */
3126 ipw_start_nic(priv);
3127
3128 /* wait for the device to finish it's initial startup sequence */
b095c381
JK
3129 rc = ipw_poll_bit(priv, IPW_INTA_RW,
3130 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
43f66a6c
JK
3131 if (rc < 0) {
3132 IPW_ERROR("device failed to boot initial fw image\n");
3133 goto error;
3134 }
3135 IPW_DEBUG_INFO("initial device response after %dms\n", rc);
3136
bf79451e 3137 /* ack fw init done interrupt */
b095c381 3138 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
43f66a6c
JK
3139
3140 /* DMA the ucode into the device */
bf79451e 3141 rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header),
43f66a6c
JK
3142 ucode->size - sizeof(struct fw_header));
3143 if (rc < 0) {
3144 IPW_ERROR("Unable to load ucode\n");
3145 goto error;
3146 }
bf79451e 3147
43f66a6c
JK
3148 /* stop nic */
3149 ipw_stop_nic(priv);
3150
3151 /* DMA bss firmware into the device */
bf79451e
JG
3152 rc = ipw_load_firmware(priv, firmware->data +
3153 sizeof(struct fw_header),
43f66a6c 3154 firmware->size - sizeof(struct fw_header));
0edd5b44 3155 if (rc < 0) {
43f66a6c
JK
3156 IPW_ERROR("Unable to load firmware\n");
3157 goto error;
3158 }
3159
3160 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
3161
3162 rc = ipw_queue_reset(priv);
3163 if (rc) {
3164 IPW_ERROR("Unable to initialize queues\n");
3165 goto error;
3166 }
3167
3168 /* Ensure interrupts are disabled */
b095c381 3169 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
c848d0af 3170 /* ack pending interrupts */
b095c381 3171 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
bf79451e 3172
43f66a6c
JK
3173 /* kick start the device */
3174 ipw_start_nic(priv);
3175
b095c381 3176 if (ipw_read32(priv, IPW_INTA_RW) & IPW_INTA_BIT_PARITY_ERROR) {
43f66a6c
JK
3177 if (retries > 0) {
3178 IPW_WARNING("Parity error. Retrying init.\n");
3179 retries--;
3180 goto retry;
3181 }
3182
3183 IPW_ERROR("TODO: Handle parity error -- schedule restart?\n");
3184 rc = -EIO;
3185 goto error;
3186 }
3187
3188 /* wait for the device */
b095c381
JK
3189 rc = ipw_poll_bit(priv, IPW_INTA_RW,
3190 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
43f66a6c
JK
3191 if (rc < 0) {
3192 IPW_ERROR("device failed to start after 500ms\n");
3193 goto error;
3194 }
3195 IPW_DEBUG_INFO("device response after %dms\n", rc);
3196
3197 /* ack fw init done interrupt */
b095c381 3198 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
43f66a6c
JK
3199
3200 /* read eeprom data and initialize the eeprom region of sram */
3201 priv->eeprom_delay = 1;
bf79451e 3202 ipw_eeprom_init_sram(priv);
43f66a6c
JK
3203
3204 /* enable interrupts */
3205 ipw_enable_interrupts(priv);
3206
3207 /* Ensure our queue has valid packets */
3208 ipw_rx_queue_replenish(priv);
3209
b095c381 3210 ipw_write32(priv, IPW_RX_READ_INDEX, priv->rxq->read);
43f66a6c
JK
3211
3212 /* ack pending interrupts */
b095c381 3213 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
43f66a6c
JK
3214
3215#ifndef CONFIG_PM
3216 release_firmware(bootfw);
3217 release_firmware(ucode);
3218 release_firmware(firmware);
3219#endif
3220 return 0;
3221
0edd5b44 3222 error:
43f66a6c
JK
3223 if (priv->rxq) {
3224 ipw_rx_queue_free(priv, priv->rxq);
3225 priv->rxq = NULL;
3226 }
3227 ipw_tx_queue_free(priv);
3228 if (bootfw)
3229 release_firmware(bootfw);
3230 if (ucode)
3231 release_firmware(ucode);
3232 if (firmware)
3233 release_firmware(firmware);
3234#ifdef CONFIG_PM
3235 fw_loaded = 0;
3236 bootfw = ucode = firmware = NULL;
3237#endif
3238
3239 return rc;
3240}
3241
bf79451e 3242/**
43f66a6c
JK
3243 * DMA services
3244 *
3245 * Theory of operation
3246 *
3247 * A queue is a circular buffers with 'Read' and 'Write' pointers.
3248 * 2 empty entries always kept in the buffer to protect from overflow.
3249 *
3250 * For Tx queue, there are low mark and high mark limits. If, after queuing
bf79451e
JG
3251 * the packet for Tx, free space become < low mark, Tx queue stopped. When
3252 * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
43f66a6c
JK
3253 * Tx queue resumed.
3254 *
3255 * The IPW operates with six queues, one receive queue in the device's
3256 * sram, one transmit queue for sending commands to the device firmware,
bf79451e 3257 * and four transmit queues for data.
43f66a6c 3258 *
bf79451e 3259 * The four transmit queues allow for performing quality of service (qos)
43f66a6c 3260 * transmissions as per the 802.11 protocol. Currently Linux does not
bf79451e 3261 * provide a mechanism to the user for utilizing prioritized queues, so
43f66a6c
JK
3262 * we only utilize the first data transmit queue (queue1).
3263 */
3264
3265/**
3266 * Driver allocates buffers of this size for Rx
3267 */
3268
3269static inline int ipw_queue_space(const struct clx2_queue *q)
3270{
3271 int s = q->last_used - q->first_empty;
3272 if (s <= 0)
3273 s += q->n_bd;
3274 s -= 2; /* keep some reserve to not confuse empty and full situations */
3275 if (s < 0)
3276 s = 0;
3277 return s;
3278}
3279
3280static inline int ipw_queue_inc_wrap(int index, int n_bd)
3281{
3282 return (++index == n_bd) ? 0 : index;
3283}
3284
3285/**
3286 * Initialize common DMA queue structure
bf79451e 3287 *
43f66a6c
JK
3288 * @param q queue to init
3289 * @param count Number of BD's to allocate. Should be power of 2
3290 * @param read_register Address for 'read' register
3291 * (not offset within BAR, full address)
3292 * @param write_register Address for 'write' register
3293 * (not offset within BAR, full address)
3294 * @param base_register Address for 'base' register
3295 * (not offset within BAR, full address)
3296 * @param size Address for 'size' register
3297 * (not offset within BAR, full address)
3298 */
bf79451e 3299static void ipw_queue_init(struct ipw_priv *priv, struct clx2_queue *q,
0edd5b44 3300 int count, u32 read, u32 write, u32 base, u32 size)
43f66a6c
JK
3301{
3302 q->n_bd = count;
3303
3304 q->low_mark = q->n_bd / 4;
3305 if (q->low_mark < 4)
3306 q->low_mark = 4;
3307
3308 q->high_mark = q->n_bd / 8;
3309 if (q->high_mark < 2)
3310 q->high_mark = 2;
3311
3312 q->first_empty = q->last_used = 0;
3313 q->reg_r = read;
3314 q->reg_w = write;
3315
3316 ipw_write32(priv, base, q->dma_addr);
3317 ipw_write32(priv, size, count);
3318 ipw_write32(priv, read, 0);
3319 ipw_write32(priv, write, 0);
3320
3321 _ipw_read32(priv, 0x90);
3322}
3323
bf79451e 3324static int ipw_queue_tx_init(struct ipw_priv *priv,
43f66a6c 3325 struct clx2_tx_queue *q,
0edd5b44 3326 int count, u32 read, u32 write, u32 base, u32 size)
43f66a6c
JK
3327{
3328 struct pci_dev *dev = priv->pci_dev;
3329
3330 q->txb = kmalloc(sizeof(q->txb[0]) * count, GFP_KERNEL);
3331 if (!q->txb) {
3332 IPW_ERROR("vmalloc for auxilary BD structures failed\n");
3333 return -ENOMEM;
3334 }
3335
0edd5b44
JG
3336 q->bd =
3337 pci_alloc_consistent(dev, sizeof(q->bd[0]) * count, &q->q.dma_addr);
43f66a6c 3338 if (!q->bd) {
aaa4d308 3339 IPW_ERROR("pci_alloc_consistent(%zd) failed\n",
0edd5b44 3340 sizeof(q->bd[0]) * count);
43f66a6c
JK
3341 kfree(q->txb);
3342 q->txb = NULL;
3343 return -ENOMEM;
3344 }
3345
3346 ipw_queue_init(priv, &q->q, count, read, write, base, size);
3347 return 0;
3348}
3349
3350/**
3351 * Free one TFD, those at index [txq->q.last_used].
3352 * Do NOT advance any indexes
bf79451e 3353 *
43f66a6c
JK
3354 * @param dev
3355 * @param txq
3356 */
3357static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,
3358 struct clx2_tx_queue *txq)
3359{
3360 struct tfd_frame *bd = &txq->bd[txq->q.last_used];
3361 struct pci_dev *dev = priv->pci_dev;
3362 int i;
bf79451e 3363
43f66a6c
JK
3364 /* classify bd */
3365 if (bd->control_flags.message_type == TX_HOST_COMMAND_TYPE)
3366 /* nothing to cleanup after for host commands */
3367 return;
3368
3369 /* sanity check */
a613bffd
JK
3370 if (le32_to_cpu(bd->u.data.num_chunks) > NUM_TFD_CHUNKS) {
3371 IPW_ERROR("Too many chunks: %i\n",
3372 le32_to_cpu(bd->u.data.num_chunks));
43f66a6c
JK
3373 /** @todo issue fatal error, it is quite serious situation */
3374 return;
3375 }
3376
3377 /* unmap chunks if any */
a613bffd
JK
3378 for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) {
3379 pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]),
3380 le16_to_cpu(bd->u.data.chunk_len[i]),
3381 PCI_DMA_TODEVICE);
43f66a6c
JK
3382 if (txq->txb[txq->q.last_used]) {
3383 ieee80211_txb_free(txq->txb[txq->q.last_used]);
3384 txq->txb[txq->q.last_used] = NULL;
3385 }
3386 }
3387}
3388
3389/**
3390 * Deallocate DMA queue.
bf79451e 3391 *
43f66a6c
JK
3392 * Empty queue by removing and destroying all BD's.
3393 * Free all buffers.
bf79451e 3394 *
43f66a6c
JK
3395 * @param dev
3396 * @param q
3397 */
0edd5b44 3398static void ipw_queue_tx_free(struct ipw_priv *priv, struct clx2_tx_queue *txq)
43f66a6c
JK
3399{
3400 struct clx2_queue *q = &txq->q;
3401 struct pci_dev *dev = priv->pci_dev;
3402
bf79451e
JG
3403 if (q->n_bd == 0)
3404 return;
43f66a6c
JK
3405
3406 /* first, empty all BD's */
3407 for (; q->first_empty != q->last_used;
3408 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {
3409 ipw_queue_tx_free_tfd(priv, txq);
3410 }
bf79451e 3411
43f66a6c 3412 /* free buffers belonging to queue itself */
0edd5b44 3413 pci_free_consistent(dev, sizeof(txq->bd[0]) * q->n_bd, txq->bd,
43f66a6c
JK
3414 q->dma_addr);
3415 kfree(txq->txb);
3416
3417 /* 0 fill whole structure */
3418 memset(txq, 0, sizeof(*txq));
3419}
3420
43f66a6c
JK
3421/**
3422 * Destroy all DMA queues and structures
bf79451e 3423 *
43f66a6c
JK
3424 * @param priv
3425 */
3426static void ipw_tx_queue_free(struct ipw_priv *priv)
3427{
3428 /* Tx CMD queue */
3429 ipw_queue_tx_free(priv, &priv->txq_cmd);
3430
3431 /* Tx queues */
3432 ipw_queue_tx_free(priv, &priv->txq[0]);
3433 ipw_queue_tx_free(priv, &priv->txq[1]);
3434 ipw_queue_tx_free(priv, &priv->txq[2]);
3435 ipw_queue_tx_free(priv, &priv->txq[3]);
3436}
3437
3438static void inline __maybe_wake_tx(struct ipw_priv *priv)
3439{
3440 if (netif_running(priv->net_dev)) {
3441 switch (priv->port_type) {
3442 case DCR_TYPE_MU_BSS:
3443 case DCR_TYPE_MU_IBSS:
a613bffd 3444 if (!(priv->status & STATUS_ASSOCIATED))
43f66a6c 3445 return;
43f66a6c
JK
3446 }
3447 netif_wake_queue(priv->net_dev);
3448 }
3449
3450}
3451
0edd5b44 3452static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)
43f66a6c
JK
3453{
3454 /* First 3 bytes are manufacturer */
3455 bssid[0] = priv->mac_addr[0];
3456 bssid[1] = priv->mac_addr[1];
3457 bssid[2] = priv->mac_addr[2];
3458
3459 /* Last bytes are random */
0edd5b44 3460 get_random_bytes(&bssid[3], ETH_ALEN - 3);
43f66a6c 3461
0edd5b44
JG
3462 bssid[0] &= 0xfe; /* clear multicast bit */
3463 bssid[0] |= 0x02; /* set local assignment bit (IEEE802) */
43f66a6c
JK
3464}
3465
0edd5b44 3466static inline u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid)
43f66a6c
JK
3467{
3468 struct ipw_station_entry entry;
3469 int i;
3470
3471 for (i = 0; i < priv->num_stations; i++) {
3472 if (!memcmp(priv->stations[i], bssid, ETH_ALEN)) {
3473 /* Another node is active in network */
3474 priv->missed_adhoc_beacons = 0;
3475 if (!(priv->config & CFG_STATIC_CHANNEL))
3476 /* when other nodes drop out, we drop out */
3477 priv->config &= ~CFG_ADHOC_PERSIST;
3478
3479 return i;
3480 }
3481 }
3482
3483 if (i == MAX_STATIONS)
3484 return IPW_INVALID_STATION;
3485
3486 IPW_DEBUG_SCAN("Adding AdHoc station: " MAC_FMT "\n", MAC_ARG(bssid));
3487
3488 entry.reserved = 0;
3489 entry.support_mode = 0;
3490 memcpy(entry.mac_addr, bssid, ETH_ALEN);
3491 memcpy(priv->stations[i], bssid, ETH_ALEN);
3492 ipw_write_direct(priv, IPW_STATION_TABLE_LOWER + i * sizeof(entry),
0edd5b44 3493 &entry, sizeof(entry));
43f66a6c
JK
3494 priv->num_stations++;
3495
3496 return i;
3497}
3498
0edd5b44 3499static inline u8 ipw_find_station(struct ipw_priv *priv, u8 * bssid)
43f66a6c
JK
3500{
3501 int i;
3502
bf79451e
JG
3503 for (i = 0; i < priv->num_stations; i++)
3504 if (!memcmp(priv->stations[i], bssid, ETH_ALEN))
43f66a6c
JK
3505 return i;
3506
3507 return IPW_INVALID_STATION;
3508}
3509
3510static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
3511{
3512 int err;
3513
3514 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))) {
3515 IPW_DEBUG_ASSOC("Disassociating while not associated.\n");
3516 return;
3517 }
3518
3519 IPW_DEBUG_ASSOC("Disassocation attempt from " MAC_FMT " "
3520 "on channel %d.\n",
bf79451e 3521 MAC_ARG(priv->assoc_request.bssid),
43f66a6c
JK
3522 priv->assoc_request.channel);
3523
3524 priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
3525 priv->status |= STATUS_DISASSOCIATING;
3526
3527 if (quiet)
3528 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
3529 else
3530 priv->assoc_request.assoc_type = HC_DISASSOCIATE;
3531 err = ipw_send_associate(priv, &priv->assoc_request);
3532 if (err) {
3533 IPW_DEBUG_HC("Attempt to send [dis]associate command "
3534 "failed.\n");
3535 return;
3536 }
3537
3538}
3539
c848d0af 3540static int ipw_disassociate(void *data)
43f66a6c 3541{
c848d0af
JK
3542 struct ipw_priv *priv = data;
3543 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
3544 return 0;
43f66a6c 3545 ipw_send_disassociate(data, 0);
c848d0af
JK
3546 return 1;
3547}
3548
3549static void ipw_bg_disassociate(void *data)
3550{
3551 struct ipw_priv *priv = data;
3552 down(&priv->sem);
3553 ipw_disassociate(data);
3554 up(&priv->sem);
43f66a6c
JK
3555}
3556
43f66a6c
JK
3557struct ipw_status_code {
3558 u16 status;
3559 const char *reason;
3560};
3561
3562static const struct ipw_status_code ipw_status_codes[] = {
3563 {0x00, "Successful"},
3564 {0x01, "Unspecified failure"},
3565 {0x0A, "Cannot support all requested capabilities in the "
3566 "Capability information field"},
3567 {0x0B, "Reassociation denied due to inability to confirm that "
3568 "association exists"},
3569 {0x0C, "Association denied due to reason outside the scope of this "
3570 "standard"},
0edd5b44
JG
3571 {0x0D,
3572 "Responding station does not support the specified authentication "
43f66a6c 3573 "algorithm"},
0edd5b44
JG
3574 {0x0E,
3575 "Received an Authentication frame with authentication sequence "
43f66a6c
JK
3576 "transaction sequence number out of expected sequence"},
3577 {0x0F, "Authentication rejected because of challenge failure"},
3578 {0x10, "Authentication rejected due to timeout waiting for next "
3579 "frame in sequence"},
3580 {0x11, "Association denied because AP is unable to handle additional "
3581 "associated stations"},
0edd5b44
JG
3582 {0x12,
3583 "Association denied due to requesting station not supporting all "
43f66a6c 3584 "of the datarates in the BSSBasicServiceSet Parameter"},
0edd5b44
JG
3585 {0x13,
3586 "Association denied due to requesting station not supporting "
43f66a6c 3587 "short preamble operation"},
0edd5b44
JG
3588 {0x14,
3589 "Association denied due to requesting station not supporting "
43f66a6c 3590 "PBCC encoding"},
0edd5b44
JG
3591 {0x15,
3592 "Association denied due to requesting station not supporting "
43f66a6c 3593 "channel agility"},
0edd5b44
JG
3594 {0x19,
3595 "Association denied due to requesting station not supporting "
43f66a6c 3596 "short slot operation"},
0edd5b44
JG
3597 {0x1A,
3598 "Association denied due to requesting station not supporting "
43f66a6c
JK
3599 "DSSS-OFDM operation"},
3600 {0x28, "Invalid Information Element"},
3601 {0x29, "Group Cipher is not valid"},
3602 {0x2A, "Pairwise Cipher is not valid"},
3603 {0x2B, "AKMP is not valid"},
3604 {0x2C, "Unsupported RSN IE version"},
3605 {0x2D, "Invalid RSN IE Capabilities"},
3606 {0x2E, "Cipher suite is rejected per security policy"},
3607};
3608
3609#ifdef CONFIG_IPW_DEBUG
bf79451e 3610static const char *ipw_get_status_code(u16 status)
43f66a6c
JK
3611{
3612 int i;
bf79451e 3613 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++)
ea2b26e0 3614 if (ipw_status_codes[i].status == (status & 0xff))
43f66a6c
JK
3615 return ipw_status_codes[i].reason;
3616 return "Unknown status value.";
3617}
3618#endif
3619
3620static void inline average_init(struct average *avg)
3621{
3622 memset(avg, 0, sizeof(*avg));
3623}
3624
3625static void inline average_add(struct average *avg, s16 val)
3626{
3627 avg->sum -= avg->entries[avg->pos];
3628 avg->sum += val;
3629 avg->entries[avg->pos++] = val;
3630 if (unlikely(avg->pos == AVG_ENTRIES)) {
3631 avg->init = 1;
3632 avg->pos = 0;
3633 }
3634}
3635
3636static s16 inline average_value(struct average *avg)
3637{
3638 if (!unlikely(avg->init)) {
3639 if (avg->pos)
3640 return avg->sum / avg->pos;
3641 return 0;
3642 }
3643
3644 return avg->sum / AVG_ENTRIES;
3645}
3646
3647static void ipw_reset_stats(struct ipw_priv *priv)
3648{
3649 u32 len = sizeof(u32);
3650
3651 priv->quality = 0;
3652
3653 average_init(&priv->average_missed_beacons);
3654 average_init(&priv->average_rssi);
3655 average_init(&priv->average_noise);
3656
3657 priv->last_rate = 0;
3658 priv->last_missed_beacons = 0;
3659 priv->last_rx_packets = 0;
3660 priv->last_tx_packets = 0;
3661 priv->last_tx_failures = 0;
bf79451e 3662
43f66a6c
JK
3663 /* Firmware managed, reset only when NIC is restarted, so we have to
3664 * normalize on the current value */
bf79451e 3665 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC,
43f66a6c 3666 &priv->last_rx_err, &len);
bf79451e 3667 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE,
43f66a6c
JK
3668 &priv->last_tx_failures, &len);
3669
3670 /* Driver managed, reset with each association */
3671 priv->missed_adhoc_beacons = 0;
3672 priv->missed_beacons = 0;
3673 priv->tx_packets = 0;
3674 priv->rx_packets = 0;
3675
3676}
3677
43f66a6c
JK
3678static inline u32 ipw_get_max_rate(struct ipw_priv *priv)
3679{
3680 u32 i = 0x80000000;
3681 u32 mask = priv->rates_mask;
3682 /* If currently associated in B mode, restrict the maximum
3683 * rate match to B rates */
3684 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
3685 mask &= IEEE80211_CCK_RATES_MASK;
3686
3687 /* TODO: Verify that the rate is supported by the current rates
3688 * list. */
3689
0edd5b44
JG
3690 while (i && !(mask & i))
3691 i >>= 1;
43f66a6c 3692 switch (i) {
ea2b26e0
JK
3693 case IEEE80211_CCK_RATE_1MB_MASK:
3694 return 1000000;
3695 case IEEE80211_CCK_RATE_2MB_MASK:
3696 return 2000000;
3697 case IEEE80211_CCK_RATE_5MB_MASK:
3698 return 5500000;
3699 case IEEE80211_OFDM_RATE_6MB_MASK:
3700 return 6000000;
3701 case IEEE80211_OFDM_RATE_9MB_MASK:
3702 return 9000000;
3703 case IEEE80211_CCK_RATE_11MB_MASK:
3704 return 11000000;
3705 case IEEE80211_OFDM_RATE_12MB_MASK:
3706 return 12000000;
3707 case IEEE80211_OFDM_RATE_18MB_MASK:
3708 return 18000000;
3709 case IEEE80211_OFDM_RATE_24MB_MASK:
3710 return 24000000;
3711 case IEEE80211_OFDM_RATE_36MB_MASK:
3712 return 36000000;
3713 case IEEE80211_OFDM_RATE_48MB_MASK:
3714 return 48000000;
3715 case IEEE80211_OFDM_RATE_54MB_MASK:
3716 return 54000000;
43f66a6c
JK
3717 }
3718
bf79451e 3719 if (priv->ieee->mode == IEEE_B)
43f66a6c
JK
3720 return 11000000;
3721 else
3722 return 54000000;
3723}
3724
3725static u32 ipw_get_current_rate(struct ipw_priv *priv)
3726{
3727 u32 rate, len = sizeof(rate);
3728 int err;
3729
bf79451e 3730 if (!(priv->status & STATUS_ASSOCIATED))
43f66a6c
JK
3731 return 0;
3732
3733 if (priv->tx_packets > IPW_REAL_RATE_RX_PACKET_THRESHOLD) {
bf79451e 3734 err = ipw_get_ordinal(priv, IPW_ORD_STAT_TX_CURR_RATE, &rate,
43f66a6c
JK
3735 &len);
3736 if (err) {
3737 IPW_DEBUG_INFO("failed querying ordinals.\n");
3738 return 0;
3739 }
bf79451e 3740 } else
43f66a6c
JK
3741 return ipw_get_max_rate(priv);
3742
3743 switch (rate) {
ea2b26e0
JK
3744 case IPW_TX_RATE_1MB:
3745 return 1000000;
3746 case IPW_TX_RATE_2MB:
3747 return 2000000;
3748 case IPW_TX_RATE_5MB:
3749 return 5500000;
3750 case IPW_TX_RATE_6MB:
3751 return 6000000;
3752 case IPW_TX_RATE_9MB:
3753 return 9000000;
3754 case IPW_TX_RATE_11MB:
3755 return 11000000;
3756 case IPW_TX_RATE_12MB:
3757 return 12000000;
3758 case IPW_TX_RATE_18MB:
3759 return 18000000;
3760 case IPW_TX_RATE_24MB:
3761 return 24000000;
3762 case IPW_TX_RATE_36MB:
3763 return 36000000;
3764 case IPW_TX_RATE_48MB:
3765 return 48000000;
3766 case IPW_TX_RATE_54MB:
3767 return 54000000;
43f66a6c
JK
3768 }
3769
3770 return 0;
3771}
3772
43f66a6c
JK
3773#define IPW_STATS_INTERVAL (2 * HZ)
3774static void ipw_gather_stats(struct ipw_priv *priv)
3775{
3776 u32 rx_err, rx_err_delta, rx_packets_delta;
3777 u32 tx_failures, tx_failures_delta, tx_packets_delta;
3778 u32 missed_beacons_percent, missed_beacons_delta;
3779 u32 quality = 0;
3780 u32 len = sizeof(u32);
3781 s16 rssi;
bf79451e 3782 u32 beacon_quality, signal_quality, tx_quality, rx_quality,
0edd5b44 3783 rate_quality;
ea2b26e0 3784 u32 max_rate;
43f66a6c
JK
3785
3786 if (!(priv->status & STATUS_ASSOCIATED)) {
3787 priv->quality = 0;
3788 return;
3789 }
3790
3791 /* Update the statistics */
bf79451e 3792 ipw_get_ordinal(priv, IPW_ORD_STAT_MISSED_BEACONS,
43f66a6c 3793 &priv->missed_beacons, &len);
0edd5b44 3794 missed_beacons_delta = priv->missed_beacons - priv->last_missed_beacons;
43f66a6c
JK
3795 priv->last_missed_beacons = priv->missed_beacons;
3796 if (priv->assoc_request.beacon_interval) {
3797 missed_beacons_percent = missed_beacons_delta *
0edd5b44
JG
3798 (HZ * priv->assoc_request.beacon_interval) /
3799 (IPW_STATS_INTERVAL * 10);
43f66a6c
JK
3800 } else {
3801 missed_beacons_percent = 0;
3802 }
3803 average_add(&priv->average_missed_beacons, missed_beacons_percent);
3804
3805 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC, &rx_err, &len);
3806 rx_err_delta = rx_err - priv->last_rx_err;
3807 priv->last_rx_err = rx_err;
3808
3809 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE, &tx_failures, &len);
3810 tx_failures_delta = tx_failures - priv->last_tx_failures;
3811 priv->last_tx_failures = tx_failures;
3812
3813 rx_packets_delta = priv->rx_packets - priv->last_rx_packets;
3814 priv->last_rx_packets = priv->rx_packets;
3815
3816 tx_packets_delta = priv->tx_packets - priv->last_tx_packets;
3817 priv->last_tx_packets = priv->tx_packets;
3818
3819 /* Calculate quality based on the following:
bf79451e 3820 *
43f66a6c
JK
3821 * Missed beacon: 100% = 0, 0% = 70% missed
3822 * Rate: 60% = 1Mbs, 100% = Max
3823 * Rx and Tx errors represent a straight % of total Rx/Tx
3824 * RSSI: 100% = > -50, 0% = < -80
3825 * Rx errors: 100% = 0, 0% = 50% missed
bf79451e 3826 *
43f66a6c
JK
3827 * The lowest computed quality is used.
3828 *
3829 */
3830#define BEACON_THRESHOLD 5
3831 beacon_quality = 100 - missed_beacons_percent;
3832 if (beacon_quality < BEACON_THRESHOLD)
3833 beacon_quality = 0;
3834 else
bf79451e 3835 beacon_quality = (beacon_quality - BEACON_THRESHOLD) * 100 /
0edd5b44 3836 (100 - BEACON_THRESHOLD);
bf79451e 3837 IPW_DEBUG_STATS("Missed beacon: %3d%% (%d%%)\n",
43f66a6c 3838 beacon_quality, missed_beacons_percent);
bf79451e 3839
43f66a6c 3840 priv->last_rate = ipw_get_current_rate(priv);
ea2b26e0
JK
3841 max_rate = ipw_get_max_rate(priv);
3842 rate_quality = priv->last_rate * 40 / max_rate + 60;
43f66a6c
JK
3843 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n",
3844 rate_quality, priv->last_rate / 1000000);
bf79451e 3845
0edd5b44 3846 if (rx_packets_delta > 100 && rx_packets_delta + rx_err_delta)
bf79451e 3847 rx_quality = 100 - (rx_err_delta * 100) /
0edd5b44 3848 (rx_packets_delta + rx_err_delta);
43f66a6c
JK
3849 else
3850 rx_quality = 100;
3851 IPW_DEBUG_STATS("Rx quality : %3d%% (%u errors, %u packets)\n",
3852 rx_quality, rx_err_delta, rx_packets_delta);
bf79451e 3853
0edd5b44 3854 if (tx_packets_delta > 100 && tx_packets_delta + tx_failures_delta)
bf79451e 3855 tx_quality = 100 - (tx_failures_delta * 100) /
0edd5b44 3856 (tx_packets_delta + tx_failures_delta);
43f66a6c
JK
3857 else
3858 tx_quality = 100;
3859 IPW_DEBUG_STATS("Tx quality : %3d%% (%u errors, %u packets)\n",
3860 tx_quality, tx_failures_delta, tx_packets_delta);
bf79451e 3861
43f66a6c 3862 rssi = average_value(&priv->average_rssi);
c848d0af
JK
3863 signal_quality =
3864 (100 *
3865 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
3866 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) -
3867 (priv->ieee->perfect_rssi - rssi) *
3868 (15 * (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) +
3869 62 * (priv->ieee->perfect_rssi - rssi))) /
3870 ((priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
3871 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi));
3872 if (signal_quality > 100)
43f66a6c 3873 signal_quality = 100;
c848d0af 3874 else if (signal_quality < 1)
43f66a6c 3875 signal_quality = 0;
ea2b26e0 3876
43f66a6c
JK
3877 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
3878 signal_quality, rssi);
bf79451e
JG
3879
3880 quality = min(beacon_quality,
43f66a6c
JK
3881 min(rate_quality,
3882 min(tx_quality, min(rx_quality, signal_quality))));
3883 if (quality == beacon_quality)
0edd5b44
JG
3884 IPW_DEBUG_STATS("Quality (%d%%): Clamped to missed beacons.\n",
3885 quality);
43f66a6c 3886 if (quality == rate_quality)
0edd5b44
JG
3887 IPW_DEBUG_STATS("Quality (%d%%): Clamped to rate quality.\n",
3888 quality);
43f66a6c 3889 if (quality == tx_quality)
0edd5b44
JG
3890 IPW_DEBUG_STATS("Quality (%d%%): Clamped to Tx quality.\n",
3891 quality);
43f66a6c 3892 if (quality == rx_quality)
0edd5b44
JG
3893 IPW_DEBUG_STATS("Quality (%d%%): Clamped to Rx quality.\n",
3894 quality);
43f66a6c 3895 if (quality == signal_quality)
0edd5b44
JG
3896 IPW_DEBUG_STATS("Quality (%d%%): Clamped to signal quality.\n",
3897 quality);
43f66a6c
JK
3898
3899 priv->quality = quality;
bf79451e
JG
3900
3901 queue_delayed_work(priv->workqueue, &priv->gather_stats,
43f66a6c
JK
3902 IPW_STATS_INTERVAL);
3903}
3904
c848d0af
JK
3905static void ipw_bg_gather_stats(void *data)
3906{
3907 struct ipw_priv *priv = data;
3908 down(&priv->sem);
3909 ipw_gather_stats(data);
3910 up(&priv->sem);
3911}
3912
ea2b26e0
JK
3913static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
3914 int missed_count)
3915{
3916 priv->notif_missed_beacons = missed_count;
3917
3918 if (missed_count > priv->missed_beacon_threshold &&
3919 priv->status & STATUS_ASSOCIATED) {
3920 /* If associated and we've hit the missed
3921 * beacon threshold, disassociate, turn
3922 * off roaming, and abort any active scans */
3923 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
3924 IPW_DL_STATE,
3925 "Missed beacon: %d - disassociate\n", missed_count);
3926 priv->status &= ~STATUS_ROAMING;
a613bffd
JK
3927 if (priv->status & STATUS_SCANNING) {
3928 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
3929 IPW_DL_STATE,
3930 "Aborting scan with missed beacon.\n");
ea2b26e0 3931 queue_work(priv->workqueue, &priv->abort_scan);
a613bffd
JK
3932 }
3933
ea2b26e0
JK
3934 queue_work(priv->workqueue, &priv->disassociate);
3935 return;
3936 }
3937
3938 if (priv->status & STATUS_ROAMING) {
3939 /* If we are currently roaming, then just
3940 * print a debug statement... */
3941 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3942 "Missed beacon: %d - roam in progress\n",
3943 missed_count);
3944 return;
3945 }
3946
3947 if (missed_count > priv->roaming_threshold) {
3948 /* If we are not already roaming, set the ROAM
3949 * bit in the status and kick off a scan */
3950 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3951 "Missed beacon: %d - initiate "
3952 "roaming\n", missed_count);
3953 if (!(priv->status & STATUS_ROAMING)) {
3954 priv->status |= STATUS_ROAMING;
3955 if (!(priv->status & STATUS_SCANNING))
3956 queue_work(priv->workqueue,
3957 &priv->request_scan);
3958 }
3959 return;
3960 }
3961
3962 if (priv->status & STATUS_SCANNING) {
3963 /* Stop scan to keep fw from getting
3964 * stuck (only if we aren't roaming --
3965 * otherwise we'll never scan more than 2 or 3
3966 * channels..) */
b095c381
JK
3967 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE,
3968 "Aborting scan with missed beacon.\n");
ea2b26e0
JK
3969 queue_work(priv->workqueue, &priv->abort_scan);
3970 }
3971
3972 IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
3973
3974}
3975
43f66a6c
JK
3976/**
3977 * Handle host notification packet.
3978 * Called from interrupt routine
3979 */
0edd5b44 3980static inline void ipw_rx_notification(struct ipw_priv *priv,
43f66a6c
JK
3981 struct ipw_rx_notification *notif)
3982{
a613bffd
JK
3983 notif->size = le16_to_cpu(notif->size);
3984
0edd5b44 3985 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size);
bf79451e 3986
43f66a6c 3987 switch (notif->subtype) {
0edd5b44
JG
3988 case HOST_NOTIFICATION_STATUS_ASSOCIATED:{
3989 struct notif_association *assoc = &notif->u.assoc;
3990
3991 switch (assoc->state) {
3992 case CMAS_ASSOCIATED:{
3993 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
3994 IPW_DL_ASSOC,
3995 "associated: '%s' " MAC_FMT
3996 " \n",
3997 escape_essid(priv->essid,
3998 priv->essid_len),
3999 MAC_ARG(priv->bssid));
4000
4001 switch (priv->ieee->iw_mode) {
4002 case IW_MODE_INFRA:
4003 memcpy(priv->ieee->bssid,
4004 priv->bssid, ETH_ALEN);
4005 break;
4006
4007 case IW_MODE_ADHOC:
4008 memcpy(priv->ieee->bssid,
4009 priv->bssid, ETH_ALEN);
4010
4011 /* clear out the station table */
4012 priv->num_stations = 0;
4013
4014 IPW_DEBUG_ASSOC
4015 ("queueing adhoc check\n");
4016 queue_delayed_work(priv->
4017 workqueue,
4018 &priv->
4019 adhoc_check,
4020 priv->
4021 assoc_request.
4022 beacon_interval);
4023 break;
4024 }
4025
4026 priv->status &= ~STATUS_ASSOCIATING;
4027 priv->status |= STATUS_ASSOCIATED;
4028
b095c381
JK
4029#ifdef CONFIG_IPW_QOS
4030 if (priv->status & STATUS_AUTH) {
4031 if ((sizeof
4032 (struct
4033 ieee80211_assoc_response_frame)
4034 <= notif->size)
4035 && (notif->size <= 2314)) {
4036 struct
4037 ieee80211_rx_stats
4038 stats = {
4039 .len =
4040 notif->
4041 size - 1,
4042 };
4043
4044 IPW_DEBUG_QOS
4045 ("QoS Associate "
4046 "size %d\n",
4047 notif->size);
4048 ieee80211_rx_mgt(priv->
4049 ieee,
4050 (struct
4051 ieee80211_hdr
4052 *)
4053 &notif->u.raw, &stats);
4054 }
4055 }
4056#endif
4057
a613bffd 4058 schedule_work(&priv->link_up);
0edd5b44 4059
0edd5b44
JG
4060 break;
4061 }
bf79451e 4062
0edd5b44
JG
4063 case CMAS_AUTHENTICATED:{
4064 if (priv->
4065 status & (STATUS_ASSOCIATED |
4066 STATUS_AUTH)) {
43f66a6c 4067#ifdef CONFIG_IPW_DEBUG
0edd5b44
JG
4068 struct notif_authenticate *auth
4069 = &notif->u.auth;
4070 IPW_DEBUG(IPW_DL_NOTIF |
4071 IPW_DL_STATE |
4072 IPW_DL_ASSOC,
4073 "deauthenticated: '%s' "
4074 MAC_FMT
4075 ": (0x%04X) - %s \n",
4076 escape_essid(priv->
4077 essid,
4078 priv->
4079 essid_len),
4080 MAC_ARG(priv->bssid),
4081 ntohs(auth->status),
4082 ipw_get_status_code
4083 (ntohs
4084 (auth->status)));
43f66a6c
JK
4085#endif
4086
0edd5b44
JG
4087 priv->status &=
4088 ~(STATUS_ASSOCIATING |
4089 STATUS_AUTH |
4090 STATUS_ASSOCIATED);
4091
a613bffd 4092 schedule_work(&priv->link_down);
0edd5b44
JG
4093 break;
4094 }
4095
4096 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4097 IPW_DL_ASSOC,
4098 "authenticated: '%s' " MAC_FMT
4099 "\n",
4100 escape_essid(priv->essid,
4101 priv->essid_len),
4102 MAC_ARG(priv->bssid));
4103 break;
4104 }
4105
4106 case CMAS_INIT:{
ea2b26e0
JK
4107 if (priv->status & STATUS_AUTH) {
4108 struct
4109 ieee80211_assoc_response
4110 *resp;
4111 resp =
4112 (struct
4113 ieee80211_assoc_response
4114 *)&notif->u.raw;
4115 IPW_DEBUG(IPW_DL_NOTIF |
4116 IPW_DL_STATE |
4117 IPW_DL_ASSOC,
4118 "association failed (0x%04X): %s\n",
4119 ntohs(resp->status),
4120 ipw_get_status_code
4121 (ntohs
4122 (resp->status)));
4123 }
4124
0edd5b44
JG
4125 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4126 IPW_DL_ASSOC,
4127 "disassociated: '%s' " MAC_FMT
4128 " \n",
4129 escape_essid(priv->essid,
4130 priv->essid_len),
4131 MAC_ARG(priv->bssid));
4132
4133 priv->status &=
4134 ~(STATUS_DISASSOCIATING |
4135 STATUS_ASSOCIATING |
4136 STATUS_ASSOCIATED | STATUS_AUTH);
b095c381
JK
4137 if (priv->assoc_network
4138 && (priv->assoc_network->
4139 capability &
4140 WLAN_CAPABILITY_IBSS))
4141 ipw_remove_current_network
4142 (priv);
0edd5b44 4143
a613bffd 4144 schedule_work(&priv->link_down);
0edd5b44 4145
0edd5b44
JG
4146 break;
4147 }
43f66a6c 4148
b095c381
JK
4149 case CMAS_RX_ASSOC_RESP:
4150 break;
4151
0edd5b44
JG
4152 default:
4153 IPW_ERROR("assoc: unknown (%d)\n",
4154 assoc->state);
43f66a6c 4155 break;
bf79451e 4156 }
43f66a6c 4157
43f66a6c
JK
4158 break;
4159 }
bf79451e 4160
0edd5b44
JG
4161 case HOST_NOTIFICATION_STATUS_AUTHENTICATE:{
4162 struct notif_authenticate *auth = &notif->u.auth;
4163 switch (auth->state) {
4164 case CMAS_AUTHENTICATED:
4165 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4166 "authenticated: '%s' " MAC_FMT " \n",
4167 escape_essid(priv->essid,
4168 priv->essid_len),
4169 MAC_ARG(priv->bssid));
4170 priv->status |= STATUS_AUTH;
4171 break;
43f66a6c 4172
0edd5b44
JG
4173 case CMAS_INIT:
4174 if (priv->status & STATUS_AUTH) {
4175 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4176 IPW_DL_ASSOC,
4177 "authentication failed (0x%04X): %s\n",
4178 ntohs(auth->status),
4179 ipw_get_status_code(ntohs
4180 (auth->
4181 status)));
4182 }
4183 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4184 IPW_DL_ASSOC,
4185 "deauthenticated: '%s' " MAC_FMT "\n",
4186 escape_essid(priv->essid,
4187 priv->essid_len),
4188 MAC_ARG(priv->bssid));
bf79451e 4189
0edd5b44
JG
4190 priv->status &= ~(STATUS_ASSOCIATING |
4191 STATUS_AUTH |
4192 STATUS_ASSOCIATED);
43f66a6c 4193
a613bffd 4194 schedule_work(&priv->link_down);
0edd5b44 4195 break;
43f66a6c 4196
0edd5b44
JG
4197 case CMAS_TX_AUTH_SEQ_1:
4198 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4199 IPW_DL_ASSOC, "AUTH_SEQ_1\n");
4200 break;
4201 case CMAS_RX_AUTH_SEQ_2:
4202 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4203 IPW_DL_ASSOC, "AUTH_SEQ_2\n");
4204 break;
4205 case CMAS_AUTH_SEQ_1_PASS:
4206 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4207 IPW_DL_ASSOC, "AUTH_SEQ_1_PASS\n");
4208 break;
4209 case CMAS_AUTH_SEQ_1_FAIL:
4210 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4211 IPW_DL_ASSOC, "AUTH_SEQ_1_FAIL\n");
4212 break;
4213 case CMAS_TX_AUTH_SEQ_3:
4214 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4215 IPW_DL_ASSOC, "AUTH_SEQ_3\n");
4216 break;
4217 case CMAS_RX_AUTH_SEQ_4:
4218 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4219 IPW_DL_ASSOC, "RX_AUTH_SEQ_4\n");
4220 break;
4221 case CMAS_AUTH_SEQ_2_PASS:
4222 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4223 IPW_DL_ASSOC, "AUTH_SEQ_2_PASS\n");
4224 break;
4225 case CMAS_AUTH_SEQ_2_FAIL:
4226 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4227 IPW_DL_ASSOC, "AUT_SEQ_2_FAIL\n");
4228 break;
4229 case CMAS_TX_ASSOC:
4230 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4231 IPW_DL_ASSOC, "TX_ASSOC\n");
4232 break;
4233 case CMAS_RX_ASSOC_RESP:
4234 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4235 IPW_DL_ASSOC, "RX_ASSOC_RESP\n");
b095c381 4236
0edd5b44
JG
4237 break;
4238 case CMAS_ASSOCIATED:
4239 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4240 IPW_DL_ASSOC, "ASSOCIATED\n");
4241 break;
4242 default:
4243 IPW_DEBUG_NOTIF("auth: failure - %d\n",
4244 auth->state);
4245 break;
43f66a6c 4246 }
43f66a6c
JK
4247 break;
4248 }
4249
0edd5b44
JG
4250 case HOST_NOTIFICATION_STATUS_SCAN_CHANNEL_RESULT:{
4251 struct notif_channel_result *x =
4252 &notif->u.channel_result;
43f66a6c 4253
0edd5b44
JG
4254 if (notif->size == sizeof(*x)) {
4255 IPW_DEBUG_SCAN("Scan result for channel %d\n",
4256 x->channel_num);
4257 } else {
4258 IPW_DEBUG_SCAN("Scan result of wrong size %d "
4259 "(should be %zd)\n",
4260 notif->size, sizeof(*x));
bf79451e 4261 }
43f66a6c
JK
4262 break;
4263 }
43f66a6c 4264
0edd5b44
JG
4265 case HOST_NOTIFICATION_STATUS_SCAN_COMPLETED:{
4266 struct notif_scan_complete *x = &notif->u.scan_complete;
4267 if (notif->size == sizeof(*x)) {
4268 IPW_DEBUG_SCAN
4269 ("Scan completed: type %d, %d channels, "
4270 "%d status\n", x->scan_type,
4271 x->num_channels, x->status);
4272 } else {
4273 IPW_ERROR("Scan completed of wrong size %d "
4274 "(should be %zd)\n",
4275 notif->size, sizeof(*x));
4276 }
43f66a6c 4277
0edd5b44
JG
4278 priv->status &=
4279 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
4280
4281 cancel_delayed_work(&priv->scan_check);
4282
b095c381
JK
4283 if (priv->status & STATUS_EXIT_PENDING)
4284 break;
4285
4286 priv->ieee->scans++;
4287
4288#ifdef CONFIG_IPW2200_MONITOR
4289 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
4290 queue_work(priv->workqueue,
4291 &priv->request_scan);
4292 break;
4293 }
4294#endif /* CONFIG_IPW2200_MONITOR */
4295
0edd5b44
JG
4296 if (!(priv->status & (STATUS_ASSOCIATED |
4297 STATUS_ASSOCIATING |
4298 STATUS_ROAMING |
4299 STATUS_DISASSOCIATING)))
4300 queue_work(priv->workqueue, &priv->associate);
4301 else if (priv->status & STATUS_ROAMING) {
4302 /* If a scan completed and we are in roam mode, then
4303 * the scan that completed was the one requested as a
4304 * result of entering roam... so, schedule the
4305 * roam work */
4306 queue_work(priv->workqueue, &priv->roam);
4307 } else if (priv->status & STATUS_SCAN_PENDING)
4308 queue_work(priv->workqueue,
4309 &priv->request_scan);
a613bffd
JK
4310 else if (priv->config & CFG_BACKGROUND_SCAN
4311 && priv->status & STATUS_ASSOCIATED)
4312 queue_delayed_work(priv->workqueue,
4313 &priv->request_scan, HZ);
0edd5b44 4314 break;
43f66a6c 4315 }
43f66a6c 4316
0edd5b44
JG
4317 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{
4318 struct notif_frag_length *x = &notif->u.frag_len;
43f66a6c 4319
a613bffd
JK
4320 if (notif->size == sizeof(*x))
4321 IPW_ERROR("Frag length: %d\n",
4322 le16_to_cpu(x->frag_length));
4323 else
0edd5b44
JG
4324 IPW_ERROR("Frag length of wrong size %d "
4325 "(should be %zd)\n",
4326 notif->size, sizeof(*x));
0edd5b44 4327 break;
43f66a6c 4328 }
43f66a6c 4329
0edd5b44
JG
4330 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{
4331 struct notif_link_deterioration *x =
4332 &notif->u.link_deterioration;
4333 if (notif->size == sizeof(*x)) {
4334 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4335 "link deterioration: '%s' " MAC_FMT
4336 " \n", escape_essid(priv->essid,
4337 priv->essid_len),
4338 MAC_ARG(priv->bssid));
4339 memcpy(&priv->last_link_deterioration, x,
4340 sizeof(*x));
4341 } else {
4342 IPW_ERROR("Link Deterioration of wrong size %d "
4343 "(should be %zd)\n",
4344 notif->size, sizeof(*x));
4345 }
43f66a6c
JK
4346 break;
4347 }
4348
0edd5b44
JG
4349 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{
4350 IPW_ERROR("Dino config\n");
4351 if (priv->hcmd
a613bffd 4352 && priv->hcmd->cmd != HOST_CMD_DINO_CONFIG)
0edd5b44 4353 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n");
a613bffd 4354
0edd5b44
JG
4355 break;
4356 }
43f66a6c 4357
0edd5b44
JG
4358 case HOST_NOTIFICATION_STATUS_BEACON_STATE:{
4359 struct notif_beacon_state *x = &notif->u.beacon_state;
4360 if (notif->size != sizeof(*x)) {
4361 IPW_ERROR
4362 ("Beacon state of wrong size %d (should "
4363 "be %zd)\n", notif->size, sizeof(*x));
4364 break;
43f66a6c
JK
4365 }
4366
a613bffd
JK
4367 if (le32_to_cpu(x->state) ==
4368 HOST_NOTIFICATION_STATUS_BEACON_MISSING)
4369 ipw_handle_missed_beacon(priv,
4370 le32_to_cpu(x->
4371 number));
43f66a6c 4372
0edd5b44
JG
4373 break;
4374 }
43f66a6c 4375
0edd5b44
JG
4376 case HOST_NOTIFICATION_STATUS_TGI_TX_KEY:{
4377 struct notif_tgi_tx_key *x = &notif->u.tgi_tx_key;
4378 if (notif->size == sizeof(*x)) {
4379 IPW_ERROR("TGi Tx Key: state 0x%02x sec type "
4380 "0x%02x station %d\n",
4381 x->key_state, x->security_type,
4382 x->station_index);
4383 break;
4384 }
43f66a6c 4385
0edd5b44
JG
4386 IPW_ERROR
4387 ("TGi Tx Key of wrong size %d (should be %zd)\n",
4388 notif->size, sizeof(*x));
43f66a6c 4389 break;
bf79451e 4390 }
43f66a6c 4391
0edd5b44
JG
4392 case HOST_NOTIFICATION_CALIB_KEEP_RESULTS:{
4393 struct notif_calibration *x = &notif->u.calibration;
43f66a6c 4394
0edd5b44
JG
4395 if (notif->size == sizeof(*x)) {
4396 memcpy(&priv->calib, x, sizeof(*x));
4397 IPW_DEBUG_INFO("TODO: Calibration\n");
4398 break;
4399 }
43f66a6c 4400
0edd5b44
JG
4401 IPW_ERROR
4402 ("Calibration of wrong size %d (should be %zd)\n",
4403 notif->size, sizeof(*x));
43f66a6c 4404 break;
bf79451e
JG
4405 }
4406
0edd5b44
JG
4407 case HOST_NOTIFICATION_NOISE_STATS:{
4408 if (notif->size == sizeof(u32)) {
4409 priv->last_noise =
a613bffd
JK
4410 (u8) (le32_to_cpu(notif->u.noise.value) &
4411 0xff);
0edd5b44
JG
4412 average_add(&priv->average_noise,
4413 priv->last_noise);
4414 break;
4415 }
43f66a6c 4416
0edd5b44
JG
4417 IPW_ERROR
4418 ("Noise stat is wrong size %d (should be %zd)\n",
4419 notif->size, sizeof(u32));
43f66a6c
JK
4420 break;
4421 }
4422
43f66a6c
JK
4423 default:
4424 IPW_ERROR("Unknown notification: "
4425 "subtype=%d,flags=0x%2x,size=%d\n",
4426 notif->subtype, notif->flags, notif->size);
4427 }
4428}
4429
4430/**
4431 * Destroys all DMA structures and initialise them again
bf79451e 4432 *
43f66a6c
JK
4433 * @param priv
4434 * @return error code
4435 */
4436static int ipw_queue_reset(struct ipw_priv *priv)
4437{
4438 int rc = 0;
4439 /** @todo customize queue sizes */
4440 int nTx = 64, nTxCmd = 8;
4441 ipw_tx_queue_free(priv);
4442 /* Tx CMD queue */
4443 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd,
b095c381
JK
4444 IPW_TX_CMD_QUEUE_READ_INDEX,
4445 IPW_TX_CMD_QUEUE_WRITE_INDEX,
4446 IPW_TX_CMD_QUEUE_BD_BASE,
4447 IPW_TX_CMD_QUEUE_BD_SIZE);
43f66a6c
JK
4448 if (rc) {
4449 IPW_ERROR("Tx Cmd queue init failed\n");
4450 goto error;
4451 }
4452 /* Tx queue(s) */
4453 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx,
b095c381
JK
4454 IPW_TX_QUEUE_0_READ_INDEX,
4455 IPW_TX_QUEUE_0_WRITE_INDEX,
4456 IPW_TX_QUEUE_0_BD_BASE, IPW_TX_QUEUE_0_BD_SIZE);
43f66a6c
JK
4457 if (rc) {
4458 IPW_ERROR("Tx 0 queue init failed\n");
4459 goto error;
4460 }
4461 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx,
b095c381
JK
4462 IPW_TX_QUEUE_1_READ_INDEX,
4463 IPW_TX_QUEUE_1_WRITE_INDEX,
4464 IPW_TX_QUEUE_1_BD_BASE, IPW_TX_QUEUE_1_BD_SIZE);
43f66a6c
JK
4465 if (rc) {
4466 IPW_ERROR("Tx 1 queue init failed\n");
4467 goto error;
4468 }
4469 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx,
b095c381
JK
4470 IPW_TX_QUEUE_2_READ_INDEX,
4471 IPW_TX_QUEUE_2_WRITE_INDEX,
4472 IPW_TX_QUEUE_2_BD_BASE, IPW_TX_QUEUE_2_BD_SIZE);
43f66a6c
JK
4473 if (rc) {
4474 IPW_ERROR("Tx 2 queue init failed\n");
4475 goto error;
4476 }
4477 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx,
b095c381
JK
4478 IPW_TX_QUEUE_3_READ_INDEX,
4479 IPW_TX_QUEUE_3_WRITE_INDEX,
4480 IPW_TX_QUEUE_3_BD_BASE, IPW_TX_QUEUE_3_BD_SIZE);
43f66a6c
JK
4481 if (rc) {
4482 IPW_ERROR("Tx 3 queue init failed\n");
4483 goto error;
4484 }
4485 /* statistics */
4486 priv->rx_bufs_min = 0;
4487 priv->rx_pend_max = 0;
4488 return rc;
4489
0edd5b44 4490 error:
43f66a6c
JK
4491 ipw_tx_queue_free(priv);
4492 return rc;
4493}
4494
4495/**
4496 * Reclaim Tx queue entries no more used by NIC.
bf79451e 4497 *
43f66a6c
JK
4498 * When FW adwances 'R' index, all entries between old and
4499 * new 'R' index need to be reclaimed. As result, some free space
4500 * forms. If there is enough free space (> low mark), wake Tx queue.
bf79451e 4501 *
43f66a6c
JK
4502 * @note Need to protect against garbage in 'R' index
4503 * @param priv
4504 * @param txq
4505 * @param qindex
4506 * @return Number of used entries remains in the queue
4507 */
bf79451e 4508static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
43f66a6c
JK
4509 struct clx2_tx_queue *txq, int qindex)
4510{
4511 u32 hw_tail;
4512 int used;
4513 struct clx2_queue *q = &txq->q;
4514
4515 hw_tail = ipw_read32(priv, q->reg_r);
4516 if (hw_tail >= q->n_bd) {
4517 IPW_ERROR
0edd5b44
JG
4518 ("Read index for DMA queue (%d) is out of range [0-%d)\n",
4519 hw_tail, q->n_bd);
43f66a6c
JK
4520 goto done;
4521 }
4522 for (; q->last_used != hw_tail;
4523 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {
4524 ipw_queue_tx_free_tfd(priv, txq);
4525 priv->tx_packets++;
4526 }
0edd5b44 4527 done:
a613bffd 4528 if (ipw_queue_space(q) > q->low_mark && qindex >= 0)
43f66a6c 4529 __maybe_wake_tx(priv);
43f66a6c
JK
4530 used = q->first_empty - q->last_used;
4531 if (used < 0)
4532 used += q->n_bd;
4533
4534 return used;
4535}
4536
4537static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
4538 int len, int sync)
4539{
4540 struct clx2_tx_queue *txq = &priv->txq_cmd;
4541 struct clx2_queue *q = &txq->q;
4542 struct tfd_frame *tfd;
4543
4544 if (ipw_queue_space(q) < (sync ? 1 : 2)) {
4545 IPW_ERROR("No space for Tx\n");
4546 return -EBUSY;
4547 }
4548
4549 tfd = &txq->bd[q->first_empty];
4550 txq->txb[q->first_empty] = NULL;
4551
4552 memset(tfd, 0, sizeof(*tfd));
4553 tfd->control_flags.message_type = TX_HOST_COMMAND_TYPE;
4554 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
4555 priv->hcmd_seq++;
4556 tfd->u.cmd.index = hcmd;
4557 tfd->u.cmd.length = len;
4558 memcpy(tfd->u.cmd.payload, buf, len);
4559 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
4560 ipw_write32(priv, q->reg_w, q->first_empty);
4561 _ipw_read32(priv, 0x90);
4562
4563 return 0;
4564}
4565
bf79451e 4566/*
43f66a6c
JK
4567 * Rx theory of operation
4568 *
4569 * The host allocates 32 DMA target addresses and passes the host address
b095c381 4570 * to the firmware at register IPW_RFDS_TABLE_LOWER + N * RFD_SIZE where N is
43f66a6c
JK
4571 * 0 to 31
4572 *
4573 * Rx Queue Indexes
4574 * The host/firmware share two index registers for managing the Rx buffers.
4575 *
bf79451e
JG
4576 * The READ index maps to the first position that the firmware may be writing
4577 * to -- the driver can read up to (but not including) this position and get
4578 * good data.
43f66a6c
JK
4579 * The READ index is managed by the firmware once the card is enabled.
4580 *
4581 * The WRITE index maps to the last position the driver has read from -- the
4582 * position preceding WRITE is the last slot the firmware can place a packet.
4583 *
4584 * The queue is empty (no good data) if WRITE = READ - 1, and is full if
bf79451e 4585 * WRITE = READ.
43f66a6c 4586 *
bf79451e 4587 * During initialization the host sets up the READ queue position to the first
43f66a6c
JK
4588 * INDEX position, and WRITE to the last (READ - 1 wrapped)
4589 *
4590 * When the firmware places a packet in a buffer it will advance the READ index
4591 * and fire the RX interrupt. The driver can then query the READ index and
4592 * process as many packets as possible, moving the WRITE index forward as it
4593 * resets the Rx queue buffers with new memory.
bf79451e 4594 *
43f66a6c 4595 * The management in the driver is as follows:
bf79451e 4596 * + A list of pre-allocated SKBs is stored in ipw->rxq->rx_free. When
43f66a6c 4597 * ipw->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
bf79451e 4598 * to replensish the ipw->rxq->rx_free.
43f66a6c
JK
4599 * + In ipw_rx_queue_replenish (scheduled) if 'processed' != 'read' then the
4600 * ipw->rxq is replenished and the READ INDEX is updated (updating the
4601 * 'processed' and 'read' driver indexes as well)
4602 * + A received packet is processed and handed to the kernel network stack,
4603 * detached from the ipw->rxq. The driver 'processed' index is updated.
4604 * + The Host/Firmware ipw->rxq is replenished at tasklet time from the rx_free
bf79451e
JG
4605 * list. If there are no allocated buffers in ipw->rxq->rx_free, the READ
4606 * INDEX is not incremented and ipw->status(RX_STALLED) is set. If there
43f66a6c
JK
4607 * were enough free buffers and RX_STALLED is set it is cleared.
4608 *
4609 *
4610 * Driver sequence:
4611 *
bf79451e 4612 * ipw_rx_queue_alloc() Allocates rx_free
43f66a6c
JK
4613 * ipw_rx_queue_replenish() Replenishes rx_free list from rx_used, and calls
4614 * ipw_rx_queue_restock
4615 * ipw_rx_queue_restock() Moves available buffers from rx_free into Rx
4616 * queue, updates firmware pointers, and updates
4617 * the WRITE index. If insufficient rx_free buffers
4618 * are available, schedules ipw_rx_queue_replenish
4619 *
4620 * -- enable interrupts --
4621 * ISR - ipw_rx() Detach ipw_rx_mem_buffers from pool up to the
bf79451e 4622 * READ INDEX, detaching the SKB from the pool.
43f66a6c
JK
4623 * Moves the packet buffer from queue to rx_used.
4624 * Calls ipw_rx_queue_restock to refill any empty
4625 * slots.
4626 * ...
4627 *
4628 */
4629
bf79451e 4630/*
43f66a6c
JK
4631 * If there are slots in the RX queue that need to be restocked,
4632 * and we have free pre-allocated buffers, fill the ranks as much
4633 * as we can pulling from rx_free.
4634 *
4635 * This moves the 'write' index forward to catch up with 'processed', and
4636 * also updates the memory address in the firmware to reference the new
4637 * target buffer.
4638 */
4639static void ipw_rx_queue_restock(struct ipw_priv *priv)
4640{
4641 struct ipw_rx_queue *rxq = priv->rxq;
4642 struct list_head *element;
4643 struct ipw_rx_mem_buffer *rxb;
4644 unsigned long flags;
4645 int write;
4646
4647 spin_lock_irqsave(&rxq->lock, flags);
4648 write = rxq->write;
4649 while ((rxq->write != rxq->processed) && (rxq->free_count)) {
4650 element = rxq->rx_free.next;
4651 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
4652 list_del(element);
4653
b095c381 4654 ipw_write32(priv, IPW_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE,
43f66a6c
JK
4655 rxb->dma_addr);
4656 rxq->queue[rxq->write] = rxb;
4657 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE;
4658 rxq->free_count--;
4659 }
4660 spin_unlock_irqrestore(&rxq->lock, flags);
4661
bf79451e 4662 /* If the pre-allocated buffer pool is dropping low, schedule to
43f66a6c
JK
4663 * refill it */
4664 if (rxq->free_count <= RX_LOW_WATERMARK)
4665 queue_work(priv->workqueue, &priv->rx_replenish);
4666
4667 /* If we've added more space for the firmware to place data, tell it */
bf79451e 4668 if (write != rxq->write)
b095c381 4669 ipw_write32(priv, IPW_RX_WRITE_INDEX, rxq->write);
43f66a6c
JK
4670}
4671
4672/*
4673 * Move all used packet from rx_used to rx_free, allocating a new SKB for each.
bf79451e
JG
4674 * Also restock the Rx queue via ipw_rx_queue_restock.
4675 *
43f66a6c
JK
4676 * This is called as a scheduled work item (except for during intialization)
4677 */
4678static void ipw_rx_queue_replenish(void *data)
4679{
4680 struct ipw_priv *priv = data;
4681 struct ipw_rx_queue *rxq = priv->rxq;
4682 struct list_head *element;
4683 struct ipw_rx_mem_buffer *rxb;
4684 unsigned long flags;
4685
4686 spin_lock_irqsave(&rxq->lock, flags);
4687 while (!list_empty(&rxq->rx_used)) {
4688 element = rxq->rx_used.next;
4689 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
b095c381 4690 rxb->skb = alloc_skb(IPW_RX_BUF_SIZE, GFP_ATOMIC);
43f66a6c
JK
4691 if (!rxb->skb) {
4692 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n",
4693 priv->net_dev->name);
4694 /* We don't reschedule replenish work here -- we will
4695 * call the restock method and if it still needs
4696 * more buffers it will schedule replenish */
4697 break;
4698 }
4699 list_del(element);
bf79451e 4700
43f66a6c 4701 rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data;
0edd5b44
JG
4702 rxb->dma_addr =
4703 pci_map_single(priv->pci_dev, rxb->skb->data,
b095c381 4704 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
bf79451e 4705
43f66a6c
JK
4706 list_add_tail(&rxb->list, &rxq->rx_free);
4707 rxq->free_count++;
4708 }
4709 spin_unlock_irqrestore(&rxq->lock, flags);
4710
4711 ipw_rx_queue_restock(priv);
4712}
4713
c848d0af
JK
4714static void ipw_bg_rx_queue_replenish(void *data)
4715{
4716 struct ipw_priv *priv = data;
4717 down(&priv->sem);
4718 ipw_rx_queue_replenish(data);
4719 up(&priv->sem);
4720}
4721
43f66a6c
JK
4722/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
4723 * If an SKB has been detached, the POOL needs to have it's SKB set to NULL
bf79451e 4724 * This free routine walks the list of POOL entries and if SKB is set to
43f66a6c
JK
4725 * non NULL it is unmapped and freed
4726 */
0edd5b44 4727static void ipw_rx_queue_free(struct ipw_priv *priv, struct ipw_rx_queue *rxq)
43f66a6c
JK
4728{
4729 int i;
4730
4731 if (!rxq)
4732 return;
bf79451e 4733
43f66a6c
JK
4734 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
4735 if (rxq->pool[i].skb != NULL) {
4736 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
b095c381 4737 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
43f66a6c
JK
4738 dev_kfree_skb(rxq->pool[i].skb);
4739 }
4740 }
4741
4742 kfree(rxq);
4743}
4744
4745static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv)
4746{
4747 struct ipw_rx_queue *rxq;
4748 int i;
4749
4750 rxq = (struct ipw_rx_queue *)kmalloc(sizeof(*rxq), GFP_KERNEL);
ad18b0ea
PI
4751 if (unlikely(!rxq)) {
4752 IPW_ERROR("memory allocation failed\n");
4753 return NULL;
4754 }
43f66a6c
JK
4755 memset(rxq, 0, sizeof(*rxq));
4756 spin_lock_init(&rxq->lock);
4757 INIT_LIST_HEAD(&rxq->rx_free);
4758 INIT_LIST_HEAD(&rxq->rx_used);
4759
4760 /* Fill the rx_used queue with _all_ of the Rx buffers */
bf79451e 4761 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
43f66a6c
JK
4762 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
4763
4764 /* Set us so that we have processed and used all buffers, but have
4765 * not restocked the Rx queue with fresh buffers */
4766 rxq->read = rxq->write = 0;
4767 rxq->processed = RX_QUEUE_SIZE - 1;
4768 rxq->free_count = 0;
4769
4770 return rxq;
4771}
4772
4773static int ipw_is_rate_in_mask(struct ipw_priv *priv, int ieee_mode, u8 rate)
4774{
4775 rate &= ~IEEE80211_BASIC_RATE_MASK;
4776 if (ieee_mode == IEEE_A) {
4777 switch (rate) {
bf79451e
JG
4778 case IEEE80211_OFDM_RATE_6MB:
4779 return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ?
0edd5b44 4780 1 : 0;
bf79451e
JG
4781 case IEEE80211_OFDM_RATE_9MB:
4782 return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ?
0edd5b44 4783 1 : 0;
bf79451e 4784 case IEEE80211_OFDM_RATE_12MB:
0edd5b44
JG
4785 return priv->
4786 rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ? 1 : 0;
bf79451e 4787 case IEEE80211_OFDM_RATE_18MB:
0edd5b44
JG
4788 return priv->
4789 rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ? 1 : 0;
bf79451e 4790 case IEEE80211_OFDM_RATE_24MB:
0edd5b44
JG
4791 return priv->
4792 rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ? 1 : 0;
bf79451e 4793 case IEEE80211_OFDM_RATE_36MB:
0edd5b44
JG
4794 return priv->
4795 rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ? 1 : 0;
bf79451e 4796 case IEEE80211_OFDM_RATE_48MB:
0edd5b44
JG
4797 return priv->
4798 rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ? 1 : 0;
bf79451e 4799 case IEEE80211_OFDM_RATE_54MB:
0edd5b44
JG
4800 return priv->
4801 rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ? 1 : 0;
43f66a6c
JK
4802 default:
4803 return 0;
4804 }
4805 }
bf79451e 4806
43f66a6c
JK
4807 /* B and G mixed */
4808 switch (rate) {
bf79451e 4809 case IEEE80211_CCK_RATE_1MB:
43f66a6c 4810 return priv->rates_mask & IEEE80211_CCK_RATE_1MB_MASK ? 1 : 0;
bf79451e 4811 case IEEE80211_CCK_RATE_2MB:
43f66a6c 4812 return priv->rates_mask & IEEE80211_CCK_RATE_2MB_MASK ? 1 : 0;
bf79451e 4813 case IEEE80211_CCK_RATE_5MB:
43f66a6c 4814 return priv->rates_mask & IEEE80211_CCK_RATE_5MB_MASK ? 1 : 0;
bf79451e 4815 case IEEE80211_CCK_RATE_11MB:
43f66a6c
JK
4816 return priv->rates_mask & IEEE80211_CCK_RATE_11MB_MASK ? 1 : 0;
4817 }
4818
4819 /* If we are limited to B modulations, bail at this point */
4820 if (ieee_mode == IEEE_B)
4821 return 0;
4822
4823 /* G */
4824 switch (rate) {
bf79451e 4825 case IEEE80211_OFDM_RATE_6MB:
43f66a6c 4826 return priv->rates_mask & IEEE80211_OFDM_RATE_6MB_MASK ? 1 : 0;
bf79451e 4827 case IEEE80211_OFDM_RATE_9MB:
43f66a6c 4828 return priv->rates_mask & IEEE80211_OFDM_RATE_9MB_MASK ? 1 : 0;
bf79451e 4829 case IEEE80211_OFDM_RATE_12MB:
43f66a6c 4830 return priv->rates_mask & IEEE80211_OFDM_RATE_12MB_MASK ? 1 : 0;
bf79451e 4831 case IEEE80211_OFDM_RATE_18MB:
43f66a6c 4832 return priv->rates_mask & IEEE80211_OFDM_RATE_18MB_MASK ? 1 : 0;
bf79451e 4833 case IEEE80211_OFDM_RATE_24MB:
43f66a6c 4834 return priv->rates_mask & IEEE80211_OFDM_RATE_24MB_MASK ? 1 : 0;
bf79451e 4835 case IEEE80211_OFDM_RATE_36MB:
43f66a6c 4836 return priv->rates_mask & IEEE80211_OFDM_RATE_36MB_MASK ? 1 : 0;
bf79451e 4837 case IEEE80211_OFDM_RATE_48MB:
43f66a6c 4838 return priv->rates_mask & IEEE80211_OFDM_RATE_48MB_MASK ? 1 : 0;
bf79451e 4839 case IEEE80211_OFDM_RATE_54MB:
43f66a6c
JK
4840 return priv->rates_mask & IEEE80211_OFDM_RATE_54MB_MASK ? 1 : 0;
4841 }
4842
4843 return 0;
4844}
4845
bf79451e 4846static int ipw_compatible_rates(struct ipw_priv *priv,
43f66a6c
JK
4847 const struct ieee80211_network *network,
4848 struct ipw_supported_rates *rates)
4849{
4850 int num_rates, i;
4851
4852 memset(rates, 0, sizeof(*rates));
0edd5b44 4853 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES);
43f66a6c
JK
4854 rates->num_rates = 0;
4855 for (i = 0; i < num_rates; i++) {
a613bffd
JK
4856 if (!ipw_is_rate_in_mask(priv, network->mode,
4857 network->rates[i])) {
4858
ea2b26e0 4859 if (network->rates[i] & IEEE80211_BASIC_RATE_MASK) {
a613bffd
JK
4860 IPW_DEBUG_SCAN("Adding masked mandatory "
4861 "rate %02X\n",
4862 network->rates[i]);
4863 rates->supported_rates[rates->num_rates++] =
4864 network->rates[i];
4865 continue;
ea2b26e0
JK
4866 }
4867
43f66a6c
JK
4868 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4869 network->rates[i], priv->rates_mask);
4870 continue;
4871 }
bf79451e 4872
43f66a6c
JK
4873 rates->supported_rates[rates->num_rates++] = network->rates[i];
4874 }
4875
a613bffd
JK
4876 num_rates = min(network->rates_ex_len,
4877 (u8) (IPW_MAX_RATES - num_rates));
43f66a6c 4878 for (i = 0; i < num_rates; i++) {
a613bffd
JK
4879 if (!ipw_is_rate_in_mask(priv, network->mode,
4880 network->rates_ex[i])) {
ea2b26e0 4881 if (network->rates_ex[i] & IEEE80211_BASIC_RATE_MASK) {
a613bffd
JK
4882 IPW_DEBUG_SCAN("Adding masked mandatory "
4883 "rate %02X\n",
4884 network->rates_ex[i]);
4885 rates->supported_rates[rates->num_rates++] =
4886 network->rates[i];
4887 continue;
ea2b26e0
JK
4888 }
4889
43f66a6c
JK
4890 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4891 network->rates_ex[i], priv->rates_mask);
4892 continue;
4893 }
bf79451e 4894
0edd5b44
JG
4895 rates->supported_rates[rates->num_rates++] =
4896 network->rates_ex[i];
43f66a6c
JK
4897 }
4898
ea2b26e0 4899 return 1;
43f66a6c
JK
4900}
4901
4902static inline void ipw_copy_rates(struct ipw_supported_rates *dest,
4903 const struct ipw_supported_rates *src)
4904{
4905 u8 i;
4906 for (i = 0; i < src->num_rates; i++)
4907 dest->supported_rates[i] = src->supported_rates[i];
4908 dest->num_rates = src->num_rates;
4909}
4910
4911/* TODO: Look at sniffed packets in the air to determine if the basic rate
4912 * mask should ever be used -- right now all callers to add the scan rates are
4913 * set with the modulation = CCK, so BASIC_RATE_MASK is never set... */
4914static void ipw_add_cck_scan_rates(struct ipw_supported_rates *rates,
0edd5b44 4915 u8 modulation, u32 rate_mask)
43f66a6c 4916{
bf79451e 4917 u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ?
0edd5b44 4918 IEEE80211_BASIC_RATE_MASK : 0;
bf79451e 4919
43f66a6c 4920 if (rate_mask & IEEE80211_CCK_RATE_1MB_MASK)
bf79451e 4921 rates->supported_rates[rates->num_rates++] =
0edd5b44 4922 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
43f66a6c
JK
4923
4924 if (rate_mask & IEEE80211_CCK_RATE_2MB_MASK)
bf79451e 4925 rates->supported_rates[rates->num_rates++] =
0edd5b44 4926 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
43f66a6c
JK
4927
4928 if (rate_mask & IEEE80211_CCK_RATE_5MB_MASK)
bf79451e 4929 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 4930 IEEE80211_CCK_RATE_5MB;
43f66a6c
JK
4931
4932 if (rate_mask & IEEE80211_CCK_RATE_11MB_MASK)
bf79451e 4933 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 4934 IEEE80211_CCK_RATE_11MB;
43f66a6c
JK
4935}
4936
4937static void ipw_add_ofdm_scan_rates(struct ipw_supported_rates *rates,
0edd5b44 4938 u8 modulation, u32 rate_mask)
43f66a6c 4939{
bf79451e 4940 u8 basic_mask = (IEEE80211_OFDM_MODULATION == modulation) ?
0edd5b44 4941 IEEE80211_BASIC_RATE_MASK : 0;
43f66a6c
JK
4942
4943 if (rate_mask & IEEE80211_OFDM_RATE_6MB_MASK)
bf79451e 4944 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 4945 IEEE80211_OFDM_RATE_6MB;
43f66a6c
JK
4946
4947 if (rate_mask & IEEE80211_OFDM_RATE_9MB_MASK)
bf79451e 4948 rates->supported_rates[rates->num_rates++] =
0edd5b44 4949 IEEE80211_OFDM_RATE_9MB;
43f66a6c
JK
4950
4951 if (rate_mask & IEEE80211_OFDM_RATE_12MB_MASK)
bf79451e 4952 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 4953 IEEE80211_OFDM_RATE_12MB;
43f66a6c
JK
4954
4955 if (rate_mask & IEEE80211_OFDM_RATE_18MB_MASK)
bf79451e 4956 rates->supported_rates[rates->num_rates++] =
0edd5b44 4957 IEEE80211_OFDM_RATE_18MB;
43f66a6c
JK
4958
4959 if (rate_mask & IEEE80211_OFDM_RATE_24MB_MASK)
bf79451e 4960 rates->supported_rates[rates->num_rates++] = basic_mask |
0edd5b44 4961 IEEE80211_OFDM_RATE_24MB;
43f66a6c
JK
4962
4963 if (rate_mask & IEEE80211_OFDM_RATE_36MB_MASK)
bf79451e 4964 rates->supported_rates[rates->num_rates++] =
0edd5b44 4965 IEEE80211_OFDM_RATE_36MB;
43f66a6c
JK
4966
4967 if (rate_mask & IEEE80211_OFDM_RATE_48MB_MASK)
bf79451e 4968 rates->supported_rates[rates->num_rates++] =
0edd5b44 4969 IEEE80211_OFDM_RATE_48MB;
43f66a6c
JK
4970
4971 if (rate_mask & IEEE80211_OFDM_RATE_54MB_MASK)
bf79451e 4972 rates->supported_rates[rates->num_rates++] =
0edd5b44 4973 IEEE80211_OFDM_RATE_54MB;
43f66a6c
JK
4974}
4975
4976struct ipw_network_match {
4977 struct ieee80211_network *network;
4978 struct ipw_supported_rates rates;
4979};
4980
c848d0af
JK
4981static int ipw_find_adhoc_network(struct ipw_priv *priv,
4982 struct ipw_network_match *match,
4983 struct ieee80211_network *network,
4984 int roaming)
4985{
4986 struct ipw_supported_rates rates;
4987
4988 /* Verify that this network's capability is compatible with the
4989 * current mode (AdHoc or Infrastructure) */
4990 if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
4991 !(network->capability & WLAN_CAPABILITY_IBSS))) {
4992 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded due to "
4993 "capability mismatch.\n",
4994 escape_essid(network->ssid, network->ssid_len),
4995 MAC_ARG(network->bssid));
4996 return 0;
4997 }
4998
4999 /* If we do not have an ESSID for this AP, we can not associate with
5000 * it */
5001 if (network->flags & NETWORK_EMPTY_ESSID) {
5002 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5003 "because of hidden ESSID.\n",
5004 escape_essid(network->ssid, network->ssid_len),
5005 MAC_ARG(network->bssid));
5006 return 0;
5007 }
5008
5009 if (unlikely(roaming)) {
5010 /* If we are roaming, then ensure check if this is a valid
5011 * network to try and roam to */
5012 if ((network->ssid_len != match->network->ssid_len) ||
5013 memcmp(network->ssid, match->network->ssid,
5014 network->ssid_len)) {
5015 IPW_DEBUG_MERGE("Netowrk '%s (" MAC_FMT ")' excluded "
5016 "because of non-network ESSID.\n",
5017 escape_essid(network->ssid,
5018 network->ssid_len),
5019 MAC_ARG(network->bssid));
5020 return 0;
5021 }
5022 } else {
5023 /* If an ESSID has been configured then compare the broadcast
5024 * ESSID to ours */
5025 if ((priv->config & CFG_STATIC_ESSID) &&
5026 ((network->ssid_len != priv->essid_len) ||
5027 memcmp(network->ssid, priv->essid,
5028 min(network->ssid_len, priv->essid_len)))) {
5029 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
5030 strncpy(escaped,
5031 escape_essid(network->ssid, network->ssid_len),
5032 sizeof(escaped));
5033 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5034 "because of ESSID mismatch: '%s'.\n",
5035 escaped, MAC_ARG(network->bssid),
5036 escape_essid(priv->essid,
5037 priv->essid_len));
5038 return 0;
5039 }
5040 }
5041
5042 /* If the old network rate is better than this one, don't bother
5043 * testing everything else. */
5044
5045 if (network->time_stamp[0] < match->network->time_stamp[0]) {
5046 IPW_DEBUG_MERGE
5047 ("Network '%s excluded because newer than current network.\n",
5048 escape_essid(match->network->ssid,
5049 match->network->ssid_len));
5050 return 0;
5051 } else if (network->time_stamp[1] < match->network->time_stamp[1]) {
5052 IPW_DEBUG_MERGE
5053 ("Network '%s excluded because newer than current network.\n",
5054 escape_essid(match->network->ssid,
5055 match->network->ssid_len));
5056 return 0;
5057 }
5058
5059 /* Now go through and see if the requested network is valid... */
5060 if (priv->ieee->scan_age != 0 &&
5061 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
5062 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5063 "because of age: %lums.\n",
5064 escape_essid(network->ssid, network->ssid_len),
5065 MAC_ARG(network->bssid),
5066 (jiffies - network->last_scanned) / (HZ / 100));
5067 return 0;
5068 }
5069
5070 if ((priv->config & CFG_STATIC_CHANNEL) &&
5071 (network->channel != priv->channel)) {
5072 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5073 "because of channel mismatch: %d != %d.\n",
5074 escape_essid(network->ssid, network->ssid_len),
5075 MAC_ARG(network->bssid),
5076 network->channel, priv->channel);
5077 return 0;
5078 }
5079
5080 /* Verify privacy compatability */
5081 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
5082 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
5083 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5084 "because of privacy mismatch: %s != %s.\n",
5085 escape_essid(network->ssid, network->ssid_len),
5086 MAC_ARG(network->bssid),
5087 priv->capability & CAP_PRIVACY_ON ? "on" :
5088 "off",
5089 network->capability &
5090 WLAN_CAPABILITY_PRIVACY ? "on" : "off");
5091 return 0;
5092 }
5093
5094 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
5095 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5096 "because of the same BSSID match: " MAC_FMT
5097 ".\n", escape_essid(network->ssid,
5098 network->ssid_len),
5099 MAC_ARG(network->bssid), MAC_ARG(priv->bssid));
5100 return 0;
5101 }
5102
5103 /* Filter out any incompatible freq / mode combinations */
5104 if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
5105 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5106 "because of invalid frequency/mode "
5107 "combination.\n",
5108 escape_essid(network->ssid, network->ssid_len),
5109 MAC_ARG(network->bssid));
5110 return 0;
5111 }
5112
5113 /* Ensure that the rates supported by the driver are compatible with
5114 * this AP, including verification of basic rates (mandatory) */
5115 if (!ipw_compatible_rates(priv, network, &rates)) {
5116 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5117 "because configured rate mask excludes "
5118 "AP mandatory rate.\n",
5119 escape_essid(network->ssid, network->ssid_len),
5120 MAC_ARG(network->bssid));
5121 return 0;
5122 }
5123
5124 if (rates.num_rates == 0) {
5125 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5126 "because of no compatible rates.\n",
5127 escape_essid(network->ssid, network->ssid_len),
5128 MAC_ARG(network->bssid));
5129 return 0;
5130 }
5131
5132 /* TODO: Perform any further minimal comparititive tests. We do not
5133 * want to put too much policy logic here; intelligent scan selection
5134 * should occur within a generic IEEE 802.11 user space tool. */
5135
5136 /* Set up 'new' AP to this network */
5137 ipw_copy_rates(&match->rates, &rates);
5138 match->network = network;
5139 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' is a viable match.\n",
5140 escape_essid(network->ssid, network->ssid_len),
5141 MAC_ARG(network->bssid));
5142
5143 return 1;
5144}
5145
5146static void ipw_merge_adhoc_network(void *data)
5147{
5148 struct ipw_priv *priv = data;
5149 struct ieee80211_network *network = NULL;
5150 struct ipw_network_match match = {
5151 .network = priv->assoc_network
5152 };
5153
5154 if ((priv->status & STATUS_ASSOCIATED)
5155 && (priv->ieee->iw_mode == IW_MODE_ADHOC)) {
5156 /* First pass through ROAM process -- look for a better
5157 * network */
5158 unsigned long flags;
5159
5160 spin_lock_irqsave(&priv->ieee->lock, flags);
5161 list_for_each_entry(network, &priv->ieee->network_list, list) {
5162 if (network != priv->assoc_network)
5163 ipw_find_adhoc_network(priv, &match, network,
5164 1);
5165 }
5166 spin_unlock_irqrestore(&priv->ieee->lock, flags);
5167
5168 if (match.network == priv->assoc_network) {
5169 IPW_DEBUG_MERGE("No better ADHOC in this network to "
5170 "merge to.\n");
5171 return;
5172 }
5173
5174 down(&priv->sem);
5175 if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
5176 IPW_DEBUG_MERGE("remove network %s\n",
5177 escape_essid(priv->essid,
5178 priv->essid_len));
5179 ipw_remove_current_network(priv);
5180 }
5181
5182 ipw_disassociate(priv);
5183 priv->assoc_network = match.network;
5184 up(&priv->sem);
5185 return;
5186 }
5187
5188}
5189
0edd5b44
JG
5190static int ipw_best_network(struct ipw_priv *priv,
5191 struct ipw_network_match *match,
5192 struct ieee80211_network *network, int roaming)
43f66a6c
JK
5193{
5194 struct ipw_supported_rates rates;
5195
5196 /* Verify that this network's capability is compatible with the
5197 * current mode (AdHoc or Infrastructure) */
5198 if ((priv->ieee->iw_mode == IW_MODE_INFRA &&
2474385e 5199 !(network->capability & WLAN_CAPABILITY_ESS)) ||
43f66a6c
JK
5200 (priv->ieee->iw_mode == IW_MODE_ADHOC &&
5201 !(network->capability & WLAN_CAPABILITY_IBSS))) {
5202 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded due to "
bf79451e 5203 "capability mismatch.\n",
43f66a6c
JK
5204 escape_essid(network->ssid, network->ssid_len),
5205 MAC_ARG(network->bssid));
5206 return 0;
5207 }
5208
5209 /* If we do not have an ESSID for this AP, we can not associate with
5210 * it */
5211 if (network->flags & NETWORK_EMPTY_ESSID) {
5212 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5213 "because of hidden ESSID.\n",
5214 escape_essid(network->ssid, network->ssid_len),
5215 MAC_ARG(network->bssid));
5216 return 0;
5217 }
bf79451e 5218
43f66a6c
JK
5219 if (unlikely(roaming)) {
5220 /* If we are roaming, then ensure check if this is a valid
5221 * network to try and roam to */
5222 if ((network->ssid_len != match->network->ssid_len) ||
bf79451e 5223 memcmp(network->ssid, match->network->ssid,
43f66a6c
JK
5224 network->ssid_len)) {
5225 IPW_DEBUG_ASSOC("Netowrk '%s (" MAC_FMT ")' excluded "
5226 "because of non-network ESSID.\n",
bf79451e 5227 escape_essid(network->ssid,
43f66a6c
JK
5228 network->ssid_len),
5229 MAC_ARG(network->bssid));
5230 return 0;
5231 }
5232 } else {
bf79451e
JG
5233 /* If an ESSID has been configured then compare the broadcast
5234 * ESSID to ours */
5235 if ((priv->config & CFG_STATIC_ESSID) &&
43f66a6c 5236 ((network->ssid_len != priv->essid_len) ||
bf79451e 5237 memcmp(network->ssid, priv->essid,
43f66a6c
JK
5238 min(network->ssid_len, priv->essid_len)))) {
5239 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
0edd5b44
JG
5240 strncpy(escaped,
5241 escape_essid(network->ssid, network->ssid_len),
43f66a6c
JK
5242 sizeof(escaped));
5243 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
bf79451e 5244 "because of ESSID mismatch: '%s'.\n",
43f66a6c 5245 escaped, MAC_ARG(network->bssid),
0edd5b44
JG
5246 escape_essid(priv->essid,
5247 priv->essid_len));
43f66a6c
JK
5248 return 0;
5249 }
5250 }
5251
5252 /* If the old network rate is better than this one, don't bother
5253 * testing everything else. */
0edd5b44 5254 if (match->network && match->network->stats.rssi > network->stats.rssi) {
43f66a6c 5255 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
bf79451e
JG
5256 strncpy(escaped,
5257 escape_essid(network->ssid, network->ssid_len),
43f66a6c
JK
5258 sizeof(escaped));
5259 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded because "
5260 "'%s (" MAC_FMT ")' has a stronger signal.\n",
5261 escaped, MAC_ARG(network->bssid),
5262 escape_essid(match->network->ssid,
5263 match->network->ssid_len),
5264 MAC_ARG(match->network->bssid));
5265 return 0;
5266 }
bf79451e 5267
43f66a6c
JK
5268 /* If this network has already had an association attempt within the
5269 * last 3 seconds, do not try and associate again... */
5270 if (network->last_associate &&
ea2b26e0 5271 time_after(network->last_associate + (HZ * 3UL), jiffies)) {
43f66a6c
JK
5272 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5273 "because of storming (%lu since last "
5274 "assoc attempt).\n",
5275 escape_essid(network->ssid, network->ssid_len),
5276 MAC_ARG(network->bssid),
5277 (jiffies - network->last_associate) / HZ);
5278 return 0;
5279 }
5280
5281 /* Now go through and see if the requested network is valid... */
bf79451e 5282 if (priv->ieee->scan_age != 0 &&
ea2b26e0 5283 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
43f66a6c
JK
5284 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5285 "because of age: %lums.\n",
5286 escape_essid(network->ssid, network->ssid_len),
5287 MAC_ARG(network->bssid),
5288 (jiffies - network->last_scanned) / (HZ / 100));
5289 return 0;
bf79451e 5290 }
43f66a6c 5291
bf79451e 5292 if ((priv->config & CFG_STATIC_CHANNEL) &&
43f66a6c
JK
5293 (network->channel != priv->channel)) {
5294 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5295 "because of channel mismatch: %d != %d.\n",
5296 escape_essid(network->ssid, network->ssid_len),
5297 MAC_ARG(network->bssid),
5298 network->channel, priv->channel);
5299 return 0;
5300 }
bf79451e 5301
43f66a6c 5302 /* Verify privacy compatability */
bf79451e 5303 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
43f66a6c
JK
5304 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
5305 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5306 "because of privacy mismatch: %s != %s.\n",
5307 escape_essid(network->ssid, network->ssid_len),
5308 MAC_ARG(network->bssid),
bf79451e 5309 priv->capability & CAP_PRIVACY_ON ? "on" :
43f66a6c 5310 "off",
bf79451e 5311 network->capability &
0edd5b44 5312 WLAN_CAPABILITY_PRIVACY ? "on" : "off");
43f66a6c
JK
5313 return 0;
5314 }
bf79451e
JG
5315
5316 if ((priv->config & CFG_STATIC_BSSID) &&
43f66a6c
JK
5317 memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
5318 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5319 "because of BSSID mismatch: " MAC_FMT ".\n",
5320 escape_essid(network->ssid, network->ssid_len),
0edd5b44 5321 MAC_ARG(network->bssid), MAC_ARG(priv->bssid));
43f66a6c
JK
5322 return 0;
5323 }
bf79451e 5324
43f66a6c
JK
5325 /* Filter out any incompatible freq / mode combinations */
5326 if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
5327 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5328 "because of invalid frequency/mode "
5329 "combination.\n",
5330 escape_essid(network->ssid, network->ssid_len),
5331 MAC_ARG(network->bssid));
5332 return 0;
5333 }
bf79451e 5334
ea2b26e0
JK
5335 /* Ensure that the rates supported by the driver are compatible with
5336 * this AP, including verification of basic rates (mandatory) */
5337 if (!ipw_compatible_rates(priv, network, &rates)) {
5338 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5339 "because configured rate mask excludes "
5340 "AP mandatory rate.\n",
5341 escape_essid(network->ssid, network->ssid_len),
5342 MAC_ARG(network->bssid));
5343 return 0;
5344 }
5345
43f66a6c
JK
5346 if (rates.num_rates == 0) {
5347 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5348 "because of no compatible rates.\n",
5349 escape_essid(network->ssid, network->ssid_len),
5350 MAC_ARG(network->bssid));
5351 return 0;
5352 }
bf79451e 5353
43f66a6c
JK
5354 /* TODO: Perform any further minimal comparititive tests. We do not
5355 * want to put too much policy logic here; intelligent scan selection
5356 * should occur within a generic IEEE 802.11 user space tool. */
5357
5358 /* Set up 'new' AP to this network */
5359 ipw_copy_rates(&match->rates, &rates);
5360 match->network = network;
5361
5362 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' is a viable match.\n",
5363 escape_essid(network->ssid, network->ssid_len),
5364 MAC_ARG(network->bssid));
5365
5366 return 1;
5367}
5368
bf79451e 5369static void ipw_adhoc_create(struct ipw_priv *priv,
0edd5b44 5370 struct ieee80211_network *network)
43f66a6c
JK
5371{
5372 /*
5373 * For the purposes of scanning, we can set our wireless mode
5374 * to trigger scans across combinations of bands, but when it
5375 * comes to creating a new ad-hoc network, we have tell the FW
5376 * exactly which band to use.
5377 *
bf79451e 5378 * We also have the possibility of an invalid channel for the
43f66a6c
JK
5379 * chossen band. Attempting to create a new ad-hoc network
5380 * with an invalid channel for wireless mode will trigger a
5381 * FW fatal error.
5382 */
b095c381
JK
5383 if (!ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
5384 const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
43f66a6c
JK
5385 IPW_WARNING("Overriding invalid channel\n");
5386 if (priv->ieee->mode & IEEE_A) {
5387 network->mode = IEEE_A;
b095c381 5388 priv->channel = geo->a[0].channel;
43f66a6c
JK
5389 } else if (priv->ieee->mode & IEEE_G) {
5390 network->mode = IEEE_G;
b095c381 5391 priv->channel = geo->bg[0].channel;
43f66a6c
JK
5392 } else {
5393 network->mode = IEEE_B;
b095c381 5394 priv->channel = geo->bg[0].channel;
43f66a6c 5395 }
b095c381
JK
5396 } else
5397 network->mode = priv->ieee->mode;
43f66a6c
JK
5398
5399 network->channel = priv->channel;
5400 priv->config |= CFG_ADHOC_PERSIST;
5401 ipw_create_bssid(priv, network->bssid);
5402 network->ssid_len = priv->essid_len;
5403 memcpy(network->ssid, priv->essid, priv->essid_len);
5404 memset(&network->stats, 0, sizeof(network->stats));
5405 network->capability = WLAN_CAPABILITY_IBSS;
ea2b26e0
JK
5406 if (!(priv->config & CFG_PREAMBLE_LONG))
5407 network->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
43f66a6c
JK
5408 if (priv->capability & CAP_PRIVACY_ON)
5409 network->capability |= WLAN_CAPABILITY_PRIVACY;
5410 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH);
0edd5b44 5411 memcpy(network->rates, priv->rates.supported_rates, network->rates_len);
43f66a6c 5412 network->rates_ex_len = priv->rates.num_rates - network->rates_len;
bf79451e 5413 memcpy(network->rates_ex,
43f66a6c
JK
5414 &priv->rates.supported_rates[network->rates_len],
5415 network->rates_ex_len);
5416 network->last_scanned = 0;
5417 network->flags = 0;
5418 network->last_associate = 0;
5419 network->time_stamp[0] = 0;
5420 network->time_stamp[1] = 0;
0edd5b44
JG
5421 network->beacon_interval = 100; /* Default */
5422 network->listen_interval = 10; /* Default */
5423 network->atim_window = 0; /* Default */
43f66a6c
JK
5424 network->wpa_ie_len = 0;
5425 network->rsn_ie_len = 0;
43f66a6c
JK
5426}
5427
b095c381
JK
5428static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)
5429{
5430 struct ipw_tgi_tx_key *key;
5431 struct host_cmd cmd = {
5432 .cmd = IPW_CMD_TGI_TX_KEY,
5433 .len = sizeof(*key)
5434 };
5435
5436 if (!(priv->ieee->sec.flags & (1 << index)))
5437 return;
5438
5439 key = (struct ipw_tgi_tx_key *)&cmd.param;
5440 key->key_id = index;
5441 memcpy(key->key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);
5442 key->security_type = type;
5443 key->station_index = 0; /* always 0 for BSS */
5444 key->flags = 0;
5445 /* 0 for new key; previous value of counter (after fatal error) */
5446 key->tx_counter[0] = 0;
5447 key->tx_counter[1] = 0;
5448
5449 if (ipw_send_cmd(priv, &cmd)) {
5450 IPW_ERROR("failed to send TGI_TX_KEY command\n");
5451 return;
5452 }
5453}
5454
5455static void ipw_send_wep_keys(struct ipw_priv *priv, int type)
43f66a6c
JK
5456{
5457 struct ipw_wep_key *key;
5458 int i;
5459 struct host_cmd cmd = {
5460 .cmd = IPW_CMD_WEP_KEY,
5461 .len = sizeof(*key)
5462 };
5463
5464 key = (struct ipw_wep_key *)&cmd.param;
5465 key->cmd_id = DINO_CMD_WEP_KEY;
5466 key->seq_num = 0;
5467
b095c381
JK
5468 /* Note: AES keys cannot be set for multiple times.
5469 * Only set it at the first time. */
bf79451e 5470 for (i = 0; i < 4; i++) {
b095c381
JK
5471 key->key_index = i | type;
5472 if (!(priv->ieee->sec.flags & (1 << i))) {
43f66a6c 5473 key->key_size = 0;
b095c381 5474 continue;
43f66a6c
JK
5475 }
5476
b095c381
JK
5477 key->key_size = priv->ieee->sec.key_sizes[i];
5478 memcpy(key->key, priv->ieee->sec.keys[i], key->key_size);
5479
43f66a6c
JK
5480 if (ipw_send_cmd(priv, &cmd)) {
5481 IPW_ERROR("failed to send WEP_KEY command\n");
5482 return;
5483 }
bf79451e 5484 }
43f66a6c
JK
5485}
5486
b095c381
JK
5487static void ipw_set_hwcrypto_keys(struct ipw_priv *priv)
5488{
5489 switch (priv->ieee->sec.level) {
5490 case SEC_LEVEL_3:
5491 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
5492 ipw_send_tgi_tx_key(priv,
5493 DCT_FLAG_EXT_SECURITY_CCM,
5494 priv->ieee->sec.active_key);
5495 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);
5496
5497 priv->sys_config.disable_unicast_decryption = 0;
5498 priv->sys_config.disable_multicast_decryption = 0;
5499 priv->ieee->host_decrypt = 0;
5500 if (ipw_send_system_config(priv, &priv->sys_config))
5501 IPW_ERROR("ipw_send_system_config failed\n");
5502
5503 break;
5504 case SEC_LEVEL_2:
5505 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
5506 ipw_send_tgi_tx_key(priv,
5507 DCT_FLAG_EXT_SECURITY_TKIP,
5508 priv->ieee->sec.active_key);
5509
5510 priv->sys_config.disable_unicast_decryption = 1;
5511 priv->sys_config.disable_multicast_decryption = 1;
5512 priv->ieee->host_decrypt = 1;
5513 if (ipw_send_system_config(priv, &priv->sys_config))
5514 IPW_ERROR("ipw_send_system_config failed\n");
5515
5516 break;
5517 case SEC_LEVEL_1:
5518 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
5519
5520 priv->sys_config.disable_unicast_decryption = 0;
5521 priv->sys_config.disable_multicast_decryption = 0;
5522 priv->ieee->host_decrypt = 0;
5523 if (ipw_send_system_config(priv, &priv->sys_config))
5524 IPW_ERROR("ipw_send_system_config failed\n");
5525
5526 break;
5527 case SEC_LEVEL_0:
5528 default:
5529 break;
5530 }
5531}
5532
43f66a6c
JK
5533static void ipw_adhoc_check(void *data)
5534{
5535 struct ipw_priv *priv = data;
bf79451e 5536
43f66a6c
JK
5537 if (priv->missed_adhoc_beacons++ > priv->missed_beacon_threshold &&
5538 !(priv->config & CFG_ADHOC_PERSIST)) {
5539 IPW_DEBUG_SCAN("Disassociating due to missed beacons\n");
5540 ipw_remove_current_network(priv);
5541 ipw_disassociate(priv);
5542 return;
5543 }
5544
bf79451e 5545 queue_delayed_work(priv->workqueue, &priv->adhoc_check,
43f66a6c
JK
5546 priv->assoc_request.beacon_interval);
5547}
5548
c848d0af
JK
5549static void ipw_bg_adhoc_check(void *data)
5550{
5551 struct ipw_priv *priv = data;
5552 down(&priv->sem);
5553 ipw_adhoc_check(data);
5554 up(&priv->sem);
5555}
5556
43f66a6c
JK
5557#ifdef CONFIG_IPW_DEBUG
5558static void ipw_debug_config(struct ipw_priv *priv)
5559{
5560 IPW_DEBUG_INFO("Scan completed, no valid APs matched "
5561 "[CFG 0x%08X]\n", priv->config);
5562 if (priv->config & CFG_STATIC_CHANNEL)
0edd5b44 5563 IPW_DEBUG_INFO("Channel locked to %d\n", priv->channel);
43f66a6c
JK
5564 else
5565 IPW_DEBUG_INFO("Channel unlocked.\n");
5566 if (priv->config & CFG_STATIC_ESSID)
bf79451e 5567 IPW_DEBUG_INFO("ESSID locked to '%s'\n",
0edd5b44 5568 escape_essid(priv->essid, priv->essid_len));
43f66a6c
JK
5569 else
5570 IPW_DEBUG_INFO("ESSID unlocked.\n");
5571 if (priv->config & CFG_STATIC_BSSID)
ea2b26e0
JK
5572 IPW_DEBUG_INFO("BSSID locked to " MAC_FMT "\n",
5573 MAC_ARG(priv->bssid));
43f66a6c
JK
5574 else
5575 IPW_DEBUG_INFO("BSSID unlocked.\n");
5576 if (priv->capability & CAP_PRIVACY_ON)
5577 IPW_DEBUG_INFO("PRIVACY on\n");
5578 else
5579 IPW_DEBUG_INFO("PRIVACY off\n");
5580 IPW_DEBUG_INFO("RATE MASK: 0x%08X\n", priv->rates_mask);
5581}
5582#else
8d45ff7d 5583#define ipw_debug_config(x) do {} while (0)
43f66a6c
JK
5584#endif
5585
b095c381 5586static inline void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
43f66a6c
JK
5587{
5588 /* TODO: Verify that this works... */
5589 struct ipw_fixed_rate fr = {
5590 .tx_rates = priv->rates_mask
5591 };
5592 u32 reg;
5593 u16 mask = 0;
5594
bf79451e 5595 /* Identify 'current FW band' and match it with the fixed
43f66a6c 5596 * Tx rates */
bf79451e 5597
43f66a6c 5598 switch (priv->ieee->freq_band) {
0edd5b44 5599 case IEEE80211_52GHZ_BAND: /* A only */
43f66a6c
JK
5600 /* IEEE_A */
5601 if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) {
5602 /* Invalid fixed rate mask */
ea2b26e0
JK
5603 IPW_DEBUG_WX
5604 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
43f66a6c
JK
5605 fr.tx_rates = 0;
5606 break;
5607 }
bf79451e 5608
43f66a6c
JK
5609 fr.tx_rates >>= IEEE80211_OFDM_SHIFT_MASK_A;
5610 break;
5611
0edd5b44 5612 default: /* 2.4Ghz or Mixed */
43f66a6c 5613 /* IEEE_B */
b095c381 5614 if (mode == IEEE_B) {
43f66a6c
JK
5615 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) {
5616 /* Invalid fixed rate mask */
ea2b26e0
JK
5617 IPW_DEBUG_WX
5618 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
43f66a6c
JK
5619 fr.tx_rates = 0;
5620 }
5621 break;
bf79451e 5622 }
43f66a6c
JK
5623
5624 /* IEEE_G */
5625 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK |
5626 IEEE80211_OFDM_RATES_MASK)) {
5627 /* Invalid fixed rate mask */
ea2b26e0
JK
5628 IPW_DEBUG_WX
5629 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
43f66a6c
JK
5630 fr.tx_rates = 0;
5631 break;
5632 }
5633
5634 if (IEEE80211_OFDM_RATE_6MB_MASK & fr.tx_rates) {
5635 mask |= (IEEE80211_OFDM_RATE_6MB_MASK >> 1);
5636 fr.tx_rates &= ~IEEE80211_OFDM_RATE_6MB_MASK;
5637 }
bf79451e 5638
43f66a6c
JK
5639 if (IEEE80211_OFDM_RATE_9MB_MASK & fr.tx_rates) {
5640 mask |= (IEEE80211_OFDM_RATE_9MB_MASK >> 1);
5641 fr.tx_rates &= ~IEEE80211_OFDM_RATE_9MB_MASK;
5642 }
bf79451e 5643
43f66a6c
JK
5644 if (IEEE80211_OFDM_RATE_12MB_MASK & fr.tx_rates) {
5645 mask |= (IEEE80211_OFDM_RATE_12MB_MASK >> 1);
5646 fr.tx_rates &= ~IEEE80211_OFDM_RATE_12MB_MASK;
5647 }
bf79451e 5648
43f66a6c
JK
5649 fr.tx_rates |= mask;
5650 break;
5651 }
5652
5653 reg = ipw_read32(priv, IPW_MEM_FIXED_OVERRIDE);
0edd5b44 5654 ipw_write_reg32(priv, reg, *(u32 *) & fr);
43f66a6c
JK
5655}
5656
ea2b26e0 5657static void ipw_abort_scan(struct ipw_priv *priv)
43f66a6c
JK
5658{
5659 int err;
5660
ea2b26e0
JK
5661 if (priv->status & STATUS_SCAN_ABORTING) {
5662 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");
5663 return;
5664 }
5665 priv->status |= STATUS_SCAN_ABORTING;
43f66a6c 5666
ea2b26e0
JK
5667 err = ipw_send_scan_abort(priv);
5668 if (err)
5669 IPW_DEBUG_HC("Request to abort scan failed.\n");
5670}
5671
5672static int ipw_request_scan(struct ipw_priv *priv)
5673{
5674 struct ipw_scan_request_ext scan;
5675 int channel_index = 0;
b095c381
JK
5676 int i, err = 0, scan_type;
5677 const struct ieee80211_geo *geo;
5678#ifdef CONFIG_IPW2200_MONITOR
5679 u8 channel;
5680#endif
ea2b26e0 5681
b095c381
JK
5682 down(&priv->sem);
5683
5684 geo = ieee80211_get_geo(priv->ieee);
43f66a6c 5685
ea2b26e0 5686 if (priv->status & STATUS_SCANNING) {
a613bffd 5687 IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n");
ea2b26e0 5688 priv->status |= STATUS_SCAN_PENDING;
b095c381 5689 goto done;
ea2b26e0 5690 }
43f66a6c 5691
ea2b26e0
JK
5692 if (priv->status & STATUS_SCAN_ABORTING) {
5693 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
5694 priv->status |= STATUS_SCAN_PENDING;
b095c381 5695 goto done;
43f66a6c
JK
5696 }
5697
ea2b26e0
JK
5698 if (priv->status & STATUS_RF_KILL_MASK) {
5699 IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n");
5700 priv->status |= STATUS_SCAN_PENDING;
b095c381 5701 goto done;
ea2b26e0 5702 }
43f66a6c 5703
ea2b26e0 5704 memset(&scan, 0, sizeof(scan));
43f66a6c 5705
b095c381
JK
5706 if (priv->config & CFG_SPEED_SCAN)
5707 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
5708 cpu_to_le16(30);
5709 else
5710 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
5711 cpu_to_le16(20);
5712
a613bffd
JK
5713 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
5714 cpu_to_le16(20);
5715 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(20);
43f66a6c 5716
a613bffd 5717 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
43f66a6c 5718
b095c381 5719#ifdef CONFIG_IPW2200_MONITOR
ea2b26e0 5720 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
b095c381 5721 u8 band = 0;
43f66a6c 5722
b095c381
JK
5723 switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
5724 case IEEE80211_52GHZ_BAND:
ea2b26e0 5725 band = (u8) (IPW_A_MODE << 6) | 1;
b095c381
JK
5726 channel = priv->channel;
5727 break;
ea2b26e0 5728
b095c381 5729 case IEEE80211_24GHZ_BAND:
ea2b26e0 5730 band = (u8) (IPW_B_MODE << 6) | 1;
b095c381
JK
5731 channel = priv->channel;
5732 break;
ea2b26e0 5733
b095c381 5734 default:
ea2b26e0
JK
5735 band = (u8) (IPW_B_MODE << 6) | 1;
5736 channel = 9;
b095c381 5737 break;
ea2b26e0
JK
5738 }
5739
b095c381
JK
5740 scan.channels_list[0] = band;
5741 scan.channels_list[1] = channel;
5742 ipw_set_scan_type(&scan, 1, IPW_SCAN_PASSIVE_FULL_DWELL_SCAN);
ea2b26e0 5743
b095c381
JK
5744 /* NOTE: The card will sit on this channel for this time
5745 * period. Scan aborts are timing sensitive and frequently
5746 * result in firmware restarts. As such, it is best to
5747 * set a small dwell_time here and just keep re-issuing
5748 * scans. Otherwise fast channel hopping will not actually
5749 * hop channels.
5750 *
5751 * TODO: Move SPEED SCAN support to all modes and bands */
a613bffd
JK
5752 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
5753 cpu_to_le16(2000);
43f66a6c 5754 } else {
b095c381
JK
5755#endif /* CONFIG_IPW2200_MONITOR */
5756 /* If we are roaming, then make this a directed scan for the
5757 * current network. Otherwise, ensure that every other scan
5758 * is a fast channel hop scan */
5759 if ((priv->status & STATUS_ROAMING)
5760 || (!(priv->status & STATUS_ASSOCIATED)
5761 && (priv->config & CFG_STATIC_ESSID)
5762 && (le32_to_cpu(scan.full_scan_index) % 2))) {
ea2b26e0
JK
5763 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
5764 if (err) {
b095c381
JK
5765 IPW_DEBUG_HC("Attempt to send SSID command "
5766 "failed.\n");
5767 goto done;
ea2b26e0 5768 }
43f66a6c 5769
ea2b26e0
JK
5770 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
5771 } else {
5772 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;
5773 }
bf79451e 5774
b095c381 5775 /* Add channels to the scan list */
ea2b26e0
JK
5776 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
5777 int start = channel_index;
b095c381 5778 for (i = 0; i < geo->a_channels; i++) {
ea2b26e0 5779 if ((priv->status & STATUS_ASSOCIATED) &&
b095c381 5780 geo->a[i].channel == priv->channel)
ea2b26e0
JK
5781 continue;
5782 channel_index++;
5783 scan.channels_list[channel_index] =
b095c381 5784 geo->a[i].channel;
ea2b26e0
JK
5785 ipw_set_scan_type(&scan, channel_index,
5786 scan_type);
5787 }
43f66a6c 5788
ea2b26e0
JK
5789 if (start != channel_index) {
5790 scan.channels_list[start] =
5791 (u8) (IPW_A_MODE << 6) | (channel_index -
5792 start);
5793 channel_index++;
5794 }
5795 }
bf79451e 5796
ea2b26e0
JK
5797 if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) {
5798 int start = channel_index;
b095c381
JK
5799 if (priv->config & CFG_SPEED_SCAN) {
5800 u8 channels[IEEE80211_24GHZ_CHANNELS] = {
5801 /* nop out the list */
5802 [0] = 0
5803 };
5804
5805 u8 channel;
5806 while (channel_index < IPW_SCAN_CHANNELS) {
5807 channel =
5808 priv->speed_scan[priv->
5809 speed_scan_pos];
5810 if (channel == 0) {
5811 priv->speed_scan_pos = 0;
5812 channel = priv->speed_scan[0];
5813 }
5814 if ((priv->status & STATUS_ASSOCIATED)
5815 && channel == priv->channel) {
5816 priv->speed_scan_pos++;
5817 continue;
5818 }
5819
5820 /* If this channel has already been
5821 * added in scan, break from loop
5822 * and this will be the first channel
5823 * in the next scan.
5824 */
5825 if (channels[channel - 1] != 0)
5826 break;
5827
5828 channels[channel - 1] = 1;
5829 priv->speed_scan_pos++;
5830 channel_index++;
5831 scan.channels_list[channel_index] =
5832 channel;
5833 ipw_set_scan_type(&scan, channel_index,
5834 scan_type);
5835 }
5836 } else {
5837 for (i = 0; i < geo->bg_channels; i++) {
5838 if ((priv->status & STATUS_ASSOCIATED)
5839 && geo->bg[i].channel ==
5840 priv->channel)
5841 continue;
5842 channel_index++;
5843 scan.channels_list[channel_index] =
5844 geo->bg[i].channel;
5845 ipw_set_scan_type(&scan, channel_index,
5846 scan_type);
5847 }
ea2b26e0
JK
5848 }
5849
5850 if (start != channel_index) {
5851 scan.channels_list[start] =
5852 (u8) (IPW_B_MODE << 6) | (channel_index -
5853 start);
5854 }
5855 }
b095c381 5856#ifdef CONFIG_IPW2200_MONITOR
43f66a6c 5857 }
ea2b26e0 5858#endif
bf79451e 5859
ea2b26e0 5860 err = ipw_send_scan_request_ext(priv, &scan);
43f66a6c 5861 if (err) {
ea2b26e0 5862 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
b095c381 5863 goto done;
43f66a6c
JK
5864 }
5865
ea2b26e0
JK
5866 priv->status |= STATUS_SCANNING;
5867 priv->status &= ~STATUS_SCAN_PENDING;
43f66a6c 5868
b095c381 5869 done:
c848d0af 5870 up(&priv->sem);
b095c381 5871 return err;
c848d0af
JK
5872}
5873
5874static void ipw_bg_abort_scan(void *data)
5875{
5876 struct ipw_priv *priv = data;
5877 down(&priv->sem);
5878 ipw_abort_scan(data);
5879 up(&priv->sem);
5880}
5881
ea2b26e0
JK
5882/* Support for wpa_supplicant. Will be replaced with WEXT once
5883 * they get WPA support. */
ea2b26e0
JK
5884
5885/* following definitions must match definitions in driver_ipw.c */
5886
5887#define IPW_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
5888
5889#define IPW_CMD_SET_WPA_PARAM 1
5890#define IPW_CMD_SET_WPA_IE 2
5891#define IPW_CMD_SET_ENCRYPTION 3
5892#define IPW_CMD_MLME 4
5893
5894#define IPW_PARAM_WPA_ENABLED 1
5895#define IPW_PARAM_TKIP_COUNTERMEASURES 2
5896#define IPW_PARAM_DROP_UNENCRYPTED 3
5897#define IPW_PARAM_PRIVACY_INVOKED 4
5898#define IPW_PARAM_AUTH_ALGS 5
5899#define IPW_PARAM_IEEE_802_1X 6
5900
5901#define IPW_MLME_STA_DEAUTH 1
5902#define IPW_MLME_STA_DISASSOC 2
5903
5904#define IPW_CRYPT_ERR_UNKNOWN_ALG 2
5905#define IPW_CRYPT_ERR_UNKNOWN_ADDR 3
5906#define IPW_CRYPT_ERR_CRYPT_INIT_FAILED 4
5907#define IPW_CRYPT_ERR_KEY_SET_FAILED 5
5908#define IPW_CRYPT_ERR_TX_KEY_SET_FAILED 6
5909#define IPW_CRYPT_ERR_CARD_CONF_FAILED 7
5910
5911#define IPW_CRYPT_ALG_NAME_LEN 16
5912
5913struct ipw_param {
5914 u32 cmd;
5915 u8 sta_addr[ETH_ALEN];
5916 union {
5917 struct {
5918 u8 name;
5919 u32 value;
5920 } wpa_param;
5921 struct {
5922 u32 len;
b095c381
JK
5923 u8 reserved[32];
5924 u8 data[0];
ea2b26e0
JK
5925 } wpa_ie;
5926 struct {
5927 int command;
5928 int reason_code;
5929 } mlme;
5930 struct {
5931 u8 alg[IPW_CRYPT_ALG_NAME_LEN];
5932 u8 set_tx;
5933 u32 err;
5934 u8 idx;
5935 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
5936 u16 key_len;
5937 u8 key[0];
5938 } crypt;
5939
5940 } u;
5941};
5942
5943/* end of driver_ipw.c code */
5944
5945static int ipw_wpa_enable(struct ipw_priv *priv, int value)
5946{
b095c381
JK
5947 /* This is called when wpa_supplicant loads and closes the driver
5948 * interface. */
5949 return 0;
ea2b26e0
JK
5950}
5951
5952#define AUTH_ALG_OPEN_SYSTEM 0x1
5953#define AUTH_ALG_SHARED_KEY 0x2
5954
5955static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
5956{
5957 struct ieee80211_device *ieee = priv->ieee;
5958 struct ieee80211_security sec = {
5959 .flags = SEC_AUTH_MODE,
5960 };
5961 int ret = 0;
5962
5963 if (value & AUTH_ALG_SHARED_KEY) {
5964 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
5965 ieee->open_wep = 0;
5966 } else {
5967 sec.auth_mode = WLAN_AUTH_OPEN;
5968 ieee->open_wep = 1;
5969 }
5970
5971 if (ieee->set_security)
5972 ieee->set_security(ieee->dev, &sec);
5973 else
5974 ret = -EOPNOTSUPP;
5975
5976 return ret;
5977}
5978
5979static int ipw_wpa_set_param(struct net_device *dev, u8 name, u32 value)
5980{
5981 struct ipw_priv *priv = ieee80211_priv(dev);
a613bffd
JK
5982 struct ieee80211_crypt_data *crypt;
5983 unsigned long flags;
ea2b26e0
JK
5984 int ret = 0;
5985
5986 switch (name) {
5987 case IPW_PARAM_WPA_ENABLED:
5988 ret = ipw_wpa_enable(priv, value);
5989 break;
5990
5991 case IPW_PARAM_TKIP_COUNTERMEASURES:
a613bffd
JK
5992 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
5993 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
5994 IPW_WARNING("Can't set TKIP countermeasures: "
5995 "crypt not set!\n");
5996 break;
5997 }
5998
5999 flags = crypt->ops->get_flags(crypt->priv);
6000
6001 if (value)
6002 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6003 else
6004 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6005
6006 crypt->ops->set_flags(flags, crypt->priv);
6007
ea2b26e0
JK
6008 break;
6009
b095c381
JK
6010 case IPW_PARAM_DROP_UNENCRYPTED:{
6011 /* HACK:
6012 *
6013 * wpa_supplicant calls set_wpa_enabled when the driver
6014 * is loaded and unloaded, regardless of if WPA is being
6015 * used. No other calls are made which can be used to
6016 * determine if encryption will be used or not prior to
6017 * association being expected. If encryption is not being
6018 * used, drop_unencrypted is set to false, else true -- we
6019 * can use this to determine if the CAP_PRIVACY_ON bit should
6020 * be set.
6021 */
6022 struct ieee80211_security sec = {
6023 .flags = SEC_ENABLED,
6024 .enabled = value,
6025 };
6026 priv->ieee->drop_unencrypted = value;
6027 /* We only change SEC_LEVEL for open mode. Others
6028 * are set by ipw_wpa_set_encryption.
6029 */
6030 if (!value) {
6031 sec.flags |= SEC_LEVEL;
6032 sec.level = SEC_LEVEL_0;
6033 } else {
6034 sec.flags |= SEC_LEVEL;
6035 sec.level = SEC_LEVEL_1;
6036 }
6037 if (priv->ieee->set_security)
6038 priv->ieee->set_security(priv->ieee->dev, &sec);
6039 break;
6040 }
ea2b26e0
JK
6041
6042 case IPW_PARAM_PRIVACY_INVOKED:
6043 priv->ieee->privacy_invoked = value;
6044 break;
6045
6046 case IPW_PARAM_AUTH_ALGS:
6047 ret = ipw_wpa_set_auth_algs(priv, value);
6048 break;
6049
6050 case IPW_PARAM_IEEE_802_1X:
6051 priv->ieee->ieee802_1x = value;
6052 break;
6053
6054 default:
6055 IPW_ERROR("%s: Unknown WPA param: %d\n", dev->name, name);
6056 ret = -EOPNOTSUPP;
6057 }
6058
6059 return ret;
6060}
6061
6062static int ipw_wpa_mlme(struct net_device *dev, int command, int reason)
6063{
6064 struct ipw_priv *priv = ieee80211_priv(dev);
6065 int ret = 0;
6066
6067 switch (command) {
6068 case IPW_MLME_STA_DEAUTH:
6069 // silently ignore
6070 break;
6071
6072 case IPW_MLME_STA_DISASSOC:
6073 ipw_disassociate(priv);
6074 break;
6075
6076 default:
6077 IPW_ERROR("%s: Unknown MLME request: %d\n", dev->name, command);
6078 ret = -EOPNOTSUPP;
6079 }
6080
6081 return ret;
6082}
6083
6084static int ipw_set_rsn_capa(struct ipw_priv *priv,
6085 char *capabilities, int length)
6086{
6087 struct host_cmd cmd = {
6088 .cmd = IPW_CMD_RSN_CAPABILITIES,
6089 .len = length,
6090 };
6091
6092 IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
6093
6094 memcpy(&cmd.param, capabilities, length);
6095 if (ipw_send_cmd(priv, &cmd)) {
6096 IPW_ERROR("failed to send HOST_CMD_RSN_CAPABILITIES command\n");
6097 return -1;
6098 }
6099 return 0;
6100}
6101
6102void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len)
6103{
6104 /* make sure WPA is enabled */
6105 ipw_wpa_enable(priv, 1);
6106
c848d0af 6107 ipw_disassociate(priv);
ea2b26e0
JK
6108}
6109
6110static int ipw_wpa_set_wpa_ie(struct net_device *dev,
6111 struct ipw_param *param, int plen)
6112{
6113 struct ipw_priv *priv = ieee80211_priv(dev);
6114 struct ieee80211_device *ieee = priv->ieee;
6115 u8 *buf;
6116
ea2b26e0
JK
6117 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
6118 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
6119 return -EINVAL;
6120
6121 if (param->u.wpa_ie.len) {
6122 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
6123 if (buf == NULL)
6124 return -ENOMEM;
6125
6126 memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
6127 kfree(ieee->wpa_ie);
6128 ieee->wpa_ie = buf;
6129 ieee->wpa_ie_len = param->u.wpa_ie.len;
6130 } else {
6131 kfree(ieee->wpa_ie);
6132 ieee->wpa_ie = NULL;
6133 ieee->wpa_ie_len = 0;
6134 }
6135
6136 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
6137 return 0;
6138}
6139
6140/* implementation borrowed from hostap driver */
6141
6142static int ipw_wpa_set_encryption(struct net_device *dev,
6143 struct ipw_param *param, int param_len)
6144{
6145 int ret = 0;
6146 struct ipw_priv *priv = ieee80211_priv(dev);
6147 struct ieee80211_device *ieee = priv->ieee;
6148 struct ieee80211_crypto_ops *ops;
6149 struct ieee80211_crypt_data **crypt;
6150
6151 struct ieee80211_security sec = {
6152 .flags = 0,
6153 };
6154
6155 param->u.crypt.err = 0;
6156 param->u.crypt.alg[IPW_CRYPT_ALG_NAME_LEN - 1] = '\0';
6157
6158 if (param_len !=
6159 (int)((char *)param->u.crypt.key - (char *)param) +
6160 param->u.crypt.key_len) {
6161 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len,
6162 param->u.crypt.key_len);
6163 return -EINVAL;
6164 }
6165 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
6166 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
6167 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
6168 if (param->u.crypt.idx >= WEP_KEYS)
6169 return -EINVAL;
6170 crypt = &ieee->crypt[param->u.crypt.idx];
6171 } else {
6172 return -EINVAL;
6173 }
6174
6175 if (strcmp(param->u.crypt.alg, "none") == 0) {
6176 if (crypt) {
6177 sec.enabled = 0;
b095c381 6178 sec.encrypt = 0;
ea2b26e0
JK
6179 sec.level = SEC_LEVEL_0;
6180 sec.flags |= SEC_ENABLED | SEC_LEVEL;
6181 ieee80211_crypt_delayed_deinit(ieee, crypt);
6182 }
6183 goto done;
6184 }
6185 sec.enabled = 1;
b095c381 6186 sec.encrypt = 1;
ea2b26e0
JK
6187 sec.flags |= SEC_ENABLED;
6188
b095c381
JK
6189 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
6190 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
6191 strcmp(param->u.crypt.alg, "TKIP"))
6192 goto skip_host_crypt;
6193
ea2b26e0
JK
6194 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6195 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
6196 request_module("ieee80211_crypt_wep");
6197 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6198 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
6199 request_module("ieee80211_crypt_tkip");
6200 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6201 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
6202 request_module("ieee80211_crypt_ccmp");
6203 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6204 }
6205 if (ops == NULL) {
6206 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
6207 dev->name, param->u.crypt.alg);
6208 param->u.crypt.err = IPW_CRYPT_ERR_UNKNOWN_ALG;
6209 ret = -EINVAL;
6210 goto done;
6211 }
6212
6213 if (*crypt == NULL || (*crypt)->ops != ops) {
6214 struct ieee80211_crypt_data *new_crypt;
6215
6216 ieee80211_crypt_delayed_deinit(ieee, crypt);
6217
6218 new_crypt = (struct ieee80211_crypt_data *)
6219 kmalloc(sizeof(*new_crypt), GFP_KERNEL);
6220 if (new_crypt == NULL) {
6221 ret = -ENOMEM;
6222 goto done;
6223 }
6224 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
6225 new_crypt->ops = ops;
6226 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
6227 new_crypt->priv =
6228 new_crypt->ops->init(param->u.crypt.idx);
6229
6230 if (new_crypt->priv == NULL) {
6231 kfree(new_crypt);
6232 param->u.crypt.err = IPW_CRYPT_ERR_CRYPT_INIT_FAILED;
6233 ret = -EINVAL;
6234 goto done;
6235 }
6236
6237 *crypt = new_crypt;
6238 }
6239
6240 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
6241 (*crypt)->ops->set_key(param->u.crypt.key,
6242 param->u.crypt.key_len, param->u.crypt.seq,
6243 (*crypt)->priv) < 0) {
6244 IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);
6245 param->u.crypt.err = IPW_CRYPT_ERR_KEY_SET_FAILED;
6246 ret = -EINVAL;
6247 goto done;
6248 }
6249
b095c381 6250 skip_host_crypt:
ea2b26e0
JK
6251 if (param->u.crypt.set_tx) {
6252 ieee->tx_keyidx = param->u.crypt.idx;
6253 sec.active_key = param->u.crypt.idx;
6254 sec.flags |= SEC_ACTIVE_KEY;
b095c381
JK
6255 } else
6256 sec.flags &= ~SEC_ACTIVE_KEY;
ea2b26e0 6257
b095c381
JK
6258 if (param->u.crypt.alg != NULL) {
6259 memcpy(sec.keys[param->u.crypt.idx],
6260 param->u.crypt.key, param->u.crypt.key_len);
6261 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
6262 sec.flags |= (1 << param->u.crypt.idx);
6263
6264 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
ea2b26e0
JK
6265 sec.flags |= SEC_LEVEL;
6266 sec.level = SEC_LEVEL_1;
b095c381 6267 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
ea2b26e0
JK
6268 sec.flags |= SEC_LEVEL;
6269 sec.level = SEC_LEVEL_2;
b095c381 6270 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
ea2b26e0
JK
6271 sec.flags |= SEC_LEVEL;
6272 sec.level = SEC_LEVEL_3;
6273 }
6274 }
6275 done:
6276 if (ieee->set_security)
6277 ieee->set_security(ieee->dev, &sec);
6278
6279 /* Do not reset port if card is in Managed mode since resetting will
6280 * generate new IEEE 802.11 authentication which may end up in looping
6281 * with IEEE 802.1X. If your hardware requires a reset after WEP
6282 * configuration (for example... Prism2), implement the reset_port in
6283 * the callbacks structures used to initialize the 802.11 stack. */
6284 if (ieee->reset_on_keychange &&
6285 ieee->iw_mode != IW_MODE_INFRA &&
6286 ieee->reset_port && ieee->reset_port(dev)) {
6287 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
6288 param->u.crypt.err = IPW_CRYPT_ERR_CARD_CONF_FAILED;
6289 return -EINVAL;
6290 }
6291
6292 return ret;
6293}
6294
6295static int ipw_wpa_supplicant(struct net_device *dev, struct iw_point *p)
6296{
6297 struct ipw_param *param;
6298 int ret = 0;
6299
6300 IPW_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
6301
6302 if (p->length < sizeof(struct ipw_param) || !p->pointer)
6303 return -EINVAL;
6304
6305 param = (struct ipw_param *)kmalloc(p->length, GFP_KERNEL);
6306 if (param == NULL)
6307 return -ENOMEM;
6308
6309 if (copy_from_user(param, p->pointer, p->length)) {
6310 kfree(param);
6311 return -EFAULT;
6312 }
6313
6314 switch (param->cmd) {
6315
6316 case IPW_CMD_SET_WPA_PARAM:
6317 ret = ipw_wpa_set_param(dev, param->u.wpa_param.name,
6318 param->u.wpa_param.value);
6319 break;
6320
6321 case IPW_CMD_SET_WPA_IE:
6322 ret = ipw_wpa_set_wpa_ie(dev, param, p->length);
6323 break;
6324
6325 case IPW_CMD_SET_ENCRYPTION:
6326 ret = ipw_wpa_set_encryption(dev, param, p->length);
6327 break;
6328
6329 case IPW_CMD_MLME:
6330 ret = ipw_wpa_mlme(dev, param->u.mlme.command,
6331 param->u.mlme.reason_code);
6332 break;
6333
6334 default:
6335 IPW_ERROR("%s: Unknown WPA supplicant request: %d\n",
6336 dev->name, param->cmd);
6337 ret = -EOPNOTSUPP;
6338 }
6339
6340 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
6341 ret = -EFAULT;
6342
6343 kfree(param);
6344 return ret;
6345}
ea2b26e0 6346
b095c381
JK
6347#ifdef CONFIG_IPW_QOS
6348
6349/* QoS */
6350/*
6351* get the modulation type of the current network or
6352* the card current mode
6353*/
6354u8 ipw_qos_current_mode(struct ipw_priv * priv)
ea2b26e0 6355{
b095c381 6356 u8 mode = 0;
ea2b26e0 6357
b095c381
JK
6358 if (priv->status & STATUS_ASSOCIATED) {
6359 unsigned long flags;
ea2b26e0 6360
b095c381
JK
6361 spin_lock_irqsave(&priv->ieee->lock, flags);
6362 mode = priv->assoc_network->mode;
6363 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6364 } else {
6365 mode = priv->ieee->mode;
ea2b26e0 6366 }
b095c381
JK
6367 IPW_DEBUG_QOS("QoS network/card mode %d \n", mode);
6368 return mode;
6369}
ea2b26e0 6370
b095c381
JK
6371/*
6372* Handle management frame beacon and probe response
6373*/
6374static int ipw_qos_handle_probe_reponse(struct ipw_priv *priv,
6375 int active_network,
6376 struct ieee80211_network *network)
6377{
6378 u32 size = sizeof(struct ieee80211_qos_parameters);
6379
6380 if ((network->capability & WLAN_CAPABILITY_IBSS))
6381 network->qos_data.active = network->qos_data.supported;
6382
6383 if (network->flags & NETWORK_HAS_QOS_MASK) {
6384 if (active_network
6385 && (network->flags & NETWORK_HAS_QOS_PARAMETERS))
6386 network->qos_data.active = network->qos_data.supported;
6387
6388 if ((network->qos_data.active == 1) && (active_network == 1) &&
6389 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
6390 (network->qos_data.old_param_count !=
6391 network->qos_data.param_count)) {
6392 network->qos_data.old_param_count =
6393 network->qos_data.param_count;
6394 schedule_work(&priv->qos_activate);
6395 IPW_DEBUG_QOS
6396 ("QoS parameters change call qos_activate\n");
6397 }
ea2b26e0 6398 } else {
b095c381
JK
6399 if ((priv->ieee->mode == IEEE_B) || (network->mode == IEEE_B)) {
6400 memcpy(&(network->qos_data.parameters),
6401 &def_parameters_CCK, size);
6402 } else {
6403 memcpy(&(network->qos_data.parameters),
6404 &def_parameters_OFDM, size);
6405 }
6406 if ((network->qos_data.active == 1) && (active_network == 1)) {
6407 IPW_DEBUG_QOS("QoS was disabled call qos_activate \n");
6408 schedule_work(&priv->qos_activate);
6409 }
6410
6411 network->qos_data.active = 0;
6412 network->qos_data.supported = 0;
ea2b26e0 6413 }
b095c381
JK
6414 if ((priv->status & STATUS_ASSOCIATED)
6415 && (priv->ieee->iw_mode == IW_MODE_ADHOC)
6416 && (active_network == 0)) {
6417
6418 if (memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
6419 if ((network->capability & WLAN_CAPABILITY_IBSS)
6420 && !(network->flags & NETWORK_EMPTY_ESSID)) {
6421 if ((network->ssid_len ==
6422 priv->assoc_network->ssid_len)
6423 && !memcmp(network->ssid,
6424 priv->assoc_network->ssid,
6425 network->ssid_len)) {
6426 queue_work(priv->workqueue,
6427 &priv->merge_networks);
6428 }
ea2b26e0 6429
b095c381
JK
6430 }
6431 }
6432 }
ea2b26e0 6433
b095c381
JK
6434 return 0;
6435}
6436
6437/*
6438* This function set up the firmware to support QoS. It sends
6439* IPW_CMD_QOS_PARAMETERS and IPW_CMD_WME_INFO
6440*/
6441static int ipw_qos_activate(struct ipw_priv *priv,
6442 struct ieee80211_qos_data *qos_network_data)
6443{
6444 int err;
6445 struct ieee80211_qos_parameters qos_parameters[QOS_QOS_SETS];
6446 struct ieee80211_qos_parameters *active_one = NULL;
6447 u32 size = sizeof(struct ieee80211_qos_parameters);
6448 u32 burst_duration;
6449 int i;
6450 u8 type;
6451
6452 type = ipw_qos_current_mode(priv);
6453
6454 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_CCK]);
6455 memcpy(active_one, priv->qos_data.def_qos_parm_CCK, size);
6456 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_OFDM]);
6457 memcpy(active_one, priv->qos_data.def_qos_parm_OFDM, size);
6458
6459 if (qos_network_data == NULL) {
6460 if (type == IEEE_B) {
6461 IPW_DEBUG_QOS("QoS activate network mode %d\n", type);
6462 active_one = &def_parameters_CCK;
6463 } else
6464 active_one = &def_parameters_OFDM;
6465
6466 memcpy(&(qos_parameters[QOS_PARAM_SET_ACTIVE]), active_one,
6467 size);
6468 burst_duration = ipw_qos_get_burst_duration(priv);
6469 for (i = 0; i < QOS_QUEUE_NUM; i++)
6470 qos_parameters[QOS_PARAM_SET_ACTIVE].
6471 tx_op_limit[i] = (u16) burst_duration;
6472 } else if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
6473 if (type == IEEE_B) {
6474 IPW_DEBUG_QOS("QoS activate IBSS nework mode %d\n",
6475 type);
6476 if (priv->qos_data.qos_enable == 0)
6477 active_one = &def_parameters_CCK;
6478 else
6479 active_one = priv->qos_data.def_qos_parm_CCK;
6480 } else {
6481 if (priv->qos_data.qos_enable == 0)
6482 active_one = &def_parameters_OFDM;
6483 else
6484 active_one = priv->qos_data.def_qos_parm_OFDM;
6485 }
6486 memcpy(&(qos_parameters[QOS_PARAM_SET_ACTIVE]), active_one,
6487 size);
6488 } else {
6489 unsigned long flags;
6490 int active;
6491
6492 spin_lock_irqsave(&priv->ieee->lock, flags);
6493 active_one = &(qos_network_data->parameters);
6494 qos_network_data->old_param_count =
6495 qos_network_data->param_count;
6496 memcpy(&(qos_parameters[QOS_PARAM_SET_ACTIVE]), active_one,
6497 size);
6498 active = qos_network_data->supported;
6499 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6500
6501 if (active == 0) {
6502 burst_duration = ipw_qos_get_burst_duration(priv);
6503 for (i = 0; i < QOS_QUEUE_NUM; i++)
6504 qos_parameters[QOS_PARAM_SET_ACTIVE].
6505 tx_op_limit[i] = (u16) burst_duration;
6506 }
6507 }
6508
6509 IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n");
6510 err =
6511 ipw_send_qos_params_command(priv,
6512 (struct ieee80211_qos_parameters *)
6513 &(qos_parameters[0]));
6514 if (err)
6515 IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n");
6516
6517 return err;
6518}
6519
6520/*
6521* send IPW_CMD_WME_INFO to the firmware
6522*/
6523static int ipw_qos_set_info_element(struct ipw_priv *priv)
6524{
6525 int ret = 0;
6526 struct ieee80211_qos_information_element qos_info;
6527
6528 if (priv == NULL)
6529 return -1;
6530
6531 qos_info.elementID = QOS_ELEMENT_ID;
6532 qos_info.length = sizeof(struct ieee80211_qos_information_element) - 2;
6533
6534 qos_info.version = QOS_VERSION_1;
6535 qos_info.ac_info = 0;
6536
6537 memcpy(qos_info.qui, qos_oui, QOS_OUI_LEN);
6538 qos_info.qui_type = QOS_OUI_TYPE;
6539 qos_info.qui_subtype = QOS_OUI_INFO_SUB_TYPE;
6540
6541 ret = ipw_send_qos_info_command(priv, &qos_info);
6542 if (ret != 0) {
6543 IPW_DEBUG_QOS("QoS error calling ipw_send_qos_info_command\n");
6544 }
6545 return ret;
6546}
6547
6548/*
6549* Set the QoS parameter with the association request structure
6550*/
6551static int ipw_qos_association(struct ipw_priv *priv,
6552 struct ieee80211_network *network)
6553{
6554 int err = 0;
6555 struct ieee80211_qos_data *qos_data = NULL;
6556 struct ieee80211_qos_data ibss_data = {
6557 .supported = 1,
6558 .active = 1,
6559 };
6560
6561 switch (priv->ieee->iw_mode) {
6562 case IW_MODE_ADHOC:
6563 if (!(network->capability & WLAN_CAPABILITY_IBSS))
6564 BUG();
6565
6566 qos_data = &ibss_data;
6567 break;
6568
6569 case IW_MODE_INFRA:
6570 qos_data = &network->qos_data;
6571 break;
6572
6573 default:
6574 BUG();
6575 break;
6576 }
6577
6578 err = ipw_qos_activate(priv, qos_data);
6579 if (err) {
6580 priv->assoc_request.policy_support &= ~HC_QOS_SUPPORT_ASSOC;
6581 return err;
6582 }
6583
6584 if (priv->qos_data.qos_enable && qos_data->supported) {
6585 IPW_DEBUG_QOS("QoS will be enabled for this association\n");
6586 priv->assoc_request.policy_support |= HC_QOS_SUPPORT_ASSOC;
6587 return ipw_qos_set_info_element(priv);
6588 }
6589
6590 return 0;
6591}
6592
6593/*
6594* handling the beaconing responces. if we get different QoS setting
6595* of the network from the the associated setting adjust the QoS
6596* setting
6597*/
6598static int ipw_qos_association_resp(struct ipw_priv *priv,
6599 struct ieee80211_network *network)
6600{
6601 int ret = 0;
6602 unsigned long flags;
6603 u32 size = sizeof(struct ieee80211_qos_parameters);
6604 int set_qos_param = 0;
6605
6606 if ((priv == NULL) || (network == NULL)
6607 || (priv->assoc_network == NULL))
6608
6609 return ret;
6610
6611 if (!(priv->status & STATUS_ASSOCIATED))
6612 return ret;
6613
6614 if ((priv->ieee->iw_mode != IW_MODE_INFRA)) {
6615 return ret;
6616 }
6617
6618 spin_lock_irqsave(&priv->ieee->lock, flags);
6619 if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
6620 memcpy(&(priv->assoc_network->qos_data), &(network->qos_data),
6621 sizeof(struct ieee80211_qos_data));
6622 priv->assoc_network->qos_data.active = 1;
6623 if ((network->qos_data.old_param_count !=
6624 network->qos_data.param_count)) {
6625 set_qos_param = 1;
6626 network->qos_data.old_param_count =
6627 network->qos_data.param_count;
6628 }
6629
6630 } else {
6631 if ((network->mode == IEEE_B) || (priv->ieee->mode == IEEE_B)) {
6632 memcpy(&(priv->assoc_network->qos_data.parameters),
6633 &def_parameters_CCK, size);
6634 } else {
6635 memcpy(&(priv->assoc_network->qos_data.parameters),
6636 &def_parameters_OFDM, size);
6637 }
6638 priv->assoc_network->qos_data.active = 0;
6639 priv->assoc_network->qos_data.supported = 0;
6640 set_qos_param = 1;
6641 }
6642
6643 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6644
6645 if (set_qos_param == 1)
6646 schedule_work(&priv->qos_activate);
6647
6648 return ret;
6649}
6650
6651static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv)
6652{
6653 u32 ret = 0;
6654
6655 if ((priv == NULL))
6656 return 0;
6657
6658 if (!(priv->ieee->modulation & IEEE80211_OFDM_MODULATION)) {
6659 ret = priv->qos_data.burst_duration_CCK;
6660 } else {
6661 ret = priv->qos_data.burst_duration_OFDM;
6662 }
6663 return ret;
6664}
6665
6666/*
6667* Initialize the setting of QoS global
6668*/
6669static void ipw_qos_init(struct ipw_priv *priv, int enable,
6670 int burst_enable, u32 burst_duration_CCK,
6671 u32 burst_duration_OFDM)
6672{
6673 priv->qos_data.qos_enable = enable;
6674
6675 if (priv->qos_data.qos_enable) {
6676 priv->qos_data.def_qos_parm_CCK = &def_qos_parameters_CCK;
6677 priv->qos_data.def_qos_parm_OFDM = &def_qos_parameters_OFDM;
6678 IPW_DEBUG_QOS("QoS is enabled\n");
6679 } else {
6680 priv->qos_data.def_qos_parm_CCK = &def_parameters_CCK;
6681 priv->qos_data.def_qos_parm_OFDM = &def_parameters_OFDM;
6682 IPW_DEBUG_QOS("QoS is not enabled\n");
6683 }
6684
6685 priv->qos_data.burst_enable = burst_enable;
6686
6687 if (burst_enable) {
6688 priv->qos_data.burst_duration_CCK = burst_duration_CCK;
6689 priv->qos_data.burst_duration_OFDM = burst_duration_OFDM;
6690 } else {
6691 priv->qos_data.burst_duration_CCK = 0;
6692 priv->qos_data.burst_duration_OFDM = 0;
6693 }
6694}
6695
6696/*
6697* map the packet priority to the right TX Queue
6698*/
6699static int ipw_get_tx_queue_number(struct ipw_priv *priv, u16 priority)
6700{
6701 if (priority > 7 || !priv->qos_data.qos_enable)
6702 priority = 0;
6703
6704 return from_priority_to_tx_queue[priority] - 1;
6705}
6706
6707/*
6708* add QoS parameter to the TX command
6709*/
6710static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv,
6711 u16 priority,
6712 struct tfd_data *tfd, u8 unicast)
6713{
6714 int ret = 0;
6715 int tx_queue_id = 0;
6716 struct ieee80211_qos_data *qos_data = NULL;
6717 int active, supported;
6718 unsigned long flags;
6719
6720 if (!(priv->status & STATUS_ASSOCIATED))
6721 return 0;
6722
6723 qos_data = &priv->assoc_network->qos_data;
6724
6725 spin_lock_irqsave(&priv->ieee->lock, flags);
6726
6727 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
6728 if (unicast == 0)
6729 qos_data->active = 0;
6730 else
6731 qos_data->active = qos_data->supported;
6732 }
6733
6734 active = qos_data->active;
6735 supported = qos_data->supported;
6736
6737 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6738
6739 IPW_DEBUG_QOS
6740 ("QoS %d network is QoS active %d supported %d unicast %d\n",
6741 priv->qos_data.qos_enable, active, supported, unicast);
6742 if (active && priv->qos_data.qos_enable) {
6743 ret = from_priority_to_tx_queue[priority];
6744 tx_queue_id = ret - 1;
6745 IPW_DEBUG_QOS("QoS packet priority is %d \n", priority);
6746 if (priority <= 7) {
6747 tfd->tx_flags_ext |= DCT_FLAG_EXT_QOS_ENABLED;
6748 tfd->tfd.tfd_26.mchdr.qos_ctrl = priority;
6749 tfd->tfd.tfd_26.mchdr.frame_ctl |=
6750 IEEE80211_STYPE_QOS_DATA;
6751
6752 if (priv->qos_data.qos_no_ack_mask &
6753 (1UL << tx_queue_id)) {
6754 tfd->tx_flags &= ~DCT_FLAG_ACK_REQD;
6755 tfd->tfd.tfd_26.mchdr.qos_ctrl |=
6756 CTRL_QOS_NO_ACK;
6757 }
6758 }
6759 }
6760
6761 return ret;
6762}
6763
6764/*
6765* background support to run QoS activate functionality
6766*/
6767static void ipw_bg_qos_activate(void *data)
6768{
6769 struct ipw_priv *priv = data;
6770
6771 if (priv == NULL)
6772 return;
6773
6774 down(&priv->sem);
6775
6776 if (priv->status & STATUS_ASSOCIATED)
6777 ipw_qos_activate(priv, &(priv->assoc_network->qos_data));
6778
6779 up(&priv->sem);
6780}
6781
6782/*
6783* Handler for probe responce and beacon frame
6784*/
6785static int ipw_handle_management_frame(struct net_device *dev,
6786 struct ieee80211_network *network,
6787 u16 type)
6788{
6789 struct ipw_priv *priv = ieee80211_priv(dev);
6790 int active_network;
6791
6792 if (priv->status & STATUS_ASSOCIATED && network == priv->assoc_network)
6793 active_network = 1;
6794 else
6795 active_network = 0;
6796
6797 switch (type) {
6798 case IEEE80211_STYPE_PROBE_RESP:
6799 case IEEE80211_STYPE_BEACON:
6800 ipw_qos_handle_probe_reponse(priv, active_network, network);
6801 break;
6802 case IEEE80211_STYPE_ASSOC_RESP:
6803 ipw_qos_association_resp(priv, network);
6804 break;
6805 default:
6806 break;
6807 }
6808
6809 return 0;
6810}
6811
6812static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
6813 *qos_param)
6814{
6815 struct host_cmd cmd = {
6816 .cmd = IPW_CMD_QOS_PARAMETERS,
6817 .len = (sizeof(struct ieee80211_qos_parameters) * 3)
6818 };
6819
6820 if (!priv || !qos_param) {
6821 IPW_ERROR("Invalid args\n");
6822 return -1;
6823 }
6824
6825 memcpy(&cmd.param, qos_param,
6826 (sizeof(struct ieee80211_qos_parameters) * 3));
6827 if (ipw_send_cmd(priv, &cmd)) {
6828 IPW_ERROR("failed to send IPW_CMD_QOS_PARAMETERS command\n");
6829 return -1;
6830 }
6831
6832 return 0;
6833}
6834
6835static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
6836 *qos_param)
6837{
6838 struct host_cmd cmd = {
6839 .cmd = IPW_CMD_WME_INFO,
6840 .len = sizeof(*qos_param)
6841 };
6842
6843 if (!priv || !qos_param) {
6844 IPW_ERROR("Invalid args\n");
6845 return -1;
6846 }
6847
6848 memcpy(&cmd.param, qos_param, sizeof(*qos_param));
6849 if (ipw_send_cmd(priv, &cmd)) {
6850 IPW_ERROR("failed to send CMD_QOS_INFO command\n");
6851 return -1;
6852 }
6853
6854 return 0;
6855}
6856
6857#endif /* CONFIG_IPW_QOS */
6858
6859static int ipw_associate_network(struct ipw_priv *priv,
6860 struct ieee80211_network *network,
6861 struct ipw_supported_rates *rates, int roaming)
6862{
6863 int err;
6864
6865 if (priv->config & CFG_FIXED_RATE)
6866 ipw_set_fixed_rate(priv, network->mode);
6867
6868 if (!(priv->config & CFG_STATIC_ESSID)) {
6869 priv->essid_len = min(network->ssid_len,
6870 (u8) IW_ESSID_MAX_SIZE);
6871 memcpy(priv->essid, network->ssid, priv->essid_len);
6872 }
6873
6874 network->last_associate = jiffies;
6875
6876 memset(&priv->assoc_request, 0, sizeof(priv->assoc_request));
6877 priv->assoc_request.channel = network->channel;
6878 if ((priv->capability & CAP_PRIVACY_ON) &&
6879 (priv->capability & CAP_SHARED_KEY)) {
6880 priv->assoc_request.auth_type = AUTH_SHARED_KEY;
6881 priv->assoc_request.auth_key = priv->ieee->sec.active_key;
6882
6883 if ((priv->capability & CAP_PRIVACY_ON) &&
6884 (priv->ieee->sec.level == SEC_LEVEL_1) &&
6885 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
6886 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
6887 } else {
6888 priv->assoc_request.auth_type = AUTH_OPEN;
6889 priv->assoc_request.auth_key = 0;
6890 }
6891
6892 if (priv->ieee->wpa_ie_len) {
ea2b26e0
JK
6893 priv->assoc_request.policy_support = 0x02; /* RSN active */
6894 ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
6895 priv->ieee->wpa_ie_len);
6896 }
ea2b26e0
JK
6897
6898 /*
6899 * It is valid for our ieee device to support multiple modes, but
6900 * when it comes to associating to a given network we have to choose
6901 * just one mode.
6902 */
6903 if (network->mode & priv->ieee->mode & IEEE_A)
6904 priv->assoc_request.ieee_mode = IPW_A_MODE;
6905 else if (network->mode & priv->ieee->mode & IEEE_G)
6906 priv->assoc_request.ieee_mode = IPW_G_MODE;
6907 else if (network->mode & priv->ieee->mode & IEEE_B)
6908 priv->assoc_request.ieee_mode = IPW_B_MODE;
6909
6910 priv->assoc_request.capability = network->capability;
6911 if ((network->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
6912 && !(priv->config & CFG_PREAMBLE_LONG)) {
6913 priv->assoc_request.preamble_length = DCT_FLAG_SHORT_PREAMBLE;
6914 } else {
6915 priv->assoc_request.preamble_length = DCT_FLAG_LONG_PREAMBLE;
6916
6917 /* Clear the short preamble if we won't be supporting it */
6918 priv->assoc_request.capability &=
6919 ~WLAN_CAPABILITY_SHORT_PREAMBLE;
6920 }
6921
6922 IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
6923 "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
6924 roaming ? "Rea" : "A",
6925 escape_essid(priv->essid, priv->essid_len),
6926 network->channel,
6927 ipw_modes[priv->assoc_request.ieee_mode],
6928 rates->num_rates,
6929 (priv->assoc_request.preamble_length ==
6930 DCT_FLAG_LONG_PREAMBLE) ? "long" : "short",
6931 network->capability &
6932 WLAN_CAPABILITY_SHORT_PREAMBLE ? "short" : "long",
6933 priv->capability & CAP_PRIVACY_ON ? "on " : "off",
6934 priv->capability & CAP_PRIVACY_ON ?
6935 (priv->capability & CAP_SHARED_KEY ? "(shared)" :
6936 "(open)") : "",
6937 priv->capability & CAP_PRIVACY_ON ? " key=" : "",
6938 priv->capability & CAP_PRIVACY_ON ?
b095c381 6939 '1' + priv->ieee->sec.active_key : '.',
ea2b26e0
JK
6940 priv->capability & CAP_PRIVACY_ON ? '.' : ' ');
6941
6942 priv->assoc_request.beacon_interval = network->beacon_interval;
6943 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
6944 (network->time_stamp[0] == 0) && (network->time_stamp[1] == 0)) {
6945 priv->assoc_request.assoc_type = HC_IBSS_START;
6946 priv->assoc_request.assoc_tsf_msw = 0;
6947 priv->assoc_request.assoc_tsf_lsw = 0;
6948 } else {
6949 if (unlikely(roaming))
6950 priv->assoc_request.assoc_type = HC_REASSOCIATE;
6951 else
6952 priv->assoc_request.assoc_type = HC_ASSOCIATE;
6953 priv->assoc_request.assoc_tsf_msw = network->time_stamp[1];
6954 priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0];
6955 }
6956
6957 memcpy(&priv->assoc_request.bssid, network->bssid, ETH_ALEN);
6958
6959 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
6960 memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN);
6961 priv->assoc_request.atim_window = network->atim_window;
6962 } else {
6963 memcpy(&priv->assoc_request.dest, network->bssid, ETH_ALEN);
6964 priv->assoc_request.atim_window = 0;
6965 }
6966
6967 priv->assoc_request.listen_interval = network->listen_interval;
6968
6969 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
6970 if (err) {
6971 IPW_DEBUG_HC("Attempt to send SSID command failed.\n");
6972 return err;
6973 }
6974
6975 rates->ieee_mode = priv->assoc_request.ieee_mode;
6976 rates->purpose = IPW_RATE_CONNECT;
6977 ipw_send_supported_rates(priv, rates);
6978
6979 if (priv->assoc_request.ieee_mode == IPW_G_MODE)
6980 priv->sys_config.dot11g_auto_detection = 1;
6981 else
6982 priv->sys_config.dot11g_auto_detection = 0;
c848d0af
JK
6983
6984 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
6985 priv->sys_config.answer_broadcast_ssid_probe = 1;
6986 else
6987 priv->sys_config.answer_broadcast_ssid_probe = 0;
6988
ea2b26e0
JK
6989 err = ipw_send_system_config(priv, &priv->sys_config);
6990 if (err) {
6991 IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
6992 return err;
6993 }
6994
6995 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi);
6996 err = ipw_set_sensitivity(priv, network->stats.rssi + IPW_RSSI_TO_DBM);
6997 if (err) {
6998 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
6999 return err;
7000 }
7001
7002 /*
7003 * If preemption is enabled, it is possible for the association
7004 * to complete before we return from ipw_send_associate. Therefore
7005 * we have to be sure and update our priviate data first.
7006 */
7007 priv->channel = network->channel;
7008 memcpy(priv->bssid, network->bssid, ETH_ALEN);
7009 priv->status |= STATUS_ASSOCIATING;
7010 priv->status &= ~STATUS_SECURITY_UPDATED;
7011
7012 priv->assoc_network = network;
7013
b095c381
JK
7014#ifdef CONFIG_IPW_QOS
7015 ipw_qos_association(priv, network);
7016#endif
7017
ea2b26e0
JK
7018 err = ipw_send_associate(priv, &priv->assoc_request);
7019 if (err) {
43f66a6c
JK
7020 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
7021 return err;
7022 }
bf79451e
JG
7023
7024 IPW_DEBUG(IPW_DL_STATE, "associating: '%s' " MAC_FMT " \n",
43f66a6c
JK
7025 escape_essid(priv->essid, priv->essid_len),
7026 MAC_ARG(priv->bssid));
7027
7028 return 0;
7029}
7030
7031static void ipw_roam(void *data)
7032{
7033 struct ipw_priv *priv = data;
7034 struct ieee80211_network *network = NULL;
7035 struct ipw_network_match match = {
7036 .network = priv->assoc_network
7037 };
7038
7039 /* The roaming process is as follows:
bf79451e
JG
7040 *
7041 * 1. Missed beacon threshold triggers the roaming process by
43f66a6c
JK
7042 * setting the status ROAM bit and requesting a scan.
7043 * 2. When the scan completes, it schedules the ROAM work
7044 * 3. The ROAM work looks at all of the known networks for one that
7045 * is a better network than the currently associated. If none
7046 * found, the ROAM process is over (ROAM bit cleared)
7047 * 4. If a better network is found, a disassociation request is
7048 * sent.
7049 * 5. When the disassociation completes, the roam work is again
7050 * scheduled. The second time through, the driver is no longer
7051 * associated, and the newly selected network is sent an
bf79451e 7052 * association request.
43f66a6c
JK
7053 * 6. At this point ,the roaming process is complete and the ROAM
7054 * status bit is cleared.
7055 */
7056
7057 /* If we are no longer associated, and the roaming bit is no longer
7058 * set, then we are not actively roaming, so just return */
7059 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ROAMING)))
7060 return;
bf79451e 7061
43f66a6c 7062 if (priv->status & STATUS_ASSOCIATED) {
bf79451e 7063 /* First pass through ROAM process -- look for a better
43f66a6c 7064 * network */
a613bffd 7065 unsigned long flags;
43f66a6c
JK
7066 u8 rssi = priv->assoc_network->stats.rssi;
7067 priv->assoc_network->stats.rssi = -128;
a613bffd 7068 spin_lock_irqsave(&priv->ieee->lock, flags);
43f66a6c
JK
7069 list_for_each_entry(network, &priv->ieee->network_list, list) {
7070 if (network != priv->assoc_network)
7071 ipw_best_network(priv, &match, network, 1);
7072 }
a613bffd 7073 spin_unlock_irqrestore(&priv->ieee->lock, flags);
43f66a6c 7074 priv->assoc_network->stats.rssi = rssi;
bf79451e 7075
43f66a6c
JK
7076 if (match.network == priv->assoc_network) {
7077 IPW_DEBUG_ASSOC("No better APs in this network to "
7078 "roam to.\n");
7079 priv->status &= ~STATUS_ROAMING;
7080 ipw_debug_config(priv);
7081 return;
7082 }
bf79451e 7083
43f66a6c
JK
7084 ipw_send_disassociate(priv, 1);
7085 priv->assoc_network = match.network;
7086
7087 return;
bf79451e 7088 }
43f66a6c
JK
7089
7090 /* Second pass through ROAM process -- request association */
7091 ipw_compatible_rates(priv, priv->assoc_network, &match.rates);
7092 ipw_associate_network(priv, priv->assoc_network, &match.rates, 1);
7093 priv->status &= ~STATUS_ROAMING;
7094}
7095
c848d0af
JK
7096static void ipw_bg_roam(void *data)
7097{
7098 struct ipw_priv *priv = data;
7099 down(&priv->sem);
7100 ipw_roam(data);
7101 up(&priv->sem);
7102}
7103
7104static int ipw_associate(void *data)
43f66a6c
JK
7105{
7106 struct ipw_priv *priv = data;
7107
7108 struct ieee80211_network *network = NULL;
7109 struct ipw_network_match match = {
7110 .network = NULL
7111 };
7112 struct ipw_supported_rates *rates;
7113 struct list_head *element;
a613bffd 7114 unsigned long flags;
43f66a6c 7115
b095c381
JK
7116 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7117 IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n");
7118 return 0;
7119 }
7120
c848d0af
JK
7121 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
7122 IPW_DEBUG_ASSOC
7123 ("Not attempting association (already in progress)\n");
7124 return 0;
7125 }
7126
7127 if (!ipw_is_init(priv) || (priv->status & STATUS_SCANNING)) {
7128 IPW_DEBUG_ASSOC
7129 ("Not attempting association (scanning or not initialized)\n");
7130 return 0;
7131 }
7132
43f66a6c
JK
7133 if (!(priv->config & CFG_ASSOCIATE) &&
7134 !(priv->config & (CFG_STATIC_ESSID |
0edd5b44 7135 CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) {
43f66a6c 7136 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
c848d0af 7137 return 0;
43f66a6c
JK
7138 }
7139
a613bffd
JK
7140 /* Protect our use of the network_list */
7141 spin_lock_irqsave(&priv->ieee->lock, flags);
bf79451e 7142 list_for_each_entry(network, &priv->ieee->network_list, list)
0edd5b44 7143 ipw_best_network(priv, &match, network, 0);
43f66a6c
JK
7144
7145 network = match.network;
7146 rates = &match.rates;
7147
7148 if (network == NULL &&
7149 priv->ieee->iw_mode == IW_MODE_ADHOC &&
7150 priv->config & CFG_ADHOC_CREATE &&
7151 priv->config & CFG_STATIC_ESSID &&
a613bffd 7152 priv->config & CFG_STATIC_CHANNEL &&
43f66a6c
JK
7153 !list_empty(&priv->ieee->network_free_list)) {
7154 element = priv->ieee->network_free_list.next;
0edd5b44 7155 network = list_entry(element, struct ieee80211_network, list);
43f66a6c
JK
7156 ipw_adhoc_create(priv, network);
7157 rates = &priv->rates;
7158 list_del(element);
7159 list_add_tail(&network->list, &priv->ieee->network_list);
7160 }
a613bffd 7161 spin_unlock_irqrestore(&priv->ieee->lock, flags);
bf79451e 7162
43f66a6c
JK
7163 /* If we reached the end of the list, then we don't have any valid
7164 * matching APs */
7165 if (!network) {
7166 ipw_debug_config(priv);
7167
b095c381
JK
7168 if (!(priv->status & STATUS_SCANNING)) {
7169 if (!(priv->config & CFG_SPEED_SCAN))
7170 queue_delayed_work(priv->workqueue,
7171 &priv->request_scan,
7172 SCAN_INTERVAL);
7173 else
7174 queue_work(priv->workqueue,
7175 &priv->request_scan);
7176 }
bf79451e 7177
c848d0af 7178 return 0;
43f66a6c
JK
7179 }
7180
7181 ipw_associate_network(priv, network, rates, 0);
c848d0af
JK
7182
7183 return 1;
7184}
7185
7186static void ipw_bg_associate(void *data)
7187{
7188 struct ipw_priv *priv = data;
7189 down(&priv->sem);
7190 ipw_associate(data);
7191 up(&priv->sem);
43f66a6c 7192}
bf79451e 7193
b095c381
JK
7194static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
7195 struct sk_buff *skb)
7196{
7197 struct ieee80211_hdr *hdr;
7198 u16 fc;
7199
7200 hdr = (struct ieee80211_hdr *)skb->data;
7201 fc = le16_to_cpu(hdr->frame_ctl);
7202 if (!(fc & IEEE80211_FCTL_PROTECTED))
7203 return;
7204
7205 fc &= ~IEEE80211_FCTL_PROTECTED;
7206 hdr->frame_ctl = cpu_to_le16(fc);
7207 switch (priv->ieee->sec.level) {
7208 case SEC_LEVEL_3:
7209 /* Remove CCMP HDR */
7210 memmove(skb->data + IEEE80211_3ADDR_LEN,
7211 skb->data + IEEE80211_3ADDR_LEN + 8,
7212 skb->len - IEEE80211_3ADDR_LEN - 8);
7213 skb_trim(skb, skb->len - 8); /* MIC */
7214 break;
7215 case SEC_LEVEL_2:
7216 break;
7217 case SEC_LEVEL_1:
7218 /* Remove IV */
7219 memmove(skb->data + IEEE80211_3ADDR_LEN,
7220 skb->data + IEEE80211_3ADDR_LEN + 4,
7221 skb->len - IEEE80211_3ADDR_LEN - 4);
7222 skb_trim(skb, skb->len - 4); /* ICV */
7223 break;
7224 case SEC_LEVEL_0:
7225 break;
7226 default:
7227 printk(KERN_ERR "Unknow security level %d\n",
7228 priv->ieee->sec.level);
7229 break;
7230 }
7231}
7232
7233static void ipw_handle_data_packet(struct ipw_priv *priv,
7234 struct ipw_rx_mem_buffer *rxb,
7235 struct ieee80211_rx_stats *stats)
43f66a6c
JK
7236{
7237 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7238
7239 /* We received data from the HW, so stop the watchdog */
7240 priv->net_dev->trans_start = jiffies;
7241
bf79451e 7242 /* We only process data packets if the
43f66a6c 7243 * interface is open */
a613bffd 7244 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
43f66a6c
JK
7245 skb_tailroom(rxb->skb))) {
7246 priv->ieee->stats.rx_errors++;
7247 priv->wstats.discard.misc++;
7248 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
7249 return;
7250 } else if (unlikely(!netif_running(priv->net_dev))) {
7251 priv->ieee->stats.rx_dropped++;
7252 priv->wstats.discard.misc++;
7253 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
7254 return;
7255 }
7256
7257 /* Advance skb->data to the start of the actual payload */
aaa4d308 7258 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data));
43f66a6c
JK
7259
7260 /* Set the size of the skb to the size of the frame */
a613bffd 7261 skb_put(rxb->skb, le16_to_cpu(pkt->u.frame.length));
43f66a6c
JK
7262
7263 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
7264
b095c381
JK
7265 /* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
7266 if (!priv->ieee->host_decrypt)
7267 ipw_rebuild_decrypted_skb(priv, rxb->skb);
7268
bf79451e 7269 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
43f66a6c 7270 priv->ieee->stats.rx_errors++;
a613bffd 7271 else { /* ieee80211_rx succeeded, so it now owns the SKB */
43f66a6c 7272 rxb->skb = NULL;
b095c381 7273 __ipw_led_activity_on(priv);
a613bffd 7274 }
43f66a6c
JK
7275}
7276
ea2b26e0
JK
7277static inline int is_network_packet(struct ipw_priv *priv,
7278 struct ieee80211_hdr_4addr *header)
7279{
7280 /* Filter incoming packets to determine if they are targetted toward
7281 * this network, discarding packets coming from ourselves */
7282 switch (priv->ieee->iw_mode) {
a613bffd 7283 case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */
c848d0af
JK
7284 /* packets from our adapter are dropped (echo) */
7285 if (!memcmp(header->addr2, priv->net_dev->dev_addr, ETH_ALEN))
7286 return 0;
7287
a613bffd 7288 /* {broad,multi}cast packets to our IBSS go through */
ea2b26e0
JK
7289 if (is_broadcast_ether_addr(header->addr1) ||
7290 is_multicast_ether_addr(header->addr1))
7291 return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
a613bffd
JK
7292
7293 /* packets to our adapter go through */
7294 return !memcmp(header->addr1, priv->net_dev->dev_addr,
7295 ETH_ALEN);
a613bffd
JK
7296
7297 case IW_MODE_INFRA: /* Header: Dest. | AP{BSSID} | Source */
c848d0af
JK
7298 /* packets from our adapter are dropped (echo) */
7299 if (!memcmp(header->addr3, priv->net_dev->dev_addr, ETH_ALEN))
7300 return 0;
7301
a613bffd
JK
7302 /* {broad,multi}cast packets to our IBSS go through */
7303 if (is_broadcast_ether_addr(header->addr1) ||
7304 is_multicast_ether_addr(header->addr1))
7305 return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
7306
7307 /* packets to our adapter go through */
7308 return !memcmp(header->addr1, priv->net_dev->dev_addr,
7309 ETH_ALEN);
ea2b26e0 7310 }
a613bffd 7311
ea2b26e0
JK
7312 return 1;
7313}
7314
b095c381
JK
7315static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
7316 struct ipw_rx_mem_buffer *rxb,
7317 struct ieee80211_rx_stats *stats)
7318{
7319 struct sk_buff *skb = rxb->skb;
7320 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)skb->data;
7321 struct ieee80211_hdr_4addr *header = (struct ieee80211_hdr_4addr *)
7322 (skb->data + IPW_RX_FRAME_SIZE);
7323
7324 ieee80211_rx_mgt(priv->ieee, header, stats);
7325
7326 if (priv->ieee->iw_mode == IW_MODE_ADHOC &&
7327 ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
7328 IEEE80211_STYPE_PROBE_RESP) ||
7329 (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
7330 IEEE80211_STYPE_BEACON))) {
7331 if (!memcmp(header->addr3, priv->bssid, ETH_ALEN))
7332 ipw_add_station(priv, header->addr2);
7333 }
7334
7335 if (priv->config & CFG_NET_STATS) {
7336 IPW_DEBUG_HC("sending stat packet\n");
7337
7338 /* Set the size of the skb to the size of the full
7339 * ipw header and 802.11 frame */
7340 skb_put(skb, le16_to_cpu(pkt->u.frame.length) +
7341 IPW_RX_FRAME_SIZE);
7342
7343 /* Advance past the ipw packet header to the 802.11 frame */
7344 skb_pull(skb, IPW_RX_FRAME_SIZE);
7345
7346 /* Push the ieee80211_rx_stats before the 802.11 frame */
7347 memcpy(skb_push(skb, sizeof(*stats)), stats, sizeof(*stats));
7348
7349 skb->dev = priv->ieee->dev;
7350
7351 /* Point raw at the ieee80211_stats */
7352 skb->mac.raw = skb->data;
7353
7354 skb->pkt_type = PACKET_OTHERHOST;
7355 skb->protocol = __constant_htons(ETH_P_80211_STATS);
7356 memset(skb->cb, 0, sizeof(rxb->skb->cb));
7357 netif_rx(skb);
7358 rxb->skb = NULL;
7359 }
7360}
7361
43f66a6c
JK
7362/*
7363 * Main entry function for recieving a packet with 80211 headers. This
7364 * should be called when ever the FW has notified us that there is a new
7365 * skb in the recieve queue.
7366 */
7367static void ipw_rx(struct ipw_priv *priv)
7368{
7369 struct ipw_rx_mem_buffer *rxb;
7370 struct ipw_rx_packet *pkt;
0dacca1f 7371 struct ieee80211_hdr_4addr *header;
43f66a6c
JK
7372 u32 r, w, i;
7373 u8 network_packet;
7374
b095c381
JK
7375 r = ipw_read32(priv, IPW_RX_READ_INDEX);
7376 w = ipw_read32(priv, IPW_RX_WRITE_INDEX);
43f66a6c
JK
7377 i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE;
7378
7379 while (i != r) {
7380 rxb = priv->rxq->queue[i];
7381#ifdef CONFIG_IPW_DEBUG
7382 if (unlikely(rxb == NULL)) {
7383 printk(KERN_CRIT "Queue not allocated!\n");
7384 break;
7385 }
7386#endif
7387 priv->rxq->queue[i] = NULL;
7388
7389 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
b095c381 7390 IPW_RX_BUF_SIZE,
43f66a6c
JK
7391 PCI_DMA_FROMDEVICE);
7392
7393 pkt = (struct ipw_rx_packet *)rxb->skb->data;
7394 IPW_DEBUG_RX("Packet: type=%02X seq=%02X bits=%02X\n",
7395 pkt->header.message_type,
0edd5b44 7396 pkt->header.rx_seq_num, pkt->header.control_bits);
43f66a6c
JK
7397
7398 switch (pkt->header.message_type) {
0edd5b44
JG
7399 case RX_FRAME_TYPE: /* 802.11 frame */ {
7400 struct ieee80211_rx_stats stats = {
c848d0af
JK
7401 .rssi =
7402 le16_to_cpu(pkt->u.frame.rssi_dbm) -
0edd5b44 7403 IPW_RSSI_TO_DBM,
c848d0af
JK
7404 .signal =
7405 le16_to_cpu(pkt->u.frame.signal),
7406 .noise =
7407 le16_to_cpu(pkt->u.frame.noise),
0edd5b44
JG
7408 .rate = pkt->u.frame.rate,
7409 .mac_time = jiffies,
7410 .received_channel =
7411 pkt->u.frame.received_channel,
7412 .freq =
7413 (pkt->u.frame.
7414 control & (1 << 0)) ?
7415 IEEE80211_24GHZ_BAND :
7416 IEEE80211_52GHZ_BAND,
a613bffd 7417 .len = le16_to_cpu(pkt->u.frame.length),
0edd5b44
JG
7418 };
7419
7420 if (stats.rssi != 0)
7421 stats.mask |= IEEE80211_STATMASK_RSSI;
7422 if (stats.signal != 0)
7423 stats.mask |= IEEE80211_STATMASK_SIGNAL;
c848d0af
JK
7424 if (stats.noise != 0)
7425 stats.mask |= IEEE80211_STATMASK_NOISE;
0edd5b44
JG
7426 if (stats.rate != 0)
7427 stats.mask |= IEEE80211_STATMASK_RATE;
7428
7429 priv->rx_packets++;
43f66a6c 7430
b095c381 7431#ifdef CONFIG_IPW2200_MONITOR
0edd5b44
JG
7432 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7433 ipw_handle_data_packet(priv, rxb,
7434 &stats);
7435 break;
7436 }
43f66a6c 7437#endif
bf79451e 7438
0edd5b44 7439 header =
0dacca1f
JK
7440 (struct ieee80211_hdr_4addr *)(rxb->skb->
7441 data +
7442 IPW_RX_FRAME_SIZE);
43f66a6c
JK
7443 /* TODO: Check Ad-Hoc dest/source and make sure
7444 * that we are actually parsing these packets
bf79451e 7445 * correctly -- we should probably use the
43f66a6c
JK
7446 * frame control of the packet and disregard
7447 * the current iw_mode */
0edd5b44 7448
ea2b26e0
JK
7449 network_packet =
7450 is_network_packet(priv, header);
0edd5b44
JG
7451 if (network_packet && priv->assoc_network) {
7452 priv->assoc_network->stats.rssi =
7453 stats.rssi;
7454 average_add(&priv->average_rssi,
7455 stats.rssi);
7456 priv->last_rx_rssi = stats.rssi;
7457 }
7458
7459 IPW_DEBUG_RX("Frame: len=%u\n",
a613bffd 7460 le16_to_cpu(pkt->u.frame.length));
0edd5b44 7461
a613bffd
JK
7462 if (le16_to_cpu(pkt->u.frame.length) <
7463 frame_hdr_len(header)) {
0edd5b44
JG
7464 IPW_DEBUG_DROP
7465 ("Received packet is too small. "
7466 "Dropping.\n");
7467 priv->ieee->stats.rx_errors++;
7468 priv->wstats.discard.misc++;
7469 break;
7470 }
7471
a613bffd
JK
7472 switch (WLAN_FC_GET_TYPE
7473 (le16_to_cpu(header->frame_ctl))) {
b095c381 7474
0edd5b44 7475 case IEEE80211_FTYPE_MGMT:
b095c381
JK
7476 ipw_handle_mgmt_packet(priv, rxb,
7477 &stats);
0edd5b44
JG
7478 break;
7479
7480 case IEEE80211_FTYPE_CTL:
7481 break;
7482
7483 case IEEE80211_FTYPE_DATA:
b095c381 7484 if (unlikely(!network_packet)) {
0edd5b44
JG
7485 IPW_DEBUG_DROP("Dropping: "
7486 MAC_FMT ", "
7487 MAC_FMT ", "
7488 MAC_FMT "\n",
7489 MAC_ARG(header->
7490 addr1),
7491 MAC_ARG(header->
7492 addr2),
7493 MAC_ARG(header->
7494 addr3));
b095c381
JK
7495 break;
7496 }
7497
7498 ipw_handle_data_packet(priv, rxb,
7499 &stats);
7500
0edd5b44
JG
7501 break;
7502 }
43f66a6c
JK
7503 break;
7504 }
bf79451e 7505
0edd5b44
JG
7506 case RX_HOST_NOTIFICATION_TYPE:{
7507 IPW_DEBUG_RX
7508 ("Notification: subtype=%02X flags=%02X size=%d\n",
43f66a6c
JK
7509 pkt->u.notification.subtype,
7510 pkt->u.notification.flags,
7511 pkt->u.notification.size);
0edd5b44
JG
7512 ipw_rx_notification(priv, &pkt->u.notification);
7513 break;
7514 }
43f66a6c
JK
7515
7516 default:
7517 IPW_DEBUG_RX("Bad Rx packet of type %d\n",
7518 pkt->header.message_type);
7519 break;
7520 }
bf79451e
JG
7521
7522 /* For now we just don't re-use anything. We can tweak this
7523 * later to try and re-use notification packets and SKBs that
43f66a6c
JK
7524 * fail to Rx correctly */
7525 if (rxb->skb != NULL) {
7526 dev_kfree_skb_any(rxb->skb);
7527 rxb->skb = NULL;
7528 }
bf79451e 7529
43f66a6c 7530 pci_unmap_single(priv->pci_dev, rxb->dma_addr,
b095c381 7531 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
43f66a6c 7532 list_add_tail(&rxb->list, &priv->rxq->rx_used);
bf79451e 7533
43f66a6c
JK
7534 i = (i + 1) % RX_QUEUE_SIZE;
7535 }
7536
7537 /* Backtrack one entry */
7538 priv->rxq->processed = (i ? i : RX_QUEUE_SIZE) - 1;
7539
7540 ipw_rx_queue_restock(priv);
7541}
7542
43f66a6c
JK
7543/*
7544 * This file defines the Wireless Extension handlers. It does not
7545 * define any methods of hardware manipulation and relies on the
7546 * functions defined in ipw_main to provide the HW interaction.
bf79451e
JG
7547 *
7548 * The exception to this is the use of the ipw_get_ordinal()
43f66a6c
JK
7549 * function used to poll the hardware vs. making unecessary calls.
7550 *
7551 */
7552
bf79451e
JG
7553static int ipw_wx_get_name(struct net_device *dev,
7554 struct iw_request_info *info,
43f66a6c
JK
7555 union iwreq_data *wrqu, char *extra)
7556{
7557 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af
JK
7558 down(&priv->sem);
7559 if (priv->status & STATUS_RF_KILL_MASK)
a613bffd 7560 strcpy(wrqu->name, "radio off");
c848d0af 7561 else if (!(priv->status & STATUS_ASSOCIATED))
43f66a6c 7562 strcpy(wrqu->name, "unassociated");
bf79451e 7563 else
43f66a6c
JK
7564 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
7565 ipw_modes[priv->assoc_request.ieee_mode]);
7566 IPW_DEBUG_WX("Name: %s\n", wrqu->name);
c848d0af 7567 up(&priv->sem);
43f66a6c
JK
7568 return 0;
7569}
7570
7571static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
7572{
b095c381
JK
7573 int i;
7574
43f66a6c
JK
7575 if (channel == 0) {
7576 IPW_DEBUG_INFO("Setting channel to ANY (0)\n");
7577 priv->config &= ~CFG_STATIC_CHANNEL;
c848d0af
JK
7578 IPW_DEBUG_ASSOC("Attempting to associate with new "
7579 "parameters.\n");
7580 ipw_associate(priv);
43f66a6c
JK
7581 return 0;
7582 }
7583
7584 priv->config |= CFG_STATIC_CHANNEL;
7585
7586 if (priv->channel == channel) {
0edd5b44
JG
7587 IPW_DEBUG_INFO("Request to set channel to current value (%d)\n",
7588 channel);
43f66a6c
JK
7589 return 0;
7590 }
7591
7592 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel);
7593 priv->channel = channel;
7594
b095c381
JK
7595#ifdef CONFIG_IPW2200_MONITOR
7596 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7597 if (priv->status & STATUS_SCANNING) {
7598 IPW_DEBUG_SCAN("scan abort triggered due to "
7599 "channel change.\n");
7600 queue_work(priv->workqueue, &priv->abort_scan);
7601 }
7602
7603 for (i = 1000; i && (priv->status & STATUS_SCANNING); i--)
7604 udelay(10);
7605
7606 if (priv->status & STATUS_SCANNING)
7607 IPW_DEBUG_SCAN("Still scanning...\n");
7608 else
7609 IPW_DEBUG_SCAN("Took %dms to abort current scan\n",
7610 1000 - i);
7611
7612 return 0;
7613 }
7614#endif /* CONFIG_IPW2200_MONITOR */
7615
c848d0af
JK
7616 /* Network configuration changed -- force [re]association */
7617 IPW_DEBUG_ASSOC("[re]association triggered due to channel change.\n");
7618 if (!ipw_disassociate(priv))
43f66a6c 7619 ipw_associate(priv);
43f66a6c
JK
7620
7621 return 0;
7622}
7623
bf79451e
JG
7624static int ipw_wx_set_freq(struct net_device *dev,
7625 struct iw_request_info *info,
7626 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
7627{
7628 struct ipw_priv *priv = ieee80211_priv(dev);
7629 struct iw_freq *fwrq = &wrqu->freq;
c848d0af 7630 int ret = 0;
b095c381
JK
7631 u8 channel;
7632
7633 if (fwrq->m == 0) {
7634 IPW_DEBUG_WX("SET Freq/Channel -> any\n");
7635 down(&priv->sem);
7636 ret = ipw_set_channel(priv, 0);
7637 up(&priv->sem);
7638 return ret;
7639 }
bf79451e 7640
43f66a6c
JK
7641 /* if setting by freq convert to channel */
7642 if (fwrq->e == 1) {
b095c381
JK
7643 channel = ieee80211_freq_to_channel(priv->ieee, fwrq->m);
7644 if (channel == 0)
7645 return -EINVAL;
7646 } else
7647 channel = fwrq->m;
bf79451e 7648
b095c381
JK
7649 if (!ieee80211_is_valid_channel(priv->ieee, channel))
7650 return -EINVAL;
43f66a6c
JK
7651
7652 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
c848d0af 7653 down(&priv->sem);
b095c381 7654 ret = ipw_set_channel(priv, channel);
c848d0af
JK
7655 up(&priv->sem);
7656 return ret;
43f66a6c
JK
7657}
7658
bf79451e
JG
7659static int ipw_wx_get_freq(struct net_device *dev,
7660 struct iw_request_info *info,
43f66a6c
JK
7661 union iwreq_data *wrqu, char *extra)
7662{
7663 struct ipw_priv *priv = ieee80211_priv(dev);
7664
7665 wrqu->freq.e = 0;
7666
7667 /* If we are associated, trying to associate, or have a statically
7668 * configured CHANNEL then return that; otherwise return ANY */
c848d0af 7669 down(&priv->sem);
43f66a6c
JK
7670 if (priv->config & CFG_STATIC_CHANNEL ||
7671 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))
7672 wrqu->freq.m = priv->channel;
bf79451e 7673 else
43f66a6c
JK
7674 wrqu->freq.m = 0;
7675
c848d0af 7676 up(&priv->sem);
43f66a6c
JK
7677 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
7678 return 0;
7679}
7680
bf79451e
JG
7681static int ipw_wx_set_mode(struct net_device *dev,
7682 struct iw_request_info *info,
43f66a6c
JK
7683 union iwreq_data *wrqu, char *extra)
7684{
7685 struct ipw_priv *priv = ieee80211_priv(dev);
7686 int err = 0;
7687
7688 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);
43f66a6c
JK
7689
7690 switch (wrqu->mode) {
b095c381 7691#ifdef CONFIG_IPW2200_MONITOR
43f66a6c
JK
7692 case IW_MODE_MONITOR:
7693#endif
7694 case IW_MODE_ADHOC:
7695 case IW_MODE_INFRA:
7696 break;
7697 case IW_MODE_AUTO:
7698 wrqu->mode = IW_MODE_INFRA;
7699 break;
7700 default:
7701 return -EINVAL;
7702 }
b095c381
JK
7703 if (wrqu->mode == priv->ieee->iw_mode)
7704 return 0;
43f66a6c 7705
b095c381
JK
7706 down(&priv->sem);
7707#ifdef CONFIG_IPW2200_MONITOR
bf79451e 7708 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
43f66a6c 7709 priv->net_dev->type = ARPHRD_ETHER;
bf79451e
JG
7710
7711 if (wrqu->mode == IW_MODE_MONITOR)
43f66a6c 7712 priv->net_dev->type = ARPHRD_IEEE80211;
b095c381 7713#endif /* CONFIG_IPW2200_MONITOR */
bf79451e 7714
43f66a6c 7715#ifdef CONFIG_PM
bf79451e 7716 /* Free the existing firmware and reset the fw_loaded
43f66a6c 7717 * flag so ipw_load() will bring in the new firmawre */
a613bffd 7718 if (fw_loaded)
43f66a6c 7719 fw_loaded = 0;
43f66a6c
JK
7720
7721 release_firmware(bootfw);
7722 release_firmware(ucode);
7723 release_firmware(firmware);
7724 bootfw = ucode = firmware = NULL;
7725#endif
7726
7727 priv->ieee->iw_mode = wrqu->mode;
bf79451e 7728
c848d0af
JK
7729 queue_work(priv->workqueue, &priv->adapter_restart);
7730 up(&priv->sem);
0edd5b44 7731 return err;
43f66a6c
JK
7732}
7733
bf79451e 7734static int ipw_wx_get_mode(struct net_device *dev,
0edd5b44
JG
7735 struct iw_request_info *info,
7736 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
7737{
7738 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 7739 down(&priv->sem);
43f66a6c
JK
7740 wrqu->mode = priv->ieee->iw_mode;
7741 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
c848d0af 7742 up(&priv->sem);
43f66a6c
JK
7743 return 0;
7744}
7745
43f66a6c
JK
7746#define DEFAULT_RTS_THRESHOLD 2304U
7747#define MIN_RTS_THRESHOLD 1U
7748#define MAX_RTS_THRESHOLD 2304U
7749#define DEFAULT_BEACON_INTERVAL 100U
7750#define DEFAULT_SHORT_RETRY_LIMIT 7U
7751#define DEFAULT_LONG_RETRY_LIMIT 4U
7752
7753/* Values are in microsecond */
7754static const s32 timeout_duration[] = {
7755 350000,
7756 250000,
7757 75000,
7758 37000,
7759 25000,
7760};
7761
7762static const s32 period_duration[] = {
7763 400000,
7764 700000,
7765 1000000,
7766 1000000,
7767 1000000
7768};
7769
bf79451e
JG
7770static int ipw_wx_get_range(struct net_device *dev,
7771 struct iw_request_info *info,
43f66a6c
JK
7772 union iwreq_data *wrqu, char *extra)
7773{
7774 struct ipw_priv *priv = ieee80211_priv(dev);
7775 struct iw_range *range = (struct iw_range *)extra;
b095c381
JK
7776 const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
7777 int i = 0, j;
43f66a6c
JK
7778
7779 wrqu->data.length = sizeof(*range);
7780 memset(range, 0, sizeof(*range));
7781
7782 /* 54Mbs == ~27 Mb/s real (802.11g) */
bf79451e 7783 range->throughput = 27 * 1000 * 1000;
43f66a6c
JK
7784
7785 range->max_qual.qual = 100;
7786 /* TODO: Find real max RSSI and stick here */
7787 range->max_qual.level = 0;
c848d0af 7788 range->max_qual.noise = priv->ieee->worst_rssi + 0x100;
0edd5b44 7789 range->max_qual.updated = 7; /* Updated all three */
43f66a6c
JK
7790
7791 range->avg_qual.qual = 70;
7792 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
0edd5b44 7793 range->avg_qual.level = 0; /* FIXME to real average level */
43f66a6c 7794 range->avg_qual.noise = 0;
0edd5b44 7795 range->avg_qual.updated = 7; /* Updated all three */
c848d0af 7796 down(&priv->sem);
0edd5b44 7797 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
43f66a6c 7798
bf79451e
JG
7799 for (i = 0; i < range->num_bitrates; i++)
7800 range->bitrate[i] = (priv->rates.supported_rates[i] & 0x7F) *
0edd5b44 7801 500000;
bf79451e 7802
43f66a6c
JK
7803 range->max_rts = DEFAULT_RTS_THRESHOLD;
7804 range->min_frag = MIN_FRAG_THRESHOLD;
7805 range->max_frag = MAX_FRAG_THRESHOLD;
7806
7807 range->encoding_size[0] = 5;
bf79451e 7808 range->encoding_size[1] = 13;
43f66a6c
JK
7809 range->num_encoding_sizes = 2;
7810 range->max_encoding_tokens = WEP_KEYS;
7811
7812 /* Set the Wireless Extension versions */
7813 range->we_version_compiled = WIRELESS_EXT;
7814 range->we_version_source = 16;
7815
b095c381
JK
7816 i = 0;
7817 if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
7818 for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES;
7819 i++, j++) {
7820 range->freq[i].i = geo->bg[j].channel;
7821 range->freq[i].m = geo->bg[j].freq * 100000;
7822 range->freq[i].e = 1;
7823 }
7824 }
43f66a6c 7825
b095c381
JK
7826 if (priv->ieee->mode & IEEE_A) {
7827 for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES;
7828 i++, j++) {
7829 range->freq[i].i = geo->a[j].channel;
7830 range->freq[i].m = geo->a[j].freq * 100000;
7831 range->freq[i].e = 1;
7832 }
43f66a6c 7833 }
b095c381
JK
7834
7835 range->num_channels = i;
7836 range->num_frequency = i;
7837
c848d0af 7838 up(&priv->sem);
43f66a6c
JK
7839 IPW_DEBUG_WX("GET Range\n");
7840 return 0;
7841}
7842
bf79451e
JG
7843static int ipw_wx_set_wap(struct net_device *dev,
7844 struct iw_request_info *info,
43f66a6c
JK
7845 union iwreq_data *wrqu, char *extra)
7846{
7847 struct ipw_priv *priv = ieee80211_priv(dev);
7848
7849 static const unsigned char any[] = {
7850 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7851 };
7852 static const unsigned char off[] = {
7853 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
7854 };
7855
bf79451e 7856 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
43f66a6c 7857 return -EINVAL;
c848d0af 7858 down(&priv->sem);
43f66a6c
JK
7859 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
7860 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
7861 /* we disable mandatory BSSID association */
7862 IPW_DEBUG_WX("Setting AP BSSID to ANY\n");
7863 priv->config &= ~CFG_STATIC_BSSID;
c848d0af
JK
7864 IPW_DEBUG_ASSOC("Attempting to associate with new "
7865 "parameters.\n");
7866 ipw_associate(priv);
7867 up(&priv->sem);
43f66a6c
JK
7868 return 0;
7869 }
7870
7871 priv->config |= CFG_STATIC_BSSID;
7872 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
7873 IPW_DEBUG_WX("BSSID set to current BSSID.\n");
c848d0af 7874 up(&priv->sem);
43f66a6c
JK
7875 return 0;
7876 }
7877
7878 IPW_DEBUG_WX("Setting mandatory BSSID to " MAC_FMT "\n",
7879 MAC_ARG(wrqu->ap_addr.sa_data));
7880
7881 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
7882
c848d0af
JK
7883 /* Network configuration changed -- force [re]association */
7884 IPW_DEBUG_ASSOC("[re]association triggered due to BSSID change.\n");
7885 if (!ipw_disassociate(priv))
43f66a6c 7886 ipw_associate(priv);
43f66a6c 7887
c848d0af 7888 up(&priv->sem);
43f66a6c
JK
7889 return 0;
7890}
7891
bf79451e
JG
7892static int ipw_wx_get_wap(struct net_device *dev,
7893 struct iw_request_info *info,
43f66a6c
JK
7894 union iwreq_data *wrqu, char *extra)
7895{
7896 struct ipw_priv *priv = ieee80211_priv(dev);
7897 /* If we are associated, trying to associate, or have a statically
7898 * configured BSSID then return that; otherwise return ANY */
c848d0af 7899 down(&priv->sem);
bf79451e 7900 if (priv->config & CFG_STATIC_BSSID ||
43f66a6c
JK
7901 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
7902 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
7903 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN);
7904 } else
7905 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
7906
7907 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
7908 MAC_ARG(wrqu->ap_addr.sa_data));
c848d0af 7909 up(&priv->sem);
43f66a6c
JK
7910 return 0;
7911}
7912
bf79451e
JG
7913static int ipw_wx_set_essid(struct net_device *dev,
7914 struct iw_request_info *info,
43f66a6c
JK
7915 union iwreq_data *wrqu, char *extra)
7916{
7917 struct ipw_priv *priv = ieee80211_priv(dev);
0edd5b44 7918 char *essid = ""; /* ANY */
43f66a6c 7919 int length = 0;
c848d0af 7920 down(&priv->sem);
43f66a6c
JK
7921 if (wrqu->essid.flags && wrqu->essid.length) {
7922 length = wrqu->essid.length - 1;
7923 essid = extra;
7924 }
7925 if (length == 0) {
7926 IPW_DEBUG_WX("Setting ESSID to ANY\n");
7927 priv->config &= ~CFG_STATIC_ESSID;
c848d0af 7928 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) {
43f66a6c
JK
7929 IPW_DEBUG_ASSOC("Attempting to associate with new "
7930 "parameters.\n");
7931 ipw_associate(priv);
7932 }
c848d0af 7933 up(&priv->sem);
43f66a6c
JK
7934 return 0;
7935 }
7936
7937 length = min(length, IW_ESSID_MAX_SIZE);
7938
7939 priv->config |= CFG_STATIC_ESSID;
7940
7941 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
7942 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
c848d0af 7943 up(&priv->sem);
43f66a6c
JK
7944 return 0;
7945 }
7946
7947 IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(essid, length),
7948 length);
7949
7950 priv->essid_len = length;
7951 memcpy(priv->essid, essid, priv->essid_len);
bf79451e 7952
c848d0af
JK
7953 /* Network configuration changed -- force [re]association */
7954 IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n");
7955 if (!ipw_disassociate(priv))
43f66a6c 7956 ipw_associate(priv);
43f66a6c 7957
c848d0af 7958 up(&priv->sem);
43f66a6c
JK
7959 return 0;
7960}
7961
bf79451e
JG
7962static int ipw_wx_get_essid(struct net_device *dev,
7963 struct iw_request_info *info,
43f66a6c
JK
7964 union iwreq_data *wrqu, char *extra)
7965{
7966 struct ipw_priv *priv = ieee80211_priv(dev);
7967
7968 /* If we are associated, trying to associate, or have a statically
7969 * configured ESSID then return that; otherwise return ANY */
c848d0af 7970 down(&priv->sem);
43f66a6c 7971 if (priv->config & CFG_STATIC_ESSID ||
bf79451e
JG
7972 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
7973 IPW_DEBUG_WX("Getting essid: '%s'\n",
43f66a6c 7974 escape_essid(priv->essid, priv->essid_len));
bf79451e 7975 memcpy(extra, priv->essid, priv->essid_len);
43f66a6c 7976 wrqu->essid.length = priv->essid_len;
0edd5b44 7977 wrqu->essid.flags = 1; /* active */
43f66a6c
JK
7978 } else {
7979 IPW_DEBUG_WX("Getting essid: ANY\n");
7980 wrqu->essid.length = 0;
0edd5b44 7981 wrqu->essid.flags = 0; /* active */
43f66a6c 7982 }
c848d0af 7983 up(&priv->sem);
43f66a6c
JK
7984 return 0;
7985}
7986
bf79451e
JG
7987static int ipw_wx_set_nick(struct net_device *dev,
7988 struct iw_request_info *info,
43f66a6c 7989 union iwreq_data *wrqu, char *extra)
bf79451e 7990{
43f66a6c
JK
7991 struct ipw_priv *priv = ieee80211_priv(dev);
7992
7993 IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
7994 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
7995 return -E2BIG;
c848d0af 7996 down(&priv->sem);
0edd5b44 7997 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
43f66a6c 7998 memset(priv->nick, 0, sizeof(priv->nick));
0edd5b44 7999 memcpy(priv->nick, extra, wrqu->data.length);
43f66a6c 8000 IPW_DEBUG_TRACE("<<\n");
c848d0af 8001 up(&priv->sem);
43f66a6c
JK
8002 return 0;
8003
8004}
8005
bf79451e
JG
8006static int ipw_wx_get_nick(struct net_device *dev,
8007 struct iw_request_info *info,
43f66a6c 8008 union iwreq_data *wrqu, char *extra)
bf79451e 8009{
43f66a6c
JK
8010 struct ipw_priv *priv = ieee80211_priv(dev);
8011 IPW_DEBUG_WX("Getting nick\n");
c848d0af 8012 down(&priv->sem);
43f66a6c
JK
8013 wrqu->data.length = strlen(priv->nick) + 1;
8014 memcpy(extra, priv->nick, wrqu->data.length);
0edd5b44 8015 wrqu->data.flags = 1; /* active */
c848d0af 8016 up(&priv->sem);
43f66a6c
JK
8017 return 0;
8018}
8019
43f66a6c
JK
8020static int ipw_wx_set_rate(struct net_device *dev,
8021 struct iw_request_info *info,
8022 union iwreq_data *wrqu, char *extra)
bf79451e 8023{
ea2b26e0
JK
8024 /* TODO: We should use semaphores or locks for access to priv */
8025 struct ipw_priv *priv = ieee80211_priv(dev);
8026 u32 target_rate = wrqu->bitrate.value;
8027 u32 fixed, mask;
8028
8029 /* value = -1, fixed = 0 means auto only, so we should use all rates offered by AP */
8030 /* value = X, fixed = 1 means only rate X */
8031 /* value = X, fixed = 0 means all rates lower equal X */
8032
8033 if (target_rate == -1) {
8034 fixed = 0;
8035 mask = IEEE80211_DEFAULT_RATES_MASK;
8036 /* Now we should reassociate */
8037 goto apply;
8038 }
8039
8040 mask = 0;
8041 fixed = wrqu->bitrate.fixed;
8042
8043 if (target_rate == 1000000 || !fixed)
8044 mask |= IEEE80211_CCK_RATE_1MB_MASK;
8045 if (target_rate == 1000000)
8046 goto apply;
8047
8048 if (target_rate == 2000000 || !fixed)
8049 mask |= IEEE80211_CCK_RATE_2MB_MASK;
8050 if (target_rate == 2000000)
8051 goto apply;
8052
8053 if (target_rate == 5500000 || !fixed)
8054 mask |= IEEE80211_CCK_RATE_5MB_MASK;
8055 if (target_rate == 5500000)
8056 goto apply;
8057
8058 if (target_rate == 6000000 || !fixed)
8059 mask |= IEEE80211_OFDM_RATE_6MB_MASK;
8060 if (target_rate == 6000000)
8061 goto apply;
8062
8063 if (target_rate == 9000000 || !fixed)
8064 mask |= IEEE80211_OFDM_RATE_9MB_MASK;
8065 if (target_rate == 9000000)
8066 goto apply;
8067
8068 if (target_rate == 11000000 || !fixed)
8069 mask |= IEEE80211_CCK_RATE_11MB_MASK;
8070 if (target_rate == 11000000)
8071 goto apply;
8072
8073 if (target_rate == 12000000 || !fixed)
8074 mask |= IEEE80211_OFDM_RATE_12MB_MASK;
8075 if (target_rate == 12000000)
8076 goto apply;
8077
8078 if (target_rate == 18000000 || !fixed)
8079 mask |= IEEE80211_OFDM_RATE_18MB_MASK;
8080 if (target_rate == 18000000)
8081 goto apply;
8082
8083 if (target_rate == 24000000 || !fixed)
8084 mask |= IEEE80211_OFDM_RATE_24MB_MASK;
8085 if (target_rate == 24000000)
8086 goto apply;
8087
8088 if (target_rate == 36000000 || !fixed)
8089 mask |= IEEE80211_OFDM_RATE_36MB_MASK;
8090 if (target_rate == 36000000)
8091 goto apply;
8092
8093 if (target_rate == 48000000 || !fixed)
8094 mask |= IEEE80211_OFDM_RATE_48MB_MASK;
8095 if (target_rate == 48000000)
8096 goto apply;
8097
8098 if (target_rate == 54000000 || !fixed)
8099 mask |= IEEE80211_OFDM_RATE_54MB_MASK;
8100 if (target_rate == 54000000)
8101 goto apply;
8102
8103 IPW_DEBUG_WX("invalid rate specified, returning error\n");
8104 return -EINVAL;
8105
8106 apply:
8107 IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
8108 mask, fixed ? "fixed" : "sub-rates");
c848d0af 8109 down(&priv->sem);
b095c381 8110 if (mask == IEEE80211_DEFAULT_RATES_MASK) {
ea2b26e0 8111 priv->config &= ~CFG_FIXED_RATE;
b095c381
JK
8112 ipw_set_fixed_rate(priv, priv->ieee->mode);
8113 } else
ea2b26e0
JK
8114 priv->config |= CFG_FIXED_RATE;
8115
c848d0af
JK
8116 if (priv->rates_mask == mask) {
8117 IPW_DEBUG_WX("Mask set to current mask.\n");
8118 up(&priv->sem);
8119 return 0;
ea2b26e0
JK
8120 }
8121
c848d0af
JK
8122 priv->rates_mask = mask;
8123
8124 /* Network configuration changed -- force [re]association */
8125 IPW_DEBUG_ASSOC("[re]association triggered due to rates change.\n");
8126 if (!ipw_disassociate(priv))
8127 ipw_associate(priv);
8128
8129 up(&priv->sem);
ea2b26e0 8130 return 0;
43f66a6c
JK
8131}
8132
bf79451e
JG
8133static int ipw_wx_get_rate(struct net_device *dev,
8134 struct iw_request_info *info,
43f66a6c 8135 union iwreq_data *wrqu, char *extra)
bf79451e 8136{
0edd5b44 8137 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8138 down(&priv->sem);
43f66a6c 8139 wrqu->bitrate.value = priv->last_rate;
c848d0af 8140 up(&priv->sem);
43f66a6c
JK
8141 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
8142 return 0;
8143}
8144
bf79451e
JG
8145static int ipw_wx_set_rts(struct net_device *dev,
8146 struct iw_request_info *info,
43f66a6c 8147 union iwreq_data *wrqu, char *extra)
bf79451e 8148{
43f66a6c 8149 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8150 down(&priv->sem);
43f66a6c
JK
8151 if (wrqu->rts.disabled)
8152 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
8153 else {
8154 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
c848d0af
JK
8155 wrqu->rts.value > MAX_RTS_THRESHOLD) {
8156 up(&priv->sem);
43f66a6c 8157 return -EINVAL;
c848d0af 8158 }
43f66a6c
JK
8159 priv->rts_threshold = wrqu->rts.value;
8160 }
8161
8162 ipw_send_rts_threshold(priv, priv->rts_threshold);
c848d0af 8163 up(&priv->sem);
43f66a6c
JK
8164 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
8165 return 0;
8166}
8167
bf79451e
JG
8168static int ipw_wx_get_rts(struct net_device *dev,
8169 struct iw_request_info *info,
43f66a6c 8170 union iwreq_data *wrqu, char *extra)
bf79451e 8171{
43f66a6c 8172 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8173 down(&priv->sem);
43f66a6c
JK
8174 wrqu->rts.value = priv->rts_threshold;
8175 wrqu->rts.fixed = 0; /* no auto select */
0edd5b44 8176 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
c848d0af 8177 up(&priv->sem);
43f66a6c
JK
8178 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
8179 return 0;
8180}
8181
bf79451e
JG
8182static int ipw_wx_set_txpow(struct net_device *dev,
8183 struct iw_request_info *info,
43f66a6c 8184 union iwreq_data *wrqu, char *extra)
bf79451e 8185{
43f66a6c
JK
8186 struct ipw_priv *priv = ieee80211_priv(dev);
8187 struct ipw_tx_power tx_power;
8188 int i;
b095c381 8189
c848d0af
JK
8190 down(&priv->sem);
8191 if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
8192 up(&priv->sem);
43f66a6c 8193 return -EINPROGRESS;
c848d0af 8194 }
43f66a6c 8195
b095c381
JK
8196 if (!wrqu->power.fixed)
8197 wrqu->power.value = IPW_TX_POWER_DEFAULT;
8198
c848d0af
JK
8199 if (wrqu->power.flags != IW_TXPOW_DBM) {
8200 up(&priv->sem);
43f66a6c 8201 return -EINVAL;
c848d0af 8202 }
43f66a6c 8203
b095c381
JK
8204 if ((wrqu->power.value > IPW_TX_POWER_MAX) ||
8205 (wrqu->power.value < -IPW_TX_POWER_MAX) || !wrqu->power.fixed) {
c848d0af 8206 up(&priv->sem);
43f66a6c 8207 return -EINVAL;
c848d0af 8208 }
43f66a6c
JK
8209
8210 priv->tx_power = wrqu->power.value;
8211
8212 memset(&tx_power, 0, sizeof(tx_power));
8213
8214 /* configure device for 'G' band */
8215 tx_power.ieee_mode = IPW_G_MODE;
8216 tx_power.num_channels = 11;
8217 for (i = 0; i < 11; i++) {
8218 tx_power.channels_tx_power[i].channel_number = i + 1;
8219 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
8220 }
8221 if (ipw_send_tx_power(priv, &tx_power))
8222 goto error;
8223
8224 /* configure device to also handle 'B' band */
8225 tx_power.ieee_mode = IPW_B_MODE;
8226 if (ipw_send_tx_power(priv, &tx_power))
8227 goto error;
8228
c848d0af 8229 up(&priv->sem);
43f66a6c
JK
8230 return 0;
8231
0edd5b44 8232 error:
c848d0af 8233 up(&priv->sem);
43f66a6c
JK
8234 return -EIO;
8235}
8236
bf79451e
JG
8237static int ipw_wx_get_txpow(struct net_device *dev,
8238 struct iw_request_info *info,
43f66a6c 8239 union iwreq_data *wrqu, char *extra)
bf79451e 8240{
43f66a6c 8241 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8242 down(&priv->sem);
43f66a6c
JK
8243 wrqu->power.value = priv->tx_power;
8244 wrqu->power.fixed = 1;
8245 wrqu->power.flags = IW_TXPOW_DBM;
8246 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
c848d0af 8247 up(&priv->sem);
43f66a6c 8248
bf79451e 8249 IPW_DEBUG_WX("GET TX Power -> %s %d \n",
0edd5b44 8250 wrqu->power.disabled ? "ON" : "OFF", wrqu->power.value);
43f66a6c
JK
8251
8252 return 0;
8253}
8254
bf79451e 8255static int ipw_wx_set_frag(struct net_device *dev,
0edd5b44
JG
8256 struct iw_request_info *info,
8257 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
8258{
8259 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8260 down(&priv->sem);
43f66a6c
JK
8261 if (wrqu->frag.disabled)
8262 priv->ieee->fts = DEFAULT_FTS;
8263 else {
8264 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
b095c381
JK
8265 wrqu->frag.value > MAX_FRAG_THRESHOLD) {
8266 up(&priv->sem);
43f66a6c 8267 return -EINVAL;
b095c381 8268 }
bf79451e 8269
43f66a6c
JK
8270 priv->ieee->fts = wrqu->frag.value & ~0x1;
8271 }
8272
8273 ipw_send_frag_threshold(priv, wrqu->frag.value);
c848d0af 8274 up(&priv->sem);
43f66a6c
JK
8275 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
8276 return 0;
8277}
8278
bf79451e 8279static int ipw_wx_get_frag(struct net_device *dev,
0edd5b44
JG
8280 struct iw_request_info *info,
8281 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
8282{
8283 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8284 down(&priv->sem);
43f66a6c
JK
8285 wrqu->frag.value = priv->ieee->fts;
8286 wrqu->frag.fixed = 0; /* no auto select */
0edd5b44 8287 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
c848d0af 8288 up(&priv->sem);
43f66a6c
JK
8289 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
8290
8291 return 0;
8292}
8293
bf79451e
JG
8294static int ipw_wx_set_retry(struct net_device *dev,
8295 struct iw_request_info *info,
43f66a6c 8296 union iwreq_data *wrqu, char *extra)
bf79451e 8297{
43f66a6c 8298 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu);
bf79451e 8299 return -EOPNOTSUPP;
43f66a6c
JK
8300}
8301
bf79451e
JG
8302static int ipw_wx_get_retry(struct net_device *dev,
8303 struct iw_request_info *info,
43f66a6c 8304 union iwreq_data *wrqu, char *extra)
bf79451e 8305{
43f66a6c 8306 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu);
bf79451e 8307 return -EOPNOTSUPP;
43f66a6c
JK
8308}
8309
bf79451e
JG
8310static int ipw_wx_set_scan(struct net_device *dev,
8311 struct iw_request_info *info,
43f66a6c
JK
8312 union iwreq_data *wrqu, char *extra)
8313{
8314 struct ipw_priv *priv = ieee80211_priv(dev);
8315 IPW_DEBUG_WX("Start scan\n");
b095c381
JK
8316
8317 queue_work(priv->workqueue, &priv->request_scan);
8318
43f66a6c
JK
8319 return 0;
8320}
8321
bf79451e
JG
8322static int ipw_wx_get_scan(struct net_device *dev,
8323 struct iw_request_info *info,
43f66a6c 8324 union iwreq_data *wrqu, char *extra)
bf79451e 8325{
43f66a6c
JK
8326 struct ipw_priv *priv = ieee80211_priv(dev);
8327 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
8328}
8329
bf79451e 8330static int ipw_wx_set_encode(struct net_device *dev,
0edd5b44
JG
8331 struct iw_request_info *info,
8332 union iwreq_data *wrqu, char *key)
43f66a6c
JK
8333{
8334 struct ipw_priv *priv = ieee80211_priv(dev);
8335 return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
8336}
8337
bf79451e 8338static int ipw_wx_get_encode(struct net_device *dev,
0edd5b44
JG
8339 struct iw_request_info *info,
8340 union iwreq_data *wrqu, char *key)
43f66a6c
JK
8341{
8342 struct ipw_priv *priv = ieee80211_priv(dev);
8343 return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key);
8344}
8345
bf79451e 8346static int ipw_wx_set_power(struct net_device *dev,
0edd5b44
JG
8347 struct iw_request_info *info,
8348 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
8349{
8350 struct ipw_priv *priv = ieee80211_priv(dev);
8351 int err;
c848d0af 8352 down(&priv->sem);
43f66a6c
JK
8353 if (wrqu->power.disabled) {
8354 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
8355 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
8356 if (err) {
8357 IPW_DEBUG_WX("failed setting power mode.\n");
c848d0af 8358 up(&priv->sem);
43f66a6c
JK
8359 return err;
8360 }
43f66a6c 8361 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
c848d0af 8362 up(&priv->sem);
43f66a6c 8363 return 0;
bf79451e 8364 }
43f66a6c
JK
8365
8366 switch (wrqu->power.flags & IW_POWER_MODE) {
0edd5b44
JG
8367 case IW_POWER_ON: /* If not specified */
8368 case IW_POWER_MODE: /* If set all mask */
8369 case IW_POWER_ALL_R: /* If explicitely state all */
43f66a6c 8370 break;
0edd5b44 8371 default: /* Otherwise we don't support it */
43f66a6c
JK
8372 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
8373 wrqu->power.flags);
c848d0af 8374 up(&priv->sem);
bf79451e 8375 return -EOPNOTSUPP;
43f66a6c 8376 }
bf79451e 8377
43f66a6c
JK
8378 /* If the user hasn't specified a power management mode yet, default
8379 * to BATTERY */
0edd5b44 8380 if (IPW_POWER_LEVEL(priv->power_mode) == IPW_POWER_AC)
43f66a6c 8381 priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY;
bf79451e 8382 else
43f66a6c
JK
8383 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
8384 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
8385 if (err) {
8386 IPW_DEBUG_WX("failed setting power mode.\n");
c848d0af 8387 up(&priv->sem);
43f66a6c
JK
8388 return err;
8389 }
8390
0edd5b44 8391 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
c848d0af 8392 up(&priv->sem);
43f66a6c
JK
8393 return 0;
8394}
8395
bf79451e 8396static int ipw_wx_get_power(struct net_device *dev,
0edd5b44
JG
8397 struct iw_request_info *info,
8398 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
8399{
8400 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8401 down(&priv->sem);
a613bffd 8402 if (!(priv->power_mode & IPW_POWER_ENABLED))
43f66a6c 8403 wrqu->power.disabled = 1;
a613bffd 8404 else
43f66a6c 8405 wrqu->power.disabled = 0;
43f66a6c 8406
c848d0af 8407 up(&priv->sem);
43f66a6c 8408 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
bf79451e 8409
43f66a6c
JK
8410 return 0;
8411}
8412
bf79451e 8413static int ipw_wx_set_powermode(struct net_device *dev,
0edd5b44
JG
8414 struct iw_request_info *info,
8415 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
8416{
8417 struct ipw_priv *priv = ieee80211_priv(dev);
8418 int mode = *(int *)extra;
8419 int err;
c848d0af 8420 down(&priv->sem);
43f66a6c
JK
8421 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
8422 mode = IPW_POWER_AC;
8423 priv->power_mode = mode;
8424 } else {
8425 priv->power_mode = IPW_POWER_ENABLED | mode;
8426 }
bf79451e 8427
43f66a6c
JK
8428 if (priv->power_mode != mode) {
8429 err = ipw_send_power_mode(priv, mode);
bf79451e 8430
43f66a6c
JK
8431 if (err) {
8432 IPW_DEBUG_WX("failed setting power mode.\n");
c848d0af 8433 up(&priv->sem);
43f66a6c
JK
8434 return err;
8435 }
8436 }
c848d0af 8437 up(&priv->sem);
43f66a6c
JK
8438 return 0;
8439}
8440
8441#define MAX_WX_STRING 80
bf79451e 8442static int ipw_wx_get_powermode(struct net_device *dev,
0edd5b44
JG
8443 struct iw_request_info *info,
8444 union iwreq_data *wrqu, char *extra)
43f66a6c
JK
8445{
8446 struct ipw_priv *priv = ieee80211_priv(dev);
8447 int level = IPW_POWER_LEVEL(priv->power_mode);
8448 char *p = extra;
8449
8450 p += snprintf(p, MAX_WX_STRING, "Power save level: %d ", level);
8451
8452 switch (level) {
8453 case IPW_POWER_AC:
8454 p += snprintf(p, MAX_WX_STRING - (p - extra), "(AC)");
8455 break;
8456 case IPW_POWER_BATTERY:
8457 p += snprintf(p, MAX_WX_STRING - (p - extra), "(BATTERY)");
8458 break;
8459 default:
8460 p += snprintf(p, MAX_WX_STRING - (p - extra),
bf79451e 8461 "(Timeout %dms, Period %dms)",
43f66a6c
JK
8462 timeout_duration[level - 1] / 1000,
8463 period_duration[level - 1] / 1000);
8464 }
8465
8466 if (!(priv->power_mode & IPW_POWER_ENABLED))
0edd5b44 8467 p += snprintf(p, MAX_WX_STRING - (p - extra), " OFF");
43f66a6c
JK
8468
8469 wrqu->data.length = p - extra + 1;
8470
8471 return 0;
8472}
8473
8474static int ipw_wx_set_wireless_mode(struct net_device *dev,
0edd5b44
JG
8475 struct iw_request_info *info,
8476 union iwreq_data *wrqu, char *extra)
43f66a6c 8477{
0edd5b44 8478 struct ipw_priv *priv = ieee80211_priv(dev);
43f66a6c
JK
8479 int mode = *(int *)extra;
8480 u8 band = 0, modulation = 0;
8481
8482 if (mode == 0 || mode & ~IEEE_MODE_MASK) {
0edd5b44 8483 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
43f66a6c
JK
8484 return -EINVAL;
8485 }
c848d0af 8486 down(&priv->sem);
43f66a6c 8487 if (priv->adapter == IPW_2915ABG) {
a33a1982 8488 priv->ieee->abg_true = 1;
43f66a6c
JK
8489 if (mode & IEEE_A) {
8490 band |= IEEE80211_52GHZ_BAND;
8491 modulation |= IEEE80211_OFDM_MODULATION;
8492 } else
a33a1982 8493 priv->ieee->abg_true = 0;
43f66a6c
JK
8494 } else {
8495 if (mode & IEEE_A) {
8496 IPW_WARNING("Attempt to set 2200BG into "
8497 "802.11a mode\n");
c848d0af 8498 up(&priv->sem);
43f66a6c
JK
8499 return -EINVAL;
8500 }
8501
a33a1982 8502 priv->ieee->abg_true = 0;
43f66a6c
JK
8503 }
8504
8505 if (mode & IEEE_B) {
8506 band |= IEEE80211_24GHZ_BAND;
8507 modulation |= IEEE80211_CCK_MODULATION;
8508 } else
a33a1982 8509 priv->ieee->abg_true = 0;
bf79451e 8510
43f66a6c
JK
8511 if (mode & IEEE_G) {
8512 band |= IEEE80211_24GHZ_BAND;
8513 modulation |= IEEE80211_OFDM_MODULATION;
8514 } else
a33a1982 8515 priv->ieee->abg_true = 0;
43f66a6c
JK
8516
8517 priv->ieee->mode = mode;
8518 priv->ieee->freq_band = band;
8519 priv->ieee->modulation = modulation;
0edd5b44 8520 init_supported_rates(priv, &priv->rates);
43f66a6c 8521
c848d0af
JK
8522 /* Network configuration changed -- force [re]association */
8523 IPW_DEBUG_ASSOC("[re]association triggered due to mode change.\n");
8524 if (!ipw_disassociate(priv)) {
43f66a6c 8525 ipw_send_supported_rates(priv, &priv->rates);
c848d0af
JK
8526 ipw_associate(priv);
8527 }
43f66a6c 8528
a613bffd
JK
8529 /* Update the band LEDs */
8530 ipw_led_band_on(priv);
8531
bf79451e 8532 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
43f66a6c 8533 mode & IEEE_A ? 'a' : '.',
0edd5b44 8534 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
c848d0af 8535 up(&priv->sem);
43f66a6c
JK
8536 return 0;
8537}
8538
8539static int ipw_wx_get_wireless_mode(struct net_device *dev,
0edd5b44
JG
8540 struct iw_request_info *info,
8541 union iwreq_data *wrqu, char *extra)
43f66a6c 8542{
0edd5b44 8543 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 8544 down(&priv->sem);
ea2b26e0
JK
8545 switch (priv->ieee->mode) {
8546 case IEEE_A:
43f66a6c
JK
8547 strncpy(extra, "802.11a (1)", MAX_WX_STRING);
8548 break;
ea2b26e0
JK
8549 case IEEE_B:
8550 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
8551 break;
8552 case IEEE_A | IEEE_B:
8553 strncpy(extra, "802.11ab (3)", MAX_WX_STRING);
8554 break;
8555 case IEEE_G:
8556 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
8557 break;
8558 case IEEE_A | IEEE_G:
8559 strncpy(extra, "802.11ag (5)", MAX_WX_STRING);
8560 break;
8561 case IEEE_B | IEEE_G:
8562 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
8563 break;
8564 case IEEE_A | IEEE_B | IEEE_G:
8565 strncpy(extra, "802.11abg (7)", MAX_WX_STRING);
8566 break;
8567 default:
8568 strncpy(extra, "unknown", MAX_WX_STRING);
43f66a6c 8569 break;
bf79451e
JG
8570 }
8571
b095c381
JK
8572 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
8573
8574 wrqu->data.length = strlen(extra) + 1;
8575 up(&priv->sem);
8576
8577 return 0;
8578}
8579
8580static int ipw_wx_set_preamble(struct net_device *dev,
8581 struct iw_request_info *info,
8582 union iwreq_data *wrqu, char *extra)
8583{
8584 struct ipw_priv *priv = ieee80211_priv(dev);
8585 int mode = *(int *)extra;
8586 down(&priv->sem);
8587 /* Switching from SHORT -> LONG requires a disassociation */
8588 if (mode == 1) {
8589 if (!(priv->config & CFG_PREAMBLE_LONG)) {
8590 priv->config |= CFG_PREAMBLE_LONG;
8591
8592 /* Network configuration changed -- force [re]association */
8593 IPW_DEBUG_ASSOC
8594 ("[re]association triggered due to preamble change.\n");
8595 if (!ipw_disassociate(priv))
8596 ipw_associate(priv);
8597 }
8598 goto done;
8599 }
8600
8601 if (mode == 0) {
8602 priv->config &= ~CFG_PREAMBLE_LONG;
8603 goto done;
8604 }
8605 up(&priv->sem);
8606 return -EINVAL;
8607
8608 done:
8609 up(&priv->sem);
8610 return 0;
8611}
8612
8613static int ipw_wx_get_preamble(struct net_device *dev,
8614 struct iw_request_info *info,
8615 union iwreq_data *wrqu, char *extra)
8616{
8617 struct ipw_priv *priv = ieee80211_priv(dev);
8618 down(&priv->sem);
8619 if (priv->config & CFG_PREAMBLE_LONG)
8620 snprintf(wrqu->name, IFNAMSIZ, "long (1)");
8621 else
8622 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
8623 up(&priv->sem);
8624 return 0;
8625}
8626
8627#ifdef CONFIG_IPW2200_MONITOR
8628static int ipw_wx_set_monitor(struct net_device *dev,
8629 struct iw_request_info *info,
8630 union iwreq_data *wrqu, char *extra)
8631{
8632 struct ipw_priv *priv = ieee80211_priv(dev);
8633 int *parms = (int *)extra;
8634 int enable = (parms[0] > 0);
8635 down(&priv->sem);
8636 IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
8637 if (enable) {
8638 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
8639 priv->net_dev->type = ARPHRD_IEEE80211;
8640 queue_work(priv->workqueue, &priv->adapter_restart);
8641 }
8642
8643 ipw_set_channel(priv, parms[1]);
8644 } else {
8645 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
8646 up(&priv->sem);
8647 return 0;
8648 }
8649 priv->net_dev->type = ARPHRD_ETHER;
8650 queue_work(priv->workqueue, &priv->adapter_restart);
8651 }
8652 up(&priv->sem);
8653 return 0;
8654}
8655
8656#endif // CONFIG_IPW2200_MONITOR
8657
8658static int ipw_wx_reset(struct net_device *dev,
8659 struct iw_request_info *info,
8660 union iwreq_data *wrqu, char *extra)
8661{
8662 struct ipw_priv *priv = ieee80211_priv(dev);
8663 IPW_DEBUG_WX("RESET\n");
8664 queue_work(priv->workqueue, &priv->adapter_restart);
8665 return 0;
8666}
8667
8668static void ipw_sw_reset(struct ipw_priv *priv, int init)
8669{
8670 int band, modulation;
8671
8672 /* Initialize module parameter values here */
8673 priv->config = 0;
8674
8675 /* We default to disabling the LED code as right now it causes
8676 * too many systems to lock up... */
8677 if (!led)
8678 priv->config |= CFG_NO_LED;
8679
8680 if (associate)
8681 priv->config |= CFG_ASSOCIATE;
8682 else
8683 IPW_DEBUG_INFO("Auto associate disabled.\n");
8684
8685 if (auto_create)
8686 priv->config |= CFG_ADHOC_CREATE;
8687 else
8688 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
8689
8690 if (disable) {
8691 priv->status |= STATUS_RF_KILL_SW;
8692 IPW_DEBUG_INFO("Radio disabled.\n");
8693 }
8694
8695 if (channel != 0) {
8696 priv->config |= CFG_STATIC_CHANNEL;
8697 priv->channel = channel;
8698 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
8699 /* TODO: Validate that provided channel is in range */
8700 }
8701#ifdef CONFIG_IPW_QOS
8702 ipw_qos_init(priv, qos_enable, qos_burst_enable,
8703 burst_duration_CCK, burst_duration_OFDM);
8704#endif /* CONFIG_IPW_QOS */
8705
8706 switch (mode) {
8707 case 1:
8708 priv->ieee->iw_mode = IW_MODE_ADHOC;
8709 priv->net_dev->type = ARPHRD_ETHER;
8710
8711 break;
8712#ifdef CONFIG_IPW2200_MONITOR
8713 case 2:
8714 priv->ieee->iw_mode = IW_MODE_MONITOR;
8715 priv->net_dev->type = ARPHRD_IEEE80211;
8716 break;
8717#endif
8718 default:
8719 case 0:
8720 priv->net_dev->type = ARPHRD_ETHER;
8721 priv->ieee->iw_mode = IW_MODE_INFRA;
8722 break;
8723 }
8724
8725 if (hwcrypto) {
8726 priv->ieee->host_encrypt = 0;
8727 priv->ieee->host_decrypt = 0;
8728 }
8729 IPW_DEBUG_INFO("Hardware crypto [%s]\n", hwcrypto ? "on" : "off");
8730
8731 if ((priv->pci_dev->device == 0x4223) ||
8732 (priv->pci_dev->device == 0x4224)) {
8733 if (init)
8734 printk(KERN_INFO DRV_NAME
8735 ": Detected Intel PRO/Wireless 2915ABG Network "
8736 "Connection\n");
8737 priv->ieee->abg_true = 1;
8738 band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
8739 modulation = IEEE80211_OFDM_MODULATION |
8740 IEEE80211_CCK_MODULATION;
8741 priv->adapter = IPW_2915ABG;
8742 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
8743 } else {
8744 if (init)
8745 printk(KERN_INFO DRV_NAME
8746 ": Detected Intel PRO/Wireless 2200BG Network "
8747 "Connection\n");
8748
8749 priv->ieee->abg_true = 0;
8750 band = IEEE80211_24GHZ_BAND;
8751 modulation = IEEE80211_OFDM_MODULATION |
8752 IEEE80211_CCK_MODULATION;
8753 priv->adapter = IPW_2200BG;
8754 priv->ieee->mode = IEEE_G | IEEE_B;
8755 }
8756
8757 priv->ieee->freq_band = band;
8758 priv->ieee->modulation = modulation;
43f66a6c 8759
b095c381 8760 priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
43f66a6c 8761
b095c381
JK
8762 priv->missed_beacon_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
8763 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
8764
8765 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
8766
8767 /* If power management is turned on, default to AC mode */
8768 priv->power_mode = IPW_POWER_AC;
8769 priv->tx_power = IPW_TX_POWER_DEFAULT;
43f66a6c
JK
8770}
8771
b095c381
JK
8772static int ipw_wx_sw_reset(struct net_device *dev,
8773 struct iw_request_info *info,
8774 union iwreq_data *wrqu, char *extra)
ea2b26e0
JK
8775{
8776 struct ipw_priv *priv = ieee80211_priv(dev);
b095c381
JK
8777 union iwreq_data wrqu_sec = {
8778 .encoding = {
8779 .flags = IW_ENCODE_DISABLED,
8780 },
8781 };
c848d0af 8782
b095c381 8783 IPW_DEBUG_WX("SW_RESET\n");
ea2b26e0 8784
b095c381 8785 down(&priv->sem);
ea2b26e0 8786
b095c381 8787 ipw_sw_reset(priv, 0);
ea2b26e0 8788
b095c381
JK
8789 /* The SW reset bit might have been toggled on by the 'disable'
8790 * module parameter, so take appropriate action */
8791 ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);
ea2b26e0 8792
b095c381
JK
8793 up(&priv->sem);
8794 ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
c848d0af 8795 down(&priv->sem);
bf79451e 8796
b095c381
JK
8797 if (!(priv->status & STATUS_RF_KILL_MASK)) {
8798 /* Configuration likely changed -- force [re]association */
8799 IPW_DEBUG_ASSOC("[re]association triggered due to sw "
8800 "reset.\n");
8801 if (!ipw_disassociate(priv))
8802 ipw_associate(priv);
43f66a6c 8803 }
b095c381 8804
c848d0af 8805 up(&priv->sem);
43f66a6c 8806
43f66a6c
JK
8807 return 0;
8808}
43f66a6c
JK
8809
8810/* Rebase the WE IOCTLs to zero for the handler array */
8811#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
0edd5b44 8812static iw_handler ipw_wx_handlers[] = {
ea2b26e0
JK
8813 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
8814 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
8815 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
8816 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
8817 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
8818 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
8819 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
8820 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
8821 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan,
8822 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan,
8823 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid,
8824 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid,
8825 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick,
8826 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick,
8827 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate,
8828 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate,
8829 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts,
8830 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts,
8831 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag,
8832 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag,
8833 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow,
8834 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow,
8835 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry,
8836 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry,
8837 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode,
8838 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
8839 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
8840 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
a613bffd
JK
8841 IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy,
8842 IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy,
8843 IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy,
8844 IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy,
43f66a6c
JK
8845};
8846
b095c381
JK
8847enum {
8848 IPW_PRIV_SET_POWER = SIOCIWFIRSTPRIV,
8849 IPW_PRIV_GET_POWER,
8850 IPW_PRIV_SET_MODE,
8851 IPW_PRIV_GET_MODE,
8852 IPW_PRIV_SET_PREAMBLE,
8853 IPW_PRIV_GET_PREAMBLE,
8854 IPW_PRIV_RESET,
8855 IPW_PRIV_SW_RESET,
8856#ifdef CONFIG_IPW2200_MONITOR
8857 IPW_PRIV_SET_MONITOR,
8858#endif
8859};
43f66a6c 8860
bf79451e 8861static struct iw_priv_args ipw_priv_args[] = {
43f66a6c 8862 {
0edd5b44
JG
8863 .cmd = IPW_PRIV_SET_POWER,
8864 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
8865 .name = "set_power"},
43f66a6c 8866 {
0edd5b44
JG
8867 .cmd = IPW_PRIV_GET_POWER,
8868 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
8869 .name = "get_power"},
43f66a6c 8870 {
0edd5b44
JG
8871 .cmd = IPW_PRIV_SET_MODE,
8872 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
8873 .name = "set_mode"},
43f66a6c 8874 {
0edd5b44
JG
8875 .cmd = IPW_PRIV_GET_MODE,
8876 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
8877 .name = "get_mode"},
43f66a6c 8878 {
ea2b26e0
JK
8879 .cmd = IPW_PRIV_SET_PREAMBLE,
8880 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
8881 .name = "set_preamble"},
8882 {
8883 .cmd = IPW_PRIV_GET_PREAMBLE,
8884 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ,
8885 .name = "get_preamble"},
43f66a6c 8886 {
0edd5b44
JG
8887 IPW_PRIV_RESET,
8888 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
b095c381
JK
8889 {
8890 IPW_PRIV_SW_RESET,
8891 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "sw_reset"},
8892#ifdef CONFIG_IPW2200_MONITOR
8893 {
8894 IPW_PRIV_SET_MONITOR,
8895 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
8896#endif /* CONFIG_IPW2200_MONITOR */
43f66a6c
JK
8897};
8898
8899static iw_handler ipw_priv_handler[] = {
8900 ipw_wx_set_powermode,
8901 ipw_wx_get_powermode,
8902 ipw_wx_set_wireless_mode,
8903 ipw_wx_get_wireless_mode,
ea2b26e0
JK
8904 ipw_wx_set_preamble,
8905 ipw_wx_get_preamble,
bf79451e 8906 ipw_wx_reset,
b095c381
JK
8907 ipw_wx_sw_reset,
8908#ifdef CONFIG_IPW2200_MONITOR
8909 ipw_wx_set_monitor,
43f66a6c
JK
8910#endif
8911};
8912
0edd5b44 8913static struct iw_handler_def ipw_wx_handler_def = {
ea2b26e0
JK
8914 .standard = ipw_wx_handlers,
8915 .num_standard = ARRAY_SIZE(ipw_wx_handlers),
8916 .num_private = ARRAY_SIZE(ipw_priv_handler),
8917 .num_private_args = ARRAY_SIZE(ipw_priv_args),
8918 .private = ipw_priv_handler,
8919 .private_args = ipw_priv_args,
43f66a6c
JK
8920};
8921
a613bffd
JK
8922static struct iw_public_data ipw_wx_data;
8923
43f66a6c
JK
8924/*
8925 * Get wireless statistics.
8926 * Called by /proc/net/wireless
8927 * Also called by SIOCGIWSTATS
8928 */
0edd5b44 8929static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
43f66a6c
JK
8930{
8931 struct ipw_priv *priv = ieee80211_priv(dev);
8932 struct iw_statistics *wstats;
bf79451e 8933
43f66a6c
JK
8934 wstats = &priv->wstats;
8935
ea2b26e0 8936 /* if hw is disabled, then ipw_get_ordinal() can't be called.
bf79451e 8937 * ipw2100_wx_wireless_stats seems to be called before fw is
43f66a6c
JK
8938 * initialized. STATUS_ASSOCIATED will only be set if the hw is up
8939 * and associated; if not associcated, the values are all meaningless
8940 * anyway, so set them all to NULL and INVALID */
8941 if (!(priv->status & STATUS_ASSOCIATED)) {
8942 wstats->miss.beacon = 0;
8943 wstats->discard.retries = 0;
8944 wstats->qual.qual = 0;
8945 wstats->qual.level = 0;
8946 wstats->qual.noise = 0;
8947 wstats->qual.updated = 7;
8948 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
0edd5b44 8949 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
43f66a6c 8950 return wstats;
bf79451e 8951 }
43f66a6c
JK
8952
8953 wstats->qual.qual = priv->quality;
8954 wstats->qual.level = average_value(&priv->average_rssi);
8955 wstats->qual.noise = average_value(&priv->average_noise);
8956 wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
0edd5b44 8957 IW_QUAL_NOISE_UPDATED;
43f66a6c
JK
8958
8959 wstats->miss.beacon = average_value(&priv->average_missed_beacons);
8960 wstats->discard.retries = priv->last_tx_failures;
8961 wstats->discard.code = priv->ieee->ieee_stats.rx_discards_undecryptable;
bf79451e 8962
43f66a6c
JK
8963/* if (ipw_get_ordinal(priv, IPW_ORD_STAT_TX_RETRY, &tx_retry, &len))
8964 goto fail_get_ordinal;
8965 wstats->discard.retries += tx_retry; */
bf79451e 8966
43f66a6c
JK
8967 return wstats;
8968}
8969
43f66a6c
JK
8970/* net device stuff */
8971
8972static inline void init_sys_config(struct ipw_sys_config *sys_config)
8973{
0edd5b44
JG
8974 memset(sys_config, 0, sizeof(struct ipw_sys_config));
8975 sys_config->bt_coexistence = 1; /* We may need to look into prvStaBtConfig */
43f66a6c
JK
8976 sys_config->answer_broadcast_ssid_probe = 0;
8977 sys_config->accept_all_data_frames = 0;
8978 sys_config->accept_non_directed_frames = 1;
8979 sys_config->exclude_unicast_unencrypted = 0;
8980 sys_config->disable_unicast_decryption = 1;
8981 sys_config->exclude_multicast_unencrypted = 0;
8982 sys_config->disable_multicast_decryption = 1;
8983 sys_config->antenna_diversity = CFG_SYS_ANTENNA_BOTH;
0edd5b44 8984 sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */
43f66a6c 8985 sys_config->dot11g_auto_detection = 0;
bf79451e 8986 sys_config->enable_cts_to_self = 0;
43f66a6c 8987 sys_config->bt_coexist_collision_thr = 0;
c848d0af 8988 sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256
43f66a6c
JK
8989}
8990
8991static int ipw_net_open(struct net_device *dev)
8992{
8993 struct ipw_priv *priv = ieee80211_priv(dev);
8994 IPW_DEBUG_INFO("dev->open\n");
8995 /* we should be verifying the device is ready to be opened */
c848d0af 8996 down(&priv->sem);
bf79451e
JG
8997 if (!(priv->status & STATUS_RF_KILL_MASK) &&
8998 (priv->status & STATUS_ASSOCIATED))
43f66a6c 8999 netif_start_queue(dev);
c848d0af 9000 up(&priv->sem);
43f66a6c
JK
9001 return 0;
9002}
9003
9004static int ipw_net_stop(struct net_device *dev)
9005{
9006 IPW_DEBUG_INFO("dev->close\n");
9007 netif_stop_queue(dev);
9008 return 0;
9009}
9010
9011/*
9012todo:
9013
9014modify to send one tfd per fragment instead of using chunking. otherwise
9015we need to heavily modify the ieee80211_skb_to_txb.
9016*/
9017
b095c381
JK
9018static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
9019 int pri)
43f66a6c 9020{
0dacca1f 9021 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
0edd5b44 9022 txb->fragments[0]->data;
43f66a6c
JK
9023 int i = 0;
9024 struct tfd_frame *tfd;
b095c381
JK
9025#ifdef CONFIG_IPW_QOS
9026 int tx_id = ipw_get_tx_queue_number(priv, pri);
9027 struct clx2_tx_queue *txq = &priv->txq[tx_id];
9028#else
43f66a6c 9029 struct clx2_tx_queue *txq = &priv->txq[0];
b095c381 9030#endif
43f66a6c
JK
9031 struct clx2_queue *q = &txq->q;
9032 u8 id, hdr_len, unicast;
9033 u16 remaining_bytes;
c848d0af 9034 int fc;
43f66a6c
JK
9035
9036 switch (priv->ieee->iw_mode) {
9037 case IW_MODE_ADHOC:
9038 hdr_len = IEEE80211_3ADDR_LEN;
9039 unicast = !is_broadcast_ether_addr(hdr->addr1) &&
0edd5b44 9040 !is_multicast_ether_addr(hdr->addr1);
43f66a6c
JK
9041 id = ipw_find_station(priv, hdr->addr1);
9042 if (id == IPW_INVALID_STATION) {
9043 id = ipw_add_station(priv, hdr->addr1);
9044 if (id == IPW_INVALID_STATION) {
9045 IPW_WARNING("Attempt to send data to "
bf79451e 9046 "invalid cell: " MAC_FMT "\n",
43f66a6c
JK
9047 MAC_ARG(hdr->addr1));
9048 goto drop;
9049 }
9050 }
9051 break;
9052
9053 case IW_MODE_INFRA:
9054 default:
9055 unicast = !is_broadcast_ether_addr(hdr->addr3) &&
0edd5b44 9056 !is_multicast_ether_addr(hdr->addr3);
43f66a6c
JK
9057 hdr_len = IEEE80211_3ADDR_LEN;
9058 id = 0;
9059 break;
9060 }
9061
9062 tfd = &txq->bd[q->first_empty];
9063 txq->txb[q->first_empty] = txb;
9064 memset(tfd, 0, sizeof(*tfd));
9065 tfd->u.data.station_number = id;
9066
9067 tfd->control_flags.message_type = TX_FRAME_TYPE;
9068 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
9069
9070 tfd->u.data.cmd_id = DINO_CMD_TX;
a613bffd 9071 tfd->u.data.len = cpu_to_le16(txb->payload_size);
43f66a6c 9072 remaining_bytes = txb->payload_size;
bf79451e 9073
43f66a6c 9074 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
b095c381 9075 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_CCK;
43f66a6c 9076 else
b095c381 9077 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_OFDM;
43f66a6c 9078
ea2b26e0
JK
9079 if (priv->assoc_request.preamble_length == DCT_FLAG_SHORT_PREAMBLE)
9080 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREAMBLE;
43f66a6c 9081
c848d0af
JK
9082 fc = le16_to_cpu(hdr->frame_ctl);
9083 hdr->frame_ctl = cpu_to_le16(fc & ~IEEE80211_FCTL_MOREFRAGS);
9084
43f66a6c
JK
9085 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
9086
b095c381
JK
9087 if (likely(unicast))
9088 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
9089
9090 if (txb->encrypted && !priv->ieee->host_encrypt) {
9091 switch (priv->ieee->sec.level) {
9092 case SEC_LEVEL_3:
9093 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9094 IEEE80211_FCTL_PROTECTED;
9095 /* XXX: ACK flag must be set for CCMP even if it
9096 * is a multicast/broadcast packet, because CCMP
9097 * group communication encrypted by GTK is
9098 * actually done by the AP. */
9099 if (!unicast)
9100 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
9101
9102 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
9103 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_CCM;
9104 tfd->u.data.key_index = 0;
9105 tfd->u.data.key_index |= DCT_WEP_INDEX_USE_IMMEDIATE;
9106 break;
9107 case SEC_LEVEL_2:
9108 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9109 IEEE80211_FCTL_PROTECTED;
9110 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
9111 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP;
9112 tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE;
9113 break;
9114 case SEC_LEVEL_1:
9115 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9116 IEEE80211_FCTL_PROTECTED;
9117 tfd->u.data.key_index = priv->ieee->tx_keyidx;
9118 if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <=
9119 40)
9120 tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;
9121 else
9122 tfd->u.data.key_index |= DCT_WEP_KEY_128Bit;
9123 break;
9124 case SEC_LEVEL_0:
9125 break;
9126 default:
9127 printk(KERN_ERR "Unknow security level %d\n",
9128 priv->ieee->sec.level);
9129 break;
9130 }
9131 } else
9132 /* No hardware encryption */
9133 tfd->u.data.tx_flags |= DCT_FLAG_NO_WEP;
9134
9135#ifdef CONFIG_IPW_QOS
9136 ipw_qos_set_tx_queue_command(priv, pri, &(tfd->u.data), unicast);
9137#endif /* CONFIG_IPW_QOS */
9138
43f66a6c 9139 /* payload */
a613bffd
JK
9140 tfd->u.data.num_chunks = cpu_to_le32(min((u8) (NUM_TFD_CHUNKS - 2),
9141 txb->nr_frags));
9142 IPW_DEBUG_FRAG("%i fragments being sent as %i chunks.\n",
9143 txb->nr_frags, le32_to_cpu(tfd->u.data.num_chunks));
9144 for (i = 0; i < le32_to_cpu(tfd->u.data.num_chunks); i++) {
9145 IPW_DEBUG_FRAG("Adding fragment %i of %i (%d bytes).\n",
9146 i, le32_to_cpu(tfd->u.data.num_chunks),
9147 txb->fragments[i]->len - hdr_len);
bf79451e 9148 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n",
43f66a6c
JK
9149 i, tfd->u.data.num_chunks,
9150 txb->fragments[i]->len - hdr_len);
bf79451e 9151 printk_buf(IPW_DL_TX, txb->fragments[i]->data + hdr_len,
43f66a6c
JK
9152 txb->fragments[i]->len - hdr_len);
9153
0edd5b44 9154 tfd->u.data.chunk_ptr[i] =
a613bffd
JK
9155 cpu_to_le32(pci_map_single
9156 (priv->pci_dev,
9157 txb->fragments[i]->data + hdr_len,
9158 txb->fragments[i]->len - hdr_len,
9159 PCI_DMA_TODEVICE));
9160 tfd->u.data.chunk_len[i] =
9161 cpu_to_le16(txb->fragments[i]->len - hdr_len);
43f66a6c
JK
9162 }
9163
9164 if (i != txb->nr_frags) {
9165 struct sk_buff *skb;
9166 u16 remaining_bytes = 0;
9167 int j;
9168
9169 for (j = i; j < txb->nr_frags; j++)
9170 remaining_bytes += txb->fragments[j]->len - hdr_len;
9171
9172 printk(KERN_INFO "Trying to reallocate for %d bytes\n",
9173 remaining_bytes);
9174 skb = alloc_skb(remaining_bytes, GFP_ATOMIC);
9175 if (skb != NULL) {
a613bffd 9176 tfd->u.data.chunk_len[i] = cpu_to_le16(remaining_bytes);
43f66a6c
JK
9177 for (j = i; j < txb->nr_frags; j++) {
9178 int size = txb->fragments[j]->len - hdr_len;
9179 printk(KERN_INFO "Adding frag %d %d...\n",
0edd5b44 9180 j, size);
43f66a6c 9181 memcpy(skb_put(skb, size),
0edd5b44 9182 txb->fragments[j]->data + hdr_len, size);
43f66a6c
JK
9183 }
9184 dev_kfree_skb_any(txb->fragments[i]);
9185 txb->fragments[i] = skb;
0edd5b44 9186 tfd->u.data.chunk_ptr[i] =
a613bffd
JK
9187 cpu_to_le32(pci_map_single
9188 (priv->pci_dev, skb->data,
9189 tfd->u.data.chunk_len[i],
9190 PCI_DMA_TODEVICE));
9191
9192 tfd->u.data.num_chunks =
9193 cpu_to_le32(le32_to_cpu(tfd->u.data.num_chunks) +
9194 1);
bf79451e 9195 }
43f66a6c
JK
9196 }
9197
9198 /* kick DMA */
9199 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
9200 ipw_write32(priv, q->reg_w, q->first_empty);
9201
bf79451e 9202 if (ipw_queue_space(q) < q->high_mark)
43f66a6c
JK
9203 netif_stop_queue(priv->net_dev);
9204
9205 return;
9206
0edd5b44 9207 drop:
43f66a6c
JK
9208 IPW_DEBUG_DROP("Silently dropping Tx packet.\n");
9209 ieee80211_txb_free(txb);
9210}
9211
9212static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
c8d42d1a 9213 struct net_device *dev, int pri)
43f66a6c
JK
9214{
9215 struct ipw_priv *priv = ieee80211_priv(dev);
9216 unsigned long flags;
9217
9218 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
43f66a6c
JK
9219 spin_lock_irqsave(&priv->lock, flags);
9220
9221 if (!(priv->status & STATUS_ASSOCIATED)) {
9222 IPW_DEBUG_INFO("Tx attempt while not associated.\n");
9223 priv->ieee->stats.tx_carrier_errors++;
9224 netif_stop_queue(dev);
9225 goto fail_unlock;
9226 }
9227
b095c381
JK
9228 ipw_tx_skb(priv, txb, pri);
9229 __ipw_led_activity_on(priv);
c848d0af 9230 spin_unlock_irqrestore(&priv->lock, flags);
43f66a6c 9231
43f66a6c
JK
9232 return 0;
9233
0edd5b44 9234 fail_unlock:
43f66a6c
JK
9235 spin_unlock_irqrestore(&priv->lock, flags);
9236 return 1;
9237}
9238
9239static struct net_device_stats *ipw_net_get_stats(struct net_device *dev)
9240{
9241 struct ipw_priv *priv = ieee80211_priv(dev);
bf79451e 9242
43f66a6c
JK
9243 priv->ieee->stats.tx_packets = priv->tx_packets;
9244 priv->ieee->stats.rx_packets = priv->rx_packets;
9245 return &priv->ieee->stats;
9246}
9247
9248static void ipw_net_set_multicast_list(struct net_device *dev)
9249{
9250
9251}
9252
9253static int ipw_net_set_mac_address(struct net_device *dev, void *p)
9254{
9255 struct ipw_priv *priv = ieee80211_priv(dev);
9256 struct sockaddr *addr = p;
9257 if (!is_valid_ether_addr(addr->sa_data))
9258 return -EADDRNOTAVAIL;
c848d0af 9259 down(&priv->sem);
43f66a6c
JK
9260 priv->config |= CFG_CUSTOM_MAC;
9261 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
9262 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
9263 priv->net_dev->name, MAC_ARG(priv->mac_addr));
a613bffd 9264 queue_work(priv->workqueue, &priv->adapter_restart);
c848d0af 9265 up(&priv->sem);
43f66a6c
JK
9266 return 0;
9267}
9268
bf79451e 9269static void ipw_ethtool_get_drvinfo(struct net_device *dev,
43f66a6c
JK
9270 struct ethtool_drvinfo *info)
9271{
9272 struct ipw_priv *p = ieee80211_priv(dev);
9273 char vers[64];
9274 char date[32];
9275 u32 len;
9276
9277 strcpy(info->driver, DRV_NAME);
9278 strcpy(info->version, DRV_VERSION);
9279
9280 len = sizeof(vers);
9281 ipw_get_ordinal(p, IPW_ORD_STAT_FW_VERSION, vers, &len);
9282 len = sizeof(date);
9283 ipw_get_ordinal(p, IPW_ORD_STAT_FW_DATE, date, &len);
9284
0edd5b44 9285 snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)",
43f66a6c
JK
9286 vers, date);
9287 strcpy(info->bus_info, pci_name(p->pci_dev));
b095c381 9288 info->eedump_len = IPW_EEPROM_IMAGE_SIZE;
43f66a6c
JK
9289}
9290
9291static u32 ipw_ethtool_get_link(struct net_device *dev)
9292{
9293 struct ipw_priv *priv = ieee80211_priv(dev);
9294 return (priv->status & STATUS_ASSOCIATED) != 0;
9295}
9296
9297static int ipw_ethtool_get_eeprom_len(struct net_device *dev)
9298{
b095c381 9299 return IPW_EEPROM_IMAGE_SIZE;
43f66a6c
JK
9300}
9301
9302static int ipw_ethtool_get_eeprom(struct net_device *dev,
0edd5b44 9303 struct ethtool_eeprom *eeprom, u8 * bytes)
43f66a6c
JK
9304{
9305 struct ipw_priv *p = ieee80211_priv(dev);
9306
b095c381 9307 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
43f66a6c 9308 return -EINVAL;
c848d0af 9309 down(&p->sem);
0edd5b44 9310 memcpy(bytes, &((u8 *) p->eeprom)[eeprom->offset], eeprom->len);
c848d0af 9311 up(&p->sem);
43f66a6c
JK
9312 return 0;
9313}
9314
9315static int ipw_ethtool_set_eeprom(struct net_device *dev,
0edd5b44 9316 struct ethtool_eeprom *eeprom, u8 * bytes)
43f66a6c
JK
9317{
9318 struct ipw_priv *p = ieee80211_priv(dev);
9319 int i;
9320
b095c381 9321 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
43f66a6c 9322 return -EINVAL;
c848d0af 9323 down(&p->sem);
0edd5b44 9324 memcpy(&((u8 *) p->eeprom)[eeprom->offset], bytes, eeprom->len);
bf79451e 9325 for (i = IPW_EEPROM_DATA;
b095c381 9326 i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++)
43f66a6c 9327 ipw_write8(p, i, p->eeprom[i]);
c848d0af 9328 up(&p->sem);
43f66a6c
JK
9329 return 0;
9330}
9331
9332static struct ethtool_ops ipw_ethtool_ops = {
ea2b26e0
JK
9333 .get_link = ipw_ethtool_get_link,
9334 .get_drvinfo = ipw_ethtool_get_drvinfo,
9335 .get_eeprom_len = ipw_ethtool_get_eeprom_len,
9336 .get_eeprom = ipw_ethtool_get_eeprom,
9337 .set_eeprom = ipw_ethtool_set_eeprom,
43f66a6c
JK
9338};
9339
9340static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
9341{
9342 struct ipw_priv *priv = data;
9343 u32 inta, inta_mask;
bf79451e 9344
43f66a6c
JK
9345 if (!priv)
9346 return IRQ_NONE;
9347
9348 spin_lock(&priv->lock);
9349
9350 if (!(priv->status & STATUS_INT_ENABLED)) {
9351 /* Shared IRQ */
9352 goto none;
9353 }
9354
b095c381
JK
9355 inta = ipw_read32(priv, IPW_INTA_RW);
9356 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
bf79451e 9357
43f66a6c
JK
9358 if (inta == 0xFFFFFFFF) {
9359 /* Hardware disappeared */
9360 IPW_WARNING("IRQ INTA == 0xFFFFFFFF\n");
9361 goto none;
9362 }
9363
b095c381 9364 if (!(inta & (IPW_INTA_MASK_ALL & inta_mask))) {
43f66a6c
JK
9365 /* Shared interrupt */
9366 goto none;
9367 }
9368
9369 /* tell the device to stop sending interrupts */
9370 ipw_disable_interrupts(priv);
bf79451e 9371
43f66a6c 9372 /* ack current interrupts */
b095c381
JK
9373 inta &= (IPW_INTA_MASK_ALL & inta_mask);
9374 ipw_write32(priv, IPW_INTA_RW, inta);
bf79451e 9375
43f66a6c
JK
9376 /* Cache INTA value for our tasklet */
9377 priv->isr_inta = inta;
9378
9379 tasklet_schedule(&priv->irq_tasklet);
9380
0edd5b44 9381 spin_unlock(&priv->lock);
43f66a6c
JK
9382
9383 return IRQ_HANDLED;
0edd5b44 9384 none:
43f66a6c
JK
9385 spin_unlock(&priv->lock);
9386 return IRQ_NONE;
9387}
9388
9389static void ipw_rf_kill(void *adapter)
9390{
9391 struct ipw_priv *priv = adapter;
9392 unsigned long flags;
bf79451e 9393
43f66a6c
JK
9394 spin_lock_irqsave(&priv->lock, flags);
9395
9396 if (rf_kill_active(priv)) {
9397 IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
9398 if (priv->workqueue)
9399 queue_delayed_work(priv->workqueue,
9400 &priv->rf_kill, 2 * HZ);
9401 goto exit_unlock;
9402 }
9403
9404 /* RF Kill is now disabled, so bring the device back up */
9405
9406 if (!(priv->status & STATUS_RF_KILL_MASK)) {
9407 IPW_DEBUG_RF_KILL("HW RF Kill no longer active, restarting "
9408 "device\n");
9409
9410 /* we can not do an adapter restart while inside an irq lock */
9411 queue_work(priv->workqueue, &priv->adapter_restart);
bf79451e 9412 } else
43f66a6c
JK
9413 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
9414 "enabled\n");
9415
0edd5b44 9416 exit_unlock:
43f66a6c
JK
9417 spin_unlock_irqrestore(&priv->lock, flags);
9418}
9419
c848d0af
JK
9420static void ipw_bg_rf_kill(void *data)
9421{
9422 struct ipw_priv *priv = data;
9423 down(&priv->sem);
9424 ipw_rf_kill(data);
9425 up(&priv->sem);
9426}
9427
a613bffd
JK
9428void ipw_link_up(struct ipw_priv *priv)
9429{
9430 netif_carrier_on(priv->net_dev);
9431 if (netif_queue_stopped(priv->net_dev)) {
9432 IPW_DEBUG_NOTIF("waking queue\n");
9433 netif_wake_queue(priv->net_dev);
9434 } else {
9435 IPW_DEBUG_NOTIF("starting queue\n");
9436 netif_start_queue(priv->net_dev);
9437 }
9438
c848d0af 9439 cancel_delayed_work(&priv->request_scan);
a613bffd
JK
9440 ipw_reset_stats(priv);
9441 /* Ensure the rate is updated immediately */
9442 priv->last_rate = ipw_get_current_rate(priv);
9443 ipw_gather_stats(priv);
9444 ipw_led_link_up(priv);
9445 notify_wx_assoc_event(priv);
9446
9447 if (priv->config & CFG_BACKGROUND_SCAN)
9448 queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
9449}
9450
c848d0af
JK
9451static void ipw_bg_link_up(void *data)
9452{
9453 struct ipw_priv *priv = data;
9454 down(&priv->sem);
9455 ipw_link_up(data);
9456 up(&priv->sem);
9457}
9458
a613bffd
JK
9459void ipw_link_down(struct ipw_priv *priv)
9460{
9461 ipw_led_link_down(priv);
9462 netif_carrier_off(priv->net_dev);
9463 netif_stop_queue(priv->net_dev);
9464 notify_wx_assoc_event(priv);
9465
9466 /* Cancel any queued work ... */
9467 cancel_delayed_work(&priv->request_scan);
9468 cancel_delayed_work(&priv->adhoc_check);
9469 cancel_delayed_work(&priv->gather_stats);
9470
9471 ipw_reset_stats(priv);
9472
9473 /* Queue up another scan... */
9474 queue_work(priv->workqueue, &priv->request_scan);
9475}
9476
c848d0af
JK
9477static void ipw_bg_link_down(void *data)
9478{
9479 struct ipw_priv *priv = data;
9480 down(&priv->sem);
9481 ipw_link_down(data);
9482 up(&priv->sem);
9483}
9484
43f66a6c
JK
9485static int ipw_setup_deferred_work(struct ipw_priv *priv)
9486{
9487 int ret = 0;
9488
43f66a6c 9489 priv->workqueue = create_workqueue(DRV_NAME);
43f66a6c
JK
9490 init_waitqueue_head(&priv->wait_command_queue);
9491
c848d0af
JK
9492 INIT_WORK(&priv->adhoc_check, ipw_bg_adhoc_check, priv);
9493 INIT_WORK(&priv->associate, ipw_bg_associate, priv);
9494 INIT_WORK(&priv->disassociate, ipw_bg_disassociate, priv);
9495 INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish, priv);
9496 INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart, priv);
9497 INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill, priv);
9498 INIT_WORK(&priv->up, (void (*)(void *))ipw_bg_up, priv);
9499 INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv);
bf79451e 9500 INIT_WORK(&priv->request_scan,
b095c381 9501 (void (*)(void *))ipw_request_scan, priv);
bf79451e 9502 INIT_WORK(&priv->gather_stats,
c848d0af
JK
9503 (void (*)(void *))ipw_bg_gather_stats, priv);
9504 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv);
9505 INIT_WORK(&priv->roam, ipw_bg_roam, priv);
9506 INIT_WORK(&priv->scan_check, ipw_bg_scan_check, priv);
9507 INIT_WORK(&priv->link_up, (void (*)(void *))ipw_bg_link_up, priv);
9508 INIT_WORK(&priv->link_down, (void (*)(void *))ipw_bg_link_down, priv);
9509 INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_bg_led_link_on,
9510 priv);
9511 INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_bg_led_link_off,
a613bffd 9512 priv);
c848d0af 9513 INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_bg_led_activity_off,
a613bffd 9514 priv);
c848d0af
JK
9515 INIT_WORK(&priv->merge_networks,
9516 (void (*)(void *))ipw_merge_adhoc_network, priv);
43f66a6c 9517
b095c381
JK
9518#ifdef CONFIG_IPW_QOS
9519 INIT_WORK(&priv->qos_activate, (void (*)(void *))ipw_bg_qos_activate,
9520 priv);
9521#endif /* CONFIG_IPW_QOS */
9522
43f66a6c
JK
9523 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
9524 ipw_irq_tasklet, (unsigned long)priv);
9525
9526 return ret;
9527}
9528
43f66a6c
JK
9529static void shim__set_security(struct net_device *dev,
9530 struct ieee80211_security *sec)
9531{
9532 struct ipw_priv *priv = ieee80211_priv(dev);
9533 int i;
c848d0af 9534 down(&priv->sem);
bf79451e 9535 for (i = 0; i < 4; i++) {
43f66a6c 9536 if (sec->flags & (1 << i)) {
b095c381 9537 priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
43f66a6c 9538 if (sec->key_sizes[i] == 0)
b095c381
JK
9539 priv->ieee->sec.flags &= ~(1 << i);
9540 else {
9541 memcpy(priv->ieee->sec.keys[i], sec->keys[i],
43f66a6c 9542 sec->key_sizes[i]);
b095c381
JK
9543 priv->ieee->sec.flags |= (1 << i);
9544 }
43f66a6c 9545 priv->status |= STATUS_SECURITY_UPDATED;
b095c381
JK
9546 } else if (sec->level != SEC_LEVEL_1)
9547 priv->ieee->sec.flags &= ~(1 << i);
43f66a6c
JK
9548 }
9549
b095c381 9550 if (sec->flags & SEC_ACTIVE_KEY) {
43f66a6c 9551 if (sec->active_key <= 3) {
b095c381
JK
9552 priv->ieee->sec.active_key = sec->active_key;
9553 priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
bf79451e 9554 } else
b095c381 9555 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
43f66a6c 9556 priv->status |= STATUS_SECURITY_UPDATED;
b095c381
JK
9557 } else
9558 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
43f66a6c
JK
9559
9560 if ((sec->flags & SEC_AUTH_MODE) &&
b095c381
JK
9561 (priv->ieee->sec.auth_mode != sec->auth_mode)) {
9562 priv->ieee->sec.auth_mode = sec->auth_mode;
9563 priv->ieee->sec.flags |= SEC_AUTH_MODE;
43f66a6c
JK
9564 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY)
9565 priv->capability |= CAP_SHARED_KEY;
9566 else
9567 priv->capability &= ~CAP_SHARED_KEY;
9568 priv->status |= STATUS_SECURITY_UPDATED;
9569 }
bf79451e 9570
b095c381
JK
9571 if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
9572 priv->ieee->sec.flags |= SEC_ENABLED;
9573 priv->ieee->sec.enabled = sec->enabled;
43f66a6c 9574 priv->status |= STATUS_SECURITY_UPDATED;
bf79451e 9575 if (sec->enabled)
43f66a6c
JK
9576 priv->capability |= CAP_PRIVACY_ON;
9577 else
9578 priv->capability &= ~CAP_PRIVACY_ON;
9579 }
b095c381 9580 priv->ieee->sec.encrypt = sec->encrypt;
bf79451e 9581
b095c381
JK
9582 if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
9583 priv->ieee->sec.level = sec->level;
9584 priv->ieee->sec.flags |= SEC_LEVEL;
43f66a6c
JK
9585 priv->status |= STATUS_SECURITY_UPDATED;
9586 }
9587
b095c381
JK
9588 if (!priv->ieee->host_encrypt)
9589 ipw_set_hwcrypto_keys(priv);
9590
bf79451e
JG
9591 /* To match current functionality of ipw2100 (which works well w/
9592 * various supplicants, we don't force a disassociate if the
43f66a6c
JK
9593 * privacy capability changes ... */
9594#if 0
9595 if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) &&
bf79451e 9596 (((priv->assoc_request.capability &
43f66a6c 9597 WLAN_CAPABILITY_PRIVACY) && !sec->enabled) ||
bf79451e 9598 (!(priv->assoc_request.capability &
0edd5b44 9599 WLAN_CAPABILITY_PRIVACY) && sec->enabled))) {
43f66a6c
JK
9600 IPW_DEBUG_ASSOC("Disassociating due to capability "
9601 "change.\n");
9602 ipw_disassociate(priv);
9603 }
9604#endif
c848d0af 9605 up(&priv->sem);
43f66a6c
JK
9606}
9607
bf79451e 9608static int init_supported_rates(struct ipw_priv *priv,
43f66a6c
JK
9609 struct ipw_supported_rates *rates)
9610{
9611 /* TODO: Mask out rates based on priv->rates_mask */
9612
9613 memset(rates, 0, sizeof(*rates));
0edd5b44 9614 /* configure supported rates */
43f66a6c
JK
9615 switch (priv->ieee->freq_band) {
9616 case IEEE80211_52GHZ_BAND:
9617 rates->ieee_mode = IPW_A_MODE;
9618 rates->purpose = IPW_RATE_CAPABILITIES;
9619 ipw_add_ofdm_scan_rates(rates, IEEE80211_CCK_MODULATION,
9620 IEEE80211_OFDM_DEFAULT_RATES_MASK);
9621 break;
9622
0edd5b44 9623 default: /* Mixed or 2.4Ghz */
43f66a6c
JK
9624 rates->ieee_mode = IPW_G_MODE;
9625 rates->purpose = IPW_RATE_CAPABILITIES;
9626 ipw_add_cck_scan_rates(rates, IEEE80211_CCK_MODULATION,
9627 IEEE80211_CCK_DEFAULT_RATES_MASK);
9628 if (priv->ieee->modulation & IEEE80211_OFDM_MODULATION) {
9629 ipw_add_ofdm_scan_rates(rates, IEEE80211_CCK_MODULATION,
9630 IEEE80211_OFDM_DEFAULT_RATES_MASK);
9631 }
9632 break;
9633 }
9634
9635 return 0;
9636}
9637
bf79451e 9638static int ipw_config(struct ipw_priv *priv)
43f66a6c
JK
9639{
9640 int i;
9641 struct ipw_tx_power tx_power;
9642
9643 memset(&priv->sys_config, 0, sizeof(priv->sys_config));
9644 memset(&tx_power, 0, sizeof(tx_power));
9645
9646 /* This is only called from ipw_up, which resets/reloads the firmware
9647 so, we don't need to first disable the card before we configure
9648 it */
9649
9650 /* configure device for 'G' band */
9651 tx_power.ieee_mode = IPW_G_MODE;
9652 tx_power.num_channels = 11;
9653 for (i = 0; i < 11; i++) {
9654 tx_power.channels_tx_power[i].channel_number = i + 1;
9655 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
9656 }
9657 if (ipw_send_tx_power(priv, &tx_power))
9658 goto error;
9659
9660 /* configure device to also handle 'B' band */
9661 tx_power.ieee_mode = IPW_B_MODE;
9662 if (ipw_send_tx_power(priv, &tx_power))
9663 goto error;
9664
9665 /* initialize adapter address */
9666 if (ipw_send_adapter_address(priv, priv->net_dev->dev_addr))
9667 goto error;
9668
9669 /* set basic system config settings */
9670 init_sys_config(&priv->sys_config);
c848d0af
JK
9671 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
9672 priv->sys_config.answer_broadcast_ssid_probe = 1;
9673 else
9674 priv->sys_config.answer_broadcast_ssid_probe = 0;
9675
43f66a6c
JK
9676 if (ipw_send_system_config(priv, &priv->sys_config))
9677 goto error;
9678
0edd5b44
JG
9679 init_supported_rates(priv, &priv->rates);
9680 if (ipw_send_supported_rates(priv, &priv->rates))
43f66a6c
JK
9681 goto error;
9682
9683 /* Set request-to-send threshold */
9684 if (priv->rts_threshold) {
9685 if (ipw_send_rts_threshold(priv, priv->rts_threshold))
9686 goto error;
9687 }
b095c381
JK
9688#ifdef CONFIG_IPW_QOS
9689 IPW_DEBUG_QOS("QoS: call ipw_qos_activate\n");
9690 ipw_qos_activate(priv, NULL);
9691#endif /* CONFIG_IPW_QOS */
43f66a6c
JK
9692
9693 if (ipw_set_random_seed(priv))
9694 goto error;
bf79451e 9695
43f66a6c
JK
9696 /* final state transition to the RUN state */
9697 if (ipw_send_host_complete(priv))
9698 goto error;
9699
9700 /* If configured to try and auto-associate, kick off a scan */
b095c381
JK
9701 if (priv->config & CFG_ASSOCIATE)
9702 queue_work(priv->workqueue, &priv->request_scan);
43f66a6c
JK
9703
9704 return 0;
bf79451e 9705
0edd5b44 9706 error:
43f66a6c
JK
9707 return -EIO;
9708}
9709
9710#define MAX_HW_RESTARTS 5
9711static int ipw_up(struct ipw_priv *priv)
9712{
9713 int rc, i;
9714
9715 if (priv->status & STATUS_EXIT_PENDING)
9716 return -EIO;
9717
0edd5b44 9718 for (i = 0; i < MAX_HW_RESTARTS; i++) {
bf79451e 9719 /* Load the microcode, firmware, and eeprom.
43f66a6c
JK
9720 * Also start the clocks. */
9721 rc = ipw_load(priv);
9722 if (rc) {
0edd5b44 9723 IPW_ERROR("Unable to load firmware: 0x%08X\n", rc);
43f66a6c
JK
9724 return rc;
9725 }
9726
9727 ipw_init_ordinals(priv);
9728 if (!(priv->config & CFG_CUSTOM_MAC))
9729 eeprom_parse_mac(priv, priv->mac_addr);
9730 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
9731
b095c381
JK
9732 if (priv->status & STATUS_RF_KILL_SW) {
9733 IPW_WARNING("Radio disabled by module parameter.\n");
9734 return 0;
9735 } else if (rf_kill_active(priv)) {
9736 IPW_WARNING("Radio Frequency Kill Switch is On:\n"
9737 "Kill switch must be turned off for "
9738 "wireless networking to work.\n");
9739 queue_delayed_work(priv->workqueue, &priv->rf_kill,
9740 2 * HZ);
43f66a6c 9741 return 0;
c848d0af 9742 }
43f66a6c
JK
9743
9744 rc = ipw_config(priv);
9745 if (!rc) {
9746 IPW_DEBUG_INFO("Configured device on count %i\n", i);
a613bffd
JK
9747 ipw_led_init(priv);
9748 ipw_led_radio_on(priv);
43f66a6c 9749 priv->notif_missed_beacons = 0;
c848d0af 9750 priv->status |= STATUS_INIT;
43f66a6c 9751 return 0;
43f66a6c 9752 }
bf79451e 9753
c848d0af 9754 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n", rc);
43f66a6c
JK
9755 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n",
9756 i, MAX_HW_RESTARTS);
9757
9758 /* We had an error bringing up the hardware, so take it
9759 * all the way back down so we can try again */
9760 ipw_down(priv);
9761 }
9762
bf79451e 9763 /* tried to restart and config the device for as long as our
43f66a6c 9764 * patience could withstand */
0edd5b44 9765 IPW_ERROR("Unable to initialize device after %d attempts.\n", i);
c848d0af 9766
43f66a6c
JK
9767 return -EIO;
9768}
9769
c848d0af
JK
9770static void ipw_bg_up(void *data)
9771{
9772 struct ipw_priv *priv = data;
9773 down(&priv->sem);
9774 ipw_up(data);
9775 up(&priv->sem);
9776}
9777
b095c381 9778static void ipw_deinit(struct ipw_priv *priv)
43f66a6c 9779{
b095c381
JK
9780 int i;
9781
9782 if (priv->status & STATUS_SCANNING) {
9783 IPW_DEBUG_INFO("Aborting scan during shutdown.\n");
9784 ipw_abort_scan(priv);
9785 }
9786
9787 if (priv->status & STATUS_ASSOCIATED) {
9788 IPW_DEBUG_INFO("Disassociating during shutdown.\n");
9789 ipw_disassociate(priv);
9790 }
9791
9792 ipw_led_shutdown(priv);
9793
9794 /* Wait up to 1s for status to change to not scanning and not
9795 * associated (disassociation can take a while for a ful 802.11
9796 * exchange */
9797 for (i = 1000; i && (priv->status &
9798 (STATUS_DISASSOCIATING |
9799 STATUS_ASSOCIATED | STATUS_SCANNING)); i--)
9800 udelay(10);
9801
9802 if (priv->status & (STATUS_DISASSOCIATING |
9803 STATUS_ASSOCIATED | STATUS_SCANNING))
9804 IPW_DEBUG_INFO("Still associated or scanning...\n");
9805 else
9806 IPW_DEBUG_INFO("Took %dms to de-init\n", 1000 - i);
9807
c848d0af 9808 /* Attempt to disable the card */
43f66a6c 9809 ipw_send_card_disable(priv, 0);
b095c381
JK
9810
9811 priv->status &= ~STATUS_INIT;
9812}
9813
9814static void ipw_down(struct ipw_priv *priv)
9815{
9816 int exit_pending = priv->status & STATUS_EXIT_PENDING;
9817
9818 priv->status |= STATUS_EXIT_PENDING;
9819
9820 if (ipw_is_init(priv))
9821 ipw_deinit(priv);
9822
9823 /* Wipe out the EXIT_PENDING status bit if we are not actually
9824 * exiting the module */
9825 if (!exit_pending)
9826 priv->status &= ~STATUS_EXIT_PENDING;
43f66a6c
JK
9827
9828 /* tell the device to stop sending interrupts */
9829 ipw_disable_interrupts(priv);
9830
9831 /* Clear all bits but the RF Kill */
b095c381 9832 priv->status &= STATUS_RF_KILL_MASK | STATUS_EXIT_PENDING;
43f66a6c
JK
9833 netif_carrier_off(priv->net_dev);
9834 netif_stop_queue(priv->net_dev);
9835
9836 ipw_stop_nic(priv);
a613bffd
JK
9837
9838 ipw_led_radio_off(priv);
43f66a6c
JK
9839}
9840
c848d0af
JK
9841static void ipw_bg_down(void *data)
9842{
9843 struct ipw_priv *priv = data;
9844 down(&priv->sem);
9845 ipw_down(data);
9846 up(&priv->sem);
9847}
9848
ea2b26e0
JK
9849static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
9850{
ea2b26e0
JK
9851 struct iwreq *wrq = (struct iwreq *)rq;
9852 int ret = -1;
9853 switch (cmd) {
9854 case IPW_IOCTL_WPA_SUPPLICANT:
9855 ret = ipw_wpa_supplicant(dev, &wrq->u.data);
9856 return ret;
9857
9858 default:
9859 return -EOPNOTSUPP;
9860 }
9861
ea2b26e0
JK
9862 return -EOPNOTSUPP;
9863}
9864
43f66a6c
JK
9865/* Called by register_netdev() */
9866static int ipw_net_init(struct net_device *dev)
9867{
9868 struct ipw_priv *priv = ieee80211_priv(dev);
c848d0af 9869 down(&priv->sem);
43f66a6c 9870
c848d0af
JK
9871 if (ipw_up(priv)) {
9872 up(&priv->sem);
43f66a6c 9873 return -EIO;
c848d0af 9874 }
43f66a6c 9875
c848d0af 9876 up(&priv->sem);
43f66a6c
JK
9877 return 0;
9878}
9879
9880/* PCI driver stuff */
9881static struct pci_device_id card_ids[] = {
9882 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2701, 0, 0, 0},
9883 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2702, 0, 0, 0},
9884 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2711, 0, 0, 0},
9885 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2712, 0, 0, 0},
9886 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2721, 0, 0, 0},
9887 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2722, 0, 0, 0},
9888 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2731, 0, 0, 0},
9889 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2732, 0, 0, 0},
9890 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2741, 0, 0, 0},
9891 {PCI_VENDOR_ID_INTEL, 0x1043, 0x103c, 0x2741, 0, 0, 0},
9892 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2742, 0, 0, 0},
9893 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2751, 0, 0, 0},
9894 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2752, 0, 0, 0},
9895 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2753, 0, 0, 0},
9896 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2754, 0, 0, 0},
9897 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2761, 0, 0, 0},
9898 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},
9899 {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
0edd5b44 9900 {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
a613bffd 9901 {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
0edd5b44
JG
9902 {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
9903 {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
bf79451e 9904
43f66a6c
JK
9905 /* required last entry */
9906 {0,}
9907};
9908
9909MODULE_DEVICE_TABLE(pci, card_ids);
9910
9911static struct attribute *ipw_sysfs_entries[] = {
9912 &dev_attr_rf_kill.attr,
9913 &dev_attr_direct_dword.attr,
9914 &dev_attr_indirect_byte.attr,
9915 &dev_attr_indirect_dword.attr,
9916 &dev_attr_mem_gpio_reg.attr,
9917 &dev_attr_command_event_reg.attr,
9918 &dev_attr_nic_type.attr,
9919 &dev_attr_status.attr,
9920 &dev_attr_cfg.attr,
9921 &dev_attr_dump_errors.attr,
9922 &dev_attr_dump_events.attr,
9923 &dev_attr_eeprom_delay.attr,
9924 &dev_attr_ucode_version.attr,
9925 &dev_attr_rtc.attr,
a613bffd
JK
9926 &dev_attr_scan_age.attr,
9927 &dev_attr_led.attr,
b095c381
JK
9928 &dev_attr_speed_scan.attr,
9929 &dev_attr_net_stats.attr,
43f66a6c
JK
9930 NULL
9931};
9932
9933static struct attribute_group ipw_attribute_group = {
9934 .name = NULL, /* put in device directory */
0edd5b44 9935 .attrs = ipw_sysfs_entries,
43f66a6c
JK
9936};
9937
0edd5b44 9938static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
43f66a6c
JK
9939{
9940 int err = 0;
9941 struct net_device *net_dev;
9942 void __iomem *base;
9943 u32 length, val;
9944 struct ipw_priv *priv;
43f66a6c
JK
9945
9946 net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
9947 if (net_dev == NULL) {
9948 err = -ENOMEM;
9949 goto out;
9950 }
9951
9952 priv = ieee80211_priv(net_dev);
9953 priv->ieee = netdev_priv(net_dev);
a613bffd 9954
43f66a6c
JK
9955 priv->net_dev = net_dev;
9956 priv->pci_dev = pdev;
9957#ifdef CONFIG_IPW_DEBUG
9958 ipw_debug_level = debug;
9959#endif
9960 spin_lock_init(&priv->lock);
9961
c848d0af 9962 init_MUTEX(&priv->sem);
43f66a6c
JK
9963 if (pci_enable_device(pdev)) {
9964 err = -ENODEV;
9965 goto out_free_ieee80211;
9966 }
9967
9968 pci_set_master(pdev);
9969
0e08b44e 9970 err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
bf79451e 9971 if (!err)
0e08b44e 9972 err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
43f66a6c
JK
9973 if (err) {
9974 printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n");
9975 goto out_pci_disable_device;
9976 }
9977
9978 pci_set_drvdata(pdev, priv);
9979
9980 err = pci_request_regions(pdev, DRV_NAME);
bf79451e 9981 if (err)
43f66a6c
JK
9982 goto out_pci_disable_device;
9983
bf79451e 9984 /* We disable the RETRY_TIMEOUT register (0x41) to keep
43f66a6c 9985 * PCI Tx retries from interfering with C3 CPU state */
bf79451e
JG
9986 pci_read_config_dword(pdev, 0x40, &val);
9987 if ((val & 0x0000ff00) != 0)
43f66a6c 9988 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
bf79451e 9989
43f66a6c
JK
9990 length = pci_resource_len(pdev, 0);
9991 priv->hw_len = length;
bf79451e 9992
43f66a6c
JK
9993 base = ioremap_nocache(pci_resource_start(pdev, 0), length);
9994 if (!base) {
9995 err = -ENODEV;
9996 goto out_pci_release_regions;
9997 }
9998
9999 priv->hw_base = base;
10000 IPW_DEBUG_INFO("pci_resource_len = 0x%08x\n", length);
10001 IPW_DEBUG_INFO("pci_resource_base = %p\n", base);
10002
10003 err = ipw_setup_deferred_work(priv);
10004 if (err) {
10005 IPW_ERROR("Unable to setup deferred work\n");
10006 goto out_iounmap;
10007 }
10008
b095c381 10009 ipw_sw_reset(priv, 1);
43f66a6c 10010
0edd5b44 10011 err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv);
43f66a6c
JK
10012 if (err) {
10013 IPW_ERROR("Error allocating IRQ %d\n", pdev->irq);
10014 goto out_destroy_workqueue;
10015 }
10016
10017 SET_MODULE_OWNER(net_dev);
10018 SET_NETDEV_DEV(net_dev, &pdev->dev);
10019
a613bffd
JK
10020 ipw_wx_data.spy_data = &priv->ieee->spy_data;
10021 ipw_wx_data.ieee80211 = priv->ieee;
10022
c848d0af
JK
10023 down(&priv->sem);
10024
43f66a6c
JK
10025 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
10026 priv->ieee->set_security = shim__set_security;
10027
b095c381
JK
10028#ifdef CONFIG_IPW_QOS
10029 priv->ieee->handle_management_frame = ipw_handle_management_frame;
10030#endif /* CONFIG_IPW_QOS */
10031
c848d0af
JK
10032 priv->ieee->perfect_rssi = -20;
10033 priv->ieee->worst_rssi = -85;
10034
43f66a6c
JK
10035 net_dev->open = ipw_net_open;
10036 net_dev->stop = ipw_net_stop;
10037 net_dev->init = ipw_net_init;
ea2b26e0 10038 net_dev->do_ioctl = ipw_ioctl;
43f66a6c
JK
10039 net_dev->get_stats = ipw_net_get_stats;
10040 net_dev->set_multicast_list = ipw_net_set_multicast_list;
10041 net_dev->set_mac_address = ipw_net_set_mac_address;
10042 net_dev->get_wireless_stats = ipw_get_wireless_stats;
a613bffd 10043 net_dev->wireless_data = &ipw_wx_data;
43f66a6c
JK
10044 net_dev->wireless_handlers = &ipw_wx_handler_def;
10045 net_dev->ethtool_ops = &ipw_ethtool_ops;
10046 net_dev->irq = pdev->irq;
0edd5b44 10047 net_dev->base_addr = (unsigned long)priv->hw_base;
43f66a6c
JK
10048 net_dev->mem_start = pci_resource_start(pdev, 0);
10049 net_dev->mem_end = net_dev->mem_start + pci_resource_len(pdev, 0) - 1;
10050
10051 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
10052 if (err) {
10053 IPW_ERROR("failed to create sysfs device attributes\n");
c848d0af 10054 up(&priv->sem);
43f66a6c
JK
10055 goto out_release_irq;
10056 }
10057
c848d0af 10058 up(&priv->sem);
43f66a6c
JK
10059 err = register_netdev(net_dev);
10060 if (err) {
10061 IPW_ERROR("failed to register network device\n");
a613bffd 10062 goto out_remove_sysfs;
43f66a6c 10063 }
43f66a6c
JK
10064 return 0;
10065
a613bffd 10066 out_remove_sysfs:
43f66a6c 10067 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
0edd5b44 10068 out_release_irq:
43f66a6c 10069 free_irq(pdev->irq, priv);
0edd5b44 10070 out_destroy_workqueue:
43f66a6c
JK
10071 destroy_workqueue(priv->workqueue);
10072 priv->workqueue = NULL;
0edd5b44 10073 out_iounmap:
43f66a6c 10074 iounmap(priv->hw_base);
0edd5b44 10075 out_pci_release_regions:
43f66a6c 10076 pci_release_regions(pdev);
0edd5b44 10077 out_pci_disable_device:
43f66a6c
JK
10078 pci_disable_device(pdev);
10079 pci_set_drvdata(pdev, NULL);
0edd5b44 10080 out_free_ieee80211:
43f66a6c 10081 free_ieee80211(priv->net_dev);
0edd5b44 10082 out:
43f66a6c
JK
10083 return err;
10084}
10085
10086static void ipw_pci_remove(struct pci_dev *pdev)
10087{
10088 struct ipw_priv *priv = pci_get_drvdata(pdev);
b095c381 10089
43f66a6c
JK
10090 if (!priv)
10091 return;
10092
b095c381 10093 down(&priv->sem);
43f66a6c 10094 ipw_down(priv);
b095c381
JK
10095 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
10096 up(&priv->sem);
43f66a6c
JK
10097
10098 unregister_netdev(priv->net_dev);
10099
10100 if (priv->rxq) {
10101 ipw_rx_queue_free(priv, priv->rxq);
10102 priv->rxq = NULL;
10103 }
10104 ipw_tx_queue_free(priv);
10105
10106 /* ipw_down will ensure that there is no more pending work
10107 * in the workqueue's, so we can safely remove them now. */
a613bffd
JK
10108 cancel_delayed_work(&priv->adhoc_check);
10109 cancel_delayed_work(&priv->gather_stats);
10110 cancel_delayed_work(&priv->request_scan);
10111 cancel_delayed_work(&priv->rf_kill);
10112 cancel_delayed_work(&priv->scan_check);
10113 destroy_workqueue(priv->workqueue);
10114 priv->workqueue = NULL;
43f66a6c
JK
10115
10116 free_irq(pdev->irq, priv);
10117 iounmap(priv->hw_base);
10118 pci_release_regions(pdev);
10119 pci_disable_device(pdev);
10120 pci_set_drvdata(pdev, NULL);
10121 free_ieee80211(priv->net_dev);
10122
10123#ifdef CONFIG_PM
10124 if (fw_loaded) {
10125 release_firmware(bootfw);
10126 release_firmware(ucode);
10127 release_firmware(firmware);
10128 fw_loaded = 0;
10129 }
10130#endif
10131}
10132
43f66a6c 10133#ifdef CONFIG_PM
583a4e88 10134static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
43f66a6c
JK
10135{
10136 struct ipw_priv *priv = pci_get_drvdata(pdev);
10137 struct net_device *dev = priv->net_dev;
10138
10139 printk(KERN_INFO "%s: Going into suspend...\n", dev->name);
10140
0edd5b44 10141 /* Take down the device; powers it off, etc. */
43f66a6c
JK
10142 ipw_down(priv);
10143
10144 /* Remove the PRESENT state of the device */
10145 netif_device_detach(dev);
10146
43f66a6c 10147 pci_save_state(pdev);
43f66a6c 10148 pci_disable_device(pdev);
583a4e88 10149 pci_set_power_state(pdev, pci_choose_state(pdev, state));
bf79451e 10150
43f66a6c
JK
10151 return 0;
10152}
10153
10154static int ipw_pci_resume(struct pci_dev *pdev)
10155{
10156 struct ipw_priv *priv = pci_get_drvdata(pdev);
10157 struct net_device *dev = priv->net_dev;
10158 u32 val;
bf79451e 10159
43f66a6c
JK
10160 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
10161
ea2b26e0 10162 pci_set_power_state(pdev, PCI_D0);
43f66a6c 10163 pci_enable_device(pdev);
43f66a6c 10164 pci_restore_state(pdev);
ea2b26e0 10165
43f66a6c
JK
10166 /*
10167 * Suspend/Resume resets the PCI configuration space, so we have to
10168 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
10169 * from interfering with C3 CPU state. pci_restore_state won't help
10170 * here since it only restores the first 64 bytes pci config header.
10171 */
bf79451e
JG
10172 pci_read_config_dword(pdev, 0x40, &val);
10173 if ((val & 0x0000ff00) != 0)
43f66a6c
JK
10174 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
10175
10176 /* Set the device back into the PRESENT state; this will also wake
10177 * the queue of needed */
10178 netif_device_attach(dev);
10179
10180 /* Bring the device back up */
10181 queue_work(priv->workqueue, &priv->up);
bf79451e 10182
43f66a6c
JK
10183 return 0;
10184}
10185#endif
10186
10187/* driver initialization stuff */
10188static struct pci_driver ipw_driver = {
10189 .name = DRV_NAME,
10190 .id_table = card_ids,
10191 .probe = ipw_pci_probe,
10192 .remove = __devexit_p(ipw_pci_remove),
10193#ifdef CONFIG_PM
10194 .suspend = ipw_pci_suspend,
10195 .resume = ipw_pci_resume,
10196#endif
10197};
10198
10199static int __init ipw_init(void)
10200{
10201 int ret;
10202
10203 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
10204 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
10205
10206 ret = pci_module_init(&ipw_driver);
10207 if (ret) {
10208 IPW_ERROR("Unable to initialize PCI module\n");
10209 return ret;
10210 }
10211
0edd5b44 10212 ret = driver_create_file(&ipw_driver.driver, &driver_attr_debug_level);
43f66a6c
JK
10213 if (ret) {
10214 IPW_ERROR("Unable to create driver sysfs file\n");
10215 pci_unregister_driver(&ipw_driver);
10216 return ret;
10217 }
10218
10219 return ret;
10220}
10221
10222static void __exit ipw_exit(void)
10223{
10224 driver_remove_file(&ipw_driver.driver, &driver_attr_debug_level);
10225 pci_unregister_driver(&ipw_driver);
10226}
10227
10228module_param(disable, int, 0444);
10229MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
10230
10231module_param(associate, int, 0444);
10232MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
10233
10234module_param(auto_create, int, 0444);
10235MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
10236
a613bffd 10237module_param(led, int, 0444);
c848d0af 10238MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n");
a613bffd 10239
43f66a6c
JK
10240module_param(debug, int, 0444);
10241MODULE_PARM_DESC(debug, "debug output mask");
10242
10243module_param(channel, int, 0444);
bf79451e 10244MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
43f66a6c 10245
b095c381
JK
10246#ifdef CONFIG_IPW_QOS
10247module_param(qos_enable, int, 0444);
10248MODULE_PARM_DESC(qos_enable, "enable all QoS functionalitis");
10249
10250module_param(qos_burst_enable, int, 0444);
10251MODULE_PARM_DESC(qos_burst_enable, "enable QoS burst mode");
10252
10253module_param(qos_no_ack_mask, int, 0444);
10254MODULE_PARM_DESC(qos_no_ack_mask, "mask Tx_Queue to no ack");
10255
10256module_param(burst_duration_CCK, int, 0444);
10257MODULE_PARM_DESC(burst_duration_CCK, "set CCK burst value");
10258
10259module_param(burst_duration_OFDM, int, 0444);
10260MODULE_PARM_DESC(burst_duration_OFDM, "set OFDM burst value");
10261#endif /* CONFIG_IPW_QOS */
10262
10263#ifdef CONFIG_IPW2200_MONITOR
43f66a6c
JK
10264module_param(mode, int, 0444);
10265MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
10266#else
10267module_param(mode, int, 0444);
10268MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
10269#endif
10270
b095c381
JK
10271module_param(hwcrypto, int, 0444);
10272MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default on)");
10273
43f66a6c
JK
10274module_exit(ipw_exit);
10275module_init(ipw_init);