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