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