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