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 = snprintf(buf, count, "%08X", ofs);
227
228 for (l = 0, i = 0; i < 2; i++) {
229 out += snprintf(buf + out, count - out, " ");
230 for (j = 0; j < 8 && l < len; j++, l++)
231 out += snprintf(buf + out, count - out, "%02X ",
232 data[(i * 8 + j)]);
233 for (; j < 8; j++)
234 out += snprintf(buf + out, count - out, " ");
235 }
236
237 out += snprintf(buf + out, count - out, " ");
238 for (l = 0, i = 0; i < 2; i++) {
239 out += snprintf(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 += snprintf(buf + out, count - out, "%c", c);
246 }
247
248 for (; j < 8; j++)
249 out += snprintf(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 += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len);
1283 for (i = 0; i < log_len; i++)
1284 len += snprintf(buf + len, PAGE_SIZE - len,
1285 "\n%08X%08X%08X",
1286 log[i].time, log[i].event, log[i].data);
1287 len += snprintf(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 += snprintf(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 += snprintf(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 += snprintf(buf + len, PAGE_SIZE - len,
1318 "\n%08X", priv->error->log_len);
1319 for (i = 0; i < priv->error->log_len; i++)
1320 len += snprintf(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 += snprintf(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 snprintf(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 += snprintf(buf + len, PAGE_SIZE - len, "\n");
1362 }
1363 len += snprintf(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 ipw_priv *priv)
1949{
1950 u32 inta, inta_mask, handled = 0;
1951 unsigned long flags;
1952 int rc = 0;
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 rc = 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 rc = 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 rc = 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 rc = 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 rc = 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[0];
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 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
3445 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
3446 dev_kfree_skb(rxq->pool[i].skb);
3447 rxq->pool[i].skb = NULL;
3448 }
3449 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
3450 }
3451
3452
3453
3454 rxq->read = rxq->write = 0;
3455 rxq->free_count = 0;
3456 spin_unlock_irqrestore(&rxq->lock, flags);
3457}
3458
3459#ifdef CONFIG_PM
3460static int fw_loaded = 0;
3461static const struct firmware *raw = NULL;
3462
3463static void free_firmware(void)
3464{
3465 if (fw_loaded) {
3466 release_firmware(raw);
3467 raw = NULL;
3468 fw_loaded = 0;
3469 }
3470}
3471#else
3472#define free_firmware() do {} while (0)
3473#endif
3474
3475static int ipw_load(struct ipw_priv *priv)
3476{
3477#ifndef CONFIG_PM
3478 const struct firmware *raw = NULL;
3479#endif
3480 struct ipw_fw *fw;
3481 u8 *boot_img, *ucode_img, *fw_img;
3482 u8 *name = NULL;
3483 int rc = 0, retries = 3;
3484
3485 switch (priv->ieee->iw_mode) {
3486 case IW_MODE_ADHOC:
3487 name = "ipw2200-ibss.fw";
3488 break;
3489#ifdef CONFIG_IPW2200_MONITOR
3490 case IW_MODE_MONITOR:
3491 name = "ipw2200-sniffer.fw";
3492 break;
3493#endif
3494 case IW_MODE_INFRA:
3495 name = "ipw2200-bss.fw";
3496 break;
3497 }
3498
3499 if (!name) {
3500 rc = -EINVAL;
3501 goto error;
3502 }
3503
3504#ifdef CONFIG_PM
3505 if (!fw_loaded) {
3506#endif
3507 rc = ipw_get_fw(priv, &raw, name);
3508 if (rc < 0)
3509 goto error;
3510#ifdef CONFIG_PM
3511 }
3512#endif
3513
3514 fw = (void *)raw->data;
3515 boot_img = &fw->data[0];
3516 ucode_img = &fw->data[le32_to_cpu(fw->boot_size)];
3517 fw_img = &fw->data[le32_to_cpu(fw->boot_size) +
3518 le32_to_cpu(fw->ucode_size)];
3519
3520 if (!priv->rxq)
3521 priv->rxq = ipw_rx_queue_alloc(priv);
3522 else
3523 ipw_rx_queue_reset(priv, priv->rxq);
3524 if (!priv->rxq) {
3525 IPW_ERROR("Unable to initialize Rx queue\n");
3526 rc = -ENOMEM;
3527 goto error;
3528 }
3529
3530 retry:
3531
3532 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
3533 priv->status &= ~STATUS_INT_ENABLED;
3534
3535
3536 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
3537
3538 ipw_stop_nic(priv);
3539
3540 rc = ipw_reset_nic(priv);
3541 if (rc < 0) {
3542 IPW_ERROR("Unable to reset NIC\n");
3543 goto error;
3544 }
3545
3546 ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
3547 IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
3548
3549
3550 rc = ipw_load_firmware(priv, boot_img, le32_to_cpu(fw->boot_size));
3551 if (rc < 0) {
3552 IPW_ERROR("Unable to load boot firmware: %d\n", rc);
3553 goto error;
3554 }
3555
3556
3557 ipw_start_nic(priv);
3558
3559
3560 rc = ipw_poll_bit(priv, IPW_INTA_RW,
3561 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
3562 if (rc < 0) {
3563 IPW_ERROR("device failed to boot initial fw image\n");
3564 goto error;
3565 }
3566 IPW_DEBUG_INFO("initial device response after %dms\n", rc);
3567
3568
3569 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
3570
3571
3572 rc = ipw_load_ucode(priv, ucode_img, le32_to_cpu(fw->ucode_size));
3573 if (rc < 0) {
3574 IPW_ERROR("Unable to load ucode: %d\n", rc);
3575 goto error;
3576 }
3577
3578
3579 ipw_stop_nic(priv);
3580
3581
3582 rc = ipw_load_firmware(priv, fw_img, le32_to_cpu(fw->fw_size));
3583 if (rc < 0) {
3584 IPW_ERROR("Unable to load firmware: %d\n", rc);
3585 goto error;
3586 }
3587#ifdef CONFIG_PM
3588 fw_loaded = 1;
3589#endif
3590
3591 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
3592
3593 rc = ipw_queue_reset(priv);
3594 if (rc < 0) {
3595 IPW_ERROR("Unable to initialize queues\n");
3596 goto error;
3597 }
3598
3599
3600 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
3601
3602 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
3603
3604
3605 ipw_start_nic(priv);
3606
3607 if (ipw_read32(priv, IPW_INTA_RW) & IPW_INTA_BIT_PARITY_ERROR) {
3608 if (retries > 0) {
3609 IPW_WARNING("Parity error. Retrying init.\n");
3610 retries--;
3611 goto retry;
3612 }
3613
3614 IPW_ERROR("TODO: Handle parity error -- schedule restart?\n");
3615 rc = -EIO;
3616 goto error;
3617 }
3618
3619
3620 rc = ipw_poll_bit(priv, IPW_INTA_RW,
3621 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
3622 if (rc < 0) {
3623 IPW_ERROR("device failed to start within 500ms\n");
3624 goto error;
3625 }
3626 IPW_DEBUG_INFO("device response after %dms\n", rc);
3627
3628
3629 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
3630
3631
3632 priv->eeprom_delay = 1;
3633 ipw_read_eeprom(priv);
3634
3635 ipw_eeprom_init_sram(priv);
3636
3637
3638 ipw_enable_interrupts(priv);
3639
3640
3641 ipw_rx_queue_replenish(priv);
3642
3643 ipw_write32(priv, IPW_RX_READ_INDEX, priv->rxq->read);
3644
3645
3646 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
3647
3648#ifndef CONFIG_PM
3649 release_firmware(raw);
3650#endif
3651 return 0;
3652
3653 error:
3654 if (priv->rxq) {
3655 ipw_rx_queue_free(priv, priv->rxq);
3656 priv->rxq = NULL;
3657 }
3658 ipw_tx_queue_free(priv);
3659 release_firmware(raw);
3660#ifdef CONFIG_PM
3661 fw_loaded = 0;
3662 raw = NULL;
3663#endif
3664
3665 return rc;
3666}
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
3698static int ipw_rx_queue_space(const struct ipw_rx_queue *q)
3699{
3700 int s = q->read - q->write;
3701 if (s <= 0)
3702 s += RX_QUEUE_SIZE;
3703
3704 s -= 2;
3705 if (s < 0)
3706 s = 0;
3707 return s;
3708}
3709
3710static inline int ipw_tx_queue_space(const struct clx2_queue *q)
3711{
3712 int s = q->last_used - q->first_empty;
3713 if (s <= 0)
3714 s += q->n_bd;
3715 s -= 2;
3716 if (s < 0)
3717 s = 0;
3718 return s;
3719}
3720
3721static inline int ipw_queue_inc_wrap(int index, int n_bd)
3722{
3723 return (++index == n_bd) ? 0 : index;
3724}
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740static void ipw_queue_init(struct ipw_priv *priv, struct clx2_queue *q,
3741 int count, u32 read, u32 write, u32 base, u32 size)
3742{
3743 q->n_bd = count;
3744
3745 q->low_mark = q->n_bd / 4;
3746 if (q->low_mark < 4)
3747 q->low_mark = 4;
3748
3749 q->high_mark = q->n_bd / 8;
3750 if (q->high_mark < 2)
3751 q->high_mark = 2;
3752
3753 q->first_empty = q->last_used = 0;
3754 q->reg_r = read;
3755 q->reg_w = write;
3756
3757 ipw_write32(priv, base, q->dma_addr);
3758 ipw_write32(priv, size, count);
3759 ipw_write32(priv, read, 0);
3760 ipw_write32(priv, write, 0);
3761
3762 _ipw_read32(priv, 0x90);
3763}
3764
3765static int ipw_queue_tx_init(struct ipw_priv *priv,
3766 struct clx2_tx_queue *q,
3767 int count, u32 read, u32 write, u32 base, u32 size)
3768{
3769 struct pci_dev *dev = priv->pci_dev;
3770
3771 q->txb = kmalloc_array(count, sizeof(q->txb[0]), GFP_KERNEL);
3772 if (!q->txb) {
3773 IPW_ERROR("vmalloc for auxiliary BD structures failed\n");
3774 return -ENOMEM;
3775 }
3776
3777 q->bd =
3778 pci_alloc_consistent(dev, sizeof(q->bd[0]) * count, &q->q.dma_addr);
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 pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]),
3821 le16_to_cpu(bd->u.data.chunk_len[i]),
3822 PCI_DMA_TODEVICE);
3823 if (txq->txb[txq->q.last_used]) {
3824 libipw_txb_free(txq->txb[txq->q.last_used]);
3825 txq->txb[txq->q.last_used] = NULL;
3826 }
3827 }
3828}
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839static void ipw_queue_tx_free(struct ipw_priv *priv, struct clx2_tx_queue *txq)
3840{
3841 struct clx2_queue *q = &txq->q;
3842 struct pci_dev *dev = priv->pci_dev;
3843
3844 if (q->n_bd == 0)
3845 return;
3846
3847
3848 for (; q->first_empty != q->last_used;
3849 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {
3850 ipw_queue_tx_free_tfd(priv, txq);
3851 }
3852
3853
3854 pci_free_consistent(dev, sizeof(txq->bd[0]) * q->n_bd, txq->bd,
3855 q->dma_addr);
3856 kfree(txq->txb);
3857
3858
3859 memset(txq, 0, sizeof(*txq));
3860}
3861
3862
3863
3864
3865
3866
3867static void ipw_tx_queue_free(struct ipw_priv *priv)
3868{
3869
3870 ipw_queue_tx_free(priv, &priv->txq_cmd);
3871
3872
3873 ipw_queue_tx_free(priv, &priv->txq[0]);
3874 ipw_queue_tx_free(priv, &priv->txq[1]);
3875 ipw_queue_tx_free(priv, &priv->txq[2]);
3876 ipw_queue_tx_free(priv, &priv->txq[3]);
3877}
3878
3879static void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)
3880{
3881
3882 bssid[0] = priv->mac_addr[0];
3883 bssid[1] = priv->mac_addr[1];
3884 bssid[2] = priv->mac_addr[2];
3885
3886
3887 get_random_bytes(&bssid[3], ETH_ALEN - 3);
3888
3889 bssid[0] &= 0xfe;
3890 bssid[0] |= 0x02;
3891}
3892
3893static u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid)
3894{
3895 struct ipw_station_entry entry;
3896 int i;
3897
3898 for (i = 0; i < priv->num_stations; i++) {
3899 if (ether_addr_equal(priv->stations[i], bssid)) {
3900
3901 priv->missed_adhoc_beacons = 0;
3902 if (!(priv->config & CFG_STATIC_CHANNEL))
3903
3904 priv->config &= ~CFG_ADHOC_PERSIST;
3905
3906 return i;
3907 }
3908 }
3909
3910 if (i == MAX_STATIONS)
3911 return IPW_INVALID_STATION;
3912
3913 IPW_DEBUG_SCAN("Adding AdHoc station: %pM\n", bssid);
3914
3915 entry.reserved = 0;
3916 entry.support_mode = 0;
3917 memcpy(entry.mac_addr, bssid, ETH_ALEN);
3918 memcpy(priv->stations[i], bssid, ETH_ALEN);
3919 ipw_write_direct(priv, IPW_STATION_TABLE_LOWER + i * sizeof(entry),
3920 &entry, sizeof(entry));
3921 priv->num_stations++;
3922
3923 return i;
3924}
3925
3926static u8 ipw_find_station(struct ipw_priv *priv, u8 * bssid)
3927{
3928 int i;
3929
3930 for (i = 0; i < priv->num_stations; i++)
3931 if (ether_addr_equal(priv->stations[i], bssid))
3932 return i;
3933
3934 return IPW_INVALID_STATION;
3935}
3936
3937static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
3938{
3939 int err;
3940
3941 if (priv->status & STATUS_ASSOCIATING) {
3942 IPW_DEBUG_ASSOC("Disassociating while associating.\n");
3943 schedule_work(&priv->disassociate);
3944 return;
3945 }
3946
3947 if (!(priv->status & STATUS_ASSOCIATED)) {
3948 IPW_DEBUG_ASSOC("Disassociating while not associated.\n");
3949 return;
3950 }
3951
3952 IPW_DEBUG_ASSOC("Disassociation attempt from %pM "
3953 "on channel %d.\n",
3954 priv->assoc_request.bssid,
3955 priv->assoc_request.channel);
3956
3957 priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
3958 priv->status |= STATUS_DISASSOCIATING;
3959
3960 if (quiet)
3961 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
3962 else
3963 priv->assoc_request.assoc_type = HC_DISASSOCIATE;
3964
3965 err = ipw_send_associate(priv, &priv->assoc_request);
3966 if (err) {
3967 IPW_DEBUG_HC("Attempt to send [dis]associate command "
3968 "failed.\n");
3969 return;
3970 }
3971
3972}
3973
3974static int ipw_disassociate(void *data)
3975{
3976 struct ipw_priv *priv = data;
3977 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
3978 return 0;
3979 ipw_send_disassociate(data, 0);
3980 netif_carrier_off(priv->net_dev);
3981 return 1;
3982}
3983
3984static void ipw_bg_disassociate(struct work_struct *work)
3985{
3986 struct ipw_priv *priv =
3987 container_of(work, struct ipw_priv, disassociate);
3988 mutex_lock(&priv->mutex);
3989 ipw_disassociate(priv);
3990 mutex_unlock(&priv->mutex);
3991}
3992
3993static void ipw_system_config(struct work_struct *work)
3994{
3995 struct ipw_priv *priv =
3996 container_of(work, struct ipw_priv, system_config);
3997
3998#ifdef CONFIG_IPW2200_PROMISCUOUS
3999 if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {
4000 priv->sys_config.accept_all_data_frames = 1;
4001 priv->sys_config.accept_non_directed_frames = 1;
4002 priv->sys_config.accept_all_mgmt_bcpr = 1;
4003 priv->sys_config.accept_all_mgmt_frames = 1;
4004 }
4005#endif
4006
4007 ipw_send_system_config(priv);
4008}
4009
4010struct ipw_status_code {
4011 u16 status;
4012 const char *reason;
4013};
4014
4015static const struct ipw_status_code ipw_status_codes[] = {
4016 {0x00, "Successful"},
4017 {0x01, "Unspecified failure"},
4018 {0x0A, "Cannot support all requested capabilities in the "
4019 "Capability information field"},
4020 {0x0B, "Reassociation denied due to inability to confirm that "
4021 "association exists"},
4022 {0x0C, "Association denied due to reason outside the scope of this "
4023 "standard"},
4024 {0x0D,
4025 "Responding station does not support the specified authentication "
4026 "algorithm"},
4027 {0x0E,
4028 "Received an Authentication frame with authentication sequence "
4029 "transaction sequence number out of expected sequence"},
4030 {0x0F, "Authentication rejected because of challenge failure"},
4031 {0x10, "Authentication rejected due to timeout waiting for next "
4032 "frame in sequence"},
4033 {0x11, "Association denied because AP is unable to handle additional "
4034 "associated stations"},
4035 {0x12,
4036 "Association denied due to requesting station not supporting all "
4037 "of the datarates in the BSSBasicServiceSet Parameter"},
4038 {0x13,
4039 "Association denied due to requesting station not supporting "
4040 "short preamble operation"},
4041 {0x14,
4042 "Association denied due to requesting station not supporting "
4043 "PBCC encoding"},
4044 {0x15,
4045 "Association denied due to requesting station not supporting "
4046 "channel agility"},
4047 {0x19,
4048 "Association denied due to requesting station not supporting "
4049 "short slot operation"},
4050 {0x1A,
4051 "Association denied due to requesting station not supporting "
4052 "DSSS-OFDM operation"},
4053 {0x28, "Invalid Information Element"},
4054 {0x29, "Group Cipher is not valid"},
4055 {0x2A, "Pairwise Cipher is not valid"},
4056 {0x2B, "AKMP is not valid"},
4057 {0x2C, "Unsupported RSN IE version"},
4058 {0x2D, "Invalid RSN IE Capabilities"},
4059 {0x2E, "Cipher suite is rejected per security policy"},
4060};
4061
4062static const char *ipw_get_status_code(u16 status)
4063{
4064 int i;
4065 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++)
4066 if (ipw_status_codes[i].status == (status & 0xff))
4067 return ipw_status_codes[i].reason;
4068 return "Unknown status value.";
4069}
4070
4071static inline void average_init(struct average *avg)
4072{
4073 memset(avg, 0, sizeof(*avg));
4074}
4075
4076#define DEPTH_RSSI 8
4077#define DEPTH_NOISE 16
4078static s16 exponential_average(s16 prev_avg, s16 val, u8 depth)
4079{
4080 return ((depth-1)*prev_avg + val)/depth;
4081}
4082
4083static void average_add(struct average *avg, s16 val)
4084{
4085 avg->sum -= avg->entries[avg->pos];
4086 avg->sum += val;
4087 avg->entries[avg->pos++] = val;
4088 if (unlikely(avg->pos == AVG_ENTRIES)) {
4089 avg->init = 1;
4090 avg->pos = 0;
4091 }
4092}
4093
4094static s16 average_value(struct average *avg)
4095{
4096 if (!unlikely(avg->init)) {
4097 if (avg->pos)
4098 return avg->sum / avg->pos;
4099 return 0;
4100 }
4101
4102 return avg->sum / AVG_ENTRIES;
4103}
4104
4105static void ipw_reset_stats(struct ipw_priv *priv)
4106{
4107 u32 len = sizeof(u32);
4108
4109 priv->quality = 0;
4110
4111 average_init(&priv->average_missed_beacons);
4112 priv->exp_avg_rssi = -60;
4113 priv->exp_avg_noise = -85 + 0x100;
4114
4115 priv->last_rate = 0;
4116 priv->last_missed_beacons = 0;
4117 priv->last_rx_packets = 0;
4118 priv->last_tx_packets = 0;
4119 priv->last_tx_failures = 0;
4120
4121
4122
4123 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC,
4124 &priv->last_rx_err, &len);
4125 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE,
4126 &priv->last_tx_failures, &len);
4127
4128
4129 priv->missed_adhoc_beacons = 0;
4130 priv->missed_beacons = 0;
4131 priv->tx_packets = 0;
4132 priv->rx_packets = 0;
4133
4134}
4135
4136static u32 ipw_get_max_rate(struct ipw_priv *priv)
4137{
4138 u32 i = 0x80000000;
4139 u32 mask = priv->rates_mask;
4140
4141
4142 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
4143 mask &= LIBIPW_CCK_RATES_MASK;
4144
4145
4146
4147
4148 while (i && !(mask & i))
4149 i >>= 1;
4150 switch (i) {
4151 case LIBIPW_CCK_RATE_1MB_MASK:
4152 return 1000000;
4153 case LIBIPW_CCK_RATE_2MB_MASK:
4154 return 2000000;
4155 case LIBIPW_CCK_RATE_5MB_MASK:
4156 return 5500000;
4157 case LIBIPW_OFDM_RATE_6MB_MASK:
4158 return 6000000;
4159 case LIBIPW_OFDM_RATE_9MB_MASK:
4160 return 9000000;
4161 case LIBIPW_CCK_RATE_11MB_MASK:
4162 return 11000000;
4163 case LIBIPW_OFDM_RATE_12MB_MASK:
4164 return 12000000;
4165 case LIBIPW_OFDM_RATE_18MB_MASK:
4166 return 18000000;
4167 case LIBIPW_OFDM_RATE_24MB_MASK:
4168 return 24000000;
4169 case LIBIPW_OFDM_RATE_36MB_MASK:
4170 return 36000000;
4171 case LIBIPW_OFDM_RATE_48MB_MASK:
4172 return 48000000;
4173 case LIBIPW_OFDM_RATE_54MB_MASK:
4174 return 54000000;
4175 }
4176
4177 if (priv->ieee->mode == IEEE_B)
4178 return 11000000;
4179 else
4180 return 54000000;
4181}
4182
4183static u32 ipw_get_current_rate(struct ipw_priv *priv)
4184{
4185 u32 rate, len = sizeof(rate);
4186 int err;
4187
4188 if (!(priv->status & STATUS_ASSOCIATED))
4189 return 0;
4190
4191 if (priv->tx_packets > IPW_REAL_RATE_RX_PACKET_THRESHOLD) {
4192 err = ipw_get_ordinal(priv, IPW_ORD_STAT_TX_CURR_RATE, &rate,
4193 &len);
4194 if (err) {
4195 IPW_DEBUG_INFO("failed querying ordinals.\n");
4196 return 0;
4197 }
4198 } else
4199 return ipw_get_max_rate(priv);
4200
4201 switch (rate) {
4202 case IPW_TX_RATE_1MB:
4203 return 1000000;
4204 case IPW_TX_RATE_2MB:
4205 return 2000000;
4206 case IPW_TX_RATE_5MB:
4207 return 5500000;
4208 case IPW_TX_RATE_6MB:
4209 return 6000000;
4210 case IPW_TX_RATE_9MB:
4211 return 9000000;
4212 case IPW_TX_RATE_11MB:
4213 return 11000000;
4214 case IPW_TX_RATE_12MB:
4215 return 12000000;
4216 case IPW_TX_RATE_18MB:
4217 return 18000000;
4218 case IPW_TX_RATE_24MB:
4219 return 24000000;
4220 case IPW_TX_RATE_36MB:
4221 return 36000000;
4222 case IPW_TX_RATE_48MB:
4223 return 48000000;
4224 case IPW_TX_RATE_54MB:
4225 return 54000000;
4226 }
4227
4228 return 0;
4229}
4230
4231#define IPW_STATS_INTERVAL (2 * HZ)
4232static void ipw_gather_stats(struct ipw_priv *priv)
4233{
4234 u32 rx_err, rx_err_delta, rx_packets_delta;
4235 u32 tx_failures, tx_failures_delta, tx_packets_delta;
4236 u32 missed_beacons_percent, missed_beacons_delta;
4237 u32 quality = 0;
4238 u32 len = sizeof(u32);
4239 s16 rssi;
4240 u32 beacon_quality, signal_quality, tx_quality, rx_quality,
4241 rate_quality;
4242 u32 max_rate;
4243
4244 if (!(priv->status & STATUS_ASSOCIATED)) {
4245 priv->quality = 0;
4246 return;
4247 }
4248
4249
4250 ipw_get_ordinal(priv, IPW_ORD_STAT_MISSED_BEACONS,
4251 &priv->missed_beacons, &len);
4252 missed_beacons_delta = priv->missed_beacons - priv->last_missed_beacons;
4253 priv->last_missed_beacons = priv->missed_beacons;
4254 if (priv->assoc_request.beacon_interval) {
4255 missed_beacons_percent = missed_beacons_delta *
4256 (HZ * le16_to_cpu(priv->assoc_request.beacon_interval)) /
4257 (IPW_STATS_INTERVAL * 10);
4258 } else {
4259 missed_beacons_percent = 0;
4260 }
4261 average_add(&priv->average_missed_beacons, missed_beacons_percent);
4262
4263 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC, &rx_err, &len);
4264 rx_err_delta = rx_err - priv->last_rx_err;
4265 priv->last_rx_err = rx_err;
4266
4267 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE, &tx_failures, &len);
4268 tx_failures_delta = tx_failures - priv->last_tx_failures;
4269 priv->last_tx_failures = tx_failures;
4270
4271 rx_packets_delta = priv->rx_packets - priv->last_rx_packets;
4272 priv->last_rx_packets = priv->rx_packets;
4273
4274 tx_packets_delta = priv->tx_packets - priv->last_tx_packets;
4275 priv->last_tx_packets = priv->tx_packets;
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288#define BEACON_THRESHOLD 5
4289 beacon_quality = 100 - missed_beacons_percent;
4290 if (beacon_quality < BEACON_THRESHOLD)
4291 beacon_quality = 0;
4292 else
4293 beacon_quality = (beacon_quality - BEACON_THRESHOLD) * 100 /
4294 (100 - BEACON_THRESHOLD);
4295 IPW_DEBUG_STATS("Missed beacon: %3d%% (%d%%)\n",
4296 beacon_quality, missed_beacons_percent);
4297
4298 priv->last_rate = ipw_get_current_rate(priv);
4299 max_rate = ipw_get_max_rate(priv);
4300 rate_quality = priv->last_rate * 40 / max_rate + 60;
4301 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n",
4302 rate_quality, priv->last_rate / 1000000);
4303
4304 if (rx_packets_delta > 100 && rx_packets_delta + rx_err_delta)
4305 rx_quality = 100 - (rx_err_delta * 100) /
4306 (rx_packets_delta + rx_err_delta);
4307 else
4308 rx_quality = 100;
4309 IPW_DEBUG_STATS("Rx quality : %3d%% (%u errors, %u packets)\n",
4310 rx_quality, rx_err_delta, rx_packets_delta);
4311
4312 if (tx_packets_delta > 100 && tx_packets_delta + tx_failures_delta)
4313 tx_quality = 100 - (tx_failures_delta * 100) /
4314 (tx_packets_delta + tx_failures_delta);
4315 else
4316 tx_quality = 100;
4317 IPW_DEBUG_STATS("Tx quality : %3d%% (%u errors, %u packets)\n",
4318 tx_quality, tx_failures_delta, tx_packets_delta);
4319
4320 rssi = priv->exp_avg_rssi;
4321 signal_quality =
4322 (100 *
4323 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4324 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) -
4325 (priv->ieee->perfect_rssi - rssi) *
4326 (15 * (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) +
4327 62 * (priv->ieee->perfect_rssi - rssi))) /
4328 ((priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4329 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi));
4330 if (signal_quality > 100)
4331 signal_quality = 100;
4332 else if (signal_quality < 1)
4333 signal_quality = 0;
4334
4335 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
4336 signal_quality, rssi);
4337
4338 quality = min(rx_quality, signal_quality);
4339 quality = min(tx_quality, quality);
4340 quality = min(rate_quality, quality);
4341 quality = min(beacon_quality, quality);
4342 if (quality == beacon_quality)
4343 IPW_DEBUG_STATS("Quality (%d%%): Clamped to missed beacons.\n",
4344 quality);
4345 if (quality == rate_quality)
4346 IPW_DEBUG_STATS("Quality (%d%%): Clamped to rate quality.\n",
4347 quality);
4348 if (quality == tx_quality)
4349 IPW_DEBUG_STATS("Quality (%d%%): Clamped to Tx quality.\n",
4350 quality);
4351 if (quality == rx_quality)
4352 IPW_DEBUG_STATS("Quality (%d%%): Clamped to Rx quality.\n",
4353 quality);
4354 if (quality == signal_quality)
4355 IPW_DEBUG_STATS("Quality (%d%%): Clamped to signal quality.\n",
4356 quality);
4357
4358 priv->quality = quality;
4359
4360 schedule_delayed_work(&priv->gather_stats, IPW_STATS_INTERVAL);
4361}
4362
4363static void ipw_bg_gather_stats(struct work_struct *work)
4364{
4365 struct ipw_priv *priv =
4366 container_of(work, struct ipw_priv, gather_stats.work);
4367 mutex_lock(&priv->mutex);
4368 ipw_gather_stats(priv);
4369 mutex_unlock(&priv->mutex);
4370}
4371
4372
4373
4374
4375
4376
4377static void ipw_handle_missed_beacon(struct ipw_priv *priv,
4378 int missed_count)
4379{
4380 priv->notif_missed_beacons = missed_count;
4381
4382 if (missed_count > priv->disassociate_threshold &&
4383 priv->status & STATUS_ASSOCIATED) {
4384
4385
4386
4387 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
4388 IPW_DL_STATE | IPW_DL_ASSOC,
4389 "Missed beacon: %d - disassociate\n", missed_count);
4390 priv->status &= ~STATUS_ROAMING;
4391 if (priv->status & STATUS_SCANNING) {
4392 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
4393 IPW_DL_STATE,
4394 "Aborting scan with missed beacon.\n");
4395 schedule_work(&priv->abort_scan);
4396 }
4397
4398 schedule_work(&priv->disassociate);
4399 return;
4400 }
4401
4402 if (priv->status & STATUS_ROAMING) {
4403
4404
4405 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4406 "Missed beacon: %d - roam in progress\n",
4407 missed_count);
4408 return;
4409 }
4410
4411 if (roaming &&
4412 (missed_count > priv->roaming_threshold &&
4413 missed_count <= priv->disassociate_threshold)) {
4414
4415
4416
4417
4418 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4419 "Missed beacon: %d - initiate "
4420 "roaming\n", missed_count);
4421 if (!(priv->status & STATUS_ROAMING)) {
4422 priv->status |= STATUS_ROAMING;
4423 if (!(priv->status & STATUS_SCANNING))
4424 schedule_delayed_work(&priv->request_scan, 0);
4425 }
4426 return;
4427 }
4428
4429 if (priv->status & STATUS_SCANNING &&
4430 missed_count > IPW_MB_SCAN_CANCEL_THRESHOLD) {
4431
4432
4433
4434
4435 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE,
4436 "Aborting scan with missed beacon.\n");
4437 schedule_work(&priv->abort_scan);
4438 }
4439
4440 IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
4441}
4442
4443static void ipw_scan_event(struct work_struct *work)
4444{
4445 union iwreq_data wrqu;
4446
4447 struct ipw_priv *priv =
4448 container_of(work, struct ipw_priv, scan_event.work);
4449
4450 wrqu.data.length = 0;
4451 wrqu.data.flags = 0;
4452 wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);
4453}
4454
4455static void handle_scan_event(struct ipw_priv *priv)
4456{
4457
4458 if (!priv->user_requested_scan) {
4459 schedule_delayed_work(&priv->scan_event,
4460 round_jiffies_relative(msecs_to_jiffies(4000)));
4461 } else {
4462 priv->user_requested_scan = 0;
4463 mod_delayed_work(system_wq, &priv->scan_event, 0);
4464 }
4465}
4466
4467
4468
4469
4470
4471static void ipw_rx_notification(struct ipw_priv *priv,
4472 struct ipw_rx_notification *notif)
4473{
4474 u16 size = le16_to_cpu(notif->size);
4475
4476 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size);
4477
4478 switch (notif->subtype) {
4479 case HOST_NOTIFICATION_STATUS_ASSOCIATED:{
4480 struct notif_association *assoc = ¬if->u.assoc;
4481
4482 switch (assoc->state) {
4483 case CMAS_ASSOCIATED:{
4484 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4485 IPW_DL_ASSOC,
4486 "associated: '%*pE' %pM\n",
4487 priv->essid_len, priv->essid,
4488 priv->bssid);
4489
4490 switch (priv->ieee->iw_mode) {
4491 case IW_MODE_INFRA:
4492 memcpy(priv->ieee->bssid,
4493 priv->bssid, ETH_ALEN);
4494 break;
4495
4496 case IW_MODE_ADHOC:
4497 memcpy(priv->ieee->bssid,
4498 priv->bssid, ETH_ALEN);
4499
4500
4501 priv->num_stations = 0;
4502
4503 IPW_DEBUG_ASSOC
4504 ("queueing adhoc check\n");
4505 schedule_delayed_work(
4506 &priv->adhoc_check,
4507 le16_to_cpu(priv->
4508 assoc_request.
4509 beacon_interval));
4510 break;
4511 }
4512
4513 priv->status &= ~STATUS_ASSOCIATING;
4514 priv->status |= STATUS_ASSOCIATED;
4515 schedule_work(&priv->system_config);
4516
4517#ifdef CONFIG_IPW2200_QOS
4518#define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
4519 le16_to_cpu(((struct ieee80211_hdr *)(x))->frame_control))
4520 if ((priv->status & STATUS_AUTH) &&
4521 (IPW_GET_PACKET_STYPE(¬if->u.raw)
4522 == IEEE80211_STYPE_ASSOC_RESP)) {
4523 if ((sizeof
4524 (struct
4525 libipw_assoc_response)
4526 <= size)
4527 && (size <= 2314)) {
4528 struct
4529 libipw_rx_stats
4530 stats = {
4531 .len = size - 1,
4532 };
4533
4534 IPW_DEBUG_QOS
4535 ("QoS Associate "
4536 "size %d\n", size);
4537 libipw_rx_mgt(priv->
4538 ieee,
4539 (struct
4540 libipw_hdr_4addr
4541 *)
4542 ¬if->u.raw, &stats);
4543 }
4544 }
4545#endif
4546
4547 schedule_work(&priv->link_up);
4548
4549 break;
4550 }
4551
4552 case CMAS_AUTHENTICATED:{
4553 if (priv->
4554 status & (STATUS_ASSOCIATED |
4555 STATUS_AUTH)) {
4556 struct notif_authenticate *auth
4557 = ¬if->u.auth;
4558 IPW_DEBUG(IPW_DL_NOTIF |
4559 IPW_DL_STATE |
4560 IPW_DL_ASSOC,
4561 "deauthenticated: '%*pE' %pM: (0x%04X) - %s\n",
4562 priv->essid_len,
4563 priv->essid,
4564 priv->bssid,
4565 le16_to_cpu(auth->status),
4566 ipw_get_status_code
4567 (le16_to_cpu
4568 (auth->status)));
4569
4570 priv->status &=
4571 ~(STATUS_ASSOCIATING |
4572 STATUS_AUTH |
4573 STATUS_ASSOCIATED);
4574
4575 schedule_work(&priv->link_down);
4576 break;
4577 }
4578
4579 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4580 IPW_DL_ASSOC,
4581 "authenticated: '%*pE' %pM\n",
4582 priv->essid_len, priv->essid,
4583 priv->bssid);
4584 break;
4585 }
4586
4587 case CMAS_INIT:{
4588 if (priv->status & STATUS_AUTH) {
4589 struct
4590 libipw_assoc_response
4591 *resp;
4592 resp =
4593 (struct
4594 libipw_assoc_response
4595 *)¬if->u.raw;
4596 IPW_DEBUG(IPW_DL_NOTIF |
4597 IPW_DL_STATE |
4598 IPW_DL_ASSOC,
4599 "association failed (0x%04X): %s\n",
4600 le16_to_cpu(resp->status),
4601 ipw_get_status_code
4602 (le16_to_cpu
4603 (resp->status)));
4604 }
4605
4606 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4607 IPW_DL_ASSOC,
4608 "disassociated: '%*pE' %pM\n",
4609 priv->essid_len, priv->essid,
4610 priv->bssid);
4611
4612 priv->status &=
4613 ~(STATUS_DISASSOCIATING |
4614 STATUS_ASSOCIATING |
4615 STATUS_ASSOCIATED | STATUS_AUTH);
4616 if (priv->assoc_network
4617 && (priv->assoc_network->
4618 capability &
4619 WLAN_CAPABILITY_IBSS))
4620 ipw_remove_current_network
4621 (priv);
4622
4623 schedule_work(&priv->link_down);
4624
4625 break;
4626 }
4627
4628 case CMAS_RX_ASSOC_RESP:
4629 break;
4630
4631 default:
4632 IPW_ERROR("assoc: unknown (%d)\n",
4633 assoc->state);
4634 break;
4635 }
4636
4637 break;
4638 }
4639
4640 case HOST_NOTIFICATION_STATUS_AUTHENTICATE:{
4641 struct notif_authenticate *auth = ¬if->u.auth;
4642 switch (auth->state) {
4643 case CMAS_AUTHENTICATED:
4644 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4645 "authenticated: '%*pE' %pM\n",
4646 priv->essid_len, priv->essid,
4647 priv->bssid);
4648 priv->status |= STATUS_AUTH;
4649 break;
4650
4651 case CMAS_INIT:
4652 if (priv->status & STATUS_AUTH) {
4653 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4654 IPW_DL_ASSOC,
4655 "authentication failed (0x%04X): %s\n",
4656 le16_to_cpu(auth->status),
4657 ipw_get_status_code(le16_to_cpu
4658 (auth->
4659 status)));
4660 }
4661 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4662 IPW_DL_ASSOC,
4663 "deauthenticated: '%*pE' %pM\n",
4664 priv->essid_len, priv->essid,
4665 priv->bssid);
4666
4667 priv->status &= ~(STATUS_ASSOCIATING |
4668 STATUS_AUTH |
4669 STATUS_ASSOCIATED);
4670
4671 schedule_work(&priv->link_down);
4672 break;
4673
4674 case CMAS_TX_AUTH_SEQ_1:
4675 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4676 IPW_DL_ASSOC, "AUTH_SEQ_1\n");
4677 break;
4678 case CMAS_RX_AUTH_SEQ_2:
4679 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4680 IPW_DL_ASSOC, "AUTH_SEQ_2\n");
4681 break;
4682 case CMAS_AUTH_SEQ_1_PASS:
4683 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4684 IPW_DL_ASSOC, "AUTH_SEQ_1_PASS\n");
4685 break;
4686 case CMAS_AUTH_SEQ_1_FAIL:
4687 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4688 IPW_DL_ASSOC, "AUTH_SEQ_1_FAIL\n");
4689 break;
4690 case CMAS_TX_AUTH_SEQ_3:
4691 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4692 IPW_DL_ASSOC, "AUTH_SEQ_3\n");
4693 break;
4694 case CMAS_RX_AUTH_SEQ_4:
4695 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4696 IPW_DL_ASSOC, "RX_AUTH_SEQ_4\n");
4697 break;
4698 case CMAS_AUTH_SEQ_2_PASS:
4699 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4700 IPW_DL_ASSOC, "AUTH_SEQ_2_PASS\n");
4701 break;
4702 case CMAS_AUTH_SEQ_2_FAIL:
4703 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4704 IPW_DL_ASSOC, "AUT_SEQ_2_FAIL\n");
4705 break;
4706 case CMAS_TX_ASSOC:
4707 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4708 IPW_DL_ASSOC, "TX_ASSOC\n");
4709 break;
4710 case CMAS_RX_ASSOC_RESP:
4711 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4712 IPW_DL_ASSOC, "RX_ASSOC_RESP\n");
4713
4714 break;
4715 case CMAS_ASSOCIATED:
4716 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4717 IPW_DL_ASSOC, "ASSOCIATED\n");
4718 break;
4719 default:
4720 IPW_DEBUG_NOTIF("auth: failure - %d\n",
4721 auth->state);
4722 break;
4723 }
4724 break;
4725 }
4726
4727 case HOST_NOTIFICATION_STATUS_SCAN_CHANNEL_RESULT:{
4728 struct notif_channel_result *x =
4729 ¬if->u.channel_result;
4730
4731 if (size == sizeof(*x)) {
4732 IPW_DEBUG_SCAN("Scan result for channel %d\n",
4733 x->channel_num);
4734 } else {
4735 IPW_DEBUG_SCAN("Scan result of wrong size %d "
4736 "(should be %zd)\n",
4737 size, sizeof(*x));
4738 }
4739 break;
4740 }
4741
4742 case HOST_NOTIFICATION_STATUS_SCAN_COMPLETED:{
4743 struct notif_scan_complete *x = ¬if->u.scan_complete;
4744 if (size == sizeof(*x)) {
4745 IPW_DEBUG_SCAN
4746 ("Scan completed: type %d, %d channels, "
4747 "%d status\n", x->scan_type,
4748 x->num_channels, x->status);
4749 } else {
4750 IPW_ERROR("Scan completed of wrong size %d "
4751 "(should be %zd)\n",
4752 size, sizeof(*x));
4753 }
4754
4755 priv->status &=
4756 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
4757
4758 wake_up_interruptible(&priv->wait_state);
4759 cancel_delayed_work(&priv->scan_check);
4760
4761 if (priv->status & STATUS_EXIT_PENDING)
4762 break;
4763
4764 priv->ieee->scans++;
4765
4766#ifdef CONFIG_IPW2200_MONITOR
4767 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
4768 priv->status |= STATUS_SCAN_FORCED;
4769 schedule_delayed_work(&priv->request_scan, 0);
4770 break;
4771 }
4772 priv->status &= ~STATUS_SCAN_FORCED;
4773#endif
4774
4775
4776 if (priv->status & STATUS_DIRECT_SCAN_PENDING)
4777 schedule_delayed_work(&priv->request_direct_scan, 0);
4778
4779 if (!(priv->status & (STATUS_ASSOCIATED |
4780 STATUS_ASSOCIATING |
4781 STATUS_ROAMING |
4782 STATUS_DISASSOCIATING)))
4783 schedule_work(&priv->associate);
4784 else if (priv->status & STATUS_ROAMING) {
4785 if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
4786
4787
4788
4789
4790 schedule_work(&priv->roam);
4791 else
4792
4793 priv->status &= ~STATUS_ROAMING;
4794 } else if (priv->status & STATUS_SCAN_PENDING)
4795 schedule_delayed_work(&priv->request_scan, 0);
4796 else if (priv->config & CFG_BACKGROUND_SCAN
4797 && priv->status & STATUS_ASSOCIATED)
4798 schedule_delayed_work(&priv->request_scan,
4799 round_jiffies_relative(HZ));
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810 if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
4811 handle_scan_event(priv);
4812 break;
4813 }
4814
4815 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{
4816 struct notif_frag_length *x = ¬if->u.frag_len;
4817
4818 if (size == sizeof(*x))
4819 IPW_ERROR("Frag length: %d\n",
4820 le16_to_cpu(x->frag_length));
4821 else
4822 IPW_ERROR("Frag length of wrong size %d "
4823 "(should be %zd)\n",
4824 size, sizeof(*x));
4825 break;
4826 }
4827
4828 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{
4829 struct notif_link_deterioration *x =
4830 ¬if->u.link_deterioration;
4831
4832 if (size == sizeof(*x)) {
4833 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4834 "link deterioration: type %d, cnt %d\n",
4835 x->silence_notification_type,
4836 x->silence_count);
4837 memcpy(&priv->last_link_deterioration, x,
4838 sizeof(*x));
4839 } else {
4840 IPW_ERROR("Link Deterioration of wrong size %d "
4841 "(should be %zd)\n",
4842 size, sizeof(*x));
4843 }
4844 break;
4845 }
4846
4847 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{
4848 IPW_ERROR("Dino config\n");
4849 if (priv->hcmd
4850 && priv->hcmd->cmd != HOST_CMD_DINO_CONFIG)
4851 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n");
4852
4853 break;
4854 }
4855
4856 case HOST_NOTIFICATION_STATUS_BEACON_STATE:{
4857 struct notif_beacon_state *x = ¬if->u.beacon_state;
4858 if (size != sizeof(*x)) {
4859 IPW_ERROR
4860 ("Beacon state of wrong size %d (should "
4861 "be %zd)\n", size, sizeof(*x));
4862 break;
4863 }
4864
4865 if (le32_to_cpu(x->state) ==
4866 HOST_NOTIFICATION_STATUS_BEACON_MISSING)
4867 ipw_handle_missed_beacon(priv,
4868 le32_to_cpu(x->
4869 number));
4870
4871 break;
4872 }
4873
4874 case HOST_NOTIFICATION_STATUS_TGI_TX_KEY:{
4875 struct notif_tgi_tx_key *x = ¬if->u.tgi_tx_key;
4876 if (size == sizeof(*x)) {
4877 IPW_ERROR("TGi Tx Key: state 0x%02x sec type "
4878 "0x%02x station %d\n",
4879 x->key_state, x->security_type,
4880 x->station_index);
4881 break;
4882 }
4883
4884 IPW_ERROR
4885 ("TGi Tx Key of wrong size %d (should be %zd)\n",
4886 size, sizeof(*x));
4887 break;
4888 }
4889
4890 case HOST_NOTIFICATION_CALIB_KEEP_RESULTS:{
4891 struct notif_calibration *x = ¬if->u.calibration;
4892
4893 if (size == sizeof(*x)) {
4894 memcpy(&priv->calib, x, sizeof(*x));
4895 IPW_DEBUG_INFO("TODO: Calibration\n");
4896 break;
4897 }
4898
4899 IPW_ERROR
4900 ("Calibration of wrong size %d (should be %zd)\n",
4901 size, sizeof(*x));
4902 break;
4903 }
4904
4905 case HOST_NOTIFICATION_NOISE_STATS:{
4906 if (size == sizeof(u32)) {
4907 priv->exp_avg_noise =
4908 exponential_average(priv->exp_avg_noise,
4909 (u8) (le32_to_cpu(notif->u.noise.value) & 0xff),
4910 DEPTH_NOISE);
4911 break;
4912 }
4913
4914 IPW_ERROR
4915 ("Noise stat is wrong size %d (should be %zd)\n",
4916 size, sizeof(u32));
4917 break;
4918 }
4919
4920 default:
4921 IPW_DEBUG_NOTIF("Unknown notification: "
4922 "subtype=%d,flags=0x%2x,size=%d\n",
4923 notif->subtype, notif->flags, size);
4924 }
4925}
4926
4927
4928
4929
4930
4931
4932
4933static int ipw_queue_reset(struct ipw_priv *priv)
4934{
4935 int rc = 0;
4936
4937 int nTx = 64, nTxCmd = 8;
4938 ipw_tx_queue_free(priv);
4939
4940 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd,
4941 IPW_TX_CMD_QUEUE_READ_INDEX,
4942 IPW_TX_CMD_QUEUE_WRITE_INDEX,
4943 IPW_TX_CMD_QUEUE_BD_BASE,
4944 IPW_TX_CMD_QUEUE_BD_SIZE);
4945 if (rc) {
4946 IPW_ERROR("Tx Cmd queue init failed\n");
4947 goto error;
4948 }
4949
4950 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx,
4951 IPW_TX_QUEUE_0_READ_INDEX,
4952 IPW_TX_QUEUE_0_WRITE_INDEX,
4953 IPW_TX_QUEUE_0_BD_BASE, IPW_TX_QUEUE_0_BD_SIZE);
4954 if (rc) {
4955 IPW_ERROR("Tx 0 queue init failed\n");
4956 goto error;
4957 }
4958 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx,
4959 IPW_TX_QUEUE_1_READ_INDEX,
4960 IPW_TX_QUEUE_1_WRITE_INDEX,
4961 IPW_TX_QUEUE_1_BD_BASE, IPW_TX_QUEUE_1_BD_SIZE);
4962 if (rc) {
4963 IPW_ERROR("Tx 1 queue init failed\n");
4964 goto error;
4965 }
4966 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx,
4967 IPW_TX_QUEUE_2_READ_INDEX,
4968 IPW_TX_QUEUE_2_WRITE_INDEX,
4969 IPW_TX_QUEUE_2_BD_BASE, IPW_TX_QUEUE_2_BD_SIZE);
4970 if (rc) {
4971 IPW_ERROR("Tx 2 queue init failed\n");
4972 goto error;
4973 }
4974 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx,
4975 IPW_TX_QUEUE_3_READ_INDEX,
4976 IPW_TX_QUEUE_3_WRITE_INDEX,
4977 IPW_TX_QUEUE_3_BD_BASE, IPW_TX_QUEUE_3_BD_SIZE);
4978 if (rc) {
4979 IPW_ERROR("Tx 3 queue init failed\n");
4980 goto error;
4981 }
4982
4983 priv->rx_bufs_min = 0;
4984 priv->rx_pend_max = 0;
4985 return rc;
4986
4987 error:
4988 ipw_tx_queue_free(priv);
4989 return rc;
4990}
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
5006 struct clx2_tx_queue *txq, int qindex)
5007{
5008 u32 hw_tail;
5009 int used;
5010 struct clx2_queue *q = &txq->q;
5011
5012 hw_tail = ipw_read32(priv, q->reg_r);
5013 if (hw_tail >= q->n_bd) {
5014 IPW_ERROR
5015 ("Read index for DMA queue (%d) is out of range [0-%d)\n",
5016 hw_tail, q->n_bd);
5017 goto done;
5018 }
5019 for (; q->last_used != hw_tail;
5020 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {
5021 ipw_queue_tx_free_tfd(priv, txq);
5022 priv->tx_packets++;
5023 }
5024 done:
5025 if ((ipw_tx_queue_space(q) > q->low_mark) &&
5026 (qindex >= 0))
5027 netif_wake_queue(priv->net_dev);
5028 used = q->first_empty - q->last_used;
5029 if (used < 0)
5030 used += q->n_bd;
5031
5032 return used;
5033}
5034
5035static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
5036 int len, int sync)
5037{
5038 struct clx2_tx_queue *txq = &priv->txq_cmd;
5039 struct clx2_queue *q = &txq->q;
5040 struct tfd_frame *tfd;
5041
5042 if (ipw_tx_queue_space(q) < (sync ? 1 : 2)) {
5043 IPW_ERROR("No space for Tx\n");
5044 return -EBUSY;
5045 }
5046
5047 tfd = &txq->bd[q->first_empty];
5048 txq->txb[q->first_empty] = NULL;
5049
5050 memset(tfd, 0, sizeof(*tfd));
5051 tfd->control_flags.message_type = TX_HOST_COMMAND_TYPE;
5052 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
5053 priv->hcmd_seq++;
5054 tfd->u.cmd.index = hcmd;
5055 tfd->u.cmd.length = len;
5056 memcpy(tfd->u.cmd.payload, buf, len);
5057 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
5058 ipw_write32(priv, q->reg_w, q->first_empty);
5059 _ipw_read32(priv, 0x90);
5060
5061 return 0;
5062}
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
5137static void ipw_rx_queue_restock(struct ipw_priv *priv)
5138{
5139 struct ipw_rx_queue *rxq = priv->rxq;
5140 struct list_head *element;
5141 struct ipw_rx_mem_buffer *rxb;
5142 unsigned long flags;
5143 int write;
5144
5145 spin_lock_irqsave(&rxq->lock, flags);
5146 write = rxq->write;
5147 while ((ipw_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
5148 element = rxq->rx_free.next;
5149 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
5150 list_del(element);
5151
5152 ipw_write32(priv, IPW_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE,
5153 rxb->dma_addr);
5154 rxq->queue[rxq->write] = rxb;
5155 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE;
5156 rxq->free_count--;
5157 }
5158 spin_unlock_irqrestore(&rxq->lock, flags);
5159
5160
5161
5162 if (rxq->free_count <= RX_LOW_WATERMARK)
5163 schedule_work(&priv->rx_replenish);
5164
5165
5166 if (write != rxq->write)
5167 ipw_write32(priv, IPW_RX_WRITE_INDEX, rxq->write);
5168}
5169
5170
5171
5172
5173
5174
5175
5176static void ipw_rx_queue_replenish(void *data)
5177{
5178 struct ipw_priv *priv = data;
5179 struct ipw_rx_queue *rxq = priv->rxq;
5180 struct list_head *element;
5181 struct ipw_rx_mem_buffer *rxb;
5182 unsigned long flags;
5183
5184 spin_lock_irqsave(&rxq->lock, flags);
5185 while (!list_empty(&rxq->rx_used)) {
5186 element = rxq->rx_used.next;
5187 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
5188 rxb->skb = alloc_skb(IPW_RX_BUF_SIZE, GFP_ATOMIC);
5189 if (!rxb->skb) {
5190 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n",
5191 priv->net_dev->name);
5192
5193
5194
5195 break;
5196 }
5197 list_del(element);
5198
5199 rxb->dma_addr =
5200 pci_map_single(priv->pci_dev, rxb->skb->data,
5201 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
5202
5203 list_add_tail(&rxb->list, &rxq->rx_free);
5204 rxq->free_count++;
5205 }
5206 spin_unlock_irqrestore(&rxq->lock, flags);
5207
5208 ipw_rx_queue_restock(priv);
5209}
5210
5211static void ipw_bg_rx_queue_replenish(struct work_struct *work)
5212{
5213 struct ipw_priv *priv =
5214 container_of(work, struct ipw_priv, rx_replenish);
5215 mutex_lock(&priv->mutex);
5216 ipw_rx_queue_replenish(priv);
5217 mutex_unlock(&priv->mutex);
5218}
5219
5220
5221
5222
5223
5224
5225static void ipw_rx_queue_free(struct ipw_priv *priv, struct ipw_rx_queue *rxq)
5226{
5227 int i;
5228
5229 if (!rxq)
5230 return;
5231
5232 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
5233 if (rxq->pool[i].skb != NULL) {
5234 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
5235 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
5236 dev_kfree_skb(rxq->pool[i].skb);
5237 }
5238 }
5239
5240 kfree(rxq);
5241}
5242
5243static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv)
5244{
5245 struct ipw_rx_queue *rxq;
5246 int i;
5247
5248 rxq = kzalloc(sizeof(*rxq), GFP_KERNEL);
5249 if (unlikely(!rxq)) {
5250 IPW_ERROR("memory allocation failed\n");
5251 return NULL;
5252 }
5253 spin_lock_init(&rxq->lock);
5254 INIT_LIST_HEAD(&rxq->rx_free);
5255 INIT_LIST_HEAD(&rxq->rx_used);
5256
5257
5258 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
5259 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
5260
5261
5262
5263 rxq->read = rxq->write = 0;
5264 rxq->free_count = 0;
5265
5266 return rxq;
5267}
5268
5269static int ipw_is_rate_in_mask(struct ipw_priv *priv, int ieee_mode, u8 rate)
5270{
5271 rate &= ~LIBIPW_BASIC_RATE_MASK;
5272 if (ieee_mode == IEEE_A) {
5273 switch (rate) {
5274 case LIBIPW_OFDM_RATE_6MB:
5275 return priv->rates_mask & LIBIPW_OFDM_RATE_6MB_MASK ?
5276 1 : 0;
5277 case LIBIPW_OFDM_RATE_9MB:
5278 return priv->rates_mask & LIBIPW_OFDM_RATE_9MB_MASK ?
5279 1 : 0;
5280 case LIBIPW_OFDM_RATE_12MB:
5281 return priv->
5282 rates_mask & LIBIPW_OFDM_RATE_12MB_MASK ? 1 : 0;
5283 case LIBIPW_OFDM_RATE_18MB:
5284 return priv->
5285 rates_mask & LIBIPW_OFDM_RATE_18MB_MASK ? 1 : 0;
5286 case LIBIPW_OFDM_RATE_24MB:
5287 return priv->
5288 rates_mask & LIBIPW_OFDM_RATE_24MB_MASK ? 1 : 0;
5289 case LIBIPW_OFDM_RATE_36MB:
5290 return priv->
5291 rates_mask & LIBIPW_OFDM_RATE_36MB_MASK ? 1 : 0;
5292 case LIBIPW_OFDM_RATE_48MB:
5293 return priv->
5294 rates_mask & LIBIPW_OFDM_RATE_48MB_MASK ? 1 : 0;
5295 case LIBIPW_OFDM_RATE_54MB:
5296 return priv->
5297 rates_mask & LIBIPW_OFDM_RATE_54MB_MASK ? 1 : 0;
5298 default:
5299 return 0;
5300 }
5301 }
5302
5303
5304 switch (rate) {
5305 case LIBIPW_CCK_RATE_1MB:
5306 return priv->rates_mask & LIBIPW_CCK_RATE_1MB_MASK ? 1 : 0;
5307 case LIBIPW_CCK_RATE_2MB:
5308 return priv->rates_mask & LIBIPW_CCK_RATE_2MB_MASK ? 1 : 0;
5309 case LIBIPW_CCK_RATE_5MB:
5310 return priv->rates_mask & LIBIPW_CCK_RATE_5MB_MASK ? 1 : 0;
5311 case LIBIPW_CCK_RATE_11MB:
5312 return priv->rates_mask & LIBIPW_CCK_RATE_11MB_MASK ? 1 : 0;
5313 }
5314
5315
5316 if (ieee_mode == IEEE_B)
5317 return 0;
5318
5319
5320 switch (rate) {
5321 case LIBIPW_OFDM_RATE_6MB:
5322 return priv->rates_mask & LIBIPW_OFDM_RATE_6MB_MASK ? 1 : 0;
5323 case LIBIPW_OFDM_RATE_9MB:
5324 return priv->rates_mask & LIBIPW_OFDM_RATE_9MB_MASK ? 1 : 0;
5325 case LIBIPW_OFDM_RATE_12MB:
5326 return priv->rates_mask & LIBIPW_OFDM_RATE_12MB_MASK ? 1 : 0;
5327 case LIBIPW_OFDM_RATE_18MB:
5328 return priv->rates_mask & LIBIPW_OFDM_RATE_18MB_MASK ? 1 : 0;
5329 case LIBIPW_OFDM_RATE_24MB:
5330 return priv->rates_mask & LIBIPW_OFDM_RATE_24MB_MASK ? 1 : 0;
5331 case LIBIPW_OFDM_RATE_36MB:
5332 return priv->rates_mask & LIBIPW_OFDM_RATE_36MB_MASK ? 1 : 0;
5333 case LIBIPW_OFDM_RATE_48MB:
5334 return priv->rates_mask & LIBIPW_OFDM_RATE_48MB_MASK ? 1 : 0;
5335 case LIBIPW_OFDM_RATE_54MB:
5336 return priv->rates_mask & LIBIPW_OFDM_RATE_54MB_MASK ? 1 : 0;
5337 }
5338
5339 return 0;
5340}
5341
5342static int ipw_compatible_rates(struct ipw_priv *priv,
5343 const struct libipw_network *network,
5344 struct ipw_supported_rates *rates)
5345{
5346 int num_rates, i;
5347
5348 memset(rates, 0, sizeof(*rates));
5349 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES);
5350 rates->num_rates = 0;
5351 for (i = 0; i < num_rates; i++) {
5352 if (!ipw_is_rate_in_mask(priv, network->mode,
5353 network->rates[i])) {
5354
5355 if (network->rates[i] & LIBIPW_BASIC_RATE_MASK) {
5356 IPW_DEBUG_SCAN("Adding masked mandatory "
5357 "rate %02X\n",
5358 network->rates[i]);
5359 rates->supported_rates[rates->num_rates++] =
5360 network->rates[i];
5361 continue;
5362 }
5363
5364 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
5365 network->rates[i], priv->rates_mask);
5366 continue;
5367 }
5368
5369 rates->supported_rates[rates->num_rates++] = network->rates[i];
5370 }
5371
5372 num_rates = min(network->rates_ex_len,
5373 (u8) (IPW_MAX_RATES - num_rates));
5374 for (i = 0; i < num_rates; i++) {
5375 if (!ipw_is_rate_in_mask(priv, network->mode,
5376 network->rates_ex[i])) {
5377 if (network->rates_ex[i] & LIBIPW_BASIC_RATE_MASK) {
5378 IPW_DEBUG_SCAN("Adding masked mandatory "
5379 "rate %02X\n",
5380 network->rates_ex[i]);
5381 rates->supported_rates[rates->num_rates++] =
5382 network->rates[i];
5383 continue;
5384 }
5385
5386 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
5387 network->rates_ex[i], priv->rates_mask);
5388 continue;
5389 }
5390
5391 rates->supported_rates[rates->num_rates++] =
5392 network->rates_ex[i];
5393 }
5394
5395 return 1;
5396}
5397
5398static void ipw_copy_rates(struct ipw_supported_rates *dest,
5399 const struct ipw_supported_rates *src)
5400{
5401 u8 i;
5402 for (i = 0; i < src->num_rates; i++)
5403 dest->supported_rates[i] = src->supported_rates[i];
5404 dest->num_rates = src->num_rates;
5405}
5406
5407
5408
5409
5410static void ipw_add_cck_scan_rates(struct ipw_supported_rates *rates,
5411 u8 modulation, u32 rate_mask)
5412{
5413 u8 basic_mask = (LIBIPW_OFDM_MODULATION == modulation) ?
5414 LIBIPW_BASIC_RATE_MASK : 0;
5415
5416 if (rate_mask & LIBIPW_CCK_RATE_1MB_MASK)
5417 rates->supported_rates[rates->num_rates++] =
5418 LIBIPW_BASIC_RATE_MASK | LIBIPW_CCK_RATE_1MB;
5419
5420 if (rate_mask & LIBIPW_CCK_RATE_2MB_MASK)
5421 rates->supported_rates[rates->num_rates++] =
5422 LIBIPW_BASIC_RATE_MASK | LIBIPW_CCK_RATE_2MB;
5423
5424 if (rate_mask & LIBIPW_CCK_RATE_5MB_MASK)
5425 rates->supported_rates[rates->num_rates++] = basic_mask |
5426 LIBIPW_CCK_RATE_5MB;
5427
5428 if (rate_mask & LIBIPW_CCK_RATE_11MB_MASK)
5429 rates->supported_rates[rates->num_rates++] = basic_mask |
5430 LIBIPW_CCK_RATE_11MB;
5431}
5432
5433static void ipw_add_ofdm_scan_rates(struct ipw_supported_rates *rates,
5434 u8 modulation, u32 rate_mask)
5435{
5436 u8 basic_mask = (LIBIPW_OFDM_MODULATION == modulation) ?
5437 LIBIPW_BASIC_RATE_MASK : 0;
5438
5439 if (rate_mask & LIBIPW_OFDM_RATE_6MB_MASK)
5440 rates->supported_rates[rates->num_rates++] = basic_mask |
5441 LIBIPW_OFDM_RATE_6MB;
5442
5443 if (rate_mask & LIBIPW_OFDM_RATE_9MB_MASK)
5444 rates->supported_rates[rates->num_rates++] =
5445 LIBIPW_OFDM_RATE_9MB;
5446
5447 if (rate_mask & LIBIPW_OFDM_RATE_12MB_MASK)
5448 rates->supported_rates[rates->num_rates++] = basic_mask |
5449 LIBIPW_OFDM_RATE_12MB;
5450
5451 if (rate_mask & LIBIPW_OFDM_RATE_18MB_MASK)
5452 rates->supported_rates[rates->num_rates++] =
5453 LIBIPW_OFDM_RATE_18MB;
5454
5455 if (rate_mask & LIBIPW_OFDM_RATE_24MB_MASK)
5456 rates->supported_rates[rates->num_rates++] = basic_mask |
5457 LIBIPW_OFDM_RATE_24MB;
5458
5459 if (rate_mask & LIBIPW_OFDM_RATE_36MB_MASK)
5460 rates->supported_rates[rates->num_rates++] =
5461 LIBIPW_OFDM_RATE_36MB;
5462
5463 if (rate_mask & LIBIPW_OFDM_RATE_48MB_MASK)
5464 rates->supported_rates[rates->num_rates++] =
5465 LIBIPW_OFDM_RATE_48MB;
5466
5467 if (rate_mask & LIBIPW_OFDM_RATE_54MB_MASK)
5468 rates->supported_rates[rates->num_rates++] =
5469 LIBIPW_OFDM_RATE_54MB;
5470}
5471
5472struct ipw_network_match {
5473 struct libipw_network *network;
5474 struct ipw_supported_rates rates;
5475};
5476
5477static int ipw_find_adhoc_network(struct ipw_priv *priv,
5478 struct ipw_network_match *match,
5479 struct libipw_network *network,
5480 int roaming)
5481{
5482 struct ipw_supported_rates rates;
5483
5484
5485
5486 if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
5487 !(network->capability & WLAN_CAPABILITY_IBSS))) {
5488 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded due to capability mismatch.\n",
5489 network->ssid_len, network->ssid,
5490 network->bssid);
5491 return 0;
5492 }
5493
5494 if (unlikely(roaming)) {
5495
5496
5497 if ((network->ssid_len != match->network->ssid_len) ||
5498 memcmp(network->ssid, match->network->ssid,
5499 network->ssid_len)) {
5500 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of non-network ESSID.\n",
5501 network->ssid_len, network->ssid,
5502 network->bssid);
5503 return 0;
5504 }
5505 } else {
5506
5507
5508 if ((priv->config & CFG_STATIC_ESSID) &&
5509 ((network->ssid_len != priv->essid_len) ||
5510 memcmp(network->ssid, priv->essid,
5511 min(network->ssid_len, priv->essid_len)))) {
5512 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of ESSID mismatch: '%*pE'.\n",
5513 network->ssid_len, network->ssid,
5514 network->bssid, priv->essid_len,
5515 priv->essid);
5516 return 0;
5517 }
5518 }
5519
5520
5521
5522
5523 if (network->time_stamp[0] < match->network->time_stamp[0]) {
5524 IPW_DEBUG_MERGE("Network '%*pE excluded because newer than current network.\n",
5525 match->network->ssid_len, match->network->ssid);
5526 return 0;
5527 } else if (network->time_stamp[1] < match->network->time_stamp[1]) {
5528 IPW_DEBUG_MERGE("Network '%*pE excluded because newer than current network.\n",
5529 match->network->ssid_len, match->network->ssid);
5530 return 0;
5531 }
5532
5533
5534 if (priv->ieee->scan_age != 0 &&
5535 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
5536 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of age: %ums.\n",
5537 network->ssid_len, network->ssid,
5538 network->bssid,
5539 jiffies_to_msecs(jiffies -
5540 network->last_scanned));
5541 return 0;
5542 }
5543
5544 if ((priv->config & CFG_STATIC_CHANNEL) &&
5545 (network->channel != priv->channel)) {
5546 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of channel mismatch: %d != %d.\n",
5547 network->ssid_len, network->ssid,
5548 network->bssid,
5549 network->channel, priv->channel);
5550 return 0;
5551 }
5552
5553
5554 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
5555 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
5556 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of privacy mismatch: %s != %s.\n",
5557 network->ssid_len, network->ssid,
5558 network->bssid,
5559 priv->
5560 capability & CAP_PRIVACY_ON ? "on" : "off",
5561 network->
5562 capability & WLAN_CAPABILITY_PRIVACY ? "on" :
5563 "off");
5564 return 0;
5565 }
5566
5567 if (ether_addr_equal(network->bssid, priv->bssid)) {
5568 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of the same BSSID match: %pM.\n",
5569 network->ssid_len, network->ssid,
5570 network->bssid, priv->bssid);
5571 return 0;
5572 }
5573
5574
5575 if (!libipw_is_valid_mode(priv->ieee, network->mode)) {
5576 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of invalid frequency/mode combination.\n",
5577 network->ssid_len, network->ssid,
5578 network->bssid);
5579 return 0;
5580 }
5581
5582
5583
5584 if (!ipw_compatible_rates(priv, network, &rates)) {
5585 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because configured rate mask excludes AP mandatory rate.\n",
5586 network->ssid_len, network->ssid,
5587 network->bssid);
5588 return 0;
5589 }
5590
5591 if (rates.num_rates == 0) {
5592 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of no compatible rates.\n",
5593 network->ssid_len, network->ssid,
5594 network->bssid);
5595 return 0;
5596 }
5597
5598
5599
5600
5601
5602
5603 ipw_copy_rates(&match->rates, &rates);
5604 match->network = network;
5605 IPW_DEBUG_MERGE("Network '%*pE (%pM)' is a viable match.\n",
5606 network->ssid_len, network->ssid, network->bssid);
5607
5608 return 1;
5609}
5610
5611static void ipw_merge_adhoc_network(struct work_struct *work)
5612{
5613 struct ipw_priv *priv =
5614 container_of(work, struct ipw_priv, merge_networks);
5615 struct libipw_network *network = NULL;
5616 struct ipw_network_match match = {
5617 .network = priv->assoc_network
5618 };
5619
5620 if ((priv->status & STATUS_ASSOCIATED) &&
5621 (priv->ieee->iw_mode == IW_MODE_ADHOC)) {
5622
5623
5624 unsigned long flags;
5625
5626 spin_lock_irqsave(&priv->ieee->lock, flags);
5627 list_for_each_entry(network, &priv->ieee->network_list, list) {
5628 if (network != priv->assoc_network)
5629 ipw_find_adhoc_network(priv, &match, network,
5630 1);
5631 }
5632 spin_unlock_irqrestore(&priv->ieee->lock, flags);
5633
5634 if (match.network == priv->assoc_network) {
5635 IPW_DEBUG_MERGE("No better ADHOC in this network to "
5636 "merge to.\n");
5637 return;
5638 }
5639
5640 mutex_lock(&priv->mutex);
5641 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5642 IPW_DEBUG_MERGE("remove network %*pE\n",
5643 priv->essid_len, priv->essid);
5644 ipw_remove_current_network(priv);
5645 }
5646
5647 ipw_disassociate(priv);
5648 priv->assoc_network = match.network;
5649 mutex_unlock(&priv->mutex);
5650 return;
5651 }
5652}
5653
5654static int ipw_best_network(struct ipw_priv *priv,
5655 struct ipw_network_match *match,
5656 struct libipw_network *network, int roaming)
5657{
5658 struct ipw_supported_rates rates;
5659
5660
5661
5662 if ((priv->ieee->iw_mode == IW_MODE_INFRA &&
5663 !(network->capability & WLAN_CAPABILITY_ESS)) ||
5664 (priv->ieee->iw_mode == IW_MODE_ADHOC &&
5665 !(network->capability & WLAN_CAPABILITY_IBSS))) {
5666 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded due to capability mismatch.\n",
5667 network->ssid_len, network->ssid,
5668 network->bssid);
5669 return 0;
5670 }
5671
5672 if (unlikely(roaming)) {
5673
5674
5675 if ((network->ssid_len != match->network->ssid_len) ||
5676 memcmp(network->ssid, match->network->ssid,
5677 network->ssid_len)) {
5678 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of non-network ESSID.\n",
5679 network->ssid_len, network->ssid,
5680 network->bssid);
5681 return 0;
5682 }
5683 } else {
5684
5685
5686 if ((priv->config & CFG_STATIC_ESSID) &&
5687 ((network->ssid_len != priv->essid_len) ||
5688 memcmp(network->ssid, priv->essid,
5689 min(network->ssid_len, priv->essid_len)))) {
5690 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of ESSID mismatch: '%*pE'.\n",
5691 network->ssid_len, network->ssid,
5692 network->bssid, priv->essid_len,
5693 priv->essid);
5694 return 0;
5695 }
5696 }
5697
5698
5699
5700 if (match->network && match->network->stats.rssi > network->stats.rssi) {
5701 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because '%*pE (%pM)' has a stronger signal.\n",
5702 network->ssid_len, network->ssid,
5703 network->bssid, match->network->ssid_len,
5704 match->network->ssid, match->network->bssid);
5705 return 0;
5706 }
5707
5708
5709
5710 if (network->last_associate &&
5711 time_after(network->last_associate + (HZ * 3UL), jiffies)) {
5712 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of storming (%ums since last assoc attempt).\n",
5713 network->ssid_len, network->ssid,
5714 network->bssid,
5715 jiffies_to_msecs(jiffies -
5716 network->last_associate));
5717 return 0;
5718 }
5719
5720
5721 if (priv->ieee->scan_age != 0 &&
5722 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
5723 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of age: %ums.\n",
5724 network->ssid_len, network->ssid,
5725 network->bssid,
5726 jiffies_to_msecs(jiffies -
5727 network->last_scanned));
5728 return 0;
5729 }
5730
5731 if ((priv->config & CFG_STATIC_CHANNEL) &&
5732 (network->channel != priv->channel)) {
5733 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of channel mismatch: %d != %d.\n",
5734 network->ssid_len, network->ssid,
5735 network->bssid,
5736 network->channel, priv->channel);
5737 return 0;
5738 }
5739
5740
5741 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
5742 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
5743 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of privacy mismatch: %s != %s.\n",
5744 network->ssid_len, network->ssid,
5745 network->bssid,
5746 priv->capability & CAP_PRIVACY_ON ? "on" :
5747 "off",
5748 network->capability &
5749 WLAN_CAPABILITY_PRIVACY ? "on" : "off");
5750 return 0;
5751 }
5752
5753 if ((priv->config & CFG_STATIC_BSSID) &&
5754 !ether_addr_equal(network->bssid, priv->bssid)) {
5755 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of BSSID mismatch: %pM.\n",
5756 network->ssid_len, network->ssid,
5757 network->bssid, priv->bssid);
5758 return 0;
5759 }
5760
5761
5762 if (!libipw_is_valid_mode(priv->ieee, network->mode)) {
5763 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of invalid frequency/mode combination.\n",
5764 network->ssid_len, network->ssid,
5765 network->bssid);
5766 return 0;
5767 }
5768
5769
5770 if (!libipw_is_valid_channel(priv->ieee, network->channel)) {
5771 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of invalid channel in current GEO\n",
5772 network->ssid_len, network->ssid,
5773 network->bssid);
5774 return 0;
5775 }
5776
5777
5778
5779 if (!ipw_compatible_rates(priv, network, &rates)) {
5780 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because configured rate mask excludes AP mandatory rate.\n",
5781 network->ssid_len, network->ssid,
5782 network->bssid);
5783 return 0;
5784 }
5785
5786 if (rates.num_rates == 0) {
5787 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of no compatible rates.\n",
5788 network->ssid_len, network->ssid,
5789 network->bssid);
5790 return 0;
5791 }
5792
5793
5794
5795
5796
5797
5798 ipw_copy_rates(&match->rates, &rates);
5799 match->network = network;
5800
5801 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' is a viable match.\n",
5802 network->ssid_len, network->ssid, network->bssid);
5803
5804 return 1;
5805}
5806
5807static void ipw_adhoc_create(struct ipw_priv *priv,
5808 struct libipw_network *network)
5809{
5810 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
5811 int i;
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825 switch (libipw_is_valid_channel(priv->ieee, priv->channel)) {
5826 case LIBIPW_52GHZ_BAND:
5827 network->mode = IEEE_A;
5828 i = libipw_channel_to_index(priv->ieee, priv->channel);
5829 BUG_ON(i == -1);
5830 if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY) {
5831 IPW_WARNING("Overriding invalid channel\n");
5832 priv->channel = geo->a[0].channel;
5833 }
5834 break;
5835
5836 case LIBIPW_24GHZ_BAND:
5837 if (priv->ieee->mode & IEEE_G)
5838 network->mode = IEEE_G;
5839 else
5840 network->mode = IEEE_B;
5841 i = libipw_channel_to_index(priv->ieee, priv->channel);
5842 BUG_ON(i == -1);
5843 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) {
5844 IPW_WARNING("Overriding invalid channel\n");
5845 priv->channel = geo->bg[0].channel;
5846 }
5847 break;
5848
5849 default:
5850 IPW_WARNING("Overriding invalid channel\n");
5851 if (priv->ieee->mode & IEEE_A) {
5852 network->mode = IEEE_A;
5853 priv->channel = geo->a[0].channel;
5854 } else if (priv->ieee->mode & IEEE_G) {
5855 network->mode = IEEE_G;
5856 priv->channel = geo->bg[0].channel;
5857 } else {
5858 network->mode = IEEE_B;
5859 priv->channel = geo->bg[0].channel;
5860 }
5861 break;
5862 }
5863
5864 network->channel = priv->channel;
5865 priv->config |= CFG_ADHOC_PERSIST;
5866 ipw_create_bssid(priv, network->bssid);
5867 network->ssid_len = priv->essid_len;
5868 memcpy(network->ssid, priv->essid, priv->essid_len);
5869 memset(&network->stats, 0, sizeof(network->stats));
5870 network->capability = WLAN_CAPABILITY_IBSS;
5871 if (!(priv->config & CFG_PREAMBLE_LONG))
5872 network->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
5873 if (priv->capability & CAP_PRIVACY_ON)
5874 network->capability |= WLAN_CAPABILITY_PRIVACY;
5875 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH);
5876 memcpy(network->rates, priv->rates.supported_rates, network->rates_len);
5877 network->rates_ex_len = priv->rates.num_rates - network->rates_len;
5878 memcpy(network->rates_ex,
5879 &priv->rates.supported_rates[network->rates_len],
5880 network->rates_ex_len);
5881 network->last_scanned = 0;
5882 network->flags = 0;
5883 network->last_associate = 0;
5884 network->time_stamp[0] = 0;
5885 network->time_stamp[1] = 0;
5886 network->beacon_interval = 100;
5887 network->listen_interval = 10;
5888 network->atim_window = 0;
5889 network->wpa_ie_len = 0;
5890 network->rsn_ie_len = 0;
5891}
5892
5893static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)
5894{
5895 struct ipw_tgi_tx_key key;
5896
5897 if (!(priv->ieee->sec.flags & (1 << index)))
5898 return;
5899
5900 key.key_id = index;
5901 memcpy(key.key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);
5902 key.security_type = type;
5903 key.station_index = 0;
5904 key.flags = 0;
5905
5906 key.tx_counter[0] = cpu_to_le32(0);
5907 key.tx_counter[1] = cpu_to_le32(0);
5908
5909 ipw_send_cmd_pdu(priv, IPW_CMD_TGI_TX_KEY, sizeof(key), &key);
5910}
5911
5912static void ipw_send_wep_keys(struct ipw_priv *priv, int type)
5913{
5914 struct ipw_wep_key key;
5915 int i;
5916
5917 key.cmd_id = DINO_CMD_WEP_KEY;
5918 key.seq_num = 0;
5919
5920
5921
5922 for (i = 0; i < 4; i++) {
5923 key.key_index = i | type;
5924 if (!(priv->ieee->sec.flags & (1 << i))) {
5925 key.key_size = 0;
5926 continue;
5927 }
5928
5929 key.key_size = priv->ieee->sec.key_sizes[i];
5930 memcpy(key.key, priv->ieee->sec.keys[i], key.key_size);
5931
5932 ipw_send_cmd_pdu(priv, IPW_CMD_WEP_KEY, sizeof(key), &key);
5933 }
5934}
5935
5936static void ipw_set_hw_decrypt_unicast(struct ipw_priv *priv, int level)
5937{
5938 if (priv->ieee->host_encrypt)
5939 return;
5940
5941 switch (level) {
5942 case SEC_LEVEL_3:
5943 priv->sys_config.disable_unicast_decryption = 0;
5944 priv->ieee->host_decrypt = 0;
5945 break;
5946 case SEC_LEVEL_2:
5947 priv->sys_config.disable_unicast_decryption = 1;
5948 priv->ieee->host_decrypt = 1;
5949 break;
5950 case SEC_LEVEL_1:
5951 priv->sys_config.disable_unicast_decryption = 0;
5952 priv->ieee->host_decrypt = 0;
5953 break;
5954 case SEC_LEVEL_0:
5955 priv->sys_config.disable_unicast_decryption = 1;
5956 break;
5957 default:
5958 break;
5959 }
5960}
5961
5962static void ipw_set_hw_decrypt_multicast(struct ipw_priv *priv, int level)
5963{
5964 if (priv->ieee->host_encrypt)
5965 return;
5966
5967 switch (level) {
5968 case SEC_LEVEL_3:
5969 priv->sys_config.disable_multicast_decryption = 0;
5970 break;
5971 case SEC_LEVEL_2:
5972 priv->sys_config.disable_multicast_decryption = 1;
5973 break;
5974 case SEC_LEVEL_1:
5975 priv->sys_config.disable_multicast_decryption = 0;
5976 break;
5977 case SEC_LEVEL_0:
5978 priv->sys_config.disable_multicast_decryption = 1;
5979 break;
5980 default:
5981 break;
5982 }
5983}
5984
5985static void ipw_set_hwcrypto_keys(struct ipw_priv *priv)
5986{
5987 switch (priv->ieee->sec.level) {
5988 case SEC_LEVEL_3:
5989 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
5990 ipw_send_tgi_tx_key(priv,
5991 DCT_FLAG_EXT_SECURITY_CCM,
5992 priv->ieee->sec.active_key);
5993
5994 if (!priv->ieee->host_mc_decrypt)
5995 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);
5996 break;
5997 case SEC_LEVEL_2:
5998 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
5999 ipw_send_tgi_tx_key(priv,
6000 DCT_FLAG_EXT_SECURITY_TKIP,
6001 priv->ieee->sec.active_key);
6002 break;
6003 case SEC_LEVEL_1:
6004 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
6005 ipw_set_hw_decrypt_unicast(priv, priv->ieee->sec.level);
6006 ipw_set_hw_decrypt_multicast(priv, priv->ieee->sec.level);
6007 break;
6008 case SEC_LEVEL_0:
6009 default:
6010 break;
6011 }
6012}
6013
6014static void ipw_adhoc_check(void *data)
6015{
6016 struct ipw_priv *priv = data;
6017
6018 if (priv->missed_adhoc_beacons++ > priv->disassociate_threshold &&
6019 !(priv->config & CFG_ADHOC_PERSIST)) {
6020 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
6021 IPW_DL_STATE | IPW_DL_ASSOC,
6022 "Missed beacon: %d - disassociate\n",
6023 priv->missed_adhoc_beacons);
6024 ipw_remove_current_network(priv);
6025 ipw_disassociate(priv);
6026 return;
6027 }
6028
6029 schedule_delayed_work(&priv->adhoc_check,
6030 le16_to_cpu(priv->assoc_request.beacon_interval));
6031}
6032
6033static void ipw_bg_adhoc_check(struct work_struct *work)
6034{
6035 struct ipw_priv *priv =
6036 container_of(work, struct ipw_priv, adhoc_check.work);
6037 mutex_lock(&priv->mutex);
6038 ipw_adhoc_check(priv);
6039 mutex_unlock(&priv->mutex);
6040}
6041
6042static void ipw_debug_config(struct ipw_priv *priv)
6043{
6044 IPW_DEBUG_INFO("Scan completed, no valid APs matched "
6045 "[CFG 0x%08X]\n", priv->config);
6046 if (priv->config & CFG_STATIC_CHANNEL)
6047 IPW_DEBUG_INFO("Channel locked to %d\n", priv->channel);
6048 else
6049 IPW_DEBUG_INFO("Channel unlocked.\n");
6050 if (priv->config & CFG_STATIC_ESSID)
6051 IPW_DEBUG_INFO("ESSID locked to '%*pE'\n",
6052 priv->essid_len, priv->essid);
6053 else
6054 IPW_DEBUG_INFO("ESSID unlocked.\n");
6055 if (priv->config & CFG_STATIC_BSSID)
6056 IPW_DEBUG_INFO("BSSID locked to %pM\n", priv->bssid);
6057 else
6058 IPW_DEBUG_INFO("BSSID unlocked.\n");
6059 if (priv->capability & CAP_PRIVACY_ON)
6060 IPW_DEBUG_INFO("PRIVACY on\n");
6061 else
6062 IPW_DEBUG_INFO("PRIVACY off\n");
6063 IPW_DEBUG_INFO("RATE MASK: 0x%08X\n", priv->rates_mask);
6064}
6065
6066static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
6067{
6068
6069 struct ipw_fixed_rate fr;
6070 u32 reg;
6071 u16 mask = 0;
6072 u16 new_tx_rates = priv->rates_mask;
6073
6074
6075
6076
6077 switch (priv->ieee->freq_band) {
6078 case LIBIPW_52GHZ_BAND:
6079
6080 if (priv->rates_mask & ~LIBIPW_OFDM_RATES_MASK) {
6081
6082 IPW_DEBUG_WX
6083 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
6084 new_tx_rates = 0;
6085 break;
6086 }
6087
6088 new_tx_rates >>= LIBIPW_OFDM_SHIFT_MASK_A;
6089 break;
6090
6091 default:
6092
6093 if (mode == IEEE_B) {
6094 if (new_tx_rates & ~LIBIPW_CCK_RATES_MASK) {
6095
6096 IPW_DEBUG_WX
6097 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
6098 new_tx_rates = 0;
6099 }
6100 break;
6101 }
6102
6103
6104 if (new_tx_rates & ~(LIBIPW_CCK_RATES_MASK |
6105 LIBIPW_OFDM_RATES_MASK)) {
6106
6107 IPW_DEBUG_WX
6108 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
6109 new_tx_rates = 0;
6110 break;
6111 }
6112
6113 if (LIBIPW_OFDM_RATE_6MB_MASK & new_tx_rates) {
6114 mask |= (LIBIPW_OFDM_RATE_6MB_MASK >> 1);
6115 new_tx_rates &= ~LIBIPW_OFDM_RATE_6MB_MASK;
6116 }
6117
6118 if (LIBIPW_OFDM_RATE_9MB_MASK & new_tx_rates) {
6119 mask |= (LIBIPW_OFDM_RATE_9MB_MASK >> 1);
6120 new_tx_rates &= ~LIBIPW_OFDM_RATE_9MB_MASK;
6121 }
6122
6123 if (LIBIPW_OFDM_RATE_12MB_MASK & new_tx_rates) {
6124 mask |= (LIBIPW_OFDM_RATE_12MB_MASK >> 1);
6125 new_tx_rates &= ~LIBIPW_OFDM_RATE_12MB_MASK;
6126 }
6127
6128 new_tx_rates |= mask;
6129 break;
6130 }
6131
6132 fr.tx_rates = cpu_to_le16(new_tx_rates);
6133
6134 reg = ipw_read32(priv, IPW_MEM_FIXED_OVERRIDE);
6135 ipw_write_reg32(priv, reg, *(u32 *) & fr);
6136}
6137
6138static void ipw_abort_scan(struct ipw_priv *priv)
6139{
6140 int err;
6141
6142 if (priv->status & STATUS_SCAN_ABORTING) {
6143 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");
6144 return;
6145 }
6146 priv->status |= STATUS_SCAN_ABORTING;
6147
6148 err = ipw_send_scan_abort(priv);
6149 if (err)
6150 IPW_DEBUG_HC("Request to abort scan failed.\n");
6151}
6152
6153static void ipw_add_scan_channels(struct ipw_priv *priv,
6154 struct ipw_scan_request_ext *scan,
6155 int scan_type)
6156{
6157 int channel_index = 0;
6158 const struct libipw_geo *geo;
6159 int i;
6160
6161 geo = libipw_get_geo(priv->ieee);
6162
6163 if (priv->ieee->freq_band & LIBIPW_52GHZ_BAND) {
6164 int start = channel_index;
6165 for (i = 0; i < geo->a_channels; i++) {
6166 if ((priv->status & STATUS_ASSOCIATED) &&
6167 geo->a[i].channel == priv->channel)
6168 continue;
6169 channel_index++;
6170 scan->channels_list[channel_index] = geo->a[i].channel;
6171 ipw_set_scan_type(scan, channel_index,
6172 geo->a[i].
6173 flags & LIBIPW_CH_PASSIVE_ONLY ?
6174 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN :
6175 scan_type);
6176 }
6177
6178 if (start != channel_index) {
6179 scan->channels_list[start] = (u8) (IPW_A_MODE << 6) |
6180 (channel_index - start);
6181 channel_index++;
6182 }
6183 }
6184
6185 if (priv->ieee->freq_band & LIBIPW_24GHZ_BAND) {
6186 int start = channel_index;
6187 if (priv->config & CFG_SPEED_SCAN) {
6188 int index;
6189 u8 channels[LIBIPW_24GHZ_CHANNELS] = {
6190
6191 [0] = 0
6192 };
6193
6194 u8 channel;
6195 while (channel_index < IPW_SCAN_CHANNELS - 1) {
6196 channel =
6197 priv->speed_scan[priv->speed_scan_pos];
6198 if (channel == 0) {
6199 priv->speed_scan_pos = 0;
6200 channel = priv->speed_scan[0];
6201 }
6202 if ((priv->status & STATUS_ASSOCIATED) &&
6203 channel == priv->channel) {
6204 priv->speed_scan_pos++;
6205 continue;
6206 }
6207
6208
6209
6210
6211
6212
6213 if (channels[channel - 1] != 0)
6214 break;
6215
6216 channels[channel - 1] = 1;
6217 priv->speed_scan_pos++;
6218 channel_index++;
6219 scan->channels_list[channel_index] = channel;
6220 index =
6221 libipw_channel_to_index(priv->ieee, channel);
6222 ipw_set_scan_type(scan, channel_index,
6223 geo->bg[index].
6224 flags &
6225 LIBIPW_CH_PASSIVE_ONLY ?
6226 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
6227 : scan_type);
6228 }
6229 } else {
6230 for (i = 0; i < geo->bg_channels; i++) {
6231 if ((priv->status & STATUS_ASSOCIATED) &&
6232 geo->bg[i].channel == priv->channel)
6233 continue;
6234 channel_index++;
6235 scan->channels_list[channel_index] =
6236 geo->bg[i].channel;
6237 ipw_set_scan_type(scan, channel_index,
6238 geo->bg[i].
6239 flags &
6240 LIBIPW_CH_PASSIVE_ONLY ?
6241 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
6242 : scan_type);
6243 }
6244 }
6245
6246 if (start != channel_index) {
6247 scan->channels_list[start] = (u8) (IPW_B_MODE << 6) |
6248 (channel_index - start);
6249 }
6250 }
6251}
6252
6253static int ipw_passive_dwell_time(struct ipw_priv *priv)
6254{
6255
6256
6257
6258
6259
6260 if (priv->status & STATUS_ASSOCIATED
6261 && priv->assoc_network->beacon_interval > 10)
6262 return priv->assoc_network->beacon_interval - 10;
6263 else
6264 return 120;
6265}
6266
6267static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)
6268{
6269 struct ipw_scan_request_ext scan;
6270 int err = 0, scan_type;
6271
6272 if (!(priv->status & STATUS_INIT) ||
6273 (priv->status & STATUS_EXIT_PENDING))
6274 return 0;
6275
6276 mutex_lock(&priv->mutex);
6277
6278 if (direct && (priv->direct_scan_ssid_len == 0)) {
6279 IPW_DEBUG_HC("Direct scan requested but no SSID to scan for\n");
6280 priv->status &= ~STATUS_DIRECT_SCAN_PENDING;
6281 goto done;
6282 }
6283
6284 if (priv->status & STATUS_SCANNING) {
6285 IPW_DEBUG_HC("Concurrent scan requested. Queuing.\n");
6286 priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING :
6287 STATUS_SCAN_PENDING;
6288 goto done;
6289 }
6290
6291 if (!(priv->status & STATUS_SCAN_FORCED) &&
6292 priv->status & STATUS_SCAN_ABORTING) {
6293 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
6294 priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING :
6295 STATUS_SCAN_PENDING;
6296 goto done;
6297 }
6298
6299 if (priv->status & STATUS_RF_KILL_MASK) {
6300 IPW_DEBUG_HC("Queuing scan due to RF Kill activation\n");
6301 priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING :
6302 STATUS_SCAN_PENDING;
6303 goto done;
6304 }
6305
6306 memset(&scan, 0, sizeof(scan));
6307 scan.full_scan_index = cpu_to_le32(libipw_get_scans(priv->ieee));
6308
6309 if (type == IW_SCAN_TYPE_PASSIVE) {
6310 IPW_DEBUG_WX("use passive scanning\n");
6311 scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN;
6312 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
6313 cpu_to_le16(ipw_passive_dwell_time(priv));
6314 ipw_add_scan_channels(priv, &scan, scan_type);
6315 goto send_request;
6316 }
6317
6318
6319 if (priv->config & CFG_SPEED_SCAN)
6320 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
6321 cpu_to_le16(30);
6322 else
6323 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
6324 cpu_to_le16(20);
6325
6326 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
6327 cpu_to_le16(20);
6328
6329 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
6330 cpu_to_le16(ipw_passive_dwell_time(priv));
6331 scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
6332
6333#ifdef CONFIG_IPW2200_MONITOR
6334 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
6335 u8 channel;
6336 u8 band = 0;
6337
6338 switch (libipw_is_valid_channel(priv->ieee, priv->channel)) {
6339 case LIBIPW_52GHZ_BAND:
6340 band = (u8) (IPW_A_MODE << 6) | 1;
6341 channel = priv->channel;
6342 break;
6343
6344 case LIBIPW_24GHZ_BAND:
6345 band = (u8) (IPW_B_MODE << 6) | 1;
6346 channel = priv->channel;
6347 break;
6348
6349 default:
6350 band = (u8) (IPW_B_MODE << 6) | 1;
6351 channel = 9;
6352 break;
6353 }
6354
6355 scan.channels_list[0] = band;
6356 scan.channels_list[1] = channel;
6357 ipw_set_scan_type(&scan, 1, IPW_SCAN_PASSIVE_FULL_DWELL_SCAN);
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
6368 cpu_to_le16(2000);
6369 } else {
6370#endif
6371
6372
6373
6374 if (direct) {
6375 err = ipw_send_ssid(priv, priv->direct_scan_ssid,
6376 priv->direct_scan_ssid_len);
6377 if (err) {
6378 IPW_DEBUG_HC("Attempt to send SSID command "
6379 "failed\n");
6380 goto done;
6381 }
6382
6383 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
6384 } else if ((priv->status & STATUS_ROAMING)
6385 || (!(priv->status & STATUS_ASSOCIATED)
6386 && (priv->config & CFG_STATIC_ESSID)
6387 && (le32_to_cpu(scan.full_scan_index) % 2))) {
6388 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
6389 if (err) {
6390 IPW_DEBUG_HC("Attempt to send SSID command "
6391 "failed.\n");
6392 goto done;
6393 }
6394
6395 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
6396 } else
6397 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;
6398
6399 ipw_add_scan_channels(priv, &scan, scan_type);
6400#ifdef CONFIG_IPW2200_MONITOR
6401 }
6402#endif
6403
6404send_request:
6405 err = ipw_send_scan_request_ext(priv, &scan);
6406 if (err) {
6407 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
6408 goto done;
6409 }
6410
6411 priv->status |= STATUS_SCANNING;
6412 if (direct) {
6413 priv->status &= ~STATUS_DIRECT_SCAN_PENDING;
6414 priv->direct_scan_ssid_len = 0;
6415 } else
6416 priv->status &= ~STATUS_SCAN_PENDING;
6417
6418 schedule_delayed_work(&priv->scan_check, IPW_SCAN_CHECK_WATCHDOG);
6419done:
6420 mutex_unlock(&priv->mutex);
6421 return err;
6422}
6423
6424static void ipw_request_passive_scan(struct work_struct *work)
6425{
6426 struct ipw_priv *priv =
6427 container_of(work, struct ipw_priv, request_passive_scan.work);
6428 ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE, 0);
6429}
6430
6431static void ipw_request_scan(struct work_struct *work)
6432{
6433 struct ipw_priv *priv =
6434 container_of(work, struct ipw_priv, request_scan.work);
6435 ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE, 0);
6436}
6437
6438static void ipw_request_direct_scan(struct work_struct *work)
6439{
6440 struct ipw_priv *priv =
6441 container_of(work, struct ipw_priv, request_direct_scan.work);
6442 ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE, 1);
6443}
6444
6445static void ipw_bg_abort_scan(struct work_struct *work)
6446{
6447 struct ipw_priv *priv =
6448 container_of(work, struct ipw_priv, abort_scan);
6449 mutex_lock(&priv->mutex);
6450 ipw_abort_scan(priv);
6451 mutex_unlock(&priv->mutex);
6452}
6453
6454static int ipw_wpa_enable(struct ipw_priv *priv, int value)
6455{
6456
6457
6458 priv->ieee->wpa_enabled = value;
6459 return 0;
6460}
6461
6462static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
6463{
6464 struct libipw_device *ieee = priv->ieee;
6465 struct libipw_security sec = {
6466 .flags = SEC_AUTH_MODE,
6467 };
6468 int ret = 0;
6469
6470 if (value & IW_AUTH_ALG_SHARED_KEY) {
6471 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
6472 ieee->open_wep = 0;
6473 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
6474 sec.auth_mode = WLAN_AUTH_OPEN;
6475 ieee->open_wep = 1;
6476 } else if (value & IW_AUTH_ALG_LEAP) {
6477 sec.auth_mode = WLAN_AUTH_LEAP;
6478 ieee->open_wep = 1;
6479 } else
6480 return -EINVAL;
6481
6482 if (ieee->set_security)
6483 ieee->set_security(ieee->dev, &sec);
6484 else
6485 ret = -EOPNOTSUPP;
6486
6487 return ret;
6488}
6489
6490static void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie,
6491 int wpa_ie_len)
6492{
6493
6494 ipw_wpa_enable(priv, 1);
6495}
6496
6497static int ipw_set_rsn_capa(struct ipw_priv *priv,
6498 char *capabilities, int length)
6499{
6500 IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
6501
6502 return ipw_send_cmd_pdu(priv, IPW_CMD_RSN_CAPABILITIES, length,
6503 capabilities);
6504}
6505
6506
6507
6508
6509
6510
6511static int ipw_wx_set_genie(struct net_device *dev,
6512 struct iw_request_info *info,
6513 union iwreq_data *wrqu, char *extra)
6514{
6515 struct ipw_priv *priv = libipw_priv(dev);
6516 struct libipw_device *ieee = priv->ieee;
6517 u8 *buf;
6518 int err = 0;
6519
6520 if (wrqu->data.length > MAX_WPA_IE_LEN ||
6521 (wrqu->data.length && extra == NULL))
6522 return -EINVAL;
6523
6524 if (wrqu->data.length) {
6525 buf = kmemdup(extra, wrqu->data.length, GFP_KERNEL);
6526 if (buf == NULL) {
6527 err = -ENOMEM;
6528 goto out;
6529 }
6530
6531 kfree(ieee->wpa_ie);
6532 ieee->wpa_ie = buf;
6533 ieee->wpa_ie_len = wrqu->data.length;
6534 } else {
6535 kfree(ieee->wpa_ie);
6536 ieee->wpa_ie = NULL;
6537 ieee->wpa_ie_len = 0;
6538 }
6539
6540 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
6541 out:
6542 return err;
6543}
6544
6545
6546static int ipw_wx_get_genie(struct net_device *dev,
6547 struct iw_request_info *info,
6548 union iwreq_data *wrqu, char *extra)
6549{
6550 struct ipw_priv *priv = libipw_priv(dev);
6551 struct libipw_device *ieee = priv->ieee;
6552 int err = 0;
6553
6554 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
6555 wrqu->data.length = 0;
6556 goto out;
6557 }
6558
6559 if (wrqu->data.length < ieee->wpa_ie_len) {
6560 err = -E2BIG;
6561 goto out;
6562 }
6563
6564 wrqu->data.length = ieee->wpa_ie_len;
6565 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
6566
6567 out:
6568 return err;
6569}
6570
6571static int wext_cipher2level(int cipher)
6572{
6573 switch (cipher) {
6574 case IW_AUTH_CIPHER_NONE:
6575 return SEC_LEVEL_0;
6576 case IW_AUTH_CIPHER_WEP40:
6577 case IW_AUTH_CIPHER_WEP104:
6578 return SEC_LEVEL_1;
6579 case IW_AUTH_CIPHER_TKIP:
6580 return SEC_LEVEL_2;
6581 case IW_AUTH_CIPHER_CCMP:
6582 return SEC_LEVEL_3;
6583 default:
6584 return -1;
6585 }
6586}
6587
6588
6589static int ipw_wx_set_auth(struct net_device *dev,
6590 struct iw_request_info *info,
6591 union iwreq_data *wrqu, char *extra)
6592{
6593 struct ipw_priv *priv = libipw_priv(dev);
6594 struct libipw_device *ieee = priv->ieee;
6595 struct iw_param *param = &wrqu->param;
6596 struct lib80211_crypt_data *crypt;
6597 unsigned long flags;
6598 int ret = 0;
6599
6600 switch (param->flags & IW_AUTH_INDEX) {
6601 case IW_AUTH_WPA_VERSION:
6602 break;
6603 case IW_AUTH_CIPHER_PAIRWISE:
6604 ipw_set_hw_decrypt_unicast(priv,
6605 wext_cipher2level(param->value));
6606 break;
6607 case IW_AUTH_CIPHER_GROUP:
6608 ipw_set_hw_decrypt_multicast(priv,
6609 wext_cipher2level(param->value));
6610 break;
6611 case IW_AUTH_KEY_MGMT:
6612
6613
6614
6615 break;
6616
6617 case IW_AUTH_TKIP_COUNTERMEASURES:
6618 crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
6619 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
6620 break;
6621
6622 flags = crypt->ops->get_flags(crypt->priv);
6623
6624 if (param->value)
6625 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6626 else
6627 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6628
6629 crypt->ops->set_flags(flags, crypt->priv);
6630
6631 break;
6632
6633 case IW_AUTH_DROP_UNENCRYPTED:{
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645 struct libipw_security sec = {
6646 .flags = SEC_ENABLED,
6647 .enabled = param->value,
6648 };
6649 priv->ieee->drop_unencrypted = param->value;
6650
6651
6652
6653 if (!param->value) {
6654 sec.flags |= SEC_LEVEL;
6655 sec.level = SEC_LEVEL_0;
6656 } else {
6657 sec.flags |= SEC_LEVEL;
6658 sec.level = SEC_LEVEL_1;
6659 }
6660 if (priv->ieee->set_security)
6661 priv->ieee->set_security(priv->ieee->dev, &sec);
6662 break;
6663 }
6664
6665 case IW_AUTH_80211_AUTH_ALG:
6666 ret = ipw_wpa_set_auth_algs(priv, param->value);
6667 break;
6668
6669 case IW_AUTH_WPA_ENABLED:
6670 ret = ipw_wpa_enable(priv, param->value);
6671 ipw_disassociate(priv);
6672 break;
6673
6674 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6675 ieee->ieee802_1x = param->value;
6676 break;
6677
6678 case IW_AUTH_PRIVACY_INVOKED:
6679 ieee->privacy_invoked = param->value;
6680 break;
6681
6682 default:
6683 return -EOPNOTSUPP;
6684 }
6685 return ret;
6686}
6687
6688
6689static int ipw_wx_get_auth(struct net_device *dev,
6690 struct iw_request_info *info,
6691 union iwreq_data *wrqu, char *extra)
6692{
6693 struct ipw_priv *priv = libipw_priv(dev);
6694 struct libipw_device *ieee = priv->ieee;
6695 struct lib80211_crypt_data *crypt;
6696 struct iw_param *param = &wrqu->param;
6697
6698 switch (param->flags & IW_AUTH_INDEX) {
6699 case IW_AUTH_WPA_VERSION:
6700 case IW_AUTH_CIPHER_PAIRWISE:
6701 case IW_AUTH_CIPHER_GROUP:
6702 case IW_AUTH_KEY_MGMT:
6703
6704
6705
6706 return -EOPNOTSUPP;
6707
6708 case IW_AUTH_TKIP_COUNTERMEASURES:
6709 crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
6710 if (!crypt || !crypt->ops->get_flags)
6711 break;
6712
6713 param->value = (crypt->ops->get_flags(crypt->priv) &
6714 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
6715
6716 break;
6717
6718 case IW_AUTH_DROP_UNENCRYPTED:
6719 param->value = ieee->drop_unencrypted;
6720 break;
6721
6722 case IW_AUTH_80211_AUTH_ALG:
6723 param->value = ieee->sec.auth_mode;
6724 break;
6725
6726 case IW_AUTH_WPA_ENABLED:
6727 param->value = ieee->wpa_enabled;
6728 break;
6729
6730 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6731 param->value = ieee->ieee802_1x;
6732 break;
6733
6734 case IW_AUTH_ROAMING_CONTROL:
6735 case IW_AUTH_PRIVACY_INVOKED:
6736 param->value = ieee->privacy_invoked;
6737 break;
6738
6739 default:
6740 return -EOPNOTSUPP;
6741 }
6742 return 0;
6743}
6744
6745
6746static int ipw_wx_set_encodeext(struct net_device *dev,
6747 struct iw_request_info *info,
6748 union iwreq_data *wrqu, char *extra)
6749{
6750 struct ipw_priv *priv = libipw_priv(dev);
6751 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6752
6753 if (hwcrypto) {
6754 if (ext->alg == IW_ENCODE_ALG_TKIP) {
6755
6756
6757 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
6758 priv->ieee->host_mc_decrypt = 1;
6759 else {
6760 priv->ieee->host_encrypt = 0;
6761 priv->ieee->host_encrypt_msdu = 1;
6762 priv->ieee->host_decrypt = 1;
6763 }
6764 } else {
6765 priv->ieee->host_encrypt = 0;
6766 priv->ieee->host_encrypt_msdu = 0;
6767 priv->ieee->host_decrypt = 0;
6768 priv->ieee->host_mc_decrypt = 0;
6769 }
6770 }
6771
6772 return libipw_wx_set_encodeext(priv->ieee, info, wrqu, extra);
6773}
6774
6775
6776static int ipw_wx_get_encodeext(struct net_device *dev,
6777 struct iw_request_info *info,
6778 union iwreq_data *wrqu, char *extra)
6779{
6780 struct ipw_priv *priv = libipw_priv(dev);
6781 return libipw_wx_get_encodeext(priv->ieee, info, wrqu, extra);
6782}
6783
6784
6785static int ipw_wx_set_mlme(struct net_device *dev,
6786 struct iw_request_info *info,
6787 union iwreq_data *wrqu, char *extra)
6788{
6789 struct ipw_priv *priv = libipw_priv(dev);
6790 struct iw_mlme *mlme = (struct iw_mlme *)extra;
6791
6792 switch (mlme->cmd) {
6793 case IW_MLME_DEAUTH:
6794
6795 break;
6796
6797 case IW_MLME_DISASSOC:
6798 ipw_disassociate(priv);
6799 break;
6800
6801 default:
6802 return -EOPNOTSUPP;
6803 }
6804 return 0;
6805}
6806
6807#ifdef CONFIG_IPW2200_QOS
6808
6809
6810
6811
6812
6813
6814static u8 ipw_qos_current_mode(struct ipw_priv * priv)
6815{
6816 u8 mode = 0;
6817
6818 if (priv->status & STATUS_ASSOCIATED) {
6819 unsigned long flags;
6820
6821 spin_lock_irqsave(&priv->ieee->lock, flags);
6822 mode = priv->assoc_network->mode;
6823 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6824 } else {
6825 mode = priv->ieee->mode;
6826 }
6827 IPW_DEBUG_QOS("QoS network/card mode %d\n", mode);
6828 return mode;
6829}
6830
6831
6832
6833
6834static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
6835 int active_network,
6836 struct libipw_network *network)
6837{
6838 u32 size = sizeof(struct libipw_qos_parameters);
6839
6840 if (network->capability & WLAN_CAPABILITY_IBSS)
6841 network->qos_data.active = network->qos_data.supported;
6842
6843 if (network->flags & NETWORK_HAS_QOS_MASK) {
6844 if (active_network &&
6845 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
6846 network->qos_data.active = network->qos_data.supported;
6847
6848 if ((network->qos_data.active == 1) && (active_network == 1) &&
6849 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
6850 (network->qos_data.old_param_count !=
6851 network->qos_data.param_count)) {
6852 network->qos_data.old_param_count =
6853 network->qos_data.param_count;
6854 schedule_work(&priv->qos_activate);
6855 IPW_DEBUG_QOS("QoS parameters change call "
6856 "qos_activate\n");
6857 }
6858 } else {
6859 if ((priv->ieee->mode == IEEE_B) || (network->mode == IEEE_B))
6860 memcpy(&network->qos_data.parameters,
6861 &def_parameters_CCK, size);
6862 else
6863 memcpy(&network->qos_data.parameters,
6864 &def_parameters_OFDM, size);
6865
6866 if ((network->qos_data.active == 1) && (active_network == 1)) {
6867 IPW_DEBUG_QOS("QoS was disabled call qos_activate\n");
6868 schedule_work(&priv->qos_activate);
6869 }
6870
6871 network->qos_data.active = 0;
6872 network->qos_data.supported = 0;
6873 }
6874 if ((priv->status & STATUS_ASSOCIATED) &&
6875 (priv->ieee->iw_mode == IW_MODE_ADHOC) && (active_network == 0)) {
6876 if (!ether_addr_equal(network->bssid, priv->bssid))
6877 if (network->capability & WLAN_CAPABILITY_IBSS)
6878 if ((network->ssid_len ==
6879 priv->assoc_network->ssid_len) &&
6880 !memcmp(network->ssid,
6881 priv->assoc_network->ssid,
6882 network->ssid_len)) {
6883 schedule_work(&priv->merge_networks);
6884 }
6885 }
6886
6887 return 0;
6888}
6889
6890
6891
6892
6893
6894static int ipw_qos_activate(struct ipw_priv *priv,
6895 struct libipw_qos_data *qos_network_data)
6896{
6897 int err;
6898 struct libipw_qos_parameters qos_parameters[QOS_QOS_SETS];
6899 struct libipw_qos_parameters *active_one = NULL;
6900 u32 size = sizeof(struct libipw_qos_parameters);
6901 u32 burst_duration;
6902 int i;
6903 u8 type;
6904
6905 type = ipw_qos_current_mode(priv);
6906
6907 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_CCK]);
6908 memcpy(active_one, priv->qos_data.def_qos_parm_CCK, size);
6909 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_OFDM]);
6910 memcpy(active_one, priv->qos_data.def_qos_parm_OFDM, size);
6911
6912 if (qos_network_data == NULL) {
6913 if (type == IEEE_B) {
6914 IPW_DEBUG_QOS("QoS activate network mode %d\n", type);
6915 active_one = &def_parameters_CCK;
6916 } else
6917 active_one = &def_parameters_OFDM;
6918
6919 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6920 burst_duration = ipw_qos_get_burst_duration(priv);
6921 for (i = 0; i < QOS_QUEUE_NUM; i++)
6922 qos_parameters[QOS_PARAM_SET_ACTIVE].tx_op_limit[i] =
6923 cpu_to_le16(burst_duration);
6924 } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
6925 if (type == IEEE_B) {
6926 IPW_DEBUG_QOS("QoS activate IBSS network mode %d\n",
6927 type);
6928 if (priv->qos_data.qos_enable == 0)
6929 active_one = &def_parameters_CCK;
6930 else
6931 active_one = priv->qos_data.def_qos_parm_CCK;
6932 } else {
6933 if (priv->qos_data.qos_enable == 0)
6934 active_one = &def_parameters_OFDM;
6935 else
6936 active_one = priv->qos_data.def_qos_parm_OFDM;
6937 }
6938 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6939 } else {
6940 unsigned long flags;
6941 int active;
6942
6943 spin_lock_irqsave(&priv->ieee->lock, flags);
6944 active_one = &(qos_network_data->parameters);
6945 qos_network_data->old_param_count =
6946 qos_network_data->param_count;
6947 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6948 active = qos_network_data->supported;
6949 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6950
6951 if (active == 0) {
6952 burst_duration = ipw_qos_get_burst_duration(priv);
6953 for (i = 0; i < QOS_QUEUE_NUM; i++)
6954 qos_parameters[QOS_PARAM_SET_ACTIVE].
6955 tx_op_limit[i] = cpu_to_le16(burst_duration);
6956 }
6957 }
6958
6959 IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n");
6960 err = ipw_send_qos_params_command(priv, &qos_parameters[0]);
6961 if (err)
6962 IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n");
6963
6964 return err;
6965}
6966
6967
6968
6969
6970static int ipw_qos_set_info_element(struct ipw_priv *priv)
6971{
6972 int ret = 0;
6973 struct libipw_qos_information_element qos_info;
6974
6975 if (priv == NULL)
6976 return -1;
6977
6978 qos_info.elementID = QOS_ELEMENT_ID;
6979 qos_info.length = sizeof(struct libipw_qos_information_element) - 2;
6980
6981 qos_info.version = QOS_VERSION_1;
6982 qos_info.ac_info = 0;
6983
6984 memcpy(qos_info.qui, qos_oui, QOS_OUI_LEN);
6985 qos_info.qui_type = QOS_OUI_TYPE;
6986 qos_info.qui_subtype = QOS_OUI_INFO_SUB_TYPE;
6987
6988 ret = ipw_send_qos_info_command(priv, &qos_info);
6989 if (ret != 0) {
6990 IPW_DEBUG_QOS("QoS error calling ipw_send_qos_info_command\n");
6991 }
6992 return ret;
6993}
6994
6995
6996
6997
6998static int ipw_qos_association(struct ipw_priv *priv,
6999 struct libipw_network *network)
7000{
7001 int err = 0;
7002 struct libipw_qos_data *qos_data = NULL;
7003 struct libipw_qos_data ibss_data = {
7004 .supported = 1,
7005 .active = 1,
7006 };
7007
7008 switch (priv->ieee->iw_mode) {
7009 case IW_MODE_ADHOC:
7010 BUG_ON(!(network->capability & WLAN_CAPABILITY_IBSS));
7011
7012 qos_data = &ibss_data;
7013 break;
7014
7015 case IW_MODE_INFRA:
7016 qos_data = &network->qos_data;
7017 break;
7018
7019 default:
7020 BUG();
7021 break;
7022 }
7023
7024 err = ipw_qos_activate(priv, qos_data);
7025 if (err) {
7026 priv->assoc_request.policy_support &= ~HC_QOS_SUPPORT_ASSOC;
7027 return err;
7028 }
7029
7030 if (priv->qos_data.qos_enable && qos_data->supported) {
7031 IPW_DEBUG_QOS("QoS will be enabled for this association\n");
7032 priv->assoc_request.policy_support |= HC_QOS_SUPPORT_ASSOC;
7033 return ipw_qos_set_info_element(priv);
7034 }
7035
7036 return 0;
7037}
7038
7039
7040
7041
7042
7043
7044static int ipw_qos_association_resp(struct ipw_priv *priv,
7045 struct libipw_network *network)
7046{
7047 int ret = 0;
7048 unsigned long flags;
7049 u32 size = sizeof(struct libipw_qos_parameters);
7050 int set_qos_param = 0;
7051
7052 if ((priv == NULL) || (network == NULL) ||
7053 (priv->assoc_network == NULL))
7054 return ret;
7055
7056 if (!(priv->status & STATUS_ASSOCIATED))
7057 return ret;
7058
7059 if ((priv->ieee->iw_mode != IW_MODE_INFRA))
7060 return ret;
7061
7062 spin_lock_irqsave(&priv->ieee->lock, flags);
7063 if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
7064 memcpy(&priv->assoc_network->qos_data, &network->qos_data,
7065 sizeof(struct libipw_qos_data));
7066 priv->assoc_network->qos_data.active = 1;
7067 if ((network->qos_data.old_param_count !=
7068 network->qos_data.param_count)) {
7069 set_qos_param = 1;
7070 network->qos_data.old_param_count =
7071 network->qos_data.param_count;
7072 }
7073
7074 } else {
7075 if ((network->mode == IEEE_B) || (priv->ieee->mode == IEEE_B))
7076 memcpy(&priv->assoc_network->qos_data.parameters,
7077 &def_parameters_CCK, size);
7078 else
7079 memcpy(&priv->assoc_network->qos_data.parameters,
7080 &def_parameters_OFDM, size);
7081 priv->assoc_network->qos_data.active = 0;
7082 priv->assoc_network->qos_data.supported = 0;
7083 set_qos_param = 1;
7084 }
7085
7086 spin_unlock_irqrestore(&priv->ieee->lock, flags);
7087
7088 if (set_qos_param == 1)
7089 schedule_work(&priv->qos_activate);
7090
7091 return ret;
7092}
7093
7094static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv)
7095{
7096 u32 ret = 0;
7097
7098 if (!priv)
7099 return 0;
7100
7101 if (!(priv->ieee->modulation & LIBIPW_OFDM_MODULATION))
7102 ret = priv->qos_data.burst_duration_CCK;
7103 else
7104 ret = priv->qos_data.burst_duration_OFDM;
7105
7106 return ret;
7107}
7108
7109
7110
7111
7112static void ipw_qos_init(struct ipw_priv *priv, int enable,
7113 int burst_enable, u32 burst_duration_CCK,
7114 u32 burst_duration_OFDM)
7115{
7116 priv->qos_data.qos_enable = enable;
7117
7118 if (priv->qos_data.qos_enable) {
7119 priv->qos_data.def_qos_parm_CCK = &def_qos_parameters_CCK;
7120 priv->qos_data.def_qos_parm_OFDM = &def_qos_parameters_OFDM;
7121 IPW_DEBUG_QOS("QoS is enabled\n");
7122 } else {
7123 priv->qos_data.def_qos_parm_CCK = &def_parameters_CCK;
7124 priv->qos_data.def_qos_parm_OFDM = &def_parameters_OFDM;
7125 IPW_DEBUG_QOS("QoS is not enabled\n");
7126 }
7127
7128 priv->qos_data.burst_enable = burst_enable;
7129
7130 if (burst_enable) {
7131 priv->qos_data.burst_duration_CCK = burst_duration_CCK;
7132 priv->qos_data.burst_duration_OFDM = burst_duration_OFDM;
7133 } else {
7134 priv->qos_data.burst_duration_CCK = 0;
7135 priv->qos_data.burst_duration_OFDM = 0;
7136 }
7137}
7138
7139
7140
7141
7142static int ipw_get_tx_queue_number(struct ipw_priv *priv, u16 priority)
7143{
7144 if (priority > 7 || !priv->qos_data.qos_enable)
7145 priority = 0;
7146
7147 return from_priority_to_tx_queue[priority] - 1;
7148}
7149
7150static int ipw_is_qos_active(struct net_device *dev,
7151 struct sk_buff *skb)
7152{
7153 struct ipw_priv *priv = libipw_priv(dev);
7154 struct libipw_qos_data *qos_data = NULL;
7155 int active, supported;
7156 u8 *daddr = skb->data + ETH_ALEN;
7157 int unicast = !is_multicast_ether_addr(daddr);
7158
7159 if (!(priv->status & STATUS_ASSOCIATED))
7160 return 0;
7161
7162 qos_data = &priv->assoc_network->qos_data;
7163
7164 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
7165 if (unicast == 0)
7166 qos_data->active = 0;
7167 else
7168 qos_data->active = qos_data->supported;
7169 }
7170 active = qos_data->active;
7171 supported = qos_data->supported;
7172 IPW_DEBUG_QOS("QoS %d network is QoS active %d supported %d "
7173 "unicast %d\n",
7174 priv->qos_data.qos_enable, active, supported, unicast);
7175 if (active && priv->qos_data.qos_enable)
7176 return 1;
7177
7178 return 0;
7179
7180}
7181
7182
7183
7184static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv,
7185 u16 priority,
7186 struct tfd_data *tfd)
7187{
7188 int tx_queue_id = 0;
7189
7190
7191 tx_queue_id = from_priority_to_tx_queue[priority] - 1;
7192 tfd->tx_flags_ext |= DCT_FLAG_EXT_QOS_ENABLED;
7193
7194 if (priv->qos_data.qos_no_ack_mask & (1UL << tx_queue_id)) {
7195 tfd->tx_flags &= ~DCT_FLAG_ACK_REQD;
7196 tfd->tfd.tfd_26.mchdr.qos_ctrl |= cpu_to_le16(CTRL_QOS_NO_ACK);
7197 }
7198 return 0;
7199}
7200
7201
7202
7203
7204static void ipw_bg_qos_activate(struct work_struct *work)
7205{
7206 struct ipw_priv *priv =
7207 container_of(work, struct ipw_priv, qos_activate);
7208
7209 mutex_lock(&priv->mutex);
7210
7211 if (priv->status & STATUS_ASSOCIATED)
7212 ipw_qos_activate(priv, &(priv->assoc_network->qos_data));
7213
7214 mutex_unlock(&priv->mutex);
7215}
7216
7217static int ipw_handle_probe_response(struct net_device *dev,
7218 struct libipw_probe_response *resp,
7219 struct libipw_network *network)
7220{
7221 struct ipw_priv *priv = libipw_priv(dev);
7222 int active_network = ((priv->status & STATUS_ASSOCIATED) &&
7223 (network == priv->assoc_network));
7224
7225 ipw_qos_handle_probe_response(priv, active_network, network);
7226
7227 return 0;
7228}
7229
7230static int ipw_handle_beacon(struct net_device *dev,
7231 struct libipw_beacon *resp,
7232 struct libipw_network *network)
7233{
7234 struct ipw_priv *priv = libipw_priv(dev);
7235 int active_network = ((priv->status & STATUS_ASSOCIATED) &&
7236 (network == priv->assoc_network));
7237
7238 ipw_qos_handle_probe_response(priv, active_network, network);
7239
7240 return 0;
7241}
7242
7243static int ipw_handle_assoc_response(struct net_device *dev,
7244 struct libipw_assoc_response *resp,
7245 struct libipw_network *network)
7246{
7247 struct ipw_priv *priv = libipw_priv(dev);
7248 ipw_qos_association_resp(priv, network);
7249 return 0;
7250}
7251
7252static int ipw_send_qos_params_command(struct ipw_priv *priv, struct libipw_qos_parameters
7253 *qos_param)
7254{
7255 return ipw_send_cmd_pdu(priv, IPW_CMD_QOS_PARAMETERS,
7256 sizeof(*qos_param) * 3, qos_param);
7257}
7258
7259static int ipw_send_qos_info_command(struct ipw_priv *priv, struct libipw_qos_information_element
7260 *qos_param)
7261{
7262 return ipw_send_cmd_pdu(priv, IPW_CMD_WME_INFO, sizeof(*qos_param),
7263 qos_param);
7264}
7265
7266#endif
7267
7268static int ipw_associate_network(struct ipw_priv *priv,
7269 struct libipw_network *network,
7270 struct ipw_supported_rates *rates, int roaming)
7271{
7272 int err;
7273
7274 if (priv->config & CFG_FIXED_RATE)
7275 ipw_set_fixed_rate(priv, network->mode);
7276
7277 if (!(priv->config & CFG_STATIC_ESSID)) {
7278 priv->essid_len = min(network->ssid_len,
7279 (u8) IW_ESSID_MAX_SIZE);
7280 memcpy(priv->essid, network->ssid, priv->essid_len);
7281 }
7282
7283 network->last_associate = jiffies;
7284
7285 memset(&priv->assoc_request, 0, sizeof(priv->assoc_request));
7286 priv->assoc_request.channel = network->channel;
7287 priv->assoc_request.auth_key = 0;
7288
7289 if ((priv->capability & CAP_PRIVACY_ON) &&
7290 (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) {
7291 priv->assoc_request.auth_type = AUTH_SHARED_KEY;
7292 priv->assoc_request.auth_key = priv->ieee->sec.active_key;
7293
7294 if (priv->ieee->sec.level == SEC_LEVEL_1)
7295 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
7296
7297 } else if ((priv->capability & CAP_PRIVACY_ON) &&
7298 (priv->ieee->sec.auth_mode == WLAN_AUTH_LEAP))
7299 priv->assoc_request.auth_type = AUTH_LEAP;
7300 else
7301 priv->assoc_request.auth_type = AUTH_OPEN;
7302
7303 if (priv->ieee->wpa_ie_len) {
7304 priv->assoc_request.policy_support = cpu_to_le16(0x02);
7305 ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
7306 priv->ieee->wpa_ie_len);
7307 }
7308
7309
7310
7311
7312
7313
7314 if (network->mode & priv->ieee->mode & IEEE_A)
7315 priv->assoc_request.ieee_mode = IPW_A_MODE;
7316 else if (network->mode & priv->ieee->mode & IEEE_G)
7317 priv->assoc_request.ieee_mode = IPW_G_MODE;
7318 else if (network->mode & priv->ieee->mode & IEEE_B)
7319 priv->assoc_request.ieee_mode = IPW_B_MODE;
7320
7321 priv->assoc_request.capability = cpu_to_le16(network->capability);
7322 if ((network->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
7323 && !(priv->config & CFG_PREAMBLE_LONG)) {
7324 priv->assoc_request.preamble_length = DCT_FLAG_SHORT_PREAMBLE;
7325 } else {
7326 priv->assoc_request.preamble_length = DCT_FLAG_LONG_PREAMBLE;
7327
7328
7329 priv->assoc_request.capability &=
7330 ~cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
7331 }
7332
7333
7334 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
7335 priv->assoc_request.capability &=
7336 ~cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
7337
7338 IPW_DEBUG_ASSOC("%ssociation attempt: '%*pE', channel %d, 802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
7339 roaming ? "Rea" : "A",
7340 priv->essid_len, priv->essid,
7341 network->channel,
7342 ipw_modes[priv->assoc_request.ieee_mode],
7343 rates->num_rates,
7344 (priv->assoc_request.preamble_length ==
7345 DCT_FLAG_LONG_PREAMBLE) ? "long" : "short",
7346 network->capability &
7347 WLAN_CAPABILITY_SHORT_PREAMBLE ? "short" : "long",
7348 priv->capability & CAP_PRIVACY_ON ? "on " : "off",
7349 priv->capability & CAP_PRIVACY_ON ?
7350 (priv->capability & CAP_SHARED_KEY ? "(shared)" :
7351 "(open)") : "",
7352 priv->capability & CAP_PRIVACY_ON ? " key=" : "",
7353 priv->capability & CAP_PRIVACY_ON ?
7354 '1' + priv->ieee->sec.active_key : '.',
7355 priv->capability & CAP_PRIVACY_ON ? '.' : ' ');
7356
7357 priv->assoc_request.beacon_interval = cpu_to_le16(network->beacon_interval);
7358 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
7359 (network->time_stamp[0] == 0) && (network->time_stamp[1] == 0)) {
7360 priv->assoc_request.assoc_type = HC_IBSS_START;
7361 priv->assoc_request.assoc_tsf_msw = 0;
7362 priv->assoc_request.assoc_tsf_lsw = 0;
7363 } else {
7364 if (unlikely(roaming))
7365 priv->assoc_request.assoc_type = HC_REASSOCIATE;
7366 else
7367 priv->assoc_request.assoc_type = HC_ASSOCIATE;
7368 priv->assoc_request.assoc_tsf_msw = cpu_to_le32(network->time_stamp[1]);
7369 priv->assoc_request.assoc_tsf_lsw = cpu_to_le32(network->time_stamp[0]);
7370 }
7371
7372 memcpy(priv->assoc_request.bssid, network->bssid, ETH_ALEN);
7373
7374 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
7375 eth_broadcast_addr(priv->assoc_request.dest);
7376 priv->assoc_request.atim_window = cpu_to_le16(network->atim_window);
7377 } else {
7378 memcpy(priv->assoc_request.dest, network->bssid, ETH_ALEN);
7379 priv->assoc_request.atim_window = 0;
7380 }
7381
7382 priv->assoc_request.listen_interval = cpu_to_le16(network->listen_interval);
7383
7384 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
7385 if (err) {
7386 IPW_DEBUG_HC("Attempt to send SSID command failed.\n");
7387 return err;
7388 }
7389
7390 rates->ieee_mode = priv->assoc_request.ieee_mode;
7391 rates->purpose = IPW_RATE_CONNECT;
7392 ipw_send_supported_rates(priv, rates);
7393
7394 if (priv->assoc_request.ieee_mode == IPW_G_MODE)
7395 priv->sys_config.dot11g_auto_detection = 1;
7396 else
7397 priv->sys_config.dot11g_auto_detection = 0;
7398
7399 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
7400 priv->sys_config.answer_broadcast_ssid_probe = 1;
7401 else
7402 priv->sys_config.answer_broadcast_ssid_probe = 0;
7403
7404 err = ipw_send_system_config(priv);
7405 if (err) {
7406 IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
7407 return err;
7408 }
7409
7410 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi);
7411 err = ipw_set_sensitivity(priv, network->stats.rssi + IPW_RSSI_TO_DBM);
7412 if (err) {
7413 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
7414 return err;
7415 }
7416
7417
7418
7419
7420
7421
7422 priv->channel = network->channel;
7423 memcpy(priv->bssid, network->bssid, ETH_ALEN);
7424 priv->status |= STATUS_ASSOCIATING;
7425 priv->status &= ~STATUS_SECURITY_UPDATED;
7426
7427 priv->assoc_network = network;
7428
7429#ifdef CONFIG_IPW2200_QOS
7430 ipw_qos_association(priv, network);
7431#endif
7432
7433 err = ipw_send_associate(priv, &priv->assoc_request);
7434 if (err) {
7435 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
7436 return err;
7437 }
7438
7439 IPW_DEBUG(IPW_DL_STATE, "associating: '%*pE' %pM\n",
7440 priv->essid_len, priv->essid, priv->bssid);
7441
7442 return 0;
7443}
7444
7445static void ipw_roam(void *data)
7446{
7447 struct ipw_priv *priv = data;
7448 struct libipw_network *network = NULL;
7449 struct ipw_network_match match = {
7450 .network = priv->assoc_network
7451 };
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ROAMING)))
7474 return;
7475
7476 if (priv->status & STATUS_ASSOCIATED) {
7477
7478
7479 unsigned long flags;
7480 u8 rssi = priv->assoc_network->stats.rssi;
7481 priv->assoc_network->stats.rssi = -128;
7482 spin_lock_irqsave(&priv->ieee->lock, flags);
7483 list_for_each_entry(network, &priv->ieee->network_list, list) {
7484 if (network != priv->assoc_network)
7485 ipw_best_network(priv, &match, network, 1);
7486 }
7487 spin_unlock_irqrestore(&priv->ieee->lock, flags);
7488 priv->assoc_network->stats.rssi = rssi;
7489
7490 if (match.network == priv->assoc_network) {
7491 IPW_DEBUG_ASSOC("No better APs in this network to "
7492 "roam to.\n");
7493 priv->status &= ~STATUS_ROAMING;
7494 ipw_debug_config(priv);
7495 return;
7496 }
7497
7498 ipw_send_disassociate(priv, 1);
7499 priv->assoc_network = match.network;
7500
7501 return;
7502 }
7503
7504
7505 ipw_compatible_rates(priv, priv->assoc_network, &match.rates);
7506 ipw_associate_network(priv, priv->assoc_network, &match.rates, 1);
7507 priv->status &= ~STATUS_ROAMING;
7508}
7509
7510static void ipw_bg_roam(struct work_struct *work)
7511{
7512 struct ipw_priv *priv =
7513 container_of(work, struct ipw_priv, roam);
7514 mutex_lock(&priv->mutex);
7515 ipw_roam(priv);
7516 mutex_unlock(&priv->mutex);
7517}
7518
7519static int ipw_associate(void *data)
7520{
7521 struct ipw_priv *priv = data;
7522
7523 struct libipw_network *network = NULL;
7524 struct ipw_network_match match = {
7525 .network = NULL
7526 };
7527 struct ipw_supported_rates *rates;
7528 struct list_head *element;
7529 unsigned long flags;
7530
7531 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7532 IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n");
7533 return 0;
7534 }
7535
7536 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
7537 IPW_DEBUG_ASSOC("Not attempting association (already in "
7538 "progress)\n");
7539 return 0;
7540 }
7541
7542 if (priv->status & STATUS_DISASSOCIATING) {
7543 IPW_DEBUG_ASSOC("Not attempting association (in disassociating)\n");
7544 schedule_work(&priv->associate);
7545 return 0;
7546 }
7547
7548 if (!ipw_is_init(priv) || (priv->status & STATUS_SCANNING)) {
7549 IPW_DEBUG_ASSOC("Not attempting association (scanning or not "
7550 "initialized)\n");
7551 return 0;
7552 }
7553
7554 if (!(priv->config & CFG_ASSOCIATE) &&
7555 !(priv->config & (CFG_STATIC_ESSID | CFG_STATIC_BSSID))) {
7556 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
7557 return 0;
7558 }
7559
7560
7561 spin_lock_irqsave(&priv->ieee->lock, flags);
7562 list_for_each_entry(network, &priv->ieee->network_list, list)
7563 ipw_best_network(priv, &match, network, 0);
7564
7565 network = match.network;
7566 rates = &match.rates;
7567
7568 if (network == NULL &&
7569 priv->ieee->iw_mode == IW_MODE_ADHOC &&
7570 priv->config & CFG_ADHOC_CREATE &&
7571 priv->config & CFG_STATIC_ESSID &&
7572 priv->config & CFG_STATIC_CHANNEL) {
7573
7574 if (list_empty(&priv->ieee->network_free_list)) {
7575 struct libipw_network *oldest = NULL;
7576 struct libipw_network *target;
7577
7578 list_for_each_entry(target, &priv->ieee->network_list, list) {
7579 if ((oldest == NULL) ||
7580 (target->last_scanned < oldest->last_scanned))
7581 oldest = target;
7582 }
7583
7584
7585 list_del(&oldest->list);
7586 target = oldest;
7587 IPW_DEBUG_ASSOC("Expired '%*pE' (%pM) from network list.\n",
7588 target->ssid_len, target->ssid,
7589 target->bssid);
7590 list_add_tail(&target->list,
7591 &priv->ieee->network_free_list);
7592 }
7593
7594 element = priv->ieee->network_free_list.next;
7595 network = list_entry(element, struct libipw_network, list);
7596 ipw_adhoc_create(priv, network);
7597 rates = &priv->rates;
7598 list_del(element);
7599 list_add_tail(&network->list, &priv->ieee->network_list);
7600 }
7601 spin_unlock_irqrestore(&priv->ieee->lock, flags);
7602
7603
7604
7605 if (!network) {
7606 ipw_debug_config(priv);
7607
7608 if (!(priv->status & STATUS_SCANNING)) {
7609 if (!(priv->config & CFG_SPEED_SCAN))
7610 schedule_delayed_work(&priv->request_scan,
7611 SCAN_INTERVAL);
7612 else
7613 schedule_delayed_work(&priv->request_scan, 0);
7614 }
7615
7616 return 0;
7617 }
7618
7619 ipw_associate_network(priv, network, rates, 0);
7620
7621 return 1;
7622}
7623
7624static void ipw_bg_associate(struct work_struct *work)
7625{
7626 struct ipw_priv *priv =
7627 container_of(work, struct ipw_priv, associate);
7628 mutex_lock(&priv->mutex);
7629 ipw_associate(priv);
7630 mutex_unlock(&priv->mutex);
7631}
7632
7633static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
7634 struct sk_buff *skb)
7635{
7636 struct ieee80211_hdr *hdr;
7637 u16 fc;
7638
7639 hdr = (struct ieee80211_hdr *)skb->data;
7640 fc = le16_to_cpu(hdr->frame_control);
7641 if (!(fc & IEEE80211_FCTL_PROTECTED))
7642 return;
7643
7644 fc &= ~IEEE80211_FCTL_PROTECTED;
7645 hdr->frame_control = cpu_to_le16(fc);
7646 switch (priv->ieee->sec.level) {
7647 case SEC_LEVEL_3:
7648
7649 memmove(skb->data + LIBIPW_3ADDR_LEN,
7650 skb->data + LIBIPW_3ADDR_LEN + 8,
7651 skb->len - LIBIPW_3ADDR_LEN - 8);
7652 skb_trim(skb, skb->len - 16);
7653 break;
7654 case SEC_LEVEL_2:
7655 break;
7656 case SEC_LEVEL_1:
7657
7658 memmove(skb->data + LIBIPW_3ADDR_LEN,
7659 skb->data + LIBIPW_3ADDR_LEN + 4,
7660 skb->len - LIBIPW_3ADDR_LEN - 4);
7661 skb_trim(skb, skb->len - 8);
7662 break;
7663 case SEC_LEVEL_0:
7664 break;
7665 default:
7666 printk(KERN_ERR "Unknown security level %d\n",
7667 priv->ieee->sec.level);
7668 break;
7669 }
7670}
7671
7672static void ipw_handle_data_packet(struct ipw_priv *priv,
7673 struct ipw_rx_mem_buffer *rxb,
7674 struct libipw_rx_stats *stats)
7675{
7676 struct net_device *dev = priv->net_dev;
7677 struct libipw_hdr_4addr *hdr;
7678 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7679
7680
7681 netif_trans_update(dev);
7682
7683
7684
7685 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
7686 skb_tailroom(rxb->skb))) {
7687 dev->stats.rx_errors++;
7688 priv->wstats.discard.misc++;
7689 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
7690 return;
7691 } else if (unlikely(!netif_running(priv->net_dev))) {
7692 dev->stats.rx_dropped++;
7693 priv->wstats.discard.misc++;
7694 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
7695 return;
7696 }
7697
7698
7699 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data));
7700
7701
7702 skb_put(rxb->skb, le16_to_cpu(pkt->u.frame.length));
7703
7704 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
7705
7706
7707 hdr = (struct libipw_hdr_4addr *)rxb->skb->data;
7708 if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
7709 (is_multicast_ether_addr(hdr->addr1) ?
7710 !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
7711 ipw_rebuild_decrypted_skb(priv, rxb->skb);
7712
7713 if (!libipw_rx(priv->ieee, rxb->skb, stats))
7714 dev->stats.rx_errors++;
7715 else {
7716 rxb->skb = NULL;
7717 __ipw_led_activity_on(priv);
7718 }
7719}
7720
7721#ifdef CONFIG_IPW2200_RADIOTAP
7722static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7723 struct ipw_rx_mem_buffer *rxb,
7724 struct libipw_rx_stats *stats)
7725{
7726 struct net_device *dev = priv->net_dev;
7727 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7728 struct ipw_rx_frame *frame = &pkt->u.frame;
7729
7730
7731 u16 received_channel = frame->received_channel;
7732 u8 antennaAndPhy = frame->antennaAndPhy;
7733 s8 antsignal = frame->rssi_dbm - IPW_RSSI_TO_DBM;
7734 u16 pktrate = frame->rate;
7735
7736
7737
7738
7739 struct ipw_rt_hdr *ipw_rt;
7740
7741 unsigned short len = le16_to_cpu(pkt->u.frame.length);
7742
7743
7744 netif_trans_update(dev);
7745
7746
7747
7748 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
7749 skb_tailroom(rxb->skb))) {
7750 dev->stats.rx_errors++;
7751 priv->wstats.discard.misc++;
7752 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
7753 return;
7754 } else if (unlikely(!netif_running(priv->net_dev))) {
7755 dev->stats.rx_dropped++;
7756 priv->wstats.discard.misc++;
7757 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
7758 return;
7759 }
7760
7761
7762
7763 if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
7764
7765 dev->stats.rx_dropped++;
7766 priv->wstats.discard.misc++;
7767 IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
7768 return;
7769 }
7770
7771
7772 memmove(rxb->skb->data + sizeof(struct ipw_rt_hdr),
7773 rxb->skb->data + IPW_RX_FRAME_SIZE, len);
7774
7775 ipw_rt = (struct ipw_rt_hdr *)rxb->skb->data;
7776
7777 ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
7778 ipw_rt->rt_hdr.it_pad = 0;
7779 ipw_rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct ipw_rt_hdr));
7780
7781
7782 ipw_rt->rt_hdr.it_present = cpu_to_le32(
7783 (1 << IEEE80211_RADIOTAP_TSFT) |
7784 (1 << IEEE80211_RADIOTAP_FLAGS) |
7785 (1 << IEEE80211_RADIOTAP_RATE) |
7786 (1 << IEEE80211_RADIOTAP_CHANNEL) |
7787 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
7788 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
7789 (1 << IEEE80211_RADIOTAP_ANTENNA));
7790
7791
7792 ipw_rt->rt_flags = 0;
7793 ipw_rt->rt_tsf = (u64)(frame->parent_tsf[3] << 24 |
7794 frame->parent_tsf[2] << 16 |
7795 frame->parent_tsf[1] << 8 |
7796 frame->parent_tsf[0]);
7797
7798
7799 ipw_rt->rt_dbmsignal = antsignal;
7800 ipw_rt->rt_dbmnoise = (s8) le16_to_cpu(frame->noise);
7801
7802
7803 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));
7804 if (received_channel > 14) {
7805 ipw_rt->rt_chbitmask =
7806 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
7807 } else if (antennaAndPhy & 32) {
7808 ipw_rt->rt_chbitmask =
7809 cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
7810 } else {
7811 ipw_rt->rt_chbitmask =
7812 cpu_to_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
7813 }
7814
7815
7816 switch (pktrate) {
7817 case IPW_TX_RATE_1MB:
7818 ipw_rt->rt_rate = 2;
7819 break;
7820 case IPW_TX_RATE_2MB:
7821 ipw_rt->rt_rate = 4;
7822 break;
7823 case IPW_TX_RATE_5MB:
7824 ipw_rt->rt_rate = 10;
7825 break;
7826 case IPW_TX_RATE_6MB:
7827 ipw_rt->rt_rate = 12;
7828 break;
7829 case IPW_TX_RATE_9MB:
7830 ipw_rt->rt_rate = 18;
7831 break;
7832 case IPW_TX_RATE_11MB:
7833 ipw_rt->rt_rate = 22;
7834 break;
7835 case IPW_TX_RATE_12MB:
7836 ipw_rt->rt_rate = 24;
7837 break;
7838 case IPW_TX_RATE_18MB:
7839 ipw_rt->rt_rate = 36;
7840 break;
7841 case IPW_TX_RATE_24MB:
7842 ipw_rt->rt_rate = 48;
7843 break;
7844 case IPW_TX_RATE_36MB:
7845 ipw_rt->rt_rate = 72;
7846 break;
7847 case IPW_TX_RATE_48MB:
7848 ipw_rt->rt_rate = 96;
7849 break;
7850 case IPW_TX_RATE_54MB:
7851 ipw_rt->rt_rate = 108;
7852 break;
7853 default:
7854 ipw_rt->rt_rate = 0;
7855 break;
7856 }
7857
7858
7859 ipw_rt->rt_antenna = (antennaAndPhy & 3);
7860
7861
7862 if ((antennaAndPhy & 64))
7863 ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
7864
7865
7866 skb_put(rxb->skb, len + sizeof(struct ipw_rt_hdr));
7867
7868 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
7869
7870 if (!libipw_rx(priv->ieee, rxb->skb, stats))
7871 dev->stats.rx_errors++;
7872 else {
7873 rxb->skb = NULL;
7874
7875 }
7876}
7877#endif
7878
7879#ifdef CONFIG_IPW2200_PROMISCUOUS
7880#define libipw_is_probe_response(fc) \
7881 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && \
7882 (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP )
7883
7884#define libipw_is_management(fc) \
7885 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
7886
7887#define libipw_is_control(fc) \
7888 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL)
7889
7890#define libipw_is_data(fc) \
7891 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
7892
7893#define libipw_is_assoc_request(fc) \
7894 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ)
7895
7896#define libipw_is_reassoc_request(fc) \
7897 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
7898
7899static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
7900 struct ipw_rx_mem_buffer *rxb,
7901 struct libipw_rx_stats *stats)
7902{
7903 struct net_device *dev = priv->prom_net_dev;
7904 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7905 struct ipw_rx_frame *frame = &pkt->u.frame;
7906 struct ipw_rt_hdr *ipw_rt;
7907
7908
7909
7910 struct ieee80211_hdr *hdr;
7911 u16 channel = frame->received_channel;
7912 u8 phy_flags = frame->antennaAndPhy;
7913 s8 signal = frame->rssi_dbm - IPW_RSSI_TO_DBM;
7914 s8 noise = (s8) le16_to_cpu(frame->noise);
7915 u8 rate = frame->rate;
7916 unsigned short len = le16_to_cpu(pkt->u.frame.length);
7917 struct sk_buff *skb;
7918 int hdr_only = 0;
7919 u16 filter = priv->prom_priv->filter;
7920
7921
7922 if (filter & IPW_PROM_NO_RX)
7923 return;
7924
7925
7926 netif_trans_update(dev);
7927
7928 if (unlikely((len + IPW_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
7929 dev->stats.rx_errors++;
7930 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
7931 return;
7932 }
7933
7934
7935 if (unlikely(!netif_running(dev))) {
7936 dev->stats.rx_dropped++;
7937 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
7938 return;
7939 }
7940
7941
7942
7943 if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
7944
7945 dev->stats.rx_dropped++;
7946 IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
7947 return;
7948 }
7949
7950 hdr = (void *)rxb->skb->data + IPW_RX_FRAME_SIZE;
7951 if (libipw_is_management(le16_to_cpu(hdr->frame_control))) {
7952 if (filter & IPW_PROM_NO_MGMT)
7953 return;
7954 if (filter & IPW_PROM_MGMT_HEADER_ONLY)
7955 hdr_only = 1;
7956 } else if (libipw_is_control(le16_to_cpu(hdr->frame_control))) {
7957 if (filter & IPW_PROM_NO_CTL)
7958 return;
7959 if (filter & IPW_PROM_CTL_HEADER_ONLY)
7960 hdr_only = 1;
7961 } else if (libipw_is_data(le16_to_cpu(hdr->frame_control))) {
7962 if (filter & IPW_PROM_NO_DATA)
7963 return;
7964 if (filter & IPW_PROM_DATA_HEADER_ONLY)
7965 hdr_only = 1;
7966 }
7967
7968
7969 skb = skb_copy(rxb->skb, GFP_ATOMIC);
7970 if (skb == NULL) {
7971 IPW_ERROR("skb_clone failed for promiscuous copy.\n");
7972 return;
7973 }
7974
7975
7976 ipw_rt = (void *)skb->data;
7977
7978 if (hdr_only)
7979 len = libipw_get_hdrlen(le16_to_cpu(hdr->frame_control));
7980
7981 memcpy(ipw_rt->payload, hdr, len);
7982
7983 ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
7984 ipw_rt->rt_hdr.it_pad = 0;
7985 ipw_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*ipw_rt));
7986
7987
7988 skb_put(skb, sizeof(*ipw_rt) + len);
7989
7990
7991 ipw_rt->rt_hdr.it_present = cpu_to_le32(
7992 (1 << IEEE80211_RADIOTAP_TSFT) |
7993 (1 << IEEE80211_RADIOTAP_FLAGS) |
7994 (1 << IEEE80211_RADIOTAP_RATE) |
7995 (1 << IEEE80211_RADIOTAP_CHANNEL) |
7996 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
7997 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
7998 (1 << IEEE80211_RADIOTAP_ANTENNA));
7999
8000
8001 ipw_rt->rt_flags = 0;
8002 ipw_rt->rt_tsf = (u64)(frame->parent_tsf[3] << 24 |
8003 frame->parent_tsf[2] << 16 |
8004 frame->parent_tsf[1] << 8 |
8005 frame->parent_tsf[0]);
8006
8007
8008 ipw_rt->rt_dbmsignal = signal;
8009 ipw_rt->rt_dbmnoise = noise;
8010
8011
8012 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(channel));
8013 if (channel > 14) {
8014 ipw_rt->rt_chbitmask =
8015 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
8016 } else if (phy_flags & (1 << 5)) {
8017 ipw_rt->rt_chbitmask =
8018 cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
8019 } else {
8020 ipw_rt->rt_chbitmask =
8021 cpu_to_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
8022 }
8023
8024
8025 switch (rate) {
8026 case IPW_TX_RATE_1MB:
8027 ipw_rt->rt_rate = 2;
8028 break;
8029 case IPW_TX_RATE_2MB:
8030 ipw_rt->rt_rate = 4;
8031 break;
8032 case IPW_TX_RATE_5MB:
8033 ipw_rt->rt_rate = 10;
8034 break;
8035 case IPW_TX_RATE_6MB:
8036 ipw_rt->rt_rate = 12;
8037 break;
8038 case IPW_TX_RATE_9MB:
8039 ipw_rt->rt_rate = 18;
8040 break;
8041 case IPW_TX_RATE_11MB:
8042 ipw_rt->rt_rate = 22;
8043 break;
8044 case IPW_TX_RATE_12MB:
8045 ipw_rt->rt_rate = 24;
8046 break;
8047 case IPW_TX_RATE_18MB:
8048 ipw_rt->rt_rate = 36;
8049 break;
8050 case IPW_TX_RATE_24MB:
8051 ipw_rt->rt_rate = 48;
8052 break;
8053 case IPW_TX_RATE_36MB:
8054 ipw_rt->rt_rate = 72;
8055 break;
8056 case IPW_TX_RATE_48MB:
8057 ipw_rt->rt_rate = 96;
8058 break;
8059 case IPW_TX_RATE_54MB:
8060 ipw_rt->rt_rate = 108;
8061 break;
8062 default:
8063 ipw_rt->rt_rate = 0;
8064 break;
8065 }
8066
8067
8068 ipw_rt->rt_antenna = (phy_flags & 3);
8069
8070
8071 if (phy_flags & (1 << 6))
8072 ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
8073
8074 IPW_DEBUG_RX("Rx packet of %d bytes.\n", skb->len);
8075
8076 if (!libipw_rx(priv->prom_priv->ieee, skb, stats)) {
8077 dev->stats.rx_errors++;
8078 dev_kfree_skb_any(skb);
8079 }
8080}
8081#endif
8082
8083static int is_network_packet(struct ipw_priv *priv,
8084 struct libipw_hdr_4addr *header)
8085{
8086
8087
8088 switch (priv->ieee->iw_mode) {
8089 case IW_MODE_ADHOC:
8090
8091 if (ether_addr_equal(header->addr2, priv->net_dev->dev_addr))
8092 return 0;
8093
8094
8095 if (is_multicast_ether_addr(header->addr1))
8096 return ether_addr_equal(header->addr3, priv->bssid);
8097
8098
8099 return ether_addr_equal(header->addr1,
8100 priv->net_dev->dev_addr);
8101
8102 case IW_MODE_INFRA:
8103
8104 if (ether_addr_equal(header->addr3, priv->net_dev->dev_addr))
8105 return 0;
8106
8107
8108 if (is_multicast_ether_addr(header->addr1))
8109 return ether_addr_equal(header->addr2, priv->bssid);
8110
8111
8112 return ether_addr_equal(header->addr1,
8113 priv->net_dev->dev_addr);
8114 }
8115
8116 return 1;
8117}
8118
8119#define IPW_PACKET_RETRY_TIME HZ
8120
8121static int is_duplicate_packet(struct ipw_priv *priv,
8122 struct libipw_hdr_4addr *header)
8123{
8124 u16 sc = le16_to_cpu(header->seq_ctl);
8125 u16 seq = WLAN_GET_SEQ_SEQ(sc);
8126 u16 frag = WLAN_GET_SEQ_FRAG(sc);
8127 u16 *last_seq, *last_frag;
8128 unsigned long *last_time;
8129
8130 switch (priv->ieee->iw_mode) {
8131 case IW_MODE_ADHOC:
8132 {
8133 struct list_head *p;
8134 struct ipw_ibss_seq *entry = NULL;
8135 u8 *mac = header->addr2;
8136 int index = mac[5] % IPW_IBSS_MAC_HASH_SIZE;
8137
8138 list_for_each(p, &priv->ibss_mac_hash[index]) {
8139 entry =
8140 list_entry(p, struct ipw_ibss_seq, list);
8141 if (ether_addr_equal(entry->mac, mac))
8142 break;
8143 }
8144 if (p == &priv->ibss_mac_hash[index]) {
8145 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
8146 if (!entry) {
8147 IPW_ERROR
8148 ("Cannot malloc new mac entry\n");
8149 return 0;
8150 }
8151 memcpy(entry->mac, mac, ETH_ALEN);
8152 entry->seq_num = seq;
8153 entry->frag_num = frag;
8154 entry->packet_time = jiffies;
8155 list_add(&entry->list,
8156 &priv->ibss_mac_hash[index]);
8157 return 0;
8158 }
8159 last_seq = &entry->seq_num;
8160 last_frag = &entry->frag_num;
8161 last_time = &entry->packet_time;
8162 break;
8163 }
8164 case IW_MODE_INFRA:
8165 last_seq = &priv->last_seq_num;
8166 last_frag = &priv->last_frag_num;
8167 last_time = &priv->last_packet_time;
8168 break;
8169 default:
8170 return 0;
8171 }
8172 if ((*last_seq == seq) &&
8173 time_after(*last_time + IPW_PACKET_RETRY_TIME, jiffies)) {
8174 if (*last_frag == frag)
8175 goto drop;
8176 if (*last_frag + 1 != frag)
8177
8178 goto drop;
8179 } else
8180 *last_seq = seq;
8181
8182 *last_frag = frag;
8183 *last_time = jiffies;
8184 return 0;
8185
8186 drop:
8187
8188
8189
8190
8191 return 1;
8192}
8193
8194static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
8195 struct ipw_rx_mem_buffer *rxb,
8196 struct libipw_rx_stats *stats)
8197{
8198 struct sk_buff *skb = rxb->skb;
8199 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)skb->data;
8200 struct libipw_hdr_4addr *header = (struct libipw_hdr_4addr *)
8201 (skb->data + IPW_RX_FRAME_SIZE);
8202
8203 libipw_rx_mgt(priv->ieee, header, stats);
8204
8205 if (priv->ieee->iw_mode == IW_MODE_ADHOC &&
8206 ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
8207 IEEE80211_STYPE_PROBE_RESP) ||
8208 (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
8209 IEEE80211_STYPE_BEACON))) {
8210 if (ether_addr_equal(header->addr3, priv->bssid))
8211 ipw_add_station(priv, header->addr2);
8212 }
8213
8214 if (priv->config & CFG_NET_STATS) {
8215 IPW_DEBUG_HC("sending stat packet\n");
8216
8217
8218
8219 skb_put(skb, le16_to_cpu(pkt->u.frame.length) +
8220 IPW_RX_FRAME_SIZE);
8221
8222
8223 skb_pull(skb, IPW_RX_FRAME_SIZE);
8224
8225
8226 memcpy(skb_push(skb, sizeof(*stats)), stats, sizeof(*stats));
8227
8228 skb->dev = priv->ieee->dev;
8229
8230
8231 skb_reset_mac_header(skb);
8232
8233 skb->pkt_type = PACKET_OTHERHOST;
8234 skb->protocol = cpu_to_be16(ETH_P_80211_STATS);
8235 memset(skb->cb, 0, sizeof(rxb->skb->cb));
8236 netif_rx(skb);
8237 rxb->skb = NULL;
8238 }
8239}
8240
8241
8242
8243
8244
8245
8246static void ipw_rx(struct ipw_priv *priv)
8247{
8248 struct ipw_rx_mem_buffer *rxb;
8249 struct ipw_rx_packet *pkt;
8250 struct libipw_hdr_4addr *header;
8251 u32 r, w, i;
8252 u8 network_packet;
8253 u8 fill_rx = 0;
8254
8255 r = ipw_read32(priv, IPW_RX_READ_INDEX);
8256 w = ipw_read32(priv, IPW_RX_WRITE_INDEX);
8257 i = priv->rxq->read;
8258
8259 if (ipw_rx_queue_space (priv->rxq) > (RX_QUEUE_SIZE / 2))
8260 fill_rx = 1;
8261
8262 while (i != r) {
8263 rxb = priv->rxq->queue[i];
8264 if (unlikely(rxb == NULL)) {
8265 printk(KERN_CRIT "Queue not allocated!\n");
8266 break;
8267 }
8268 priv->rxq->queue[i] = NULL;
8269
8270 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
8271 IPW_RX_BUF_SIZE,
8272 PCI_DMA_FROMDEVICE);
8273
8274 pkt = (struct ipw_rx_packet *)rxb->skb->data;
8275 IPW_DEBUG_RX("Packet: type=%02X seq=%02X bits=%02X\n",
8276 pkt->header.message_type,
8277 pkt->header.rx_seq_num, pkt->header.control_bits);
8278
8279 switch (pkt->header.message_type) {
8280 case RX_FRAME_TYPE: {
8281 struct libipw_rx_stats stats = {
8282 .rssi = pkt->u.frame.rssi_dbm -
8283 IPW_RSSI_TO_DBM,
8284 .signal =
8285 pkt->u.frame.rssi_dbm -
8286 IPW_RSSI_TO_DBM + 0x100,
8287 .noise =
8288 le16_to_cpu(pkt->u.frame.noise),
8289 .rate = pkt->u.frame.rate,
8290 .mac_time = jiffies,
8291 .received_channel =
8292 pkt->u.frame.received_channel,
8293 .freq =
8294 (pkt->u.frame.
8295 control & (1 << 0)) ?
8296 LIBIPW_24GHZ_BAND :
8297 LIBIPW_52GHZ_BAND,
8298 .len = le16_to_cpu(pkt->u.frame.length),
8299 };
8300
8301 if (stats.rssi != 0)
8302 stats.mask |= LIBIPW_STATMASK_RSSI;
8303 if (stats.signal != 0)
8304 stats.mask |= LIBIPW_STATMASK_SIGNAL;
8305 if (stats.noise != 0)
8306 stats.mask |= LIBIPW_STATMASK_NOISE;
8307 if (stats.rate != 0)
8308 stats.mask |= LIBIPW_STATMASK_RATE;
8309
8310 priv->rx_packets++;
8311
8312#ifdef CONFIG_IPW2200_PROMISCUOUS
8313 if (priv->prom_net_dev && netif_running(priv->prom_net_dev))
8314 ipw_handle_promiscuous_rx(priv, rxb, &stats);
8315#endif
8316
8317#ifdef CONFIG_IPW2200_MONITOR
8318 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
8319#ifdef CONFIG_IPW2200_RADIOTAP
8320
8321 ipw_handle_data_packet_monitor(priv,
8322 rxb,
8323 &stats);
8324#else
8325 ipw_handle_data_packet(priv, rxb,
8326 &stats);
8327#endif
8328 break;
8329 }
8330#endif
8331
8332 header =
8333 (struct libipw_hdr_4addr *)(rxb->skb->
8334 data +
8335 IPW_RX_FRAME_SIZE);
8336
8337
8338
8339
8340
8341
8342 network_packet =
8343 is_network_packet(priv, header);
8344 if (network_packet && priv->assoc_network) {
8345 priv->assoc_network->stats.rssi =
8346 stats.rssi;
8347 priv->exp_avg_rssi =
8348 exponential_average(priv->exp_avg_rssi,
8349 stats.rssi, DEPTH_RSSI);
8350 }
8351
8352 IPW_DEBUG_RX("Frame: len=%u\n",
8353 le16_to_cpu(pkt->u.frame.length));
8354
8355 if (le16_to_cpu(pkt->u.frame.length) <
8356 libipw_get_hdrlen(le16_to_cpu(
8357 header->frame_ctl))) {
8358 IPW_DEBUG_DROP
8359 ("Received packet is too small. "
8360 "Dropping.\n");
8361 priv->net_dev->stats.rx_errors++;
8362 priv->wstats.discard.misc++;
8363 break;
8364 }
8365
8366 switch (WLAN_FC_GET_TYPE
8367 (le16_to_cpu(header->frame_ctl))) {
8368
8369 case IEEE80211_FTYPE_MGMT:
8370 ipw_handle_mgmt_packet(priv, rxb,
8371 &stats);
8372 break;
8373
8374 case IEEE80211_FTYPE_CTL:
8375 break;
8376
8377 case IEEE80211_FTYPE_DATA:
8378 if (unlikely(!network_packet ||
8379 is_duplicate_packet(priv,
8380 header)))
8381 {
8382 IPW_DEBUG_DROP("Dropping: "
8383 "%pM, "
8384 "%pM, "
8385 "%pM\n",
8386 header->addr1,
8387 header->addr2,
8388 header->addr3);
8389 break;
8390 }
8391
8392 ipw_handle_data_packet(priv, rxb,
8393 &stats);
8394
8395 break;
8396 }
8397 break;
8398 }
8399
8400 case RX_HOST_NOTIFICATION_TYPE:{
8401 IPW_DEBUG_RX
8402 ("Notification: subtype=%02X flags=%02X size=%d\n",
8403 pkt->u.notification.subtype,
8404 pkt->u.notification.flags,
8405 le16_to_cpu(pkt->u.notification.size));
8406 ipw_rx_notification(priv, &pkt->u.notification);
8407 break;
8408 }
8409
8410 default:
8411 IPW_DEBUG_RX("Bad Rx packet of type %d\n",
8412 pkt->header.message_type);
8413 break;
8414 }
8415
8416
8417
8418
8419 if (rxb->skb != NULL) {
8420 dev_kfree_skb_any(rxb->skb);
8421 rxb->skb = NULL;
8422 }
8423
8424 pci_unmap_single(priv->pci_dev, rxb->dma_addr,
8425 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
8426 list_add_tail(&rxb->list, &priv->rxq->rx_used);
8427
8428 i = (i + 1) % RX_QUEUE_SIZE;
8429
8430
8431
8432 if (fill_rx) {
8433 priv->rxq->read = i;
8434 ipw_rx_queue_replenish(priv);
8435 }
8436 }
8437
8438
8439 priv->rxq->read = i;
8440 ipw_rx_queue_restock(priv);
8441}
8442
8443#define DEFAULT_RTS_THRESHOLD 2304U
8444#define MIN_RTS_THRESHOLD 1U
8445#define MAX_RTS_THRESHOLD 2304U
8446#define DEFAULT_BEACON_INTERVAL 100U
8447#define DEFAULT_SHORT_RETRY_LIMIT 7U
8448#define DEFAULT_LONG_RETRY_LIMIT 4U
8449
8450
8451
8452
8453
8454
8455
8456
8457static int ipw_sw_reset(struct ipw_priv *priv, int option)
8458{
8459 int band, modulation;
8460 int old_mode = priv->ieee->iw_mode;
8461
8462
8463 priv->config = 0;
8464
8465
8466
8467 if (!led_support)
8468 priv->config |= CFG_NO_LED;
8469
8470 if (associate)
8471 priv->config |= CFG_ASSOCIATE;
8472 else
8473 IPW_DEBUG_INFO("Auto associate disabled.\n");
8474
8475 if (auto_create)
8476 priv->config |= CFG_ADHOC_CREATE;
8477 else
8478 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
8479
8480 priv->config &= ~CFG_STATIC_ESSID;
8481 priv->essid_len = 0;
8482 memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
8483
8484 if (disable && option) {
8485 priv->status |= STATUS_RF_KILL_SW;
8486 IPW_DEBUG_INFO("Radio disabled.\n");
8487 }
8488
8489 if (default_channel != 0) {
8490 priv->config |= CFG_STATIC_CHANNEL;
8491 priv->channel = default_channel;
8492 IPW_DEBUG_INFO("Bind to static channel %d\n", default_channel);
8493
8494 }
8495#ifdef CONFIG_IPW2200_QOS
8496 ipw_qos_init(priv, qos_enable, qos_burst_enable,
8497 burst_duration_CCK, burst_duration_OFDM);
8498#endif
8499
8500 switch (network_mode) {
8501 case 1:
8502 priv->ieee->iw_mode = IW_MODE_ADHOC;
8503 priv->net_dev->type = ARPHRD_ETHER;
8504
8505 break;
8506#ifdef CONFIG_IPW2200_MONITOR
8507 case 2:
8508 priv->ieee->iw_mode = IW_MODE_MONITOR;
8509#ifdef CONFIG_IPW2200_RADIOTAP
8510 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
8511#else
8512 priv->net_dev->type = ARPHRD_IEEE80211;
8513#endif
8514 break;
8515#endif
8516 default:
8517 case 0:
8518 priv->net_dev->type = ARPHRD_ETHER;
8519 priv->ieee->iw_mode = IW_MODE_INFRA;
8520 break;
8521 }
8522
8523 if (hwcrypto) {
8524 priv->ieee->host_encrypt = 0;
8525 priv->ieee->host_encrypt_msdu = 0;
8526 priv->ieee->host_decrypt = 0;
8527 priv->ieee->host_mc_decrypt = 0;
8528 }
8529 IPW_DEBUG_INFO("Hardware crypto [%s]\n", hwcrypto ? "on" : "off");
8530
8531
8532 priv->ieee->host_open_frag = 0;
8533
8534 if ((priv->pci_dev->device == 0x4223) ||
8535 (priv->pci_dev->device == 0x4224)) {
8536 if (option == 1)
8537 printk(KERN_INFO DRV_NAME
8538 ": Detected Intel PRO/Wireless 2915ABG Network "
8539 "Connection\n");
8540 priv->ieee->abg_true = 1;
8541 band = LIBIPW_52GHZ_BAND | LIBIPW_24GHZ_BAND;
8542 modulation = LIBIPW_OFDM_MODULATION |
8543 LIBIPW_CCK_MODULATION;
8544 priv->adapter = IPW_2915ABG;
8545 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
8546 } else {
8547 if (option == 1)
8548 printk(KERN_INFO DRV_NAME
8549 ": Detected Intel PRO/Wireless 2200BG Network "
8550 "Connection\n");
8551
8552 priv->ieee->abg_true = 0;
8553 band = LIBIPW_24GHZ_BAND;
8554 modulation = LIBIPW_OFDM_MODULATION |
8555 LIBIPW_CCK_MODULATION;
8556 priv->adapter = IPW_2200BG;
8557 priv->ieee->mode = IEEE_G | IEEE_B;
8558 }
8559
8560 priv->ieee->freq_band = band;
8561 priv->ieee->modulation = modulation;
8562
8563 priv->rates_mask = LIBIPW_DEFAULT_RATES_MASK;
8564
8565 priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
8566 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
8567
8568 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
8569 priv->short_retry_limit = DEFAULT_SHORT_RETRY_LIMIT;
8570 priv->long_retry_limit = DEFAULT_LONG_RETRY_LIMIT;
8571
8572
8573 priv->power_mode = IPW_POWER_AC;
8574 priv->tx_power = IPW_TX_POWER_DEFAULT;
8575
8576 return old_mode == priv->ieee->iw_mode;
8577}
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
8590{
8591 if (channel == 0) {
8592 IPW_DEBUG_INFO("Setting channel to ANY (0)\n");
8593 priv->config &= ~CFG_STATIC_CHANNEL;
8594 IPW_DEBUG_ASSOC("Attempting to associate with new "
8595 "parameters.\n");
8596 ipw_associate(priv);
8597 return 0;
8598 }
8599
8600 priv->config |= CFG_STATIC_CHANNEL;
8601
8602 if (priv->channel == channel) {
8603 IPW_DEBUG_INFO("Request to set channel to current value (%d)\n",
8604 channel);
8605 return 0;
8606 }
8607
8608 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel);
8609 priv->channel = channel;
8610
8611#ifdef CONFIG_IPW2200_MONITOR
8612 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
8613 int i;
8614 if (priv->status & STATUS_SCANNING) {
8615 IPW_DEBUG_SCAN("Scan abort triggered due to "
8616 "channel change.\n");
8617 ipw_abort_scan(priv);
8618 }
8619
8620 for (i = 1000; i && (priv->status & STATUS_SCANNING); i--)
8621 udelay(10);
8622
8623 if (priv->status & STATUS_SCANNING)
8624 IPW_DEBUG_SCAN("Still scanning...\n");
8625 else
8626 IPW_DEBUG_SCAN("Took %dms to abort current scan\n",
8627 1000 - i);
8628
8629 return 0;
8630 }
8631#endif
8632
8633
8634 IPW_DEBUG_ASSOC("[re]association triggered due to channel change.\n");
8635 if (!ipw_disassociate(priv))
8636 ipw_associate(priv);
8637
8638 return 0;
8639}
8640
8641static int ipw_wx_set_freq(struct net_device *dev,
8642 struct iw_request_info *info,
8643 union iwreq_data *wrqu, char *extra)
8644{
8645 struct ipw_priv *priv = libipw_priv(dev);
8646 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
8647 struct iw_freq *fwrq = &wrqu->freq;
8648 int ret = 0, i;
8649 u8 channel, flags;
8650 int band;
8651
8652 if (fwrq->m == 0) {
8653 IPW_DEBUG_WX("SET Freq/Channel -> any\n");
8654 mutex_lock(&priv->mutex);
8655 ret = ipw_set_channel(priv, 0);
8656 mutex_unlock(&priv->mutex);
8657 return ret;
8658 }
8659
8660 if (fwrq->e == 1) {
8661 channel = libipw_freq_to_channel(priv->ieee, fwrq->m);
8662 if (channel == 0)
8663 return -EINVAL;
8664 } else
8665 channel = fwrq->m;
8666
8667 if (!(band = libipw_is_valid_channel(priv->ieee, channel)))
8668 return -EINVAL;
8669
8670 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
8671 i = libipw_channel_to_index(priv->ieee, channel);
8672 if (i == -1)
8673 return -EINVAL;
8674
8675 flags = (band == LIBIPW_24GHZ_BAND) ?
8676 geo->bg[i].flags : geo->a[i].flags;
8677 if (flags & LIBIPW_CH_PASSIVE_ONLY) {
8678 IPW_DEBUG_WX("Invalid Ad-Hoc channel for 802.11a\n");
8679 return -EINVAL;
8680 }
8681 }
8682
8683 IPW_DEBUG_WX("SET Freq/Channel -> %d\n", fwrq->m);
8684 mutex_lock(&priv->mutex);
8685 ret = ipw_set_channel(priv, channel);
8686 mutex_unlock(&priv->mutex);
8687 return ret;
8688}
8689
8690static int ipw_wx_get_freq(struct net_device *dev,
8691 struct iw_request_info *info,
8692 union iwreq_data *wrqu, char *extra)
8693{
8694 struct ipw_priv *priv = libipw_priv(dev);
8695
8696 wrqu->freq.e = 0;
8697
8698
8699
8700 mutex_lock(&priv->mutex);
8701 if (priv->config & CFG_STATIC_CHANNEL ||
8702 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) {
8703 int i;
8704
8705 i = libipw_channel_to_index(priv->ieee, priv->channel);
8706 BUG_ON(i == -1);
8707 wrqu->freq.e = 1;
8708
8709 switch (libipw_is_valid_channel(priv->ieee, priv->channel)) {
8710 case LIBIPW_52GHZ_BAND:
8711 wrqu->freq.m = priv->ieee->geo.a[i].freq * 100000;
8712 break;
8713
8714 case LIBIPW_24GHZ_BAND:
8715 wrqu->freq.m = priv->ieee->geo.bg[i].freq * 100000;
8716 break;
8717
8718 default:
8719 BUG();
8720 }
8721 } else
8722 wrqu->freq.m = 0;
8723
8724 mutex_unlock(&priv->mutex);
8725 IPW_DEBUG_WX("GET Freq/Channel -> %d\n", priv->channel);
8726 return 0;
8727}
8728
8729static int ipw_wx_set_mode(struct net_device *dev,
8730 struct iw_request_info *info,
8731 union iwreq_data *wrqu, char *extra)
8732{
8733 struct ipw_priv *priv = libipw_priv(dev);
8734 int err = 0;
8735
8736 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);
8737
8738 switch (wrqu->mode) {
8739#ifdef CONFIG_IPW2200_MONITOR
8740 case IW_MODE_MONITOR:
8741#endif
8742 case IW_MODE_ADHOC:
8743 case IW_MODE_INFRA:
8744 break;
8745 case IW_MODE_AUTO:
8746 wrqu->mode = IW_MODE_INFRA;
8747 break;
8748 default:
8749 return -EINVAL;
8750 }
8751 if (wrqu->mode == priv->ieee->iw_mode)
8752 return 0;
8753
8754 mutex_lock(&priv->mutex);
8755
8756 ipw_sw_reset(priv, 0);
8757
8758#ifdef CONFIG_IPW2200_MONITOR
8759 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
8760 priv->net_dev->type = ARPHRD_ETHER;
8761
8762 if (wrqu->mode == IW_MODE_MONITOR)
8763#ifdef CONFIG_IPW2200_RADIOTAP
8764 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
8765#else
8766 priv->net_dev->type = ARPHRD_IEEE80211;
8767#endif
8768#endif
8769
8770
8771
8772 free_firmware();
8773
8774 priv->ieee->iw_mode = wrqu->mode;
8775
8776 schedule_work(&priv->adapter_restart);
8777 mutex_unlock(&priv->mutex);
8778 return err;
8779}
8780
8781static int ipw_wx_get_mode(struct net_device *dev,
8782 struct iw_request_info *info,
8783 union iwreq_data *wrqu, char *extra)
8784{
8785 struct ipw_priv *priv = libipw_priv(dev);
8786 mutex_lock(&priv->mutex);
8787 wrqu->mode = priv->ieee->iw_mode;
8788 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
8789 mutex_unlock(&priv->mutex);
8790 return 0;
8791}
8792
8793
8794static const s32 timeout_duration[] = {
8795 350000,
8796 250000,
8797 75000,
8798 37000,
8799 25000,
8800};
8801
8802static const s32 period_duration[] = {
8803 400000,
8804 700000,
8805 1000000,
8806 1000000,
8807 1000000
8808};
8809
8810static int ipw_wx_get_range(struct net_device *dev,
8811 struct iw_request_info *info,
8812 union iwreq_data *wrqu, char *extra)
8813{
8814 struct ipw_priv *priv = libipw_priv(dev);
8815 struct iw_range *range = (struct iw_range *)extra;
8816 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
8817 int i = 0, j;
8818
8819 wrqu->data.length = sizeof(*range);
8820 memset(range, 0, sizeof(*range));
8821
8822
8823 range->throughput = 27 * 1000 * 1000;
8824
8825 range->max_qual.qual = 100;
8826
8827 range->max_qual.level = 0;
8828 range->max_qual.noise = 0;
8829 range->max_qual.updated = 7;
8830
8831 range->avg_qual.qual = 70;
8832
8833 range->avg_qual.level = 0;
8834 range->avg_qual.noise = 0;
8835 range->avg_qual.updated = 7;
8836 mutex_lock(&priv->mutex);
8837 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
8838
8839 for (i = 0; i < range->num_bitrates; i++)
8840 range->bitrate[i] = (priv->rates.supported_rates[i] & 0x7F) *
8841 500000;
8842
8843 range->max_rts = DEFAULT_RTS_THRESHOLD;
8844 range->min_frag = MIN_FRAG_THRESHOLD;
8845 range->max_frag = MAX_FRAG_THRESHOLD;
8846
8847 range->encoding_size[0] = 5;
8848 range->encoding_size[1] = 13;
8849 range->num_encoding_sizes = 2;
8850 range->max_encoding_tokens = WEP_KEYS;
8851
8852
8853 range->we_version_compiled = WIRELESS_EXT;
8854 range->we_version_source = 18;
8855
8856 i = 0;
8857 if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
8858 for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES; j++) {
8859 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
8860 (geo->bg[j].flags & LIBIPW_CH_PASSIVE_ONLY))
8861 continue;
8862
8863 range->freq[i].i = geo->bg[j].channel;
8864 range->freq[i].m = geo->bg[j].freq * 100000;
8865 range->freq[i].e = 1;
8866 i++;
8867 }
8868 }
8869
8870 if (priv->ieee->mode & IEEE_A) {
8871 for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES; j++) {
8872 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
8873 (geo->a[j].flags & LIBIPW_CH_PASSIVE_ONLY))
8874 continue;
8875
8876 range->freq[i].i = geo->a[j].channel;
8877 range->freq[i].m = geo->a[j].freq * 100000;
8878 range->freq[i].e = 1;
8879 i++;
8880 }
8881 }
8882
8883 range->num_channels = i;
8884 range->num_frequency = i;
8885
8886 mutex_unlock(&priv->mutex);
8887
8888
8889 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
8890 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
8891 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
8892 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
8893 range->event_capa[1] = IW_EVENT_CAPA_K_1;
8894
8895 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
8896 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
8897
8898 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE;
8899
8900 IPW_DEBUG_WX("GET Range\n");
8901 return 0;
8902}
8903
8904static int ipw_wx_set_wap(struct net_device *dev,
8905 struct iw_request_info *info,
8906 union iwreq_data *wrqu, char *extra)
8907{
8908 struct ipw_priv *priv = libipw_priv(dev);
8909
8910 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
8911 return -EINVAL;
8912 mutex_lock(&priv->mutex);
8913 if (is_broadcast_ether_addr(wrqu->ap_addr.sa_data) ||
8914 is_zero_ether_addr(wrqu->ap_addr.sa_data)) {
8915
8916 IPW_DEBUG_WX("Setting AP BSSID to ANY\n");
8917 priv->config &= ~CFG_STATIC_BSSID;
8918 IPW_DEBUG_ASSOC("Attempting to associate with new "
8919 "parameters.\n");
8920 ipw_associate(priv);
8921 mutex_unlock(&priv->mutex);
8922 return 0;
8923 }
8924
8925 priv->config |= CFG_STATIC_BSSID;
8926 if (ether_addr_equal(priv->bssid, wrqu->ap_addr.sa_data)) {
8927 IPW_DEBUG_WX("BSSID set to current BSSID.\n");
8928 mutex_unlock(&priv->mutex);
8929 return 0;
8930 }
8931
8932 IPW_DEBUG_WX("Setting mandatory BSSID to %pM\n",
8933 wrqu->ap_addr.sa_data);
8934
8935 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
8936
8937
8938 IPW_DEBUG_ASSOC("[re]association triggered due to BSSID change.\n");
8939 if (!ipw_disassociate(priv))
8940 ipw_associate(priv);
8941
8942 mutex_unlock(&priv->mutex);
8943 return 0;
8944}
8945
8946static int ipw_wx_get_wap(struct net_device *dev,
8947 struct iw_request_info *info,
8948 union iwreq_data *wrqu, char *extra)
8949{
8950 struct ipw_priv *priv = libipw_priv(dev);
8951
8952
8953
8954 mutex_lock(&priv->mutex);
8955 if (priv->config & CFG_STATIC_BSSID ||
8956 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
8957 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
8958 memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
8959 } else
8960 eth_zero_addr(wrqu->ap_addr.sa_data);
8961
8962 IPW_DEBUG_WX("Getting WAP BSSID: %pM\n",
8963 wrqu->ap_addr.sa_data);
8964 mutex_unlock(&priv->mutex);
8965 return 0;
8966}
8967
8968static int ipw_wx_set_essid(struct net_device *dev,
8969 struct iw_request_info *info,
8970 union iwreq_data *wrqu, char *extra)
8971{
8972 struct ipw_priv *priv = libipw_priv(dev);
8973 int length;
8974
8975 mutex_lock(&priv->mutex);
8976
8977 if (!wrqu->essid.flags)
8978 {
8979 IPW_DEBUG_WX("Setting ESSID to ANY\n");
8980 ipw_disassociate(priv);
8981 priv->config &= ~CFG_STATIC_ESSID;
8982 ipw_associate(priv);
8983 mutex_unlock(&priv->mutex);
8984 return 0;
8985 }
8986
8987 length = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE);
8988
8989 priv->config |= CFG_STATIC_ESSID;
8990
8991 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)
8992 && (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) {
8993 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
8994 mutex_unlock(&priv->mutex);
8995 return 0;
8996 }
8997
8998 IPW_DEBUG_WX("Setting ESSID: '%*pE' (%d)\n", length, extra, length);
8999
9000 priv->essid_len = length;
9001 memcpy(priv->essid, extra, priv->essid_len);
9002
9003
9004 IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n");
9005 if (!ipw_disassociate(priv))
9006 ipw_associate(priv);
9007
9008 mutex_unlock(&priv->mutex);
9009 return 0;
9010}
9011
9012static int ipw_wx_get_essid(struct net_device *dev,
9013 struct iw_request_info *info,
9014 union iwreq_data *wrqu, char *extra)
9015{
9016 struct ipw_priv *priv = libipw_priv(dev);
9017
9018
9019
9020 mutex_lock(&priv->mutex);
9021 if (priv->config & CFG_STATIC_ESSID ||
9022 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
9023 IPW_DEBUG_WX("Getting essid: '%*pE'\n",
9024 priv->essid_len, priv->essid);
9025 memcpy(extra, priv->essid, priv->essid_len);
9026 wrqu->essid.length = priv->essid_len;
9027 wrqu->essid.flags = 1;
9028 } else {
9029 IPW_DEBUG_WX("Getting essid: ANY\n");
9030 wrqu->essid.length = 0;
9031 wrqu->essid.flags = 0;
9032 }
9033 mutex_unlock(&priv->mutex);
9034 return 0;
9035}
9036
9037static int ipw_wx_set_nick(struct net_device *dev,
9038 struct iw_request_info *info,
9039 union iwreq_data *wrqu, char *extra)
9040{
9041 struct ipw_priv *priv = libipw_priv(dev);
9042
9043 IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
9044 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
9045 return -E2BIG;
9046 mutex_lock(&priv->mutex);
9047 wrqu->data.length = min_t(size_t, wrqu->data.length, sizeof(priv->nick));
9048 memset(priv->nick, 0, sizeof(priv->nick));
9049 memcpy(priv->nick, extra, wrqu->data.length);
9050 IPW_DEBUG_TRACE("<<\n");
9051 mutex_unlock(&priv->mutex);
9052 return 0;
9053
9054}
9055
9056static int ipw_wx_get_nick(struct net_device *dev,
9057 struct iw_request_info *info,
9058 union iwreq_data *wrqu, char *extra)
9059{
9060 struct ipw_priv *priv = libipw_priv(dev);
9061 IPW_DEBUG_WX("Getting nick\n");
9062 mutex_lock(&priv->mutex);
9063 wrqu->data.length = strlen(priv->nick);
9064 memcpy(extra, priv->nick, wrqu->data.length);
9065 wrqu->data.flags = 1;
9066 mutex_unlock(&priv->mutex);
9067 return 0;
9068}
9069
9070static int ipw_wx_set_sens(struct net_device *dev,
9071 struct iw_request_info *info,
9072 union iwreq_data *wrqu, char *extra)
9073{
9074 struct ipw_priv *priv = libipw_priv(dev);
9075 int err = 0;
9076
9077 IPW_DEBUG_WX("Setting roaming threshold to %d\n", wrqu->sens.value);
9078 IPW_DEBUG_WX("Setting disassociate threshold to %d\n", 3*wrqu->sens.value);
9079 mutex_lock(&priv->mutex);
9080
9081 if (wrqu->sens.fixed == 0)
9082 {
9083 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
9084 priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
9085 goto out;
9086 }
9087 if ((wrqu->sens.value > IPW_MB_ROAMING_THRESHOLD_MAX) ||
9088 (wrqu->sens.value < IPW_MB_ROAMING_THRESHOLD_MIN)) {
9089 err = -EINVAL;
9090 goto out;
9091 }
9092
9093 priv->roaming_threshold = wrqu->sens.value;
9094 priv->disassociate_threshold = 3*wrqu->sens.value;
9095 out:
9096 mutex_unlock(&priv->mutex);
9097 return err;
9098}
9099
9100static int ipw_wx_get_sens(struct net_device *dev,
9101 struct iw_request_info *info,
9102 union iwreq_data *wrqu, char *extra)
9103{
9104 struct ipw_priv *priv = libipw_priv(dev);
9105 mutex_lock(&priv->mutex);
9106 wrqu->sens.fixed = 1;
9107 wrqu->sens.value = priv->roaming_threshold;
9108 mutex_unlock(&priv->mutex);
9109
9110 IPW_DEBUG_WX("GET roaming threshold -> %s %d\n",
9111 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
9112
9113 return 0;
9114}
9115
9116static int ipw_wx_set_rate(struct net_device *dev,
9117 struct iw_request_info *info,
9118 union iwreq_data *wrqu, char *extra)
9119{
9120
9121 struct ipw_priv *priv = libipw_priv(dev);
9122 u32 target_rate = wrqu->bitrate.value;
9123 u32 fixed, mask;
9124
9125
9126
9127
9128
9129 if (target_rate == -1) {
9130 fixed = 0;
9131 mask = LIBIPW_DEFAULT_RATES_MASK;
9132
9133 goto apply;
9134 }
9135
9136 mask = 0;
9137 fixed = wrqu->bitrate.fixed;
9138
9139 if (target_rate == 1000000 || !fixed)
9140 mask |= LIBIPW_CCK_RATE_1MB_MASK;
9141 if (target_rate == 1000000)
9142 goto apply;
9143
9144 if (target_rate == 2000000 || !fixed)
9145 mask |= LIBIPW_CCK_RATE_2MB_MASK;
9146 if (target_rate == 2000000)
9147 goto apply;
9148
9149 if (target_rate == 5500000 || !fixed)
9150 mask |= LIBIPW_CCK_RATE_5MB_MASK;
9151 if (target_rate == 5500000)
9152 goto apply;
9153
9154 if (target_rate == 6000000 || !fixed)
9155 mask |= LIBIPW_OFDM_RATE_6MB_MASK;
9156 if (target_rate == 6000000)
9157 goto apply;
9158
9159 if (target_rate == 9000000 || !fixed)
9160 mask |= LIBIPW_OFDM_RATE_9MB_MASK;
9161 if (target_rate == 9000000)
9162 goto apply;
9163
9164 if (target_rate == 11000000 || !fixed)
9165 mask |= LIBIPW_CCK_RATE_11MB_MASK;
9166 if (target_rate == 11000000)
9167 goto apply;
9168
9169 if (target_rate == 12000000 || !fixed)
9170 mask |= LIBIPW_OFDM_RATE_12MB_MASK;
9171 if (target_rate == 12000000)
9172 goto apply;
9173
9174 if (target_rate == 18000000 || !fixed)
9175 mask |= LIBIPW_OFDM_RATE_18MB_MASK;
9176 if (target_rate == 18000000)
9177 goto apply;
9178
9179 if (target_rate == 24000000 || !fixed)
9180 mask |= LIBIPW_OFDM_RATE_24MB_MASK;
9181 if (target_rate == 24000000)
9182 goto apply;
9183
9184 if (target_rate == 36000000 || !fixed)
9185 mask |= LIBIPW_OFDM_RATE_36MB_MASK;
9186 if (target_rate == 36000000)
9187 goto apply;
9188
9189 if (target_rate == 48000000 || !fixed)
9190 mask |= LIBIPW_OFDM_RATE_48MB_MASK;
9191 if (target_rate == 48000000)
9192 goto apply;
9193
9194 if (target_rate == 54000000 || !fixed)
9195 mask |= LIBIPW_OFDM_RATE_54MB_MASK;
9196 if (target_rate == 54000000)
9197 goto apply;
9198
9199 IPW_DEBUG_WX("invalid rate specified, returning error\n");
9200 return -EINVAL;
9201
9202 apply:
9203 IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
9204 mask, fixed ? "fixed" : "sub-rates");
9205 mutex_lock(&priv->mutex);
9206 if (mask == LIBIPW_DEFAULT_RATES_MASK) {
9207 priv->config &= ~CFG_FIXED_RATE;
9208 ipw_set_fixed_rate(priv, priv->ieee->mode);
9209 } else
9210 priv->config |= CFG_FIXED_RATE;
9211
9212 if (priv->rates_mask == mask) {
9213 IPW_DEBUG_WX("Mask set to current mask.\n");
9214 mutex_unlock(&priv->mutex);
9215 return 0;
9216 }
9217
9218 priv->rates_mask = mask;
9219
9220
9221 IPW_DEBUG_ASSOC("[re]association triggered due to rates change.\n");
9222 if (!ipw_disassociate(priv))
9223 ipw_associate(priv);
9224
9225 mutex_unlock(&priv->mutex);
9226 return 0;
9227}
9228
9229static int ipw_wx_get_rate(struct net_device *dev,
9230 struct iw_request_info *info,
9231 union iwreq_data *wrqu, char *extra)
9232{
9233 struct ipw_priv *priv = libipw_priv(dev);
9234 mutex_lock(&priv->mutex);
9235 wrqu->bitrate.value = priv->last_rate;
9236 wrqu->bitrate.fixed = (priv->config & CFG_FIXED_RATE) ? 1 : 0;
9237 mutex_unlock(&priv->mutex);
9238 IPW_DEBUG_WX("GET Rate -> %d\n", wrqu->bitrate.value);
9239 return 0;
9240}
9241
9242static int ipw_wx_set_rts(struct net_device *dev,
9243 struct iw_request_info *info,
9244 union iwreq_data *wrqu, char *extra)
9245{
9246 struct ipw_priv *priv = libipw_priv(dev);
9247 mutex_lock(&priv->mutex);
9248 if (wrqu->rts.disabled || !wrqu->rts.fixed)
9249 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
9250 else {
9251 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
9252 wrqu->rts.value > MAX_RTS_THRESHOLD) {
9253 mutex_unlock(&priv->mutex);
9254 return -EINVAL;
9255 }
9256 priv->rts_threshold = wrqu->rts.value;
9257 }
9258
9259 ipw_send_rts_threshold(priv, priv->rts_threshold);
9260 mutex_unlock(&priv->mutex);
9261 IPW_DEBUG_WX("SET RTS Threshold -> %d\n", priv->rts_threshold);
9262 return 0;
9263}
9264
9265static int ipw_wx_get_rts(struct net_device *dev,
9266 struct iw_request_info *info,
9267 union iwreq_data *wrqu, char *extra)
9268{
9269 struct ipw_priv *priv = libipw_priv(dev);
9270 mutex_lock(&priv->mutex);
9271 wrqu->rts.value = priv->rts_threshold;
9272 wrqu->rts.fixed = 0;
9273 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
9274 mutex_unlock(&priv->mutex);
9275 IPW_DEBUG_WX("GET RTS Threshold -> %d\n", wrqu->rts.value);
9276 return 0;
9277}
9278
9279static int ipw_wx_set_txpow(struct net_device *dev,
9280 struct iw_request_info *info,
9281 union iwreq_data *wrqu, char *extra)
9282{
9283 struct ipw_priv *priv = libipw_priv(dev);
9284 int err = 0;
9285
9286 mutex_lock(&priv->mutex);
9287 if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
9288 err = -EINPROGRESS;
9289 goto out;
9290 }
9291
9292 if (!wrqu->power.fixed)
9293 wrqu->power.value = IPW_TX_POWER_DEFAULT;
9294
9295 if (wrqu->power.flags != IW_TXPOW_DBM) {
9296 err = -EINVAL;
9297 goto out;
9298 }
9299
9300 if ((wrqu->power.value > IPW_TX_POWER_MAX) ||
9301 (wrqu->power.value < IPW_TX_POWER_MIN)) {
9302 err = -EINVAL;
9303 goto out;
9304 }
9305
9306 priv->tx_power = wrqu->power.value;
9307 err = ipw_set_tx_power(priv);
9308 out:
9309 mutex_unlock(&priv->mutex);
9310 return err;
9311}
9312
9313static int ipw_wx_get_txpow(struct net_device *dev,
9314 struct iw_request_info *info,
9315 union iwreq_data *wrqu, char *extra)
9316{
9317 struct ipw_priv *priv = libipw_priv(dev);
9318 mutex_lock(&priv->mutex);
9319 wrqu->power.value = priv->tx_power;
9320 wrqu->power.fixed = 1;
9321 wrqu->power.flags = IW_TXPOW_DBM;
9322 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
9323 mutex_unlock(&priv->mutex);
9324
9325 IPW_DEBUG_WX("GET TX Power -> %s %d\n",
9326 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
9327
9328 return 0;
9329}
9330
9331static int ipw_wx_set_frag(struct net_device *dev,
9332 struct iw_request_info *info,
9333 union iwreq_data *wrqu, char *extra)
9334{
9335 struct ipw_priv *priv = libipw_priv(dev);
9336 mutex_lock(&priv->mutex);
9337 if (wrqu->frag.disabled || !wrqu->frag.fixed)
9338 priv->ieee->fts = DEFAULT_FTS;
9339 else {
9340 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
9341 wrqu->frag.value > MAX_FRAG_THRESHOLD) {
9342 mutex_unlock(&priv->mutex);
9343 return -EINVAL;
9344 }
9345
9346 priv->ieee->fts = wrqu->frag.value & ~0x1;
9347 }
9348
9349 ipw_send_frag_threshold(priv, wrqu->frag.value);
9350 mutex_unlock(&priv->mutex);
9351 IPW_DEBUG_WX("SET Frag Threshold -> %d\n", wrqu->frag.value);
9352 return 0;
9353}
9354
9355static int ipw_wx_get_frag(struct net_device *dev,
9356 struct iw_request_info *info,
9357 union iwreq_data *wrqu, char *extra)
9358{
9359 struct ipw_priv *priv = libipw_priv(dev);
9360 mutex_lock(&priv->mutex);
9361 wrqu->frag.value = priv->ieee->fts;
9362 wrqu->frag.fixed = 0;
9363 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
9364 mutex_unlock(&priv->mutex);
9365 IPW_DEBUG_WX("GET Frag Threshold -> %d\n", wrqu->frag.value);
9366
9367 return 0;
9368}
9369
9370static int ipw_wx_set_retry(struct net_device *dev,
9371 struct iw_request_info *info,
9372 union iwreq_data *wrqu, char *extra)
9373{
9374 struct ipw_priv *priv = libipw_priv(dev);
9375
9376 if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
9377 return -EINVAL;
9378
9379 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
9380 return 0;
9381
9382 if (wrqu->retry.value < 0 || wrqu->retry.value >= 255)
9383 return -EINVAL;
9384
9385 mutex_lock(&priv->mutex);
9386 if (wrqu->retry.flags & IW_RETRY_SHORT)
9387 priv->short_retry_limit = (u8) wrqu->retry.value;
9388 else if (wrqu->retry.flags & IW_RETRY_LONG)
9389 priv->long_retry_limit = (u8) wrqu->retry.value;
9390 else {
9391 priv->short_retry_limit = (u8) wrqu->retry.value;
9392 priv->long_retry_limit = (u8) wrqu->retry.value;
9393 }
9394
9395 ipw_send_retry_limit(priv, priv->short_retry_limit,
9396 priv->long_retry_limit);
9397 mutex_unlock(&priv->mutex);
9398 IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n",
9399 priv->short_retry_limit, priv->long_retry_limit);
9400 return 0;
9401}
9402
9403static int ipw_wx_get_retry(struct net_device *dev,
9404 struct iw_request_info *info,
9405 union iwreq_data *wrqu, char *extra)
9406{
9407 struct ipw_priv *priv = libipw_priv(dev);
9408
9409 mutex_lock(&priv->mutex);
9410 wrqu->retry.disabled = 0;
9411
9412 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
9413 mutex_unlock(&priv->mutex);
9414 return -EINVAL;
9415 }
9416
9417 if (wrqu->retry.flags & IW_RETRY_LONG) {
9418 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
9419 wrqu->retry.value = priv->long_retry_limit;
9420 } else if (wrqu->retry.flags & IW_RETRY_SHORT) {
9421 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
9422 wrqu->retry.value = priv->short_retry_limit;
9423 } else {
9424 wrqu->retry.flags = IW_RETRY_LIMIT;
9425 wrqu->retry.value = priv->short_retry_limit;
9426 }
9427 mutex_unlock(&priv->mutex);
9428
9429 IPW_DEBUG_WX("GET retry -> %d\n", wrqu->retry.value);
9430
9431 return 0;
9432}
9433
9434static int ipw_wx_set_scan(struct net_device *dev,
9435 struct iw_request_info *info,
9436 union iwreq_data *wrqu, char *extra)
9437{
9438 struct ipw_priv *priv = libipw_priv(dev);
9439 struct iw_scan_req *req = (struct iw_scan_req *)extra;
9440 struct delayed_work *work = NULL;
9441
9442 mutex_lock(&priv->mutex);
9443
9444 priv->user_requested_scan = 1;
9445
9446 if (wrqu->data.length == sizeof(struct iw_scan_req)) {
9447 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
9448 int len = min((int)req->essid_len,
9449 (int)sizeof(priv->direct_scan_ssid));
9450 memcpy(priv->direct_scan_ssid, req->essid, len);
9451 priv->direct_scan_ssid_len = len;
9452 work = &priv->request_direct_scan;
9453 } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) {
9454 work = &priv->request_passive_scan;
9455 }
9456 } else {
9457
9458 work = &priv->request_scan;
9459 }
9460
9461 mutex_unlock(&priv->mutex);
9462
9463 IPW_DEBUG_WX("Start scan\n");
9464
9465 schedule_delayed_work(work, 0);
9466
9467 return 0;
9468}
9469
9470static int ipw_wx_get_scan(struct net_device *dev,
9471 struct iw_request_info *info,
9472 union iwreq_data *wrqu, char *extra)
9473{
9474 struct ipw_priv *priv = libipw_priv(dev);
9475 return libipw_wx_get_scan(priv->ieee, info, wrqu, extra);
9476}
9477
9478static int ipw_wx_set_encode(struct net_device *dev,
9479 struct iw_request_info *info,
9480 union iwreq_data *wrqu, char *key)
9481{
9482 struct ipw_priv *priv = libipw_priv(dev);
9483 int ret;
9484 u32 cap = priv->capability;
9485
9486 mutex_lock(&priv->mutex);
9487 ret = libipw_wx_set_encode(priv->ieee, info, wrqu, key);
9488
9489
9490
9491 if (cap != priv->capability &&
9492 priv->ieee->iw_mode == IW_MODE_ADHOC &&
9493 priv->status & STATUS_ASSOCIATED)
9494 ipw_disassociate(priv);
9495
9496 mutex_unlock(&priv->mutex);
9497 return ret;
9498}
9499
9500static int ipw_wx_get_encode(struct net_device *dev,
9501 struct iw_request_info *info,
9502 union iwreq_data *wrqu, char *key)
9503{
9504 struct ipw_priv *priv = libipw_priv(dev);
9505 return libipw_wx_get_encode(priv->ieee, info, wrqu, key);
9506}
9507
9508static int ipw_wx_set_power(struct net_device *dev,
9509 struct iw_request_info *info,
9510 union iwreq_data *wrqu, char *extra)
9511{
9512 struct ipw_priv *priv = libipw_priv(dev);
9513 int err;
9514 mutex_lock(&priv->mutex);
9515 if (wrqu->power.disabled) {
9516 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
9517 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
9518 if (err) {
9519 IPW_DEBUG_WX("failed setting power mode.\n");
9520 mutex_unlock(&priv->mutex);
9521 return err;
9522 }
9523 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
9524 mutex_unlock(&priv->mutex);
9525 return 0;
9526 }
9527
9528 switch (wrqu->power.flags & IW_POWER_MODE) {
9529 case IW_POWER_ON:
9530 case IW_POWER_MODE:
9531 case IW_POWER_ALL_R:
9532 break;
9533 default:
9534 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
9535 wrqu->power.flags);
9536 mutex_unlock(&priv->mutex);
9537 return -EOPNOTSUPP;
9538 }
9539
9540
9541
9542 if (IPW_POWER_LEVEL(priv->power_mode) == IPW_POWER_AC)
9543 priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY;
9544 else
9545 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
9546
9547 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
9548 if (err) {
9549 IPW_DEBUG_WX("failed setting power mode.\n");
9550 mutex_unlock(&priv->mutex);
9551 return err;
9552 }
9553
9554 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
9555 mutex_unlock(&priv->mutex);
9556 return 0;
9557}
9558
9559static int ipw_wx_get_power(struct net_device *dev,
9560 struct iw_request_info *info,
9561 union iwreq_data *wrqu, char *extra)
9562{
9563 struct ipw_priv *priv = libipw_priv(dev);
9564 mutex_lock(&priv->mutex);
9565 if (!(priv->power_mode & IPW_POWER_ENABLED))
9566 wrqu->power.disabled = 1;
9567 else
9568 wrqu->power.disabled = 0;
9569
9570 mutex_unlock(&priv->mutex);
9571 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
9572
9573 return 0;
9574}
9575
9576static int ipw_wx_set_powermode(struct net_device *dev,
9577 struct iw_request_info *info,
9578 union iwreq_data *wrqu, char *extra)
9579{
9580 struct ipw_priv *priv = libipw_priv(dev);
9581 int mode = *(int *)extra;
9582 int err;
9583
9584 mutex_lock(&priv->mutex);
9585 if ((mode < 1) || (mode > IPW_POWER_LIMIT))
9586 mode = IPW_POWER_AC;
9587
9588 if (IPW_POWER_LEVEL(priv->power_mode) != mode) {
9589 err = ipw_send_power_mode(priv, mode);
9590 if (err) {
9591 IPW_DEBUG_WX("failed setting power mode.\n");
9592 mutex_unlock(&priv->mutex);
9593 return err;
9594 }
9595 priv->power_mode = IPW_POWER_ENABLED | mode;
9596 }
9597 mutex_unlock(&priv->mutex);
9598 return 0;
9599}
9600
9601#define MAX_WX_STRING 80
9602static int ipw_wx_get_powermode(struct net_device *dev,
9603 struct iw_request_info *info,
9604 union iwreq_data *wrqu, char *extra)
9605{
9606 struct ipw_priv *priv = libipw_priv(dev);
9607 int level = IPW_POWER_LEVEL(priv->power_mode);
9608 char *p = extra;
9609
9610 p += snprintf(p, MAX_WX_STRING, "Power save level: %d ", level);
9611
9612 switch (level) {
9613 case IPW_POWER_AC:
9614 p += snprintf(p, MAX_WX_STRING - (p - extra), "(AC)");
9615 break;
9616 case IPW_POWER_BATTERY:
9617 p += snprintf(p, MAX_WX_STRING - (p - extra), "(BATTERY)");
9618 break;
9619 default:
9620 p += snprintf(p, MAX_WX_STRING - (p - extra),
9621 "(Timeout %dms, Period %dms)",
9622 timeout_duration[level - 1] / 1000,
9623 period_duration[level - 1] / 1000);
9624 }
9625
9626 if (!(priv->power_mode & IPW_POWER_ENABLED))
9627 p += snprintf(p, MAX_WX_STRING - (p - extra), " OFF");
9628
9629 wrqu->data.length = p - extra + 1;
9630
9631 return 0;
9632}
9633
9634static int ipw_wx_set_wireless_mode(struct net_device *dev,
9635 struct iw_request_info *info,
9636 union iwreq_data *wrqu, char *extra)
9637{
9638 struct ipw_priv *priv = libipw_priv(dev);
9639 int mode = *(int *)extra;
9640 u8 band = 0, modulation = 0;
9641
9642 if (mode == 0 || mode & ~IEEE_MODE_MASK) {
9643 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
9644 return -EINVAL;
9645 }
9646 mutex_lock(&priv->mutex);
9647 if (priv->adapter == IPW_2915ABG) {
9648 priv->ieee->abg_true = 1;
9649 if (mode & IEEE_A) {
9650 band |= LIBIPW_52GHZ_BAND;
9651 modulation |= LIBIPW_OFDM_MODULATION;
9652 } else
9653 priv->ieee->abg_true = 0;
9654 } else {
9655 if (mode & IEEE_A) {
9656 IPW_WARNING("Attempt to set 2200BG into "
9657 "802.11a mode\n");
9658 mutex_unlock(&priv->mutex);
9659 return -EINVAL;
9660 }
9661
9662 priv->ieee->abg_true = 0;
9663 }
9664
9665 if (mode & IEEE_B) {
9666 band |= LIBIPW_24GHZ_BAND;
9667 modulation |= LIBIPW_CCK_MODULATION;
9668 } else
9669 priv->ieee->abg_true = 0;
9670
9671 if (mode & IEEE_G) {
9672 band |= LIBIPW_24GHZ_BAND;
9673 modulation |= LIBIPW_OFDM_MODULATION;
9674 } else
9675 priv->ieee->abg_true = 0;
9676
9677 priv->ieee->mode = mode;
9678 priv->ieee->freq_band = band;
9679 priv->ieee->modulation = modulation;
9680 init_supported_rates(priv, &priv->rates);
9681
9682
9683 IPW_DEBUG_ASSOC("[re]association triggered due to mode change.\n");
9684 if (!ipw_disassociate(priv)) {
9685 ipw_send_supported_rates(priv, &priv->rates);
9686 ipw_associate(priv);
9687 }
9688
9689
9690 ipw_led_band_on(priv);
9691
9692 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
9693 mode & IEEE_A ? 'a' : '.',
9694 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
9695 mutex_unlock(&priv->mutex);
9696 return 0;
9697}
9698
9699static int ipw_wx_get_wireless_mode(struct net_device *dev,
9700 struct iw_request_info *info,
9701 union iwreq_data *wrqu, char *extra)
9702{
9703 struct ipw_priv *priv = libipw_priv(dev);
9704 mutex_lock(&priv->mutex);
9705 switch (priv->ieee->mode) {
9706 case IEEE_A:
9707 strncpy(extra, "802.11a (1)", MAX_WX_STRING);
9708 break;
9709 case IEEE_B:
9710 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
9711 break;
9712 case IEEE_A | IEEE_B:
9713 strncpy(extra, "802.11ab (3)", MAX_WX_STRING);
9714 break;
9715 case IEEE_G:
9716 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
9717 break;
9718 case IEEE_A | IEEE_G:
9719 strncpy(extra, "802.11ag (5)", MAX_WX_STRING);
9720 break;
9721 case IEEE_B | IEEE_G:
9722 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
9723 break;
9724 case IEEE_A | IEEE_B | IEEE_G:
9725 strncpy(extra, "802.11abg (7)", MAX_WX_STRING);
9726 break;
9727 default:
9728 strncpy(extra, "unknown", MAX_WX_STRING);
9729 break;
9730 }
9731 extra[MAX_WX_STRING - 1] = '\0';
9732
9733 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
9734
9735 wrqu->data.length = strlen(extra) + 1;
9736 mutex_unlock(&priv->mutex);
9737
9738 return 0;
9739}
9740
9741static int ipw_wx_set_preamble(struct net_device *dev,
9742 struct iw_request_info *info,
9743 union iwreq_data *wrqu, char *extra)
9744{
9745 struct ipw_priv *priv = libipw_priv(dev);
9746 int mode = *(int *)extra;
9747 mutex_lock(&priv->mutex);
9748
9749 if (mode == 1) {
9750 if (!(priv->config & CFG_PREAMBLE_LONG)) {
9751 priv->config |= CFG_PREAMBLE_LONG;
9752
9753
9754 IPW_DEBUG_ASSOC
9755 ("[re]association triggered due to preamble change.\n");
9756 if (!ipw_disassociate(priv))
9757 ipw_associate(priv);
9758 }
9759 goto done;
9760 }
9761
9762 if (mode == 0) {
9763 priv->config &= ~CFG_PREAMBLE_LONG;
9764 goto done;
9765 }
9766 mutex_unlock(&priv->mutex);
9767 return -EINVAL;
9768
9769 done:
9770 mutex_unlock(&priv->mutex);
9771 return 0;
9772}
9773
9774static int ipw_wx_get_preamble(struct net_device *dev,
9775 struct iw_request_info *info,
9776 union iwreq_data *wrqu, char *extra)
9777{
9778 struct ipw_priv *priv = libipw_priv(dev);
9779 mutex_lock(&priv->mutex);
9780 if (priv->config & CFG_PREAMBLE_LONG)
9781 snprintf(wrqu->name, IFNAMSIZ, "long (1)");
9782 else
9783 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
9784 mutex_unlock(&priv->mutex);
9785 return 0;
9786}
9787
9788#ifdef CONFIG_IPW2200_MONITOR
9789static int ipw_wx_set_monitor(struct net_device *dev,
9790 struct iw_request_info *info,
9791 union iwreq_data *wrqu, char *extra)
9792{
9793 struct ipw_priv *priv = libipw_priv(dev);
9794 int *parms = (int *)extra;
9795 int enable = (parms[0] > 0);
9796 mutex_lock(&priv->mutex);
9797 IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
9798 if (enable) {
9799 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
9800#ifdef CONFIG_IPW2200_RADIOTAP
9801 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
9802#else
9803 priv->net_dev->type = ARPHRD_IEEE80211;
9804#endif
9805 schedule_work(&priv->adapter_restart);
9806 }
9807
9808 ipw_set_channel(priv, parms[1]);
9809 } else {
9810 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
9811 mutex_unlock(&priv->mutex);
9812 return 0;
9813 }
9814 priv->net_dev->type = ARPHRD_ETHER;
9815 schedule_work(&priv->adapter_restart);
9816 }
9817 mutex_unlock(&priv->mutex);
9818 return 0;
9819}
9820
9821#endif
9822
9823static int ipw_wx_reset(struct net_device *dev,
9824 struct iw_request_info *info,
9825 union iwreq_data *wrqu, char *extra)
9826{
9827 struct ipw_priv *priv = libipw_priv(dev);
9828 IPW_DEBUG_WX("RESET\n");
9829 schedule_work(&priv->adapter_restart);
9830 return 0;
9831}
9832
9833static int ipw_wx_sw_reset(struct net_device *dev,
9834 struct iw_request_info *info,
9835 union iwreq_data *wrqu, char *extra)
9836{
9837 struct ipw_priv *priv = libipw_priv(dev);
9838 union iwreq_data wrqu_sec = {
9839 .encoding = {
9840 .flags = IW_ENCODE_DISABLED,
9841 },
9842 };
9843 int ret;
9844
9845 IPW_DEBUG_WX("SW_RESET\n");
9846
9847 mutex_lock(&priv->mutex);
9848
9849 ret = ipw_sw_reset(priv, 2);
9850 if (!ret) {
9851 free_firmware();
9852 ipw_adapter_restart(priv);
9853 }
9854
9855
9856
9857 ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);
9858
9859 mutex_unlock(&priv->mutex);
9860 libipw_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
9861 mutex_lock(&priv->mutex);
9862
9863 if (!(priv->status & STATUS_RF_KILL_MASK)) {
9864
9865 IPW_DEBUG_ASSOC("[re]association triggered due to sw "
9866 "reset.\n");
9867 if (!ipw_disassociate(priv))
9868 ipw_associate(priv);
9869 }
9870
9871 mutex_unlock(&priv->mutex);
9872
9873 return 0;
9874}
9875
9876
9877static iw_handler ipw_wx_handlers[] = {
9878 IW_HANDLER(SIOCGIWNAME, (iw_handler)cfg80211_wext_giwname),
9879 IW_HANDLER(SIOCSIWFREQ, ipw_wx_set_freq),
9880 IW_HANDLER(SIOCGIWFREQ, ipw_wx_get_freq),
9881 IW_HANDLER(SIOCSIWMODE, ipw_wx_set_mode),
9882 IW_HANDLER(SIOCGIWMODE, ipw_wx_get_mode),
9883 IW_HANDLER(SIOCSIWSENS, ipw_wx_set_sens),
9884 IW_HANDLER(SIOCGIWSENS, ipw_wx_get_sens),
9885 IW_HANDLER(SIOCGIWRANGE, ipw_wx_get_range),
9886 IW_HANDLER(SIOCSIWAP, ipw_wx_set_wap),
9887 IW_HANDLER(SIOCGIWAP, ipw_wx_get_wap),
9888 IW_HANDLER(SIOCSIWSCAN, ipw_wx_set_scan),
9889 IW_HANDLER(SIOCGIWSCAN, ipw_wx_get_scan),
9890 IW_HANDLER(SIOCSIWESSID, ipw_wx_set_essid),
9891 IW_HANDLER(SIOCGIWESSID, ipw_wx_get_essid),
9892 IW_HANDLER(SIOCSIWNICKN, ipw_wx_set_nick),
9893 IW_HANDLER(SIOCGIWNICKN, ipw_wx_get_nick),
9894 IW_HANDLER(SIOCSIWRATE, ipw_wx_set_rate),
9895 IW_HANDLER(SIOCGIWRATE, ipw_wx_get_rate),
9896 IW_HANDLER(SIOCSIWRTS, ipw_wx_set_rts),
9897 IW_HANDLER(SIOCGIWRTS, ipw_wx_get_rts),
9898 IW_HANDLER(SIOCSIWFRAG, ipw_wx_set_frag),
9899 IW_HANDLER(SIOCGIWFRAG, ipw_wx_get_frag),
9900 IW_HANDLER(SIOCSIWTXPOW, ipw_wx_set_txpow),
9901 IW_HANDLER(SIOCGIWTXPOW, ipw_wx_get_txpow),
9902 IW_HANDLER(SIOCSIWRETRY, ipw_wx_set_retry),
9903 IW_HANDLER(SIOCGIWRETRY, ipw_wx_get_retry),
9904 IW_HANDLER(SIOCSIWENCODE, ipw_wx_set_encode),
9905 IW_HANDLER(SIOCGIWENCODE, ipw_wx_get_encode),
9906 IW_HANDLER(SIOCSIWPOWER, ipw_wx_set_power),
9907 IW_HANDLER(SIOCGIWPOWER, ipw_wx_get_power),
9908 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
9909 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
9910 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
9911 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
9912 IW_HANDLER(SIOCSIWGENIE, ipw_wx_set_genie),
9913 IW_HANDLER(SIOCGIWGENIE, ipw_wx_get_genie),
9914 IW_HANDLER(SIOCSIWMLME, ipw_wx_set_mlme),
9915 IW_HANDLER(SIOCSIWAUTH, ipw_wx_set_auth),
9916 IW_HANDLER(SIOCGIWAUTH, ipw_wx_get_auth),
9917 IW_HANDLER(SIOCSIWENCODEEXT, ipw_wx_set_encodeext),
9918 IW_HANDLER(SIOCGIWENCODEEXT, ipw_wx_get_encodeext),
9919};
9920
9921enum {
9922 IPW_PRIV_SET_POWER = SIOCIWFIRSTPRIV,
9923 IPW_PRIV_GET_POWER,
9924 IPW_PRIV_SET_MODE,
9925 IPW_PRIV_GET_MODE,
9926 IPW_PRIV_SET_PREAMBLE,
9927 IPW_PRIV_GET_PREAMBLE,
9928 IPW_PRIV_RESET,
9929 IPW_PRIV_SW_RESET,
9930#ifdef CONFIG_IPW2200_MONITOR
9931 IPW_PRIV_SET_MONITOR,
9932#endif
9933};
9934
9935static struct iw_priv_args ipw_priv_args[] = {
9936 {
9937 .cmd = IPW_PRIV_SET_POWER,
9938 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9939 .name = "set_power"},
9940 {
9941 .cmd = IPW_PRIV_GET_POWER,
9942 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
9943 .name = "get_power"},
9944 {
9945 .cmd = IPW_PRIV_SET_MODE,
9946 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9947 .name = "set_mode"},
9948 {
9949 .cmd = IPW_PRIV_GET_MODE,
9950 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
9951 .name = "get_mode"},
9952 {
9953 .cmd = IPW_PRIV_SET_PREAMBLE,
9954 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9955 .name = "set_preamble"},
9956 {
9957 .cmd = IPW_PRIV_GET_PREAMBLE,
9958 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ,
9959 .name = "get_preamble"},
9960 {
9961 IPW_PRIV_RESET,
9962 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
9963 {
9964 IPW_PRIV_SW_RESET,
9965 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "sw_reset"},
9966#ifdef CONFIG_IPW2200_MONITOR
9967 {
9968 IPW_PRIV_SET_MONITOR,
9969 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
9970#endif
9971};
9972
9973static iw_handler ipw_priv_handler[] = {
9974 ipw_wx_set_powermode,
9975 ipw_wx_get_powermode,
9976 ipw_wx_set_wireless_mode,
9977 ipw_wx_get_wireless_mode,
9978 ipw_wx_set_preamble,
9979 ipw_wx_get_preamble,
9980 ipw_wx_reset,
9981 ipw_wx_sw_reset,
9982#ifdef CONFIG_IPW2200_MONITOR
9983 ipw_wx_set_monitor,
9984#endif
9985};
9986
9987static const struct iw_handler_def ipw_wx_handler_def = {
9988 .standard = ipw_wx_handlers,
9989 .num_standard = ARRAY_SIZE(ipw_wx_handlers),
9990 .num_private = ARRAY_SIZE(ipw_priv_handler),
9991 .num_private_args = ARRAY_SIZE(ipw_priv_args),
9992 .private = ipw_priv_handler,
9993 .private_args = ipw_priv_args,
9994 .get_wireless_stats = ipw_get_wireless_stats,
9995};
9996
9997
9998
9999
10000
10001
10002static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
10003{
10004 struct ipw_priv *priv = libipw_priv(dev);
10005 struct iw_statistics *wstats;
10006
10007 wstats = &priv->wstats;
10008
10009
10010
10011
10012
10013
10014 if (!(priv->status & STATUS_ASSOCIATED)) {
10015 wstats->miss.beacon = 0;
10016 wstats->discard.retries = 0;
10017 wstats->qual.qual = 0;
10018 wstats->qual.level = 0;
10019 wstats->qual.noise = 0;
10020 wstats->qual.updated = 7;
10021 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
10022 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
10023 return wstats;
10024 }
10025
10026 wstats->qual.qual = priv->quality;
10027 wstats->qual.level = priv->exp_avg_rssi;
10028 wstats->qual.noise = priv->exp_avg_noise;
10029 wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |
10030 IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM;
10031
10032 wstats->miss.beacon = average_value(&priv->average_missed_beacons);
10033 wstats->discard.retries = priv->last_tx_failures;
10034 wstats->discard.code = priv->ieee->ieee_stats.rx_discards_undecryptable;
10035
10036
10037
10038
10039
10040 return wstats;
10041}
10042
10043
10044
10045static void init_sys_config(struct ipw_sys_config *sys_config)
10046{
10047 memset(sys_config, 0, sizeof(struct ipw_sys_config));
10048 sys_config->bt_coexistence = 0;
10049 sys_config->answer_broadcast_ssid_probe = 0;
10050 sys_config->accept_all_data_frames = 0;
10051 sys_config->accept_non_directed_frames = 1;
10052 sys_config->exclude_unicast_unencrypted = 0;
10053 sys_config->disable_unicast_decryption = 1;
10054 sys_config->exclude_multicast_unencrypted = 0;
10055 sys_config->disable_multicast_decryption = 1;
10056 if (antenna < CFG_SYS_ANTENNA_BOTH || antenna > CFG_SYS_ANTENNA_B)
10057 antenna = CFG_SYS_ANTENNA_BOTH;
10058 sys_config->antenna_diversity = antenna;
10059 sys_config->pass_crc_to_host = 0;
10060 sys_config->dot11g_auto_detection = 0;
10061 sys_config->enable_cts_to_self = 0;
10062 sys_config->bt_coexist_collision_thr = 0;
10063 sys_config->pass_noise_stats_to_host = 1;
10064 sys_config->silence_threshold = 0x1e;
10065}
10066
10067static int ipw_net_open(struct net_device *dev)
10068{
10069 IPW_DEBUG_INFO("dev->open\n");
10070 netif_start_queue(dev);
10071 return 0;
10072}
10073
10074static int ipw_net_stop(struct net_device *dev)
10075{
10076 IPW_DEBUG_INFO("dev->close\n");
10077 netif_stop_queue(dev);
10078 return 0;
10079}
10080
10081
10082
10083
10084
10085
10086
10087
10088static int ipw_tx_skb(struct ipw_priv *priv, struct libipw_txb *txb,
10089 int pri)
10090{
10091 struct libipw_hdr_3addrqos *hdr = (struct libipw_hdr_3addrqos *)
10092 txb->fragments[0]->data;
10093 int i = 0;
10094 struct tfd_frame *tfd;
10095#ifdef CONFIG_IPW2200_QOS
10096 int tx_id = ipw_get_tx_queue_number(priv, pri);
10097 struct clx2_tx_queue *txq = &priv->txq[tx_id];
10098#else
10099 struct clx2_tx_queue *txq = &priv->txq[0];
10100#endif
10101 struct clx2_queue *q = &txq->q;
10102 u8 id, hdr_len, unicast;
10103 int fc;
10104
10105 if (!(priv->status & STATUS_ASSOCIATED))
10106 goto drop;
10107
10108 hdr_len = libipw_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
10109 switch (priv->ieee->iw_mode) {
10110 case IW_MODE_ADHOC:
10111 unicast = !is_multicast_ether_addr(hdr->addr1);
10112 id = ipw_find_station(priv, hdr->addr1);
10113 if (id == IPW_INVALID_STATION) {
10114 id = ipw_add_station(priv, hdr->addr1);
10115 if (id == IPW_INVALID_STATION) {
10116 IPW_WARNING("Attempt to send data to "
10117 "invalid cell: %pM\n",
10118 hdr->addr1);
10119 goto drop;
10120 }
10121 }
10122 break;
10123
10124 case IW_MODE_INFRA:
10125 default:
10126 unicast = !is_multicast_ether_addr(hdr->addr3);
10127 id = 0;
10128 break;
10129 }
10130
10131 tfd = &txq->bd[q->first_empty];
10132 txq->txb[q->first_empty] = txb;
10133 memset(tfd, 0, sizeof(*tfd));
10134 tfd->u.data.station_number = id;
10135
10136 tfd->control_flags.message_type = TX_FRAME_TYPE;
10137 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
10138
10139 tfd->u.data.cmd_id = DINO_CMD_TX;
10140 tfd->u.data.len = cpu_to_le16(txb->payload_size);
10141
10142 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
10143 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_CCK;
10144 else
10145 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_OFDM;
10146
10147 if (priv->assoc_request.preamble_length == DCT_FLAG_SHORT_PREAMBLE)
10148 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREAMBLE;
10149
10150 fc = le16_to_cpu(hdr->frame_ctl);
10151 hdr->frame_ctl = cpu_to_le16(fc & ~IEEE80211_FCTL_MOREFRAGS);
10152
10153 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
10154
10155 if (likely(unicast))
10156 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
10157
10158 if (txb->encrypted && !priv->ieee->host_encrypt) {
10159 switch (priv->ieee->sec.level) {
10160 case SEC_LEVEL_3:
10161 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
10162 cpu_to_le16(IEEE80211_FCTL_PROTECTED);
10163
10164
10165
10166
10167 if (!unicast)
10168 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
10169
10170 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
10171 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_CCM;
10172 tfd->u.data.key_index = 0;
10173 tfd->u.data.key_index |= DCT_WEP_INDEX_USE_IMMEDIATE;
10174 break;
10175 case SEC_LEVEL_2:
10176 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
10177 cpu_to_le16(IEEE80211_FCTL_PROTECTED);
10178 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
10179 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP;
10180 tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE;
10181 break;
10182 case SEC_LEVEL_1:
10183 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
10184 cpu_to_le16(IEEE80211_FCTL_PROTECTED);
10185 tfd->u.data.key_index = priv->ieee->crypt_info.tx_keyidx;
10186 if (priv->ieee->sec.key_sizes[priv->ieee->crypt_info.tx_keyidx] <=
10187 40)
10188 tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;
10189 else
10190 tfd->u.data.key_index |= DCT_WEP_KEY_128Bit;
10191 break;
10192 case SEC_LEVEL_0:
10193 break;
10194 default:
10195 printk(KERN_ERR "Unknown security level %d\n",
10196 priv->ieee->sec.level);
10197 break;
10198 }
10199 } else
10200
10201 tfd->u.data.tx_flags |= DCT_FLAG_NO_WEP;
10202
10203#ifdef CONFIG_IPW2200_QOS
10204 if (fc & IEEE80211_STYPE_QOS_DATA)
10205 ipw_qos_set_tx_queue_command(priv, pri, &(tfd->u.data));
10206#endif
10207
10208
10209 tfd->u.data.num_chunks = cpu_to_le32(min((u8) (NUM_TFD_CHUNKS - 2),
10210 txb->nr_frags));
10211 IPW_DEBUG_FRAG("%i fragments being sent as %i chunks.\n",
10212 txb->nr_frags, le32_to_cpu(tfd->u.data.num_chunks));
10213 for (i = 0; i < le32_to_cpu(tfd->u.data.num_chunks); i++) {
10214 IPW_DEBUG_FRAG("Adding fragment %i of %i (%d bytes).\n",
10215 i, le32_to_cpu(tfd->u.data.num_chunks),
10216 txb->fragments[i]->len - hdr_len);
10217 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n",
10218 i, tfd->u.data.num_chunks,
10219 txb->fragments[i]->len - hdr_len);
10220 printk_buf(IPW_DL_TX, txb->fragments[i]->data + hdr_len,
10221 txb->fragments[i]->len - hdr_len);
10222
10223 tfd->u.data.chunk_ptr[i] =
10224 cpu_to_le32(pci_map_single
10225 (priv->pci_dev,
10226 txb->fragments[i]->data + hdr_len,
10227 txb->fragments[i]->len - hdr_len,
10228 PCI_DMA_TODEVICE));
10229 tfd->u.data.chunk_len[i] =
10230 cpu_to_le16(txb->fragments[i]->len - hdr_len);
10231 }
10232
10233 if (i != txb->nr_frags) {
10234 struct sk_buff *skb;
10235 u16 remaining_bytes = 0;
10236 int j;
10237
10238 for (j = i; j < txb->nr_frags; j++)
10239 remaining_bytes += txb->fragments[j]->len - hdr_len;
10240
10241 printk(KERN_INFO "Trying to reallocate for %d bytes\n",
10242 remaining_bytes);
10243 skb = alloc_skb(remaining_bytes, GFP_ATOMIC);
10244 if (skb != NULL) {
10245 tfd->u.data.chunk_len[i] = cpu_to_le16(remaining_bytes);
10246 for (j = i; j < txb->nr_frags; j++) {
10247 int size = txb->fragments[j]->len - hdr_len;
10248
10249 printk(KERN_INFO "Adding frag %d %d...\n",
10250 j, size);
10251 skb_put_data(skb,
10252 txb->fragments[j]->data + hdr_len,
10253 size);
10254 }
10255 dev_kfree_skb_any(txb->fragments[i]);
10256 txb->fragments[i] = skb;
10257 tfd->u.data.chunk_ptr[i] =
10258 cpu_to_le32(pci_map_single
10259 (priv->pci_dev, skb->data,
10260 remaining_bytes,
10261 PCI_DMA_TODEVICE));
10262
10263 le32_add_cpu(&tfd->u.data.num_chunks, 1);
10264 }
10265 }
10266
10267
10268 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
10269 ipw_write32(priv, q->reg_w, q->first_empty);
10270
10271 if (ipw_tx_queue_space(q) < q->high_mark)
10272 netif_stop_queue(priv->net_dev);
10273
10274 return NETDEV_TX_OK;
10275
10276 drop:
10277 IPW_DEBUG_DROP("Silently dropping Tx packet.\n");
10278 libipw_txb_free(txb);
10279 return NETDEV_TX_OK;
10280}
10281
10282static int ipw_net_is_queue_full(struct net_device *dev, int pri)
10283{
10284 struct ipw_priv *priv = libipw_priv(dev);
10285#ifdef CONFIG_IPW2200_QOS
10286 int tx_id = ipw_get_tx_queue_number(priv, pri);
10287 struct clx2_tx_queue *txq = &priv->txq[tx_id];
10288#else
10289 struct clx2_tx_queue *txq = &priv->txq[0];
10290#endif
10291
10292 if (ipw_tx_queue_space(&txq->q) < txq->q.high_mark)
10293 return 1;
10294
10295 return 0;
10296}
10297
10298#ifdef CONFIG_IPW2200_PROMISCUOUS
10299static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
10300 struct libipw_txb *txb)
10301{
10302 struct libipw_rx_stats dummystats;
10303 struct ieee80211_hdr *hdr;
10304 u8 n;
10305 u16 filter = priv->prom_priv->filter;
10306 int hdr_only = 0;
10307
10308 if (filter & IPW_PROM_NO_TX)
10309 return;
10310
10311 memset(&dummystats, 0, sizeof(dummystats));
10312
10313
10314 hdr = (void *)txb->fragments[0]->data;
10315 if (libipw_is_management(le16_to_cpu(hdr->frame_control))) {
10316 if (filter & IPW_PROM_NO_MGMT)
10317 return;
10318 if (filter & IPW_PROM_MGMT_HEADER_ONLY)
10319 hdr_only = 1;
10320 } else if (libipw_is_control(le16_to_cpu(hdr->frame_control))) {
10321 if (filter & IPW_PROM_NO_CTL)
10322 return;
10323 if (filter & IPW_PROM_CTL_HEADER_ONLY)
10324 hdr_only = 1;
10325 } else if (libipw_is_data(le16_to_cpu(hdr->frame_control))) {
10326 if (filter & IPW_PROM_NO_DATA)
10327 return;
10328 if (filter & IPW_PROM_DATA_HEADER_ONLY)
10329 hdr_only = 1;
10330 }
10331
10332 for(n=0; n<txb->nr_frags; ++n) {
10333 struct sk_buff *src = txb->fragments[n];
10334 struct sk_buff *dst;
10335 struct ieee80211_radiotap_header *rt_hdr;
10336 int len;
10337
10338 if (hdr_only) {
10339 hdr = (void *)src->data;
10340 len = libipw_get_hdrlen(le16_to_cpu(hdr->frame_control));
10341 } else
10342 len = src->len;
10343
10344 dst = alloc_skb(len + sizeof(*rt_hdr) + sizeof(u16)*2, GFP_ATOMIC);
10345 if (!dst)
10346 continue;
10347
10348 rt_hdr = skb_put(dst, sizeof(*rt_hdr));
10349
10350 rt_hdr->it_version = PKTHDR_RADIOTAP_VERSION;
10351 rt_hdr->it_pad = 0;
10352 rt_hdr->it_present = 0;
10353 rt_hdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_CHANNEL);
10354
10355 *(__le16*)skb_put(dst, sizeof(u16)) = cpu_to_le16(
10356 ieee80211chan2mhz(priv->channel));
10357 if (priv->channel > 14)
10358 *(__le16*)skb_put(dst, sizeof(u16)) =
10359 cpu_to_le16(IEEE80211_CHAN_OFDM |
10360 IEEE80211_CHAN_5GHZ);
10361 else if (priv->ieee->mode == IEEE_B)
10362 *(__le16*)skb_put(dst, sizeof(u16)) =
10363 cpu_to_le16(IEEE80211_CHAN_CCK |
10364 IEEE80211_CHAN_2GHZ);
10365 else
10366 *(__le16*)skb_put(dst, sizeof(u16)) =
10367 cpu_to_le16(IEEE80211_CHAN_OFDM |
10368 IEEE80211_CHAN_2GHZ);
10369
10370 rt_hdr->it_len = cpu_to_le16(dst->len);
10371
10372 skb_copy_from_linear_data(src, skb_put(dst, len), len);
10373
10374 if (!libipw_rx(priv->prom_priv->ieee, dst, &dummystats))
10375 dev_kfree_skb_any(dst);
10376 }
10377}
10378#endif
10379
10380static netdev_tx_t ipw_net_hard_start_xmit(struct libipw_txb *txb,
10381 struct net_device *dev, int pri)
10382{
10383 struct ipw_priv *priv = libipw_priv(dev);
10384 unsigned long flags;
10385 netdev_tx_t ret;
10386
10387 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
10388 spin_lock_irqsave(&priv->lock, flags);
10389
10390#ifdef CONFIG_IPW2200_PROMISCUOUS
10391 if (rtap_iface && netif_running(priv->prom_net_dev))
10392 ipw_handle_promiscuous_tx(priv, txb);
10393#endif
10394
10395 ret = ipw_tx_skb(priv, txb, pri);
10396 if (ret == NETDEV_TX_OK)
10397 __ipw_led_activity_on(priv);
10398 spin_unlock_irqrestore(&priv->lock, flags);
10399
10400 return ret;
10401}
10402
10403static void ipw_net_set_multicast_list(struct net_device *dev)
10404{
10405
10406}
10407
10408static int ipw_net_set_mac_address(struct net_device *dev, void *p)
10409{
10410 struct ipw_priv *priv = libipw_priv(dev);
10411 struct sockaddr *addr = p;
10412
10413 if (!is_valid_ether_addr(addr->sa_data))
10414 return -EADDRNOTAVAIL;
10415 mutex_lock(&priv->mutex);
10416 priv->config |= CFG_CUSTOM_MAC;
10417 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
10418 printk(KERN_INFO "%s: Setting MAC to %pM\n",
10419 priv->net_dev->name, priv->mac_addr);
10420 schedule_work(&priv->adapter_restart);
10421 mutex_unlock(&priv->mutex);
10422 return 0;
10423}
10424
10425static void ipw_ethtool_get_drvinfo(struct net_device *dev,
10426 struct ethtool_drvinfo *info)
10427{
10428 struct ipw_priv *p = libipw_priv(dev);
10429 char vers[64];
10430 char date[32];
10431 u32 len;
10432
10433 strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
10434 strlcpy(info->version, DRV_VERSION, sizeof(info->version));
10435
10436 len = sizeof(vers);
10437 ipw_get_ordinal(p, IPW_ORD_STAT_FW_VERSION, vers, &len);
10438 len = sizeof(date);
10439 ipw_get_ordinal(p, IPW_ORD_STAT_FW_DATE, date, &len);
10440
10441 snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)",
10442 vers, date);
10443 strlcpy(info->bus_info, pci_name(p->pci_dev),
10444 sizeof(info->bus_info));
10445}
10446
10447static u32 ipw_ethtool_get_link(struct net_device *dev)
10448{
10449 struct ipw_priv *priv = libipw_priv(dev);
10450 return (priv->status & STATUS_ASSOCIATED) != 0;
10451}
10452
10453static int ipw_ethtool_get_eeprom_len(struct net_device *dev)
10454{
10455 return IPW_EEPROM_IMAGE_SIZE;
10456}
10457
10458static int ipw_ethtool_get_eeprom(struct net_device *dev,
10459 struct ethtool_eeprom *eeprom, u8 * bytes)
10460{
10461 struct ipw_priv *p = libipw_priv(dev);
10462
10463 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
10464 return -EINVAL;
10465 mutex_lock(&p->mutex);
10466 memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len);
10467 mutex_unlock(&p->mutex);
10468 return 0;
10469}
10470
10471static int ipw_ethtool_set_eeprom(struct net_device *dev,
10472 struct ethtool_eeprom *eeprom, u8 * bytes)
10473{
10474 struct ipw_priv *p = libipw_priv(dev);
10475 int i;
10476
10477 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
10478 return -EINVAL;
10479 mutex_lock(&p->mutex);
10480 memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
10481 for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
10482 ipw_write8(p, i + IPW_EEPROM_DATA, p->eeprom[i]);
10483 mutex_unlock(&p->mutex);
10484 return 0;
10485}
10486
10487static const struct ethtool_ops ipw_ethtool_ops = {
10488 .get_link = ipw_ethtool_get_link,
10489 .get_drvinfo = ipw_ethtool_get_drvinfo,
10490 .get_eeprom_len = ipw_ethtool_get_eeprom_len,
10491 .get_eeprom = ipw_ethtool_get_eeprom,
10492 .set_eeprom = ipw_ethtool_set_eeprom,
10493};
10494
10495static irqreturn_t ipw_isr(int irq, void *data)
10496{
10497 struct ipw_priv *priv = data;
10498 u32 inta, inta_mask;
10499
10500 if (!priv)
10501 return IRQ_NONE;
10502
10503 spin_lock(&priv->irq_lock);
10504
10505 if (!(priv->status & STATUS_INT_ENABLED)) {
10506
10507 goto none;
10508 }
10509
10510 inta = ipw_read32(priv, IPW_INTA_RW);
10511 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
10512
10513 if (inta == 0xFFFFFFFF) {
10514
10515 IPW_WARNING("IRQ INTA == 0xFFFFFFFF\n");
10516 goto none;
10517 }
10518
10519 if (!(inta & (IPW_INTA_MASK_ALL & inta_mask))) {
10520
10521 goto none;
10522 }
10523
10524
10525 __ipw_disable_interrupts(priv);
10526
10527
10528 inta &= (IPW_INTA_MASK_ALL & inta_mask);
10529 ipw_write32(priv, IPW_INTA_RW, inta);
10530
10531
10532 priv->isr_inta = inta;
10533
10534 tasklet_schedule(&priv->irq_tasklet);
10535
10536 spin_unlock(&priv->irq_lock);
10537
10538 return IRQ_HANDLED;
10539 none:
10540 spin_unlock(&priv->irq_lock);
10541 return IRQ_NONE;
10542}
10543
10544static void ipw_rf_kill(void *adapter)
10545{
10546 struct ipw_priv *priv = adapter;
10547 unsigned long flags;
10548
10549 spin_lock_irqsave(&priv->lock, flags);
10550
10551 if (rf_kill_active(priv)) {
10552 IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
10553 schedule_delayed_work(&priv->rf_kill, 2 * HZ);
10554 goto exit_unlock;
10555 }
10556
10557
10558
10559 if (!(priv->status & STATUS_RF_KILL_MASK)) {
10560 IPW_DEBUG_RF_KILL("HW RF Kill no longer active, restarting "
10561 "device\n");
10562
10563
10564 schedule_work(&priv->adapter_restart);
10565 } else
10566 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
10567 "enabled\n");
10568
10569 exit_unlock:
10570 spin_unlock_irqrestore(&priv->lock, flags);
10571}
10572
10573static void ipw_bg_rf_kill(struct work_struct *work)
10574{
10575 struct ipw_priv *priv =
10576 container_of(work, struct ipw_priv, rf_kill.work);
10577 mutex_lock(&priv->mutex);
10578 ipw_rf_kill(priv);
10579 mutex_unlock(&priv->mutex);
10580}
10581
10582static void ipw_link_up(struct ipw_priv *priv)
10583{
10584 priv->last_seq_num = -1;
10585 priv->last_frag_num = -1;
10586 priv->last_packet_time = 0;
10587
10588 netif_carrier_on(priv->net_dev);
10589
10590 cancel_delayed_work(&priv->request_scan);
10591 cancel_delayed_work(&priv->request_direct_scan);
10592 cancel_delayed_work(&priv->request_passive_scan);
10593 cancel_delayed_work(&priv->scan_event);
10594 ipw_reset_stats(priv);
10595
10596 priv->last_rate = ipw_get_current_rate(priv);
10597 ipw_gather_stats(priv);
10598 ipw_led_link_up(priv);
10599 notify_wx_assoc_event(priv);
10600
10601 if (priv->config & CFG_BACKGROUND_SCAN)
10602 schedule_delayed_work(&priv->request_scan, HZ);
10603}
10604
10605static void ipw_bg_link_up(struct work_struct *work)
10606{
10607 struct ipw_priv *priv =
10608 container_of(work, struct ipw_priv, link_up);
10609 mutex_lock(&priv->mutex);
10610 ipw_link_up(priv);
10611 mutex_unlock(&priv->mutex);
10612}
10613
10614static void ipw_link_down(struct ipw_priv *priv)
10615{
10616 ipw_led_link_down(priv);
10617 netif_carrier_off(priv->net_dev);
10618 notify_wx_assoc_event(priv);
10619
10620
10621 cancel_delayed_work(&priv->request_scan);
10622 cancel_delayed_work(&priv->request_direct_scan);
10623 cancel_delayed_work(&priv->request_passive_scan);
10624 cancel_delayed_work(&priv->adhoc_check);
10625 cancel_delayed_work(&priv->gather_stats);
10626
10627 ipw_reset_stats(priv);
10628
10629 if (!(priv->status & STATUS_EXIT_PENDING)) {
10630
10631 schedule_delayed_work(&priv->request_scan, 0);
10632 } else
10633 cancel_delayed_work(&priv->scan_event);
10634}
10635
10636static void ipw_bg_link_down(struct work_struct *work)
10637{
10638 struct ipw_priv *priv =
10639 container_of(work, struct ipw_priv, link_down);
10640 mutex_lock(&priv->mutex);
10641 ipw_link_down(priv);
10642 mutex_unlock(&priv->mutex);
10643}
10644
10645static int ipw_setup_deferred_work(struct ipw_priv *priv)
10646{
10647 int ret = 0;
10648
10649 init_waitqueue_head(&priv->wait_command_queue);
10650 init_waitqueue_head(&priv->wait_state);
10651
10652 INIT_DELAYED_WORK(&priv->adhoc_check, ipw_bg_adhoc_check);
10653 INIT_WORK(&priv->associate, ipw_bg_associate);
10654 INIT_WORK(&priv->disassociate, ipw_bg_disassociate);
10655 INIT_WORK(&priv->system_config, ipw_system_config);
10656 INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish);
10657 INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart);
10658 INIT_DELAYED_WORK(&priv->rf_kill, ipw_bg_rf_kill);
10659 INIT_WORK(&priv->up, ipw_bg_up);
10660 INIT_WORK(&priv->down, ipw_bg_down);
10661 INIT_DELAYED_WORK(&priv->request_scan, ipw_request_scan);
10662 INIT_DELAYED_WORK(&priv->request_direct_scan, ipw_request_direct_scan);
10663 INIT_DELAYED_WORK(&priv->request_passive_scan, ipw_request_passive_scan);
10664 INIT_DELAYED_WORK(&priv->scan_event, ipw_scan_event);
10665 INIT_DELAYED_WORK(&priv->gather_stats, ipw_bg_gather_stats);
10666 INIT_WORK(&priv->abort_scan, ipw_bg_abort_scan);
10667 INIT_WORK(&priv->roam, ipw_bg_roam);
10668 INIT_DELAYED_WORK(&priv->scan_check, ipw_bg_scan_check);
10669 INIT_WORK(&priv->link_up, ipw_bg_link_up);
10670 INIT_WORK(&priv->link_down, ipw_bg_link_down);
10671 INIT_DELAYED_WORK(&priv->led_link_on, ipw_bg_led_link_on);
10672 INIT_DELAYED_WORK(&priv->led_link_off, ipw_bg_led_link_off);
10673 INIT_DELAYED_WORK(&priv->led_act_off, ipw_bg_led_activity_off);
10674 INIT_WORK(&priv->merge_networks, ipw_merge_adhoc_network);
10675
10676#ifdef CONFIG_IPW2200_QOS
10677 INIT_WORK(&priv->qos_activate, ipw_bg_qos_activate);
10678#endif
10679
10680 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
10681 ipw_irq_tasklet, (unsigned long)priv);
10682
10683 return ret;
10684}
10685
10686static void shim__set_security(struct net_device *dev,
10687 struct libipw_security *sec)
10688{
10689 struct ipw_priv *priv = libipw_priv(dev);
10690 int i;
10691 for (i = 0; i < 4; i++) {
10692 if (sec->flags & (1 << i)) {
10693 priv->ieee->sec.encode_alg[i] = sec->encode_alg[i];
10694 priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
10695 if (sec->key_sizes[i] == 0)
10696 priv->ieee->sec.flags &= ~(1 << i);
10697 else {
10698 memcpy(priv->ieee->sec.keys[i], sec->keys[i],
10699 sec->key_sizes[i]);
10700 priv->ieee->sec.flags |= (1 << i);
10701 }
10702 priv->status |= STATUS_SECURITY_UPDATED;
10703 } else if (sec->level != SEC_LEVEL_1)
10704 priv->ieee->sec.flags &= ~(1 << i);
10705 }
10706
10707 if (sec->flags & SEC_ACTIVE_KEY) {
10708 priv->ieee->sec.active_key = sec->active_key;
10709 priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
10710 priv->status |= STATUS_SECURITY_UPDATED;
10711 } else
10712 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
10713
10714 if ((sec->flags & SEC_AUTH_MODE) &&
10715 (priv->ieee->sec.auth_mode != sec->auth_mode)) {
10716 priv->ieee->sec.auth_mode = sec->auth_mode;
10717 priv->ieee->sec.flags |= SEC_AUTH_MODE;
10718 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY)
10719 priv->capability |= CAP_SHARED_KEY;
10720 else
10721 priv->capability &= ~CAP_SHARED_KEY;
10722 priv->status |= STATUS_SECURITY_UPDATED;
10723 }
10724
10725 if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
10726 priv->ieee->sec.flags |= SEC_ENABLED;
10727 priv->ieee->sec.enabled = sec->enabled;
10728 priv->status |= STATUS_SECURITY_UPDATED;
10729 if (sec->enabled)
10730 priv->capability |= CAP_PRIVACY_ON;
10731 else
10732 priv->capability &= ~CAP_PRIVACY_ON;
10733 }
10734
10735 if (sec->flags & SEC_ENCRYPT)
10736 priv->ieee->sec.encrypt = sec->encrypt;
10737
10738 if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
10739 priv->ieee->sec.level = sec->level;
10740 priv->ieee->sec.flags |= SEC_LEVEL;
10741 priv->status |= STATUS_SECURITY_UPDATED;
10742 }
10743
10744 if (!priv->ieee->host_encrypt && (sec->flags & SEC_ENCRYPT))
10745 ipw_set_hwcrypto_keys(priv);
10746
10747
10748
10749
10750#if 0
10751 if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) &&
10752 (((priv->assoc_request.capability &
10753 cpu_to_le16(WLAN_CAPABILITY_PRIVACY)) && !sec->enabled) ||
10754 (!(priv->assoc_request.capability &
10755 cpu_to_le16(WLAN_CAPABILITY_PRIVACY)) && sec->enabled))) {
10756 IPW_DEBUG_ASSOC("Disassociating due to capability "
10757 "change.\n");
10758 ipw_disassociate(priv);
10759 }
10760#endif
10761}
10762
10763static int init_supported_rates(struct ipw_priv *priv,
10764 struct ipw_supported_rates *rates)
10765{
10766
10767
10768 memset(rates, 0, sizeof(*rates));
10769
10770 switch (priv->ieee->freq_band) {
10771 case LIBIPW_52GHZ_BAND:
10772 rates->ieee_mode = IPW_A_MODE;
10773 rates->purpose = IPW_RATE_CAPABILITIES;
10774 ipw_add_ofdm_scan_rates(rates, LIBIPW_CCK_MODULATION,
10775 LIBIPW_OFDM_DEFAULT_RATES_MASK);
10776 break;
10777
10778 default:
10779 rates->ieee_mode = IPW_G_MODE;
10780 rates->purpose = IPW_RATE_CAPABILITIES;
10781 ipw_add_cck_scan_rates(rates, LIBIPW_CCK_MODULATION,
10782 LIBIPW_CCK_DEFAULT_RATES_MASK);
10783 if (priv->ieee->modulation & LIBIPW_OFDM_MODULATION) {
10784 ipw_add_ofdm_scan_rates(rates, LIBIPW_CCK_MODULATION,
10785 LIBIPW_OFDM_DEFAULT_RATES_MASK);
10786 }
10787 break;
10788 }
10789
10790 return 0;
10791}
10792
10793static int ipw_config(struct ipw_priv *priv)
10794{
10795
10796
10797
10798 if (ipw_set_tx_power(priv))
10799 goto error;
10800
10801
10802 if (ipw_send_adapter_address(priv, priv->net_dev->dev_addr))
10803 goto error;
10804
10805
10806 init_sys_config(&priv->sys_config);
10807
10808
10809
10810 if (bt_coexist) {
10811 unsigned char bt_caps = priv->eeprom[EEPROM_SKU_CAPABILITY];
10812
10813 if (bt_caps & EEPROM_SKU_CAP_BT_CHANNEL_SIG)
10814 priv->sys_config.bt_coexistence
10815 |= CFG_BT_COEXISTENCE_SIGNAL_CHNL;
10816 if (bt_caps & EEPROM_SKU_CAP_BT_OOB)
10817 priv->sys_config.bt_coexistence
10818 |= CFG_BT_COEXISTENCE_OOB;
10819 }
10820
10821#ifdef CONFIG_IPW2200_PROMISCUOUS
10822 if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {
10823 priv->sys_config.accept_all_data_frames = 1;
10824 priv->sys_config.accept_non_directed_frames = 1;
10825 priv->sys_config.accept_all_mgmt_bcpr = 1;
10826 priv->sys_config.accept_all_mgmt_frames = 1;
10827 }
10828#endif
10829
10830 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
10831 priv->sys_config.answer_broadcast_ssid_probe = 1;
10832 else
10833 priv->sys_config.answer_broadcast_ssid_probe = 0;
10834
10835 if (ipw_send_system_config(priv))
10836 goto error;
10837
10838 init_supported_rates(priv, &priv->rates);
10839 if (ipw_send_supported_rates(priv, &priv->rates))
10840 goto error;
10841
10842
10843 if (priv->rts_threshold) {
10844 if (ipw_send_rts_threshold(priv, priv->rts_threshold))
10845 goto error;
10846 }
10847#ifdef CONFIG_IPW2200_QOS
10848 IPW_DEBUG_QOS("QoS: call ipw_qos_activate\n");
10849 ipw_qos_activate(priv, NULL);
10850#endif
10851
10852 if (ipw_set_random_seed(priv))
10853 goto error;
10854
10855
10856 if (ipw_send_host_complete(priv))
10857 goto error;
10858
10859 priv->status |= STATUS_INIT;
10860
10861 ipw_led_init(priv);
10862 ipw_led_radio_on(priv);
10863 priv->notif_missed_beacons = 0;
10864
10865
10866 if ((priv->capability & CAP_PRIVACY_ON) &&
10867 (priv->ieee->sec.level == SEC_LEVEL_1) &&
10868 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
10869 ipw_set_hwcrypto_keys(priv);
10870
10871 return 0;
10872
10873 error:
10874 return -EIO;
10875}
10876
10877
10878
10879
10880
10881
10882
10883
10884
10885
10886
10887
10888
10889
10890
10891static const struct libipw_geo ipw_geos[] = {
10892 {
10893 "---",
10894 .bg_channels = 11,
10895 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10896 {2427, 4}, {2432, 5}, {2437, 6},
10897 {2442, 7}, {2447, 8}, {2452, 9},
10898 {2457, 10}, {2462, 11}},
10899 },
10900
10901 {
10902 "ZZF",
10903 .bg_channels = 11,
10904 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10905 {2427, 4}, {2432, 5}, {2437, 6},
10906 {2442, 7}, {2447, 8}, {2452, 9},
10907 {2457, 10}, {2462, 11}},
10908 .a_channels = 8,
10909 .a = {{5180, 36},
10910 {5200, 40},
10911 {5220, 44},
10912 {5240, 48},
10913 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
10914 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
10915 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
10916 {5320, 64, LIBIPW_CH_PASSIVE_ONLY}},
10917 },
10918
10919 {
10920 "ZZD",
10921 .bg_channels = 13,
10922 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10923 {2427, 4}, {2432, 5}, {2437, 6},
10924 {2442, 7}, {2447, 8}, {2452, 9},
10925 {2457, 10}, {2462, 11}, {2467, 12},
10926 {2472, 13}},
10927 },
10928
10929 {
10930 "ZZA",
10931 .bg_channels = 11,
10932 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10933 {2427, 4}, {2432, 5}, {2437, 6},
10934 {2442, 7}, {2447, 8}, {2452, 9},
10935 {2457, 10}, {2462, 11}},
10936 .a_channels = 13,
10937 .a = {{5180, 36},
10938 {5200, 40},
10939 {5220, 44},
10940 {5240, 48},
10941 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
10942 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
10943 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
10944 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
10945 {5745, 149},
10946 {5765, 153},
10947 {5785, 157},
10948 {5805, 161},
10949 {5825, 165}},
10950 },
10951
10952 {
10953 "ZZB",
10954 .bg_channels = 11,
10955 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10956 {2427, 4}, {2432, 5}, {2437, 6},
10957 {2442, 7}, {2447, 8}, {2452, 9},
10958 {2457, 10}, {2462, 11}},
10959 .a_channels = 13,
10960 .a = {{5180, 36},
10961 {5200, 40},
10962 {5220, 44},
10963 {5240, 48},
10964 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
10965 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
10966 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
10967 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
10968 {5745, 149, LIBIPW_CH_PASSIVE_ONLY},
10969 {5765, 153, LIBIPW_CH_PASSIVE_ONLY},
10970 {5785, 157, LIBIPW_CH_PASSIVE_ONLY},
10971 {5805, 161, LIBIPW_CH_PASSIVE_ONLY},
10972 {5825, 165, LIBIPW_CH_PASSIVE_ONLY}},
10973 },
10974
10975 {
10976 "ZZC",
10977 .bg_channels = 11,
10978 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10979 {2427, 4}, {2432, 5}, {2437, 6},
10980 {2442, 7}, {2447, 8}, {2452, 9},
10981 {2457, 10}, {2462, 11}},
10982 .a_channels = 4,
10983 .a = {{5170, 34}, {5190, 38},
10984 {5210, 42}, {5230, 46}},
10985 },
10986
10987 {
10988 "ZZM",
10989 .bg_channels = 11,
10990 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10991 {2427, 4}, {2432, 5}, {2437, 6},
10992 {2442, 7}, {2447, 8}, {2452, 9},
10993 {2457, 10}, {2462, 11}},
10994 },
10995
10996 {
10997 "ZZE",
10998 .bg_channels = 13,
10999 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11000 {2427, 4}, {2432, 5}, {2437, 6},
11001 {2442, 7}, {2447, 8}, {2452, 9},
11002 {2457, 10}, {2462, 11}, {2467, 12},
11003 {2472, 13}},
11004 .a_channels = 19,
11005 .a = {{5180, 36},
11006 {5200, 40},
11007 {5220, 44},
11008 {5240, 48},
11009 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
11010 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
11011 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
11012 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
11013 {5500, 100, LIBIPW_CH_PASSIVE_ONLY},
11014 {5520, 104, LIBIPW_CH_PASSIVE_ONLY},
11015 {5540, 108, LIBIPW_CH_PASSIVE_ONLY},
11016 {5560, 112, LIBIPW_CH_PASSIVE_ONLY},
11017 {5580, 116, LIBIPW_CH_PASSIVE_ONLY},
11018 {5600, 120, LIBIPW_CH_PASSIVE_ONLY},
11019 {5620, 124, LIBIPW_CH_PASSIVE_ONLY},
11020 {5640, 128, LIBIPW_CH_PASSIVE_ONLY},
11021 {5660, 132, LIBIPW_CH_PASSIVE_ONLY},
11022 {5680, 136, LIBIPW_CH_PASSIVE_ONLY},
11023 {5700, 140, LIBIPW_CH_PASSIVE_ONLY}},
11024 },
11025
11026 {
11027 "ZZJ",
11028 .bg_channels = 14,
11029 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11030 {2427, 4}, {2432, 5}, {2437, 6},
11031 {2442, 7}, {2447, 8}, {2452, 9},
11032 {2457, 10}, {2462, 11}, {2467, 12},
11033 {2472, 13}, {2484, 14, LIBIPW_CH_B_ONLY}},
11034 .a_channels = 4,
11035 .a = {{5170, 34}, {5190, 38},
11036 {5210, 42}, {5230, 46}},
11037 },
11038
11039 {
11040 "ZZR",
11041 .bg_channels = 14,
11042 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11043 {2427, 4}, {2432, 5}, {2437, 6},
11044 {2442, 7}, {2447, 8}, {2452, 9},
11045 {2457, 10}, {2462, 11}, {2467, 12},
11046 {2472, 13}, {2484, 14, LIBIPW_CH_B_ONLY |
11047 LIBIPW_CH_PASSIVE_ONLY}},
11048 },
11049
11050 {
11051 "ZZH",
11052 .bg_channels = 13,
11053 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11054 {2427, 4}, {2432, 5}, {2437, 6},
11055 {2442, 7}, {2447, 8}, {2452, 9},
11056 {2457, 10}, {2462, 11},
11057 {2467, 12, LIBIPW_CH_PASSIVE_ONLY},
11058 {2472, 13, LIBIPW_CH_PASSIVE_ONLY}},
11059 .a_channels = 4,
11060 .a = {{5745, 149}, {5765, 153},
11061 {5785, 157}, {5805, 161}},
11062 },
11063
11064 {
11065 "ZZG",
11066 .bg_channels = 13,
11067 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11068 {2427, 4}, {2432, 5}, {2437, 6},
11069 {2442, 7}, {2447, 8}, {2452, 9},
11070 {2457, 10}, {2462, 11},
11071 {2467, 12}, {2472, 13}},
11072 .a_channels = 4,
11073 .a = {{5180, 36}, {5200, 40},
11074 {5220, 44}, {5240, 48}},
11075 },
11076
11077 {
11078 "ZZK",
11079 .bg_channels = 13,
11080 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11081 {2427, 4}, {2432, 5}, {2437, 6},
11082 {2442, 7}, {2447, 8}, {2452, 9},
11083 {2457, 10}, {2462, 11},
11084 {2467, 12, LIBIPW_CH_PASSIVE_ONLY},
11085 {2472, 13, LIBIPW_CH_PASSIVE_ONLY}},
11086 .a_channels = 24,
11087 .a = {{5180, 36, LIBIPW_CH_PASSIVE_ONLY},
11088 {5200, 40, LIBIPW_CH_PASSIVE_ONLY},
11089 {5220, 44, LIBIPW_CH_PASSIVE_ONLY},
11090 {5240, 48, LIBIPW_CH_PASSIVE_ONLY},
11091 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
11092 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
11093 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
11094 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
11095 {5500, 100, LIBIPW_CH_PASSIVE_ONLY},
11096 {5520, 104, LIBIPW_CH_PASSIVE_ONLY},
11097 {5540, 108, LIBIPW_CH_PASSIVE_ONLY},
11098 {5560, 112, LIBIPW_CH_PASSIVE_ONLY},
11099 {5580, 116, LIBIPW_CH_PASSIVE_ONLY},
11100 {5600, 120, LIBIPW_CH_PASSIVE_ONLY},
11101 {5620, 124, LIBIPW_CH_PASSIVE_ONLY},
11102 {5640, 128, LIBIPW_CH_PASSIVE_ONLY},
11103 {5660, 132, LIBIPW_CH_PASSIVE_ONLY},
11104 {5680, 136, LIBIPW_CH_PASSIVE_ONLY},
11105 {5700, 140, LIBIPW_CH_PASSIVE_ONLY},
11106 {5745, 149, LIBIPW_CH_PASSIVE_ONLY},
11107 {5765, 153, LIBIPW_CH_PASSIVE_ONLY},
11108 {5785, 157, LIBIPW_CH_PASSIVE_ONLY},
11109 {5805, 161, LIBIPW_CH_PASSIVE_ONLY},
11110 {5825, 165, LIBIPW_CH_PASSIVE_ONLY}},
11111 },
11112
11113 {
11114 "ZZL",
11115 .bg_channels = 11,
11116 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
11117 {2427, 4}, {2432, 5}, {2437, 6},
11118 {2442, 7}, {2447, 8}, {2452, 9},
11119 {2457, 10}, {2462, 11}},
11120 .a_channels = 13,
11121 .a = {{5180, 36, LIBIPW_CH_PASSIVE_ONLY},
11122 {5200, 40, LIBIPW_CH_PASSIVE_ONLY},
11123 {5220, 44, LIBIPW_CH_PASSIVE_ONLY},
11124 {5240, 48, LIBIPW_CH_PASSIVE_ONLY},
11125 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},
11126 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},
11127 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},
11128 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},
11129 {5745, 149, LIBIPW_CH_PASSIVE_ONLY},
11130 {5765, 153, LIBIPW_CH_PASSIVE_ONLY},
11131 {5785, 157, LIBIPW_CH_PASSIVE_ONLY},
11132 {5805, 161, LIBIPW_CH_PASSIVE_ONLY},
11133 {5825, 165, LIBIPW_CH_PASSIVE_ONLY}},
11134 }
11135};
11136
11137static void ipw_set_geo(struct ipw_priv *priv)
11138{
11139 int j;
11140
11141 for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
11142 if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
11143 ipw_geos[j].name, 3))
11144 break;
11145 }
11146
11147 if (j == ARRAY_SIZE(ipw_geos)) {
11148 IPW_WARNING("SKU [%c%c%c] not recognized.\n",
11149 priv->eeprom[EEPROM_COUNTRY_CODE + 0],
11150 priv->eeprom[EEPROM_COUNTRY_CODE + 1],
11151 priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
11152 j = 0;
11153 }
11154
11155 libipw_set_geo(priv->ieee, &ipw_geos[j]);
11156}
11157
11158#define MAX_HW_RESTARTS 5
11159static int ipw_up(struct ipw_priv *priv)
11160{
11161 int rc, i;
11162
11163
11164 if (priv->suspend_time) {
11165 libipw_networks_age(priv->ieee, priv->suspend_time);
11166 priv->suspend_time = 0;
11167 }
11168
11169 if (priv->status & STATUS_EXIT_PENDING)
11170 return -EIO;
11171
11172 if (cmdlog && !priv->cmdlog) {
11173 priv->cmdlog = kcalloc(cmdlog, sizeof(*priv->cmdlog),
11174 GFP_KERNEL);
11175 if (priv->cmdlog == NULL) {
11176 IPW_ERROR("Error allocating %d command log entries.\n",
11177 cmdlog);
11178 return -ENOMEM;
11179 } else {
11180 priv->cmdlog_len = cmdlog;
11181 }
11182 }
11183
11184 for (i = 0; i < MAX_HW_RESTARTS; i++) {
11185
11186
11187 rc = ipw_load(priv);
11188 if (rc) {
11189 IPW_ERROR("Unable to load firmware: %d\n", rc);
11190 return rc;
11191 }
11192
11193 ipw_init_ordinals(priv);
11194 if (!(priv->config & CFG_CUSTOM_MAC))
11195 eeprom_parse_mac(priv, priv->mac_addr);
11196 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
11197
11198 ipw_set_geo(priv);
11199
11200 if (priv->status & STATUS_RF_KILL_SW) {
11201 IPW_WARNING("Radio disabled by module parameter.\n");
11202 return 0;
11203 } else if (rf_kill_active(priv)) {
11204 IPW_WARNING("Radio Frequency Kill Switch is On:\n"
11205 "Kill switch must be turned off for "
11206 "wireless networking to work.\n");
11207 schedule_delayed_work(&priv->rf_kill, 2 * HZ);
11208 return 0;
11209 }
11210
11211 rc = ipw_config(priv);
11212 if (!rc) {
11213 IPW_DEBUG_INFO("Configured device on count %i\n", i);
11214
11215
11216
11217 schedule_delayed_work(&priv->request_scan, 0);
11218
11219 return 0;
11220 }
11221
11222 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n", rc);
11223 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n",
11224 i, MAX_HW_RESTARTS);
11225
11226
11227
11228 ipw_down(priv);
11229 }
11230
11231
11232
11233 IPW_ERROR("Unable to initialize device after %d attempts.\n", i);
11234
11235 return -EIO;
11236}
11237
11238static void ipw_bg_up(struct work_struct *work)
11239{
11240 struct ipw_priv *priv =
11241 container_of(work, struct ipw_priv, up);
11242 mutex_lock(&priv->mutex);
11243 ipw_up(priv);
11244 mutex_unlock(&priv->mutex);
11245}
11246
11247static void ipw_deinit(struct ipw_priv *priv)
11248{
11249 int i;
11250
11251 if (priv->status & STATUS_SCANNING) {
11252 IPW_DEBUG_INFO("Aborting scan during shutdown.\n");
11253 ipw_abort_scan(priv);
11254 }
11255
11256 if (priv->status & STATUS_ASSOCIATED) {
11257 IPW_DEBUG_INFO("Disassociating during shutdown.\n");
11258 ipw_disassociate(priv);
11259 }
11260
11261 ipw_led_shutdown(priv);
11262
11263
11264
11265
11266 for (i = 1000; i && (priv->status &
11267 (STATUS_DISASSOCIATING |
11268 STATUS_ASSOCIATED | STATUS_SCANNING)); i--)
11269 udelay(10);
11270
11271 if (priv->status & (STATUS_DISASSOCIATING |
11272 STATUS_ASSOCIATED | STATUS_SCANNING))
11273 IPW_DEBUG_INFO("Still associated or scanning...\n");
11274 else
11275 IPW_DEBUG_INFO("Took %dms to de-init\n", 1000 - i);
11276
11277
11278 ipw_send_card_disable(priv, 0);
11279
11280 priv->status &= ~STATUS_INIT;
11281}
11282
11283static void ipw_down(struct ipw_priv *priv)
11284{
11285 int exit_pending = priv->status & STATUS_EXIT_PENDING;
11286
11287 priv->status |= STATUS_EXIT_PENDING;
11288
11289 if (ipw_is_init(priv))
11290 ipw_deinit(priv);
11291
11292
11293
11294 if (!exit_pending)
11295 priv->status &= ~STATUS_EXIT_PENDING;
11296
11297
11298 ipw_disable_interrupts(priv);
11299
11300
11301 priv->status &= STATUS_RF_KILL_MASK | STATUS_EXIT_PENDING;
11302 netif_carrier_off(priv->net_dev);
11303
11304 ipw_stop_nic(priv);
11305
11306 ipw_led_radio_off(priv);
11307}
11308
11309static void ipw_bg_down(struct work_struct *work)
11310{
11311 struct ipw_priv *priv =
11312 container_of(work, struct ipw_priv, down);
11313 mutex_lock(&priv->mutex);
11314 ipw_down(priv);
11315 mutex_unlock(&priv->mutex);
11316}
11317
11318static int ipw_wdev_init(struct net_device *dev)
11319{
11320 int i, rc = 0;
11321 struct ipw_priv *priv = libipw_priv(dev);
11322 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
11323 struct wireless_dev *wdev = &priv->ieee->wdev;
11324
11325 memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN);
11326
11327
11328 if (geo->bg_channels) {
11329 struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band;
11330
11331 bg_band->band = NL80211_BAND_2GHZ;
11332 bg_band->n_channels = geo->bg_channels;
11333 bg_band->channels = kcalloc(geo->bg_channels,
11334 sizeof(struct ieee80211_channel),
11335 GFP_KERNEL);
11336 if (!bg_band->channels) {
11337 rc = -ENOMEM;
11338 goto out;
11339 }
11340
11341 for (i = 0; i < geo->bg_channels; i++) {
11342 bg_band->channels[i].band = NL80211_BAND_2GHZ;
11343 bg_band->channels[i].center_freq = geo->bg[i].freq;
11344 bg_band->channels[i].hw_value = geo->bg[i].channel;
11345 bg_band->channels[i].max_power = geo->bg[i].max_power;
11346 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
11347 bg_band->channels[i].flags |=
11348 IEEE80211_CHAN_NO_IR;
11349 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
11350 bg_band->channels[i].flags |=
11351 IEEE80211_CHAN_NO_IR;
11352 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
11353 bg_band->channels[i].flags |=
11354 IEEE80211_CHAN_RADAR;
11355
11356
11357
11358 }
11359
11360 bg_band->bitrates = ipw2200_bg_rates;
11361 bg_band->n_bitrates = ipw2200_num_bg_rates;
11362
11363 wdev->wiphy->bands[NL80211_BAND_2GHZ] = bg_band;
11364 }
11365
11366
11367 if (geo->a_channels) {
11368 struct ieee80211_supported_band *a_band = &priv->ieee->a_band;
11369
11370 a_band->band = NL80211_BAND_5GHZ;
11371 a_band->n_channels = geo->a_channels;
11372 a_band->channels = kcalloc(geo->a_channels,
11373 sizeof(struct ieee80211_channel),
11374 GFP_KERNEL);
11375 if (!a_band->channels) {
11376 rc = -ENOMEM;
11377 goto out;
11378 }
11379
11380 for (i = 0; i < geo->a_channels; i++) {
11381 a_band->channels[i].band = NL80211_BAND_5GHZ;
11382 a_band->channels[i].center_freq = geo->a[i].freq;
11383 a_band->channels[i].hw_value = geo->a[i].channel;
11384 a_band->channels[i].max_power = geo->a[i].max_power;
11385 if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
11386 a_band->channels[i].flags |=
11387 IEEE80211_CHAN_NO_IR;
11388 if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
11389 a_band->channels[i].flags |=
11390 IEEE80211_CHAN_NO_IR;
11391 if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
11392 a_band->channels[i].flags |=
11393 IEEE80211_CHAN_RADAR;
11394
11395
11396
11397 }
11398
11399 a_band->bitrates = ipw2200_a_rates;
11400 a_band->n_bitrates = ipw2200_num_a_rates;
11401
11402 wdev->wiphy->bands[NL80211_BAND_5GHZ] = a_band;
11403 }
11404
11405 wdev->wiphy->cipher_suites = ipw_cipher_suites;
11406 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(ipw_cipher_suites);
11407
11408 set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
11409
11410
11411 if (wiphy_register(wdev->wiphy))
11412 rc = -EIO;
11413out:
11414 return rc;
11415}
11416
11417
11418static const struct pci_device_id card_ids[] = {
11419 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2701, 0, 0, 0},
11420 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2702, 0, 0, 0},
11421 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2711, 0, 0, 0},
11422 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2712, 0, 0, 0},
11423 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2721, 0, 0, 0},
11424 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2722, 0, 0, 0},
11425 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2731, 0, 0, 0},
11426 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2732, 0, 0, 0},
11427 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2741, 0, 0, 0},
11428 {PCI_VENDOR_ID_INTEL, 0x1043, 0x103c, 0x2741, 0, 0, 0},
11429 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2742, 0, 0, 0},
11430 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2751, 0, 0, 0},
11431 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2752, 0, 0, 0},
11432 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2753, 0, 0, 0},
11433 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2754, 0, 0, 0},
11434 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2761, 0, 0, 0},
11435 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},
11436 {PCI_VDEVICE(INTEL, 0x104f), 0},
11437 {PCI_VDEVICE(INTEL, 0x4220), 0},
11438 {PCI_VDEVICE(INTEL, 0x4221), 0},
11439 {PCI_VDEVICE(INTEL, 0x4223), 0},
11440 {PCI_VDEVICE(INTEL, 0x4224), 0},
11441
11442
11443 {0,}
11444};
11445
11446MODULE_DEVICE_TABLE(pci, card_ids);
11447
11448static struct attribute *ipw_sysfs_entries[] = {
11449 &dev_attr_rf_kill.attr,
11450 &dev_attr_direct_dword.attr,
11451 &dev_attr_indirect_byte.attr,
11452 &dev_attr_indirect_dword.attr,
11453 &dev_attr_mem_gpio_reg.attr,
11454 &dev_attr_command_event_reg.attr,
11455 &dev_attr_nic_type.attr,
11456 &dev_attr_status.attr,
11457 &dev_attr_cfg.attr,
11458 &dev_attr_error.attr,
11459 &dev_attr_event_log.attr,
11460 &dev_attr_cmd_log.attr,
11461 &dev_attr_eeprom_delay.attr,
11462 &dev_attr_ucode_version.attr,
11463 &dev_attr_rtc.attr,
11464 &dev_attr_scan_age.attr,
11465 &dev_attr_led.attr,
11466 &dev_attr_speed_scan.attr,
11467 &dev_attr_net_stats.attr,
11468 &dev_attr_channels.attr,
11469#ifdef CONFIG_IPW2200_PROMISCUOUS
11470 &dev_attr_rtap_iface.attr,
11471 &dev_attr_rtap_filter.attr,
11472#endif
11473 NULL
11474};
11475
11476static const struct attribute_group ipw_attribute_group = {
11477 .name = NULL,
11478 .attrs = ipw_sysfs_entries,
11479};
11480
11481#ifdef CONFIG_IPW2200_PROMISCUOUS
11482static int ipw_prom_open(struct net_device *dev)
11483{
11484 struct ipw_prom_priv *prom_priv = libipw_priv(dev);
11485 struct ipw_priv *priv = prom_priv->priv;
11486
11487 IPW_DEBUG_INFO("prom dev->open\n");
11488 netif_carrier_off(dev);
11489
11490 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
11491 priv->sys_config.accept_all_data_frames = 1;
11492 priv->sys_config.accept_non_directed_frames = 1;
11493 priv->sys_config.accept_all_mgmt_bcpr = 1;
11494 priv->sys_config.accept_all_mgmt_frames = 1;
11495
11496 ipw_send_system_config(priv);
11497 }
11498
11499 return 0;
11500}
11501
11502static int ipw_prom_stop(struct net_device *dev)
11503{
11504 struct ipw_prom_priv *prom_priv = libipw_priv(dev);
11505 struct ipw_priv *priv = prom_priv->priv;
11506
11507 IPW_DEBUG_INFO("prom dev->stop\n");
11508
11509 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
11510 priv->sys_config.accept_all_data_frames = 0;
11511 priv->sys_config.accept_non_directed_frames = 0;
11512 priv->sys_config.accept_all_mgmt_bcpr = 0;
11513 priv->sys_config.accept_all_mgmt_frames = 0;
11514
11515 ipw_send_system_config(priv);
11516 }
11517
11518 return 0;
11519}
11520
11521static netdev_tx_t ipw_prom_hard_start_xmit(struct sk_buff *skb,
11522 struct net_device *dev)
11523{
11524 IPW_DEBUG_INFO("prom dev->xmit\n");
11525 dev_kfree_skb(skb);
11526 return NETDEV_TX_OK;
11527}
11528
11529static const struct net_device_ops ipw_prom_netdev_ops = {
11530 .ndo_open = ipw_prom_open,
11531 .ndo_stop = ipw_prom_stop,
11532 .ndo_start_xmit = ipw_prom_hard_start_xmit,
11533 .ndo_set_mac_address = eth_mac_addr,
11534 .ndo_validate_addr = eth_validate_addr,
11535};
11536
11537static int ipw_prom_alloc(struct ipw_priv *priv)
11538{
11539 int rc = 0;
11540
11541 if (priv->prom_net_dev)
11542 return -EPERM;
11543
11544 priv->prom_net_dev = alloc_libipw(sizeof(struct ipw_prom_priv), 1);
11545 if (priv->prom_net_dev == NULL)
11546 return -ENOMEM;
11547
11548 priv->prom_priv = libipw_priv(priv->prom_net_dev);
11549 priv->prom_priv->ieee = netdev_priv(priv->prom_net_dev);
11550 priv->prom_priv->priv = priv;
11551
11552 strcpy(priv->prom_net_dev->name, "rtap%d");
11553 memcpy(priv->prom_net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
11554
11555 priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
11556 priv->prom_net_dev->netdev_ops = &ipw_prom_netdev_ops;
11557
11558 priv->prom_net_dev->min_mtu = 68;
11559 priv->prom_net_dev->max_mtu = LIBIPW_DATA_LEN;
11560
11561 priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;
11562 SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev);
11563
11564 rc = register_netdev(priv->prom_net_dev);
11565 if (rc) {
11566 free_libipw(priv->prom_net_dev, 1);
11567 priv->prom_net_dev = NULL;
11568 return rc;
11569 }
11570
11571 return 0;
11572}
11573
11574static void ipw_prom_free(struct ipw_priv *priv)
11575{
11576 if (!priv->prom_net_dev)
11577 return;
11578
11579 unregister_netdev(priv->prom_net_dev);
11580 free_libipw(priv->prom_net_dev, 1);
11581
11582 priv->prom_net_dev = NULL;
11583}
11584
11585#endif
11586
11587static const struct net_device_ops ipw_netdev_ops = {
11588 .ndo_open = ipw_net_open,
11589 .ndo_stop = ipw_net_stop,
11590 .ndo_set_rx_mode = ipw_net_set_multicast_list,
11591 .ndo_set_mac_address = ipw_net_set_mac_address,
11592 .ndo_start_xmit = libipw_xmit,
11593 .ndo_validate_addr = eth_validate_addr,
11594};
11595
11596static int ipw_pci_probe(struct pci_dev *pdev,
11597 const struct pci_device_id *ent)
11598{
11599 int err = 0;
11600 struct net_device *net_dev;
11601 void __iomem *base;
11602 u32 length, val;
11603 struct ipw_priv *priv;
11604 int i;
11605
11606 net_dev = alloc_libipw(sizeof(struct ipw_priv), 0);
11607 if (net_dev == NULL) {
11608 err = -ENOMEM;
11609 goto out;
11610 }
11611
11612 priv = libipw_priv(net_dev);
11613 priv->ieee = netdev_priv(net_dev);
11614
11615 priv->net_dev = net_dev;
11616 priv->pci_dev = pdev;
11617 ipw_debug_level = debug;
11618 spin_lock_init(&priv->irq_lock);
11619 spin_lock_init(&priv->lock);
11620 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
11621 INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
11622
11623 mutex_init(&priv->mutex);
11624 if (pci_enable_device(pdev)) {
11625 err = -ENODEV;
11626 goto out_free_libipw;
11627 }
11628
11629 pci_set_master(pdev);
11630
11631 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
11632 if (!err)
11633 err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
11634 if (err) {
11635 printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n");
11636 goto out_pci_disable_device;
11637 }
11638
11639 pci_set_drvdata(pdev, priv);
11640
11641 err = pci_request_regions(pdev, DRV_NAME);
11642 if (err)
11643 goto out_pci_disable_device;
11644
11645
11646
11647 pci_read_config_dword(pdev, 0x40, &val);
11648 if ((val & 0x0000ff00) != 0)
11649 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
11650
11651 length = pci_resource_len(pdev, 0);
11652 priv->hw_len = length;
11653
11654 base = pci_ioremap_bar(pdev, 0);
11655 if (!base) {
11656 err = -ENODEV;
11657 goto out_pci_release_regions;
11658 }
11659
11660 priv->hw_base = base;
11661 IPW_DEBUG_INFO("pci_resource_len = 0x%08x\n", length);
11662 IPW_DEBUG_INFO("pci_resource_base = %p\n", base);
11663
11664 err = ipw_setup_deferred_work(priv);
11665 if (err) {
11666 IPW_ERROR("Unable to setup deferred work\n");
11667 goto out_iounmap;
11668 }
11669
11670 ipw_sw_reset(priv, 1);
11671
11672 err = request_irq(pdev->irq, ipw_isr, IRQF_SHARED, DRV_NAME, priv);
11673 if (err) {
11674 IPW_ERROR("Error allocating IRQ %d\n", pdev->irq);
11675 goto out_iounmap;
11676 }
11677
11678 SET_NETDEV_DEV(net_dev, &pdev->dev);
11679
11680 mutex_lock(&priv->mutex);
11681
11682 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
11683 priv->ieee->set_security = shim__set_security;
11684 priv->ieee->is_queue_full = ipw_net_is_queue_full;
11685
11686#ifdef CONFIG_IPW2200_QOS
11687 priv->ieee->is_qos_active = ipw_is_qos_active;
11688 priv->ieee->handle_probe_response = ipw_handle_beacon;
11689 priv->ieee->handle_beacon = ipw_handle_probe_response;
11690 priv->ieee->handle_assoc_response = ipw_handle_assoc_response;
11691#endif
11692
11693 priv->ieee->perfect_rssi = -20;
11694 priv->ieee->worst_rssi = -85;
11695
11696 net_dev->netdev_ops = &ipw_netdev_ops;
11697 priv->wireless_data.spy_data = &priv->ieee->spy_data;
11698 net_dev->wireless_data = &priv->wireless_data;
11699 net_dev->wireless_handlers = &ipw_wx_handler_def;
11700 net_dev->ethtool_ops = &ipw_ethtool_ops;
11701
11702 net_dev->min_mtu = 68;
11703 net_dev->max_mtu = LIBIPW_DATA_LEN;
11704
11705 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
11706 if (err) {
11707 IPW_ERROR("failed to create sysfs device attributes\n");
11708 mutex_unlock(&priv->mutex);
11709 goto out_release_irq;
11710 }
11711
11712 if (ipw_up(priv)) {
11713 mutex_unlock(&priv->mutex);
11714 err = -EIO;
11715 goto out_remove_sysfs;
11716 }
11717
11718 mutex_unlock(&priv->mutex);
11719
11720 err = ipw_wdev_init(net_dev);
11721 if (err) {
11722 IPW_ERROR("failed to register wireless device\n");
11723 goto out_remove_sysfs;
11724 }
11725
11726 err = register_netdev(net_dev);
11727 if (err) {
11728 IPW_ERROR("failed to register network device\n");
11729 goto out_unregister_wiphy;
11730 }
11731
11732#ifdef CONFIG_IPW2200_PROMISCUOUS
11733 if (rtap_iface) {
11734 err = ipw_prom_alloc(priv);
11735 if (err) {
11736 IPW_ERROR("Failed to register promiscuous network "
11737 "device (error %d).\n", err);
11738 unregister_netdev(priv->net_dev);
11739 goto out_unregister_wiphy;
11740 }
11741 }
11742#endif
11743
11744 printk(KERN_INFO DRV_NAME ": Detected geography %s (%d 802.11bg "
11745 "channels, %d 802.11a channels)\n",
11746 priv->ieee->geo.name, priv->ieee->geo.bg_channels,
11747 priv->ieee->geo.a_channels);
11748
11749 return 0;
11750
11751 out_unregister_wiphy:
11752 wiphy_unregister(priv->ieee->wdev.wiphy);
11753 kfree(priv->ieee->a_band.channels);
11754 kfree(priv->ieee->bg_band.channels);
11755 out_remove_sysfs:
11756 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
11757 out_release_irq:
11758 free_irq(pdev->irq, priv);
11759 out_iounmap:
11760 iounmap(priv->hw_base);
11761 out_pci_release_regions:
11762 pci_release_regions(pdev);
11763 out_pci_disable_device:
11764 pci_disable_device(pdev);
11765 out_free_libipw:
11766 free_libipw(priv->net_dev, 0);
11767 out:
11768 return err;
11769}
11770
11771static void ipw_pci_remove(struct pci_dev *pdev)
11772{
11773 struct ipw_priv *priv = pci_get_drvdata(pdev);
11774 struct list_head *p, *q;
11775 int i;
11776
11777 if (!priv)
11778 return;
11779
11780 mutex_lock(&priv->mutex);
11781
11782 priv->status |= STATUS_EXIT_PENDING;
11783 ipw_down(priv);
11784 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
11785
11786 mutex_unlock(&priv->mutex);
11787
11788 unregister_netdev(priv->net_dev);
11789
11790 if (priv->rxq) {
11791 ipw_rx_queue_free(priv, priv->rxq);
11792 priv->rxq = NULL;
11793 }
11794 ipw_tx_queue_free(priv);
11795
11796 if (priv->cmdlog) {
11797 kfree(priv->cmdlog);
11798 priv->cmdlog = NULL;
11799 }
11800
11801
11802 cancel_delayed_work_sync(&priv->adhoc_check);
11803 cancel_work_sync(&priv->associate);
11804 cancel_work_sync(&priv->disassociate);
11805 cancel_work_sync(&priv->system_config);
11806 cancel_work_sync(&priv->rx_replenish);
11807 cancel_work_sync(&priv->adapter_restart);
11808 cancel_delayed_work_sync(&priv->rf_kill);
11809 cancel_work_sync(&priv->up);
11810 cancel_work_sync(&priv->down);
11811 cancel_delayed_work_sync(&priv->request_scan);
11812 cancel_delayed_work_sync(&priv->request_direct_scan);
11813 cancel_delayed_work_sync(&priv->request_passive_scan);
11814 cancel_delayed_work_sync(&priv->scan_event);
11815 cancel_delayed_work_sync(&priv->gather_stats);
11816 cancel_work_sync(&priv->abort_scan);
11817 cancel_work_sync(&priv->roam);
11818 cancel_delayed_work_sync(&priv->scan_check);
11819 cancel_work_sync(&priv->link_up);
11820 cancel_work_sync(&priv->link_down);
11821 cancel_delayed_work_sync(&priv->led_link_on);
11822 cancel_delayed_work_sync(&priv->led_link_off);
11823 cancel_delayed_work_sync(&priv->led_act_off);
11824 cancel_work_sync(&priv->merge_networks);
11825
11826
11827 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) {
11828 list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
11829 list_del(p);
11830 kfree(list_entry(p, struct ipw_ibss_seq, list));
11831 }
11832 }
11833
11834 kfree(priv->error);
11835 priv->error = NULL;
11836
11837#ifdef CONFIG_IPW2200_PROMISCUOUS
11838 ipw_prom_free(priv);
11839#endif
11840
11841 free_irq(pdev->irq, priv);
11842 iounmap(priv->hw_base);
11843 pci_release_regions(pdev);
11844 pci_disable_device(pdev);
11845
11846 wiphy_unregister(priv->ieee->wdev.wiphy);
11847 kfree(priv->ieee->a_band.channels);
11848 kfree(priv->ieee->bg_band.channels);
11849 free_libipw(priv->net_dev, 0);
11850 free_firmware();
11851}
11852
11853#ifdef CONFIG_PM
11854static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
11855{
11856 struct ipw_priv *priv = pci_get_drvdata(pdev);
11857 struct net_device *dev = priv->net_dev;
11858
11859 printk(KERN_INFO "%s: Going into suspend...\n", dev->name);
11860
11861
11862 ipw_down(priv);
11863
11864
11865 netif_device_detach(dev);
11866
11867 pci_save_state(pdev);
11868 pci_disable_device(pdev);
11869 pci_set_power_state(pdev, pci_choose_state(pdev, state));
11870
11871 priv->suspend_at = ktime_get_boottime_seconds();
11872
11873 return 0;
11874}
11875
11876static int ipw_pci_resume(struct pci_dev *pdev)
11877{
11878 struct ipw_priv *priv = pci_get_drvdata(pdev);
11879 struct net_device *dev = priv->net_dev;
11880 int err;
11881 u32 val;
11882
11883 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
11884
11885 pci_set_power_state(pdev, PCI_D0);
11886 err = pci_enable_device(pdev);
11887 if (err) {
11888 printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
11889 dev->name);
11890 return err;
11891 }
11892 pci_restore_state(pdev);
11893
11894
11895
11896
11897
11898
11899
11900 pci_read_config_dword(pdev, 0x40, &val);
11901 if ((val & 0x0000ff00) != 0)
11902 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
11903
11904
11905
11906 netif_device_attach(dev);
11907
11908 priv->suspend_time = ktime_get_boottime_seconds() - priv->suspend_at;
11909
11910
11911 schedule_work(&priv->up);
11912
11913 return 0;
11914}
11915#endif
11916
11917static void ipw_pci_shutdown(struct pci_dev *pdev)
11918{
11919 struct ipw_priv *priv = pci_get_drvdata(pdev);
11920
11921
11922 ipw_down(priv);
11923
11924 pci_disable_device(pdev);
11925}
11926
11927
11928static struct pci_driver ipw_driver = {
11929 .name = DRV_NAME,
11930 .id_table = card_ids,
11931 .probe = ipw_pci_probe,
11932 .remove = ipw_pci_remove,
11933#ifdef CONFIG_PM
11934 .suspend = ipw_pci_suspend,
11935 .resume = ipw_pci_resume,
11936#endif
11937 .shutdown = ipw_pci_shutdown,
11938};
11939
11940static int __init ipw_init(void)
11941{
11942 int ret;
11943
11944 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
11945 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
11946
11947 ret = pci_register_driver(&ipw_driver);
11948 if (ret) {
11949 IPW_ERROR("Unable to initialize PCI module\n");
11950 return ret;
11951 }
11952
11953 ret = driver_create_file(&ipw_driver.driver, &driver_attr_debug_level);
11954 if (ret) {
11955 IPW_ERROR("Unable to create driver sysfs file\n");
11956 pci_unregister_driver(&ipw_driver);
11957 return ret;
11958 }
11959
11960 return ret;
11961}
11962
11963static void __exit ipw_exit(void)
11964{
11965 driver_remove_file(&ipw_driver.driver, &driver_attr_debug_level);
11966 pci_unregister_driver(&ipw_driver);
11967}
11968
11969module_param(disable, int, 0444);
11970MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
11971
11972module_param(associate, int, 0444);
11973MODULE_PARM_DESC(associate, "auto associate when scanning (default off)");
11974
11975module_param(auto_create, int, 0444);
11976MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
11977
11978module_param_named(led, led_support, int, 0444);
11979MODULE_PARM_DESC(led, "enable led control on some systems (default 1 on)");
11980
11981module_param(debug, int, 0444);
11982MODULE_PARM_DESC(debug, "debug output mask");
11983
11984module_param_named(channel, default_channel, int, 0444);
11985MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
11986
11987#ifdef CONFIG_IPW2200_PROMISCUOUS
11988module_param(rtap_iface, int, 0444);
11989MODULE_PARM_DESC(rtap_iface, "create the rtap interface (1 - create, default 0)");
11990#endif
11991
11992#ifdef CONFIG_IPW2200_QOS
11993module_param(qos_enable, int, 0444);
11994MODULE_PARM_DESC(qos_enable, "enable all QoS functionalities");
11995
11996module_param(qos_burst_enable, int, 0444);
11997MODULE_PARM_DESC(qos_burst_enable, "enable QoS burst mode");
11998
11999module_param(qos_no_ack_mask, int, 0444);
12000MODULE_PARM_DESC(qos_no_ack_mask, "mask Tx_Queue to no ack");
12001
12002module_param(burst_duration_CCK, int, 0444);
12003MODULE_PARM_DESC(burst_duration_CCK, "set CCK burst value");
12004
12005module_param(burst_duration_OFDM, int, 0444);
12006MODULE_PARM_DESC(burst_duration_OFDM, "set OFDM burst value");
12007#endif
12008
12009#ifdef CONFIG_IPW2200_MONITOR
12010module_param_named(mode, network_mode, int, 0444);
12011MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
12012#else
12013module_param_named(mode, network_mode, int, 0444);
12014MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
12015#endif
12016
12017module_param(bt_coexist, int, 0444);
12018MODULE_PARM_DESC(bt_coexist, "enable bluetooth coexistence (default off)");
12019
12020module_param(hwcrypto, int, 0444);
12021MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default off)");
12022
12023module_param(cmdlog, int, 0444);
12024MODULE_PARM_DESC(cmdlog,
12025 "allocate a ring buffer for logging firmware commands");
12026
12027module_param(roaming, int, 0444);
12028MODULE_PARM_DESC(roaming, "enable roaming support (default on)");
12029
12030module_param(antenna, int, 0444);
12031MODULE_PARM_DESC(antenna, "select antenna 1=Main, 3=Aux, default 0 [both], 2=slow_diversity (choose the one with lower background noise)");
12032
12033module_exit(ipw_exit);
12034module_init(ipw_init);
12035