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