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