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