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