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