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 <linux/slab.h>
35#include "ipw2200.h"
36
37
38#ifndef KBUILD_EXTMOD
39#define VK "k"
40#else
41#define VK
42#endif
43
44#ifdef CONFIG_IPW2200_DEBUG
45#define VD "d"
46#else
47#define VD
48#endif
49
50#ifdef CONFIG_IPW2200_MONITOR
51#define VM "m"
52#else
53#define VM
54#endif
55
56#ifdef CONFIG_IPW2200_PROMISCUOUS
57#define VP "p"
58#else
59#define VP
60#endif
61
62#ifdef CONFIG_IPW2200_RADIOTAP
63#define VR "r"
64#else
65#define VR
66#endif
67
68#ifdef CONFIG_IPW2200_QOS
69#define VQ "q"
70#else
71#define VQ
72#endif
73
74#define IPW2200_VERSION "1.2.2" VK VD VM VP VR VQ
75#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
76#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
77#define DRV_VERSION IPW2200_VERSION
78
79#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)
80
81MODULE_DESCRIPTION(DRV_DESCRIPTION);
82MODULE_VERSION(DRV_VERSION);
83MODULE_AUTHOR(DRV_COPYRIGHT);
84MODULE_LICENSE("GPL");
85MODULE_FIRMWARE("ipw2200-ibss.fw");
86#ifdef CONFIG_IPW2200_MONITOR
87MODULE_FIRMWARE("ipw2200-sniffer.fw");
88#endif
89MODULE_FIRMWARE("ipw2200-bss.fw");
90
91static int cmdlog = 0;
92static int debug = 0;
93static int default_channel = 0;
94static int network_mode = 0;
95
96static u32 ipw_debug_level;
97static int associate;
98static int auto_create = 1;
99static int led_support = 0;
100static int disable = 0;
101static int bt_coexist = 0;
102static int hwcrypto = 0;
103static int roaming = 1;
104static const char ipw_modes[] = {
105 'a', 'b', 'g', '?'
106};
107static int antenna = CFG_SYS_ANTENNA_BOTH;
108
109#ifdef CONFIG_IPW2200_PROMISCUOUS
110static int rtap_iface = 0;
111#endif
112
113static struct ieee80211_rate ipw2200_rates[] = {
114 { .bitrate = 10 },
115 { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
116 { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
117 { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
118 { .bitrate = 60 },
119 { .bitrate = 90 },
120 { .bitrate = 120 },
121 { .bitrate = 180 },
122 { .bitrate = 240 },
123 { .bitrate = 360 },
124 { .bitrate = 480 },
125 { .bitrate = 540 }
126};
127
128#define ipw2200_a_rates (ipw2200_rates + 4)
129#define ipw2200_num_a_rates 8
130#define ipw2200_bg_rates (ipw2200_rates + 0)
131#define ipw2200_num_bg_rates 12
132
133#ifdef CONFIG_IPW2200_QOS
134static int qos_enable = 0;
135static int qos_burst_enable = 0;
136static int qos_no_ack_mask = 0;
137static int burst_duration_CCK = 0;
138static int burst_duration_OFDM = 0;
139
140static struct libipw_qos_parameters def_qos_parameters_OFDM = {
141 {QOS_TX0_CW_MIN_OFDM, QOS_TX1_CW_MIN_OFDM, QOS_TX2_CW_MIN_OFDM,
142 QOS_TX3_CW_MIN_OFDM},
143 {QOS_TX0_CW_MAX_OFDM, QOS_TX1_CW_MAX_OFDM, QOS_TX2_CW_MAX_OFDM,
144 QOS_TX3_CW_MAX_OFDM},
145 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
146 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
147 {QOS_TX0_TXOP_LIMIT_OFDM, QOS_TX1_TXOP_LIMIT_OFDM,
148 QOS_TX2_TXOP_LIMIT_OFDM, QOS_TX3_TXOP_LIMIT_OFDM}
149};
150
151static struct libipw_qos_parameters def_qos_parameters_CCK = {
152 {QOS_TX0_CW_MIN_CCK, QOS_TX1_CW_MIN_CCK, QOS_TX2_CW_MIN_CCK,
153 QOS_TX3_CW_MIN_CCK},
154 {QOS_TX0_CW_MAX_CCK, QOS_TX1_CW_MAX_CCK, QOS_TX2_CW_MAX_CCK,
155 QOS_TX3_CW_MAX_CCK},
156 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
157 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
158 {QOS_TX0_TXOP_LIMIT_CCK, QOS_TX1_TXOP_LIMIT_CCK, QOS_TX2_TXOP_LIMIT_CCK,
159 QOS_TX3_TXOP_LIMIT_CCK}
160};
161
162static struct libipw_qos_parameters def_parameters_OFDM = {
163 {DEF_TX0_CW_MIN_OFDM, DEF_TX1_CW_MIN_OFDM, DEF_TX2_CW_MIN_OFDM,
164 DEF_TX3_CW_MIN_OFDM},
165 {DEF_TX0_CW_MAX_OFDM, DEF_TX1_CW_MAX_OFDM, DEF_TX2_CW_MAX_OFDM,
166 DEF_TX3_CW_MAX_OFDM},
167 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
168 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
169 {DEF_TX0_TXOP_LIMIT_OFDM, DEF_TX1_TXOP_LIMIT_OFDM,
170 DEF_TX2_TXOP_LIMIT_OFDM, DEF_TX3_TXOP_LIMIT_OFDM}
171};
172
173static struct libipw_qos_parameters def_parameters_CCK = {
174 {DEF_TX0_CW_MIN_CCK, DEF_TX1_CW_MIN_CCK, DEF_TX2_CW_MIN_CCK,
175 DEF_TX3_CW_MIN_CCK},
176 {DEF_TX0_CW_MAX_CCK, DEF_TX1_CW_MAX_CCK, DEF_TX2_CW_MAX_CCK,
177 DEF_TX3_CW_MAX_CCK},
178 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
179 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
180 {DEF_TX0_TXOP_LIMIT_CCK, DEF_TX1_TXOP_LIMIT_CCK, DEF_TX2_TXOP_LIMIT_CCK,
181 DEF_TX3_TXOP_LIMIT_CCK}
182};
183
184static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
185
186static int from_priority_to_tx_queue[] = {
187 IPW_TX_QUEUE_1, IPW_TX_QUEUE_2, IPW_TX_QUEUE_2, IPW_TX_QUEUE_1,
188 IPW_TX_QUEUE_3, IPW_TX_QUEUE_3, IPW_TX_QUEUE_4, IPW_TX_QUEUE_4
189};
190
191static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv);
192
193static int ipw_send_qos_params_command(struct ipw_priv *priv, struct libipw_qos_parameters
194 *qos_param);
195static int ipw_send_qos_info_command(struct ipw_priv *priv, struct libipw_qos_information_element
196 *qos_param);
197#endif
198
199static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev);
200static void ipw_remove_current_network(struct ipw_priv *priv);
201static void ipw_rx(struct ipw_priv *priv);
202static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
203 struct clx2_tx_queue *txq, int qindex);
204static int ipw_queue_reset(struct ipw_priv *priv);
205
206static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
207 int len, int sync);
208
209static void ipw_tx_queue_free(struct ipw_priv *);
210
211static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *);
212static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);
213static void ipw_rx_queue_replenish(void *);
214static int ipw_up(struct ipw_priv *);
215static void ipw_bg_up(struct work_struct *work);
216static void ipw_down(struct ipw_priv *);
217static void ipw_bg_down(struct work_struct *work);
218static int ipw_config(struct ipw_priv *);
219static int init_supported_rates(struct ipw_priv *priv,
220 struct ipw_supported_rates *prates);
221static void ipw_set_hwcrypto_keys(struct ipw_priv *);
222static void ipw_send_wep_keys(struct ipw_priv *, int);
223
224static int snprint_line(char *buf, size_t count,
225 const u8 * data, u32 len, u32 ofs)
226{
227 int out, i, j, l;
228 char c;
229
230 out = snprintf(buf, count, "%08X", ofs);
231
232 for (l = 0, i = 0; i < 2; i++) {
233 out += snprintf(buf + out, count - out, " ");
234 for (j = 0; j < 8 && l < len; j++, l++)
235 out += snprintf(buf + out, count - out, "%02X ",
236 data[(i * 8 + j)]);
237 for (; j < 8; j++)
238 out += snprintf(buf + out, count - out, " ");
239 }
240
241 out += snprintf(buf + out, count - out, " ");
242 for (l = 0, i = 0; i < 2; i++) {
243 out += snprintf(buf + out, count - out, " ");
244 for (j = 0; j < 8 && l < len; j++, l++) {
245 c = data[(i * 8 + j)];
246 if (!isascii(c) || !isprint(c))
247 c = '.';
248
249 out += snprintf(buf + out, count - out, "%c", c);
250 }
251
252 for (; j < 8; j++)
253 out += snprintf(buf + out, count - out, " ");
254 }
255
256 return out;
257}
258
259static void printk_buf(int level, const u8 * data, u32 len)
260{
261 char line[81];
262 u32 ofs = 0;
263 if (!(ipw_debug_level & level))
264 return;
265
266 while (len) {
267 snprint_line(line, sizeof(line), &data[ofs],
268 min(len, 16U), ofs);
269 printk(KERN_DEBUG "%s\n", line);
270 ofs += 16;
271 len -= min(len, 16U);
272 }
273}
274
275static int snprintk_buf(u8 * output, size_t size, const u8 * data, size_t len)
276{
277 size_t out = size;
278 u32 ofs = 0;
279 int total = 0;
280
281 while (size && len) {
282 out = snprint_line(output, size, &data[ofs],
283 min_t(size_t, len, 16U), ofs);
284
285 ofs += 16;
286 output += out;
287 size -= out;
288 len -= min_t(size_t, len, 16U);
289 total += out;
290 }
291 return total;
292}
293
294
295static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
296#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
297
298
299static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg);
300#define ipw_read_reg8(a, b) _ipw_read_reg8(a, b)
301
302
303static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value);
304static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c)
305{
306 IPW_DEBUG_IO("%s %d: write_indirect8(0x%08X, 0x%08X)\n", __FILE__,
307 __LINE__, (u32) (b), (u32) (c));
308 _ipw_write_reg8(a, b, c);
309}
310
311
312static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value);
313static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c)
314{
315 IPW_DEBUG_IO("%s %d: write_indirect16(0x%08X, 0x%08X)\n", __FILE__,
316 __LINE__, (u32) (b), (u32) (c));
317 _ipw_write_reg16(a, b, c);
318}
319
320
321static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value);
322static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
323{
324 IPW_DEBUG_IO("%s %d: write_indirect32(0x%08X, 0x%08X)\n", __FILE__,
325 __LINE__, (u32) (b), (u32) (c));
326 _ipw_write_reg32(a, b, c);
327}
328
329
330static inline void _ipw_write8(struct ipw_priv *ipw, unsigned long ofs,
331 u8 val)
332{
333 writeb(val, ipw->hw_base + ofs);
334}
335
336
337#define ipw_write8(ipw, ofs, val) do { \
338 IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, \
339 __LINE__, (u32)(ofs), (u32)(val)); \
340 _ipw_write8(ipw, ofs, val); \
341} while (0)
342
343
344static inline void _ipw_write16(struct ipw_priv *ipw, unsigned long ofs,
345 u16 val)
346{
347 writew(val, ipw->hw_base + ofs);
348}
349
350
351#define ipw_write16(ipw, ofs, val) do { \
352 IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, \
353 __LINE__, (u32)(ofs), (u32)(val)); \
354 _ipw_write16(ipw, ofs, val); \
355} while (0)
356
357
358static inline void _ipw_write32(struct ipw_priv *ipw, unsigned long ofs,
359 u32 val)
360{
361 writel(val, ipw->hw_base + ofs);
362}
363
364
365#define ipw_write32(ipw, ofs, val) do { \
366 IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, \
367 __LINE__, (u32)(ofs), (u32)(val)); \
368 _ipw_write32(ipw, ofs, val); \
369} while (0)
370
371
372static inline u8 _ipw_read8(struct ipw_priv *ipw, unsigned long ofs)
373{
374 return readb(ipw->hw_base + ofs);
375}
376
377
378#define ipw_read8(ipw, ofs) ({ \
379 IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", __FILE__, __LINE__, \
380 (u32)(ofs)); \
381 _ipw_read8(ipw, ofs); \
382})
383
384
385static inline u16 _ipw_read16(struct ipw_priv *ipw, unsigned long ofs)
386{
387 return readw(ipw->hw_base + ofs);
388}
389
390
391#define ipw_read16(ipw, ofs) ({ \
392 IPW_DEBUG_IO("%s %d: read_direct16(0x%08X)\n", __FILE__, __LINE__, \
393 (u32)(ofs)); \
394 _ipw_read16(ipw, ofs); \
395})
396
397
398static inline u32 _ipw_read32(struct ipw_priv *ipw, unsigned long ofs)
399{
400 return readl(ipw->hw_base + ofs);
401}
402
403
404#define ipw_read32(ipw, ofs) ({ \
405 IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", __FILE__, __LINE__, \
406 (u32)(ofs)); \
407 _ipw_read32(ipw, ofs); \
408})
409
410static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
411
412#define ipw_read_indirect(a, b, c, d) ({ \
413 IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %u bytes\n", __FILE__, \
414 __LINE__, (u32)(b), (u32)(d)); \
415 _ipw_read_indirect(a, b, c, d); \
416})
417
418
419static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
420 int num);
421#define ipw_write_indirect(a, b, c, d) do { \
422 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %u bytes\n", __FILE__, \
423 __LINE__, (u32)(b), (u32)(d)); \
424 _ipw_write_indirect(a, b, c, d); \
425} while (0)
426
427
428static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
429{
430 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
431 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
432 _ipw_write32(priv, IPW_INDIRECT_DATA, value);
433}
434
435
436static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
437{
438 u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK;
439 u32 dif_len = reg - aligned_addr;
440
441 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
442 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
443 _ipw_write8(priv, IPW_INDIRECT_DATA + dif_len, value);
444}
445
446
447static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
448{
449 u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK;
450 u32 dif_len = (reg - aligned_addr) & (~0x1ul);
451
452 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
453 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
454 _ipw_write16(priv, IPW_INDIRECT_DATA + dif_len, value);
455}
456
457
458static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
459{
460 u32 word;
461 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
462 IPW_DEBUG_IO(" reg = 0x%8X :\n", reg);
463 word = _ipw_read32(priv, IPW_INDIRECT_DATA);
464 return (word >> ((reg & 0x3) * 8)) & 0xff;
465}
466
467
468static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
469{
470 u32 value;
471
472 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg);
473
474 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
475 value = _ipw_read32(priv, IPW_INDIRECT_DATA);
476 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x\n", reg, value);
477 return value;
478}
479
480
481
482static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
483 int num)
484{
485 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
486 u32 dif_len = addr - aligned_addr;
487 u32 i;
488
489 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
490
491 if (num <= 0) {
492 return;
493 }
494
495
496 if (unlikely(dif_len)) {
497 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
498
499 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--)
500 *buf++ = _ipw_read8(priv, IPW_INDIRECT_DATA + i);
501 aligned_addr += 4;
502 }
503
504
505 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
506 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
507 *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA);
508
509
510 if (unlikely(num)) {
511 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
512 for (i = 0; num > 0; i++, num--)
513 *buf++ = ipw_read8(priv, IPW_INDIRECT_DATA + i);
514 }
515}
516
517
518
519static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
520 int num)
521{
522 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
523 u32 dif_len = addr - aligned_addr;
524 u32 i;
525
526 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
527
528 if (num <= 0) {
529 return;
530 }
531
532
533 if (unlikely(dif_len)) {
534 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
535
536 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
537 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
538 aligned_addr += 4;
539 }
540
541
542 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
543 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
544 _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);
545
546
547 if (unlikely(num)) {
548 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
549 for (i = 0; num > 0; i++, num--, buf++)
550 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
551 }
552}
553
554
555
556static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
557 int num)
558{
559 memcpy_toio((priv->hw_base + addr), buf, num);
560}
561
562
563static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask)
564{
565 ipw_write32(priv, reg, ipw_read32(priv, reg) | mask);
566}
567
568
569static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask)
570{
571 ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask);
572}
573
574static inline void __ipw_enable_interrupts(struct ipw_priv *priv)
575{
576 if (priv->status & STATUS_INT_ENABLED)
577 return;
578 priv->status |= STATUS_INT_ENABLED;
579 ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL);
580}
581
582static inline void __ipw_disable_interrupts(struct ipw_priv *priv)
583{
584 if (!(priv->status & STATUS_INT_ENABLED))
585 return;
586 priv->status &= ~STATUS_INT_ENABLED;
587 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
588}
589
590static inline void ipw_enable_interrupts(struct ipw_priv *priv)
591{
592 unsigned long flags;
593
594 spin_lock_irqsave(&priv->irq_lock, flags);
595 __ipw_enable_interrupts(priv);
596 spin_unlock_irqrestore(&priv->irq_lock, flags);
597}
598
599static inline void ipw_disable_interrupts(struct ipw_priv *priv)
600{
601 unsigned long flags;
602
603 spin_lock_irqsave(&priv->irq_lock, flags);
604 __ipw_disable_interrupts(priv);
605 spin_unlock_irqrestore(&priv->irq_lock, flags);
606}
607
608static char *ipw_error_desc(u32 val)
609{
610 switch (val) {
611 case IPW_FW_ERROR_OK:
612 return "ERROR_OK";
613 case IPW_FW_ERROR_FAIL:
614 return "ERROR_FAIL";
615 case IPW_FW_ERROR_MEMORY_UNDERFLOW:
616 return "MEMORY_UNDERFLOW";
617 case IPW_FW_ERROR_MEMORY_OVERFLOW:
618 return "MEMORY_OVERFLOW";
619 case IPW_FW_ERROR_BAD_PARAM:
620 return "BAD_PARAM";
621 case IPW_FW_ERROR_BAD_CHECKSUM:
622 return "BAD_CHECKSUM";
623 case IPW_FW_ERROR_NMI_INTERRUPT:
624 return "NMI_INTERRUPT";
625 case IPW_FW_ERROR_BAD_DATABASE:
626 return "BAD_DATABASE";
627 case IPW_FW_ERROR_ALLOC_FAIL:
628 return "ALLOC_FAIL";
629 case IPW_FW_ERROR_DMA_UNDERRUN:
630 return "DMA_UNDERRUN";
631 case IPW_FW_ERROR_DMA_STATUS:
632 return "DMA_STATUS";
633 case IPW_FW_ERROR_DINO_ERROR:
634 return "DINO_ERROR";
635 case IPW_FW_ERROR_EEPROM_ERROR:
636 return "EEPROM_ERROR";
637 case IPW_FW_ERROR_SYSASSERT:
638 return "SYSASSERT";
639 case IPW_FW_ERROR_FATAL_ERROR:
640 return "FATAL_ERROR";
641 default:
642 return "UNKNOWN_ERROR";
643 }
644}
645
646static void ipw_dump_error_log(struct ipw_priv *priv,
647 struct ipw_fw_error *error)
648{
649 u32 i;
650
651 if (!error) {
652 IPW_ERROR("Error allocating and capturing error log. "
653 "Nothing to dump.\n");
654 return;
655 }
656
657 IPW_ERROR("Start IPW Error Log Dump:\n");
658 IPW_ERROR("Status: 0x%08X, Config: %08X\n",
659 error->status, error->config);
660
661 for (i = 0; i < error->elem_len; i++)
662 IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
663 ipw_error_desc(error->elem[i].desc),
664 error->elem[i].time,
665 error->elem[i].blink1,
666 error->elem[i].blink2,
667 error->elem[i].link1,
668 error->elem[i].link2, error->elem[i].data);
669 for (i = 0; i < error->log_len; i++)
670 IPW_ERROR("%i\t0x%08x\t%i\n",
671 error->log[i].time,
672 error->log[i].data, error->log[i].event);
673}
674
675static inline int ipw_is_init(struct ipw_priv *priv)
676{
677 return (priv->status & STATUS_INIT) ? 1 : 0;
678}
679
680static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)
681{
682 u32 addr, field_info, field_len, field_count, total_len;
683
684 IPW_DEBUG_ORD("ordinal = %i\n", ord);
685
686 if (!priv || !val || !len) {
687 IPW_DEBUG_ORD("Invalid argument\n");
688 return -EINVAL;
689 }
690
691
692 if (!priv->table0_addr || !priv->table1_addr || !priv->table2_addr) {
693 IPW_DEBUG_ORD("Access ordinals before initialization\n");
694 return -EINVAL;
695 }
696
697 switch (IPW_ORD_TABLE_ID_MASK & ord) {
698 case IPW_ORD_TABLE_0_MASK:
699
700
701
702
703
704
705
706
707 ord &= IPW_ORD_TABLE_VALUE_MASK;
708
709
710 if (ord > priv->table0_len) {
711 IPW_DEBUG_ORD("ordinal value (%i) longer then "
712 "max (%i)\n", ord, priv->table0_len);
713 return -EINVAL;
714 }
715
716
717 if (*len < sizeof(u32)) {
718 IPW_DEBUG_ORD("ordinal buffer length too small, "
719 "need %zd\n", sizeof(u32));
720 return -EINVAL;
721 }
722
723 IPW_DEBUG_ORD("Reading TABLE0[%i] from offset 0x%08x\n",
724 ord, priv->table0_addr + (ord << 2));
725
726 *len = sizeof(u32);
727 ord <<= 2;
728 *((u32 *) val) = ipw_read32(priv, priv->table0_addr + ord);
729 break;
730
731 case IPW_ORD_TABLE_1_MASK:
732
733
734
735
736
737
738
739
740
741 ord &= IPW_ORD_TABLE_VALUE_MASK;
742
743
744 if (ord > priv->table1_len) {
745 IPW_DEBUG_ORD("ordinal value too long\n");
746 return -EINVAL;
747 }
748
749
750 if (*len < sizeof(u32)) {
751 IPW_DEBUG_ORD("ordinal buffer length too small, "
752 "need %zd\n", sizeof(u32));
753 return -EINVAL;
754 }
755
756 *((u32 *) val) =
757 ipw_read_reg32(priv, (priv->table1_addr + (ord << 2)));
758 *len = sizeof(u32);
759 break;
760
761 case IPW_ORD_TABLE_2_MASK:
762
763
764
765
766
767
768
769
770
771
772 ord &= IPW_ORD_TABLE_VALUE_MASK;
773
774
775 if (ord > priv->table2_len) {
776 IPW_DEBUG_ORD("ordinal value too long\n");
777 return -EINVAL;
778 }
779
780
781 addr = ipw_read_reg32(priv, priv->table2_addr + (ord << 3));
782
783
784
785 field_info =
786 ipw_read_reg32(priv,
787 priv->table2_addr + (ord << 3) +
788 sizeof(u32));
789
790
791 field_len = *((u16 *) & field_info);
792
793
794 field_count = *(((u16 *) & field_info) + 1);
795
796
797 total_len = field_len * field_count;
798 if (total_len > *len) {
799 *len = total_len;
800 return -EINVAL;
801 }
802
803 *len = total_len;
804 if (!total_len)
805 return 0;
806
807 IPW_DEBUG_ORD("addr = 0x%08x, total_len = %i, "
808 "field_info = 0x%08x\n",
809 addr, total_len, field_info);
810 ipw_read_indirect(priv, addr, val, total_len);
811 break;
812
813 default:
814 IPW_DEBUG_ORD("Invalid ordinal!\n");
815 return -EINVAL;
816
817 }
818
819 return 0;
820}
821
822static void ipw_init_ordinals(struct ipw_priv *priv)
823{
824 priv->table0_addr = IPW_ORDINALS_TABLE_LOWER;
825 priv->table0_len = ipw_read32(priv, priv->table0_addr);
826
827 IPW_DEBUG_ORD("table 0 offset at 0x%08x, len = %i\n",
828 priv->table0_addr, priv->table0_len);
829
830 priv->table1_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_1);
831 priv->table1_len = ipw_read_reg32(priv, priv->table1_addr);
832
833 IPW_DEBUG_ORD("table 1 offset at 0x%08x, len = %i\n",
834 priv->table1_addr, priv->table1_len);
835
836 priv->table2_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_2);
837 priv->table2_len = ipw_read_reg32(priv, priv->table2_addr);
838 priv->table2_len &= 0x0000ffff;
839
840 IPW_DEBUG_ORD("table 2 offset at 0x%08x, len = %i\n",
841 priv->table2_addr, priv->table2_len);
842
843}
844
845static u32 ipw_register_toggle(u32 reg)
846{
847 reg &= ~IPW_START_STANDBY;
848 if (reg & IPW_GATE_ODMA)
849 reg &= ~IPW_GATE_ODMA;
850 if (reg & IPW_GATE_IDMA)
851 reg &= ~IPW_GATE_IDMA;
852 if (reg & IPW_GATE_ADMA)
853 reg &= ~IPW_GATE_ADMA;
854 return reg;
855}
856
857
858
859
860
861
862
863
864
865
866#define LD_TIME_LINK_ON msecs_to_jiffies(300)
867#define LD_TIME_LINK_OFF msecs_to_jiffies(2700)
868#define LD_TIME_ACT_ON msecs_to_jiffies(250)
869
870static void ipw_led_link_on(struct ipw_priv *priv)
871{
872 unsigned long flags;
873 u32 led;
874
875
876
877 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
878 return;
879
880 spin_lock_irqsave(&priv->lock, flags);
881
882 if (!(priv->status & STATUS_RF_KILL_MASK) &&
883 !(priv->status & STATUS_LED_LINK_ON)) {
884 IPW_DEBUG_LED("Link LED On\n");
885 led = ipw_read_reg32(priv, IPW_EVENT_REG);
886 led |= priv->led_association_on;
887
888 led = ipw_register_toggle(led);
889
890 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
891 ipw_write_reg32(priv, IPW_EVENT_REG, led);
892
893 priv->status |= STATUS_LED_LINK_ON;
894
895
896 if (!(priv->status & STATUS_ASSOCIATED))
897 queue_delayed_work(priv->workqueue,
898 &priv->led_link_off,
899 LD_TIME_LINK_ON);
900 }
901
902 spin_unlock_irqrestore(&priv->lock, flags);
903}
904
905static void ipw_bg_led_link_on(struct work_struct *work)
906{
907 struct ipw_priv *priv =
908 container_of(work, struct ipw_priv, led_link_on.work);
909 mutex_lock(&priv->mutex);
910 ipw_led_link_on(priv);
911 mutex_unlock(&priv->mutex);
912}
913
914static void ipw_led_link_off(struct ipw_priv *priv)
915{
916 unsigned long flags;
917 u32 led;
918
919
920
921 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
922 return;
923
924 spin_lock_irqsave(&priv->lock, flags);
925
926 if (priv->status & STATUS_LED_LINK_ON) {
927 led = ipw_read_reg32(priv, IPW_EVENT_REG);
928 led &= priv->led_association_off;
929 led = ipw_register_toggle(led);
930
931 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
932 ipw_write_reg32(priv, IPW_EVENT_REG, led);
933
934 IPW_DEBUG_LED("Link LED Off\n");
935
936 priv->status &= ~STATUS_LED_LINK_ON;
937
938
939
940 if (!(priv->status & STATUS_RF_KILL_MASK) &&
941 !(priv->status & STATUS_ASSOCIATED))
942 queue_delayed_work(priv->workqueue, &priv->led_link_on,
943 LD_TIME_LINK_OFF);
944
945 }
946
947 spin_unlock_irqrestore(&priv->lock, flags);
948}
949
950static void ipw_bg_led_link_off(struct work_struct *work)
951{
952 struct ipw_priv *priv =
953 container_of(work, struct ipw_priv, led_link_off.work);
954 mutex_lock(&priv->mutex);
955 ipw_led_link_off(priv);
956 mutex_unlock(&priv->mutex);
957}
958
959static void __ipw_led_activity_on(struct ipw_priv *priv)
960{
961 u32 led;
962
963 if (priv->config & CFG_NO_LED)
964 return;
965
966 if (priv->status & STATUS_RF_KILL_MASK)
967 return;
968
969 if (!(priv->status & STATUS_LED_ACT_ON)) {
970 led = ipw_read_reg32(priv, IPW_EVENT_REG);
971 led |= priv->led_activity_on;
972
973 led = ipw_register_toggle(led);
974
975 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
976 ipw_write_reg32(priv, IPW_EVENT_REG, led);
977
978 IPW_DEBUG_LED("Activity LED On\n");
979
980 priv->status |= STATUS_LED_ACT_ON;
981
982 cancel_delayed_work(&priv->led_act_off);
983 queue_delayed_work(priv->workqueue, &priv->led_act_off,
984 LD_TIME_ACT_ON);
985 } else {
986
987 cancel_delayed_work(&priv->led_act_off);
988 queue_delayed_work(priv->workqueue, &priv->led_act_off,
989 LD_TIME_ACT_ON);
990 }
991}
992
993#if 0
994void ipw_led_activity_on(struct ipw_priv *priv)
995{
996 unsigned long flags;
997 spin_lock_irqsave(&priv->lock, flags);
998 __ipw_led_activity_on(priv);
999 spin_unlock_irqrestore(&priv->lock, flags);
1000}
1001#endif
1002
1003static void ipw_led_activity_off(struct ipw_priv *priv)
1004{
1005 unsigned long flags;
1006 u32 led;
1007
1008 if (priv->config & CFG_NO_LED)
1009 return;
1010
1011 spin_lock_irqsave(&priv->lock, flags);
1012
1013 if (priv->status & STATUS_LED_ACT_ON) {
1014 led = ipw_read_reg32(priv, IPW_EVENT_REG);
1015 led &= priv->led_activity_off;
1016
1017 led = ipw_register_toggle(led);
1018
1019 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
1020 ipw_write_reg32(priv, IPW_EVENT_REG, led);
1021
1022 IPW_DEBUG_LED("Activity LED Off\n");
1023
1024 priv->status &= ~STATUS_LED_ACT_ON;
1025 }
1026
1027 spin_unlock_irqrestore(&priv->lock, flags);
1028}
1029
1030static void ipw_bg_led_activity_off(struct work_struct *work)
1031{
1032 struct ipw_priv *priv =
1033 container_of(work, struct ipw_priv, led_act_off.work);
1034 mutex_lock(&priv->mutex);
1035 ipw_led_activity_off(priv);
1036 mutex_unlock(&priv->mutex);
1037}
1038
1039static void ipw_led_band_on(struct ipw_priv *priv)
1040{
1041 unsigned long flags;
1042 u32 led;
1043
1044
1045 if (priv->config & CFG_NO_LED ||
1046 priv->nic_type != EEPROM_NIC_TYPE_1 || !priv->assoc_network)
1047 return;
1048
1049 spin_lock_irqsave(&priv->lock, flags);
1050
1051 led = ipw_read_reg32(priv, IPW_EVENT_REG);
1052 if (priv->assoc_network->mode == IEEE_A) {
1053 led |= priv->led_ofdm_on;
1054 led &= priv->led_association_off;
1055 IPW_DEBUG_LED("Mode LED On: 802.11a\n");
1056 } else if (priv->assoc_network->mode == IEEE_G) {
1057 led |= priv->led_ofdm_on;
1058 led |= priv->led_association_on;
1059 IPW_DEBUG_LED("Mode LED On: 802.11g\n");
1060 } else {
1061 led &= priv->led_ofdm_off;
1062 led |= priv->led_association_on;
1063 IPW_DEBUG_LED("Mode LED On: 802.11b\n");
1064 }
1065
1066 led = ipw_register_toggle(led);
1067
1068 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
1069 ipw_write_reg32(priv, IPW_EVENT_REG, led);
1070
1071 spin_unlock_irqrestore(&priv->lock, flags);
1072}
1073
1074static void ipw_led_band_off(struct ipw_priv *priv)
1075{
1076 unsigned long flags;
1077 u32 led;
1078
1079
1080 if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
1081 return;
1082
1083 spin_lock_irqsave(&priv->lock, flags);
1084
1085 led = ipw_read_reg32(priv, IPW_EVENT_REG);
1086 led &= priv->led_ofdm_off;
1087 led &= priv->led_association_off;
1088
1089 led = ipw_register_toggle(led);
1090
1091 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
1092 ipw_write_reg32(priv, IPW_EVENT_REG, led);
1093
1094 spin_unlock_irqrestore(&priv->lock, flags);
1095}
1096
1097static void ipw_led_radio_on(struct ipw_priv *priv)
1098{
1099 ipw_led_link_on(priv);
1100}
1101
1102static void ipw_led_radio_off(struct ipw_priv *priv)
1103{
1104 ipw_led_activity_off(priv);
1105 ipw_led_link_off(priv);
1106}
1107
1108static void ipw_led_link_up(struct ipw_priv *priv)
1109{
1110
1111 ipw_led_link_on(priv);
1112}
1113
1114static void ipw_led_link_down(struct ipw_priv *priv)
1115{
1116 ipw_led_activity_off(priv);
1117 ipw_led_link_off(priv);
1118
1119 if (priv->status & STATUS_RF_KILL_MASK)
1120 ipw_led_radio_off(priv);
1121}
1122
1123static void ipw_led_init(struct ipw_priv *priv)
1124{
1125 priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
1126
1127
1128 priv->led_activity_on = IPW_ACTIVITY_LED;
1129 priv->led_activity_off = ~(IPW_ACTIVITY_LED);
1130
1131 priv->led_association_on = IPW_ASSOCIATED_LED;
1132 priv->led_association_off = ~(IPW_ASSOCIATED_LED);
1133
1134
1135 priv->led_ofdm_on = IPW_OFDM_LED;
1136 priv->led_ofdm_off = ~(IPW_OFDM_LED);
1137
1138 switch (priv->nic_type) {
1139 case EEPROM_NIC_TYPE_1:
1140
1141 priv->led_activity_on = IPW_ASSOCIATED_LED;
1142 priv->led_activity_off = ~(IPW_ASSOCIATED_LED);
1143 priv->led_association_on = IPW_ACTIVITY_LED;
1144 priv->led_association_off = ~(IPW_ACTIVITY_LED);
1145
1146 if (!(priv->config & CFG_NO_LED))
1147 ipw_led_band_on(priv);
1148
1149
1150
1151 return;
1152
1153 case EEPROM_NIC_TYPE_3:
1154 case EEPROM_NIC_TYPE_2:
1155 case EEPROM_NIC_TYPE_4:
1156 case EEPROM_NIC_TYPE_0:
1157 break;
1158
1159 default:
1160 IPW_DEBUG_INFO("Unknown NIC type from EEPROM: %d\n",
1161 priv->nic_type);
1162 priv->nic_type = EEPROM_NIC_TYPE_0;
1163 break;
1164 }
1165
1166 if (!(priv->config & CFG_NO_LED)) {
1167 if (priv->status & STATUS_ASSOCIATED)
1168 ipw_led_link_on(priv);
1169 else
1170 ipw_led_link_off(priv);
1171 }
1172}
1173
1174static void ipw_led_shutdown(struct ipw_priv *priv)
1175{
1176 ipw_led_activity_off(priv);
1177 ipw_led_link_off(priv);
1178 ipw_led_band_off(priv);
1179 cancel_delayed_work(&priv->led_link_on);
1180 cancel_delayed_work(&priv->led_link_off);
1181 cancel_delayed_work(&priv->led_act_off);
1182}
1183
1184
1185
1186
1187
1188
1189
1190
1191static ssize_t show_debug_level(struct device_driver *d, char *buf)
1192{
1193 return sprintf(buf, "0x%08X\n", ipw_debug_level);
1194}
1195
1196static ssize_t store_debug_level(struct device_driver *d, const char *buf,
1197 size_t count)
1198{
1199 char *p = (char *)buf;
1200 u32 val;
1201
1202 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
1203 p++;
1204 if (p[0] == 'x' || p[0] == 'X')
1205 p++;
1206 val = simple_strtoul(p, &p, 16);
1207 } else
1208 val = simple_strtoul(p, &p, 10);
1209 if (p == buf)
1210 printk(KERN_INFO DRV_NAME
1211 ": %s is not in hex or decimal form.\n", buf);
1212 else
1213 ipw_debug_level = val;
1214
1215 return strnlen(buf, count);
1216}
1217
1218static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
1219 show_debug_level, store_debug_level);
1220
1221static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)
1222{
1223
1224 return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));
1225}
1226
1227static void ipw_capture_event_log(struct ipw_priv *priv,
1228 u32 log_len, struct ipw_event *log)
1229{
1230 u32 base;
1231
1232 if (log_len) {
1233 base = ipw_read32(priv, IPW_EVENT_LOG);
1234 ipw_read_indirect(priv, base + sizeof(base) + sizeof(u32),
1235 (u8 *) log, sizeof(*log) * log_len);
1236 }
1237}
1238
1239static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
1240{
1241 struct ipw_fw_error *error;
1242 u32 log_len = ipw_get_event_log_len(priv);
1243 u32 base = ipw_read32(priv, IPW_ERROR_LOG);
1244 u32 elem_len = ipw_read_reg32(priv, base);
1245
1246 error = kmalloc(sizeof(*error) +
1247 sizeof(*error->elem) * elem_len +
1248 sizeof(*error->log) * log_len, GFP_ATOMIC);
1249 if (!error) {
1250 IPW_ERROR("Memory allocation for firmware error log "
1251 "failed.\n");
1252 return NULL;
1253 }
1254 error->jiffies = jiffies;
1255 error->status = priv->status;
1256 error->config = priv->config;
1257 error->elem_len = elem_len;
1258 error->log_len = log_len;
1259 error->elem = (struct ipw_error_elem *)error->payload;
1260 error->log = (struct ipw_event *)(error->elem + elem_len);
1261
1262 ipw_capture_event_log(priv, log_len, error->log);
1263
1264 if (elem_len)
1265 ipw_read_indirect(priv, base + sizeof(base), (u8 *) error->elem,
1266 sizeof(*error->elem) * elem_len);
1267
1268 return error;
1269}
1270
1271static ssize_t show_event_log(struct device *d,
1272 struct device_attribute *attr, char *buf)
1273{
1274 struct ipw_priv *priv = dev_get_drvdata(d);
1275 u32 log_len = ipw_get_event_log_len(priv);
1276 u32 log_size;
1277 struct ipw_event *log;
1278 u32 len = 0, i;
1279
1280
1281 log_size = PAGE_SIZE / sizeof(*log) > log_len ?
1282 sizeof(*log) * log_len : PAGE_SIZE;
1283 log = kzalloc(log_size, GFP_KERNEL);
1284 if (!log) {
1285 IPW_ERROR("Unable to allocate memory for log\n");
1286 return 0;
1287 }
1288 log_len = log_size / sizeof(*log);
1289 ipw_capture_event_log(priv, log_len, log);
1290
1291 len += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len);
1292 for (i = 0; i < log_len; i++)
1293 len += snprintf(buf + len, PAGE_SIZE - len,
1294 "\n%08X%08X%08X",
1295 log[i].time, log[i].event, log[i].data);
1296 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1297 kfree(log);
1298 return len;
1299}
1300
1301static DEVICE_ATTR(event_log, S_IRUGO, show_event_log, NULL);
1302
1303static ssize_t show_error(struct device *d,
1304 struct device_attribute *attr, char *buf)
1305{
1306 struct ipw_priv *priv = dev_get_drvdata(d);
1307 u32 len = 0, i;
1308 if (!priv->error)
1309 return 0;
1310 len += snprintf(buf + len, PAGE_SIZE - len,
1311 "%08lX%08X%08X%08X",
1312 priv->error->jiffies,
1313 priv->error->status,
1314 priv->error->config, priv->error->elem_len);
1315 for (i = 0; i < priv->error->elem_len; i++)
1316 len += snprintf(buf + len, PAGE_SIZE - len,
1317 "\n%08X%08X%08X%08X%08X%08X%08X",
1318 priv->error->elem[i].time,
1319 priv->error->elem[i].desc,
1320 priv->error->elem[i].blink1,
1321 priv->error->elem[i].blink2,
1322 priv->error->elem[i].link1,
1323 priv->error->elem[i].link2,
1324 priv->error->elem[i].data);
1325
1326 len += snprintf(buf + len, PAGE_SIZE - len,
1327 "\n%08X", priv->error->log_len);
1328 for (i = 0; i < priv->error->log_len; i++)
1329 len += snprintf(buf + len, PAGE_SIZE - len,
1330 "\n%08X%08X%08X",
1331 priv->error->log[i].time,
1332 priv->error->log[i].event,
1333 priv->error->log[i].data);
1334 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1335 return len;
1336}
1337
1338static ssize_t clear_error(struct device *d,
1339 struct device_attribute *attr,
1340 const char *buf, size_t count)
1341{
1342 struct ipw_priv *priv = dev_get_drvdata(d);
1343
1344 kfree(priv->error);
1345 priv->error = NULL;
1346 return count;
1347}
1348
1349static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error);
1350
1351static ssize_t show_cmd_log(struct device *d,
1352 struct device_attribute *attr, char *buf)
1353{
1354 struct ipw_priv *priv = dev_get_drvdata(d);
1355 u32 len = 0, i;
1356 if (!priv->cmdlog)
1357 return 0;
1358 for (i = (priv->cmdlog_pos + 1) % priv->cmdlog_len;
1359 (i != priv->cmdlog_pos) && (PAGE_SIZE - len);
1360 i = (i + 1) % priv->cmdlog_len) {
1361 len +=
1362 snprintf(buf + len, PAGE_SIZE - len,
1363 "\n%08lX%08X%08X%08X\n", priv->cmdlog[i].jiffies,
1364 priv->cmdlog[i].retcode, priv->cmdlog[i].cmd.cmd,
1365 priv->cmdlog[i].cmd.len);
1366 len +=
1367 snprintk_buf(buf + len, PAGE_SIZE - len,
1368 (u8 *) priv->cmdlog[i].cmd.param,
1369 priv->cmdlog[i].cmd.len);
1370 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1371 }
1372 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1373 return len;
1374}
1375
1376static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL);
1377
1378#ifdef CONFIG_IPW2200_PROMISCUOUS
1379static void ipw_prom_free(struct ipw_priv *priv);
1380static int ipw_prom_alloc(struct ipw_priv *priv);
1381static ssize_t store_rtap_iface(struct device *d,
1382 struct device_attribute *attr,
1383 const char *buf, size_t count)
1384{
1385 struct ipw_priv *priv = dev_get_drvdata(d);
1386 int rc = 0;
1387
1388 if (count < 1)
1389 return -EINVAL;
1390
1391 switch (buf[0]) {
1392 case '0':
1393 if (!rtap_iface)
1394 return count;
1395
1396 if (netif_running(priv->prom_net_dev)) {
1397 IPW_WARNING("Interface is up. Cannot unregister.\n");
1398 return count;
1399 }
1400
1401 ipw_prom_free(priv);
1402 rtap_iface = 0;
1403 break;
1404
1405 case '1':
1406 if (rtap_iface)
1407 return count;
1408
1409 rc = ipw_prom_alloc(priv);
1410 if (!rc)
1411 rtap_iface = 1;
1412 break;
1413
1414 default:
1415 return -EINVAL;
1416 }
1417
1418 if (rc) {
1419 IPW_ERROR("Failed to register promiscuous network "
1420 "device (error %d).\n", rc);
1421 }
1422
1423 return count;
1424}
1425
1426static ssize_t show_rtap_iface(struct device *d,
1427 struct device_attribute *attr,
1428 char *buf)
1429{
1430 struct ipw_priv *priv = dev_get_drvdata(d);
1431 if (rtap_iface)
1432 return sprintf(buf, "%s", priv->prom_net_dev->name);
1433 else {
1434 buf[0] = '-';
1435 buf[1] = '1';
1436 buf[2] = '\0';
1437 return 3;
1438 }
1439}
1440
1441static DEVICE_ATTR(rtap_iface, S_IWUSR | S_IRUSR, show_rtap_iface,
1442 store_rtap_iface);
1443
1444static ssize_t store_rtap_filter(struct device *d,
1445 struct device_attribute *attr,
1446 const char *buf, size_t count)
1447{
1448 struct ipw_priv *priv = dev_get_drvdata(d);
1449
1450 if (!priv->prom_priv) {
1451 IPW_ERROR("Attempting to set filter without "
1452 "rtap_iface enabled.\n");
1453 return -EPERM;
1454 }
1455
1456 priv->prom_priv->filter = simple_strtol(buf, NULL, 0);
1457
1458 IPW_DEBUG_INFO("Setting rtap filter to " BIT_FMT16 "\n",
1459 BIT_ARG16(priv->prom_priv->filter));
1460
1461 return count;
1462}
1463
1464static ssize_t show_rtap_filter(struct device *d,
1465 struct device_attribute *attr,
1466 char *buf)
1467{
1468 struct ipw_priv *priv = dev_get_drvdata(d);
1469 return sprintf(buf, "0x%04X",
1470 priv->prom_priv ? priv->prom_priv->filter : 0);
1471}
1472
1473static DEVICE_ATTR(rtap_filter, S_IWUSR | S_IRUSR, show_rtap_filter,
1474 store_rtap_filter);
1475#endif
1476
1477static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
1478 char *buf)
1479{
1480 struct ipw_priv *priv = dev_get_drvdata(d);
1481 return sprintf(buf, "%d\n", priv->ieee->scan_age);
1482}
1483
1484static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
1485 const char *buf, size_t count)
1486{
1487 struct ipw_priv *priv = dev_get_drvdata(d);
1488 struct net_device *dev = priv->net_dev;
1489 char buffer[] = "00000000";
1490 unsigned long len =
1491 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
1492 unsigned long val;
1493 char *p = buffer;
1494
1495 IPW_DEBUG_INFO("enter\n");
1496
1497 strncpy(buffer, buf, len);
1498 buffer[len] = 0;
1499
1500 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
1501 p++;
1502 if (p[0] == 'x' || p[0] == 'X')
1503 p++;
1504 val = simple_strtoul(p, &p, 16);
1505 } else
1506 val = simple_strtoul(p, &p, 10);
1507 if (p == buffer) {
1508 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
1509 } else {
1510 priv->ieee->scan_age = val;
1511 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
1512 }
1513
1514 IPW_DEBUG_INFO("exit\n");
1515 return len;
1516}
1517
1518static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
1519
1520static ssize_t show_led(struct device *d, struct device_attribute *attr,
1521 char *buf)
1522{
1523 struct ipw_priv *priv = dev_get_drvdata(d);
1524 return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);
1525}
1526
1527static ssize_t store_led(struct device *d, struct device_attribute *attr,
1528 const char *buf, size_t count)
1529{
1530 struct ipw_priv *priv = dev_get_drvdata(d);
1531
1532 IPW_DEBUG_INFO("enter\n");
1533
1534 if (count == 0)
1535 return 0;
1536
1537 if (*buf == 0) {
1538 IPW_DEBUG_LED("Disabling LED control.\n");
1539 priv->config |= CFG_NO_LED;
1540 ipw_led_shutdown(priv);
1541 } else {
1542 IPW_DEBUG_LED("Enabling LED control.\n");
1543 priv->config &= ~CFG_NO_LED;
1544 ipw_led_init(priv);
1545 }
1546
1547 IPW_DEBUG_INFO("exit\n");
1548 return count;
1549}
1550
1551static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
1552
1553static ssize_t show_status(struct device *d,
1554 struct device_attribute *attr, char *buf)
1555{
1556 struct ipw_priv *p = dev_get_drvdata(d);
1557 return sprintf(buf, "0x%08x\n", (int)p->status);
1558}
1559
1560static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
1561
1562static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
1563 char *buf)
1564{
1565 struct ipw_priv *p = dev_get_drvdata(d);
1566 return sprintf(buf, "0x%08x\n", (int)p->config);
1567}
1568
1569static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
1570
1571static ssize_t show_nic_type(struct device *d,
1572 struct device_attribute *attr, char *buf)
1573{
1574 struct ipw_priv *priv = dev_get_drvdata(d);
1575 return sprintf(buf, "TYPE: %d\n", priv->nic_type);
1576}
1577
1578static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
1579
1580static ssize_t show_ucode_version(struct device *d,
1581 struct device_attribute *attr, char *buf)
1582{
1583 u32 len = sizeof(u32), tmp = 0;
1584 struct ipw_priv *p = dev_get_drvdata(d);
1585
1586 if (ipw_get_ordinal(p, IPW_ORD_STAT_UCODE_VERSION, &tmp, &len))
1587 return 0;
1588
1589 return sprintf(buf, "0x%08x\n", tmp);
1590}
1591
1592static DEVICE_ATTR(ucode_version, S_IWUSR | S_IRUGO, show_ucode_version, NULL);
1593
1594static ssize_t show_rtc(struct device *d, struct device_attribute *attr,
1595 char *buf)
1596{
1597 u32 len = sizeof(u32), tmp = 0;
1598 struct ipw_priv *p = dev_get_drvdata(d);
1599
1600 if (ipw_get_ordinal(p, IPW_ORD_STAT_RTC, &tmp, &len))
1601 return 0;
1602
1603 return sprintf(buf, "0x%08x\n", tmp);
1604}
1605
1606static DEVICE_ATTR(rtc, S_IWUSR | S_IRUGO, show_rtc, NULL);
1607
1608
1609
1610
1611
1612static ssize_t show_eeprom_delay(struct device *d,
1613 struct device_attribute *attr, char *buf)
1614{
1615 struct ipw_priv *p = dev_get_drvdata(d);
1616 int n = p->eeprom_delay;
1617 return sprintf(buf, "%i\n", n);
1618}
1619static ssize_t store_eeprom_delay(struct device *d,
1620 struct device_attribute *attr,
1621 const char *buf, size_t count)
1622{
1623 struct ipw_priv *p = dev_get_drvdata(d);
1624 sscanf(buf, "%i", &p->eeprom_delay);
1625 return strnlen(buf, count);
1626}
1627
1628static DEVICE_ATTR(eeprom_delay, S_IWUSR | S_IRUGO,
1629 show_eeprom_delay, store_eeprom_delay);
1630
1631static ssize_t show_command_event_reg(struct device *d,
1632 struct device_attribute *attr, char *buf)
1633{
1634 u32 reg = 0;
1635 struct ipw_priv *p = dev_get_drvdata(d);
1636
1637 reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT);
1638 return sprintf(buf, "0x%08x\n", reg);
1639}
1640static ssize_t store_command_event_reg(struct device *d,
1641 struct device_attribute *attr,
1642 const char *buf, size_t count)
1643{
1644 u32 reg;
1645 struct ipw_priv *p = dev_get_drvdata(d);
1646
1647 sscanf(buf, "%x", ®);
1648 ipw_write_reg32(p, IPW_INTERNAL_CMD_EVENT, reg);
1649 return strnlen(buf, count);
1650}
1651
1652static DEVICE_ATTR(command_event_reg, S_IWUSR | S_IRUGO,
1653 show_command_event_reg, store_command_event_reg);
1654
1655static ssize_t show_mem_gpio_reg(struct device *d,
1656 struct device_attribute *attr, char *buf)
1657{
1658 u32 reg = 0;
1659 struct ipw_priv *p = dev_get_drvdata(d);
1660
1661 reg = ipw_read_reg32(p, 0x301100);
1662 return sprintf(buf, "0x%08x\n", reg);
1663}
1664static ssize_t store_mem_gpio_reg(struct device *d,
1665 struct device_attribute *attr,
1666 const char *buf, size_t count)
1667{
1668 u32 reg;
1669 struct ipw_priv *p = dev_get_drvdata(d);
1670
1671 sscanf(buf, "%x", ®);
1672 ipw_write_reg32(p, 0x301100, reg);
1673 return strnlen(buf, count);
1674}
1675
1676static DEVICE_ATTR(mem_gpio_reg, S_IWUSR | S_IRUGO,
1677 show_mem_gpio_reg, store_mem_gpio_reg);
1678
1679static ssize_t show_indirect_dword(struct device *d,
1680 struct device_attribute *attr, char *buf)
1681{
1682 u32 reg = 0;
1683 struct ipw_priv *priv = dev_get_drvdata(d);
1684
1685 if (priv->status & STATUS_INDIRECT_DWORD)
1686 reg = ipw_read_reg32(priv, priv->indirect_dword);
1687 else
1688 reg = 0;
1689
1690 return sprintf(buf, "0x%08x\n", reg);
1691}
1692static ssize_t store_indirect_dword(struct device *d,
1693 struct device_attribute *attr,
1694 const char *buf, size_t count)
1695{
1696 struct ipw_priv *priv = dev_get_drvdata(d);
1697
1698 sscanf(buf, "%x", &priv->indirect_dword);
1699 priv->status |= STATUS_INDIRECT_DWORD;
1700 return strnlen(buf, count);
1701}
1702
1703static DEVICE_ATTR(indirect_dword, S_IWUSR | S_IRUGO,
1704 show_indirect_dword, store_indirect_dword);
1705
1706static ssize_t show_indirect_byte(struct device *d,
1707 struct device_attribute *attr, char *buf)
1708{
1709 u8 reg = 0;
1710 struct ipw_priv *priv = dev_get_drvdata(d);
1711
1712 if (priv->status & STATUS_INDIRECT_BYTE)
1713 reg = ipw_read_reg8(priv, priv->indirect_byte);
1714 else
1715 reg = 0;
1716
1717 return sprintf(buf, "0x%02x\n", reg);
1718}
1719static ssize_t store_indirect_byte(struct device *d,
1720 struct device_attribute *attr,
1721 const char *buf, size_t count)
1722{
1723 struct ipw_priv *priv = dev_get_drvdata(d);
1724
1725 sscanf(buf, "%x", &priv->indirect_byte);
1726 priv->status |= STATUS_INDIRECT_BYTE;
1727 return strnlen(buf, count);
1728}
1729
1730static DEVICE_ATTR(indirect_byte, S_IWUSR | S_IRUGO,
1731 show_indirect_byte, store_indirect_byte);
1732
1733static ssize_t show_direct_dword(struct device *d,
1734 struct device_attribute *attr, char *buf)
1735{
1736 u32 reg = 0;
1737 struct ipw_priv *priv = dev_get_drvdata(d);
1738
1739 if (priv->status & STATUS_DIRECT_DWORD)
1740 reg = ipw_read32(priv, priv->direct_dword);
1741 else
1742 reg = 0;
1743
1744 return sprintf(buf, "0x%08x\n", reg);
1745}
1746static ssize_t store_direct_dword(struct device *d,
1747 struct device_attribute *attr,
1748 const char *buf, size_t count)
1749{
1750 struct ipw_priv *priv = dev_get_drvdata(d);
1751
1752 sscanf(buf, "%x", &priv->direct_dword);
1753 priv->status |= STATUS_DIRECT_DWORD;
1754 return strnlen(buf, count);
1755}
1756
1757static DEVICE_ATTR(direct_dword, S_IWUSR | S_IRUGO,
1758 show_direct_dword, store_direct_dword);
1759
1760static int rf_kill_active(struct ipw_priv *priv)
1761{
1762 if (0 == (ipw_read32(priv, 0x30) & 0x10000)) {
1763 priv->status |= STATUS_RF_KILL_HW;
1764 wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true);
1765 } else {
1766 priv->status &= ~STATUS_RF_KILL_HW;
1767 wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false);
1768 }
1769
1770 return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0;
1771}
1772
1773static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
1774 char *buf)
1775{
1776
1777
1778
1779
1780 struct ipw_priv *priv = dev_get_drvdata(d);
1781 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
1782 (rf_kill_active(priv) ? 0x2 : 0x0);
1783 return sprintf(buf, "%i\n", val);
1784}
1785
1786static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
1787{
1788 if ((disable_radio ? 1 : 0) ==
1789 ((priv->status & STATUS_RF_KILL_SW) ? 1 : 0))
1790 return 0;
1791
1792 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
1793 disable_radio ? "OFF" : "ON");
1794
1795 if (disable_radio) {
1796 priv->status |= STATUS_RF_KILL_SW;
1797
1798 if (priv->workqueue) {
1799 cancel_delayed_work(&priv->request_scan);
1800 cancel_delayed_work(&priv->request_direct_scan);
1801 cancel_delayed_work(&priv->request_passive_scan);
1802 cancel_delayed_work(&priv->scan_event);
1803 }
1804 queue_work(priv->workqueue, &priv->down);
1805 } else {
1806 priv->status &= ~STATUS_RF_KILL_SW;
1807 if (rf_kill_active(priv)) {
1808 IPW_DEBUG_RF_KILL("Can not turn radio back on - "
1809 "disabled by HW switch\n");
1810
1811 cancel_delayed_work(&priv->rf_kill);
1812 queue_delayed_work(priv->workqueue, &priv->rf_kill,
1813 round_jiffies_relative(2 * HZ));
1814 } else
1815 queue_work(priv->workqueue, &priv->up);
1816 }
1817
1818 return 1;
1819}
1820
1821static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
1822 const char *buf, size_t count)
1823{
1824 struct ipw_priv *priv = dev_get_drvdata(d);
1825
1826 ipw_radio_kill_sw(priv, buf[0] == '1');
1827
1828 return count;
1829}
1830
1831static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
1832
1833static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
1834 char *buf)
1835{
1836 struct ipw_priv *priv = dev_get_drvdata(d);
1837 int pos = 0, len = 0;
1838 if (priv->config & CFG_SPEED_SCAN) {
1839 while (priv->speed_scan[pos] != 0)
1840 len += sprintf(&buf[len], "%d ",
1841 priv->speed_scan[pos++]);
1842 return len + sprintf(&buf[len], "\n");
1843 }
1844
1845 return sprintf(buf, "0\n");
1846}
1847
1848static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
1849 const char *buf, size_t count)
1850{
1851 struct ipw_priv *priv = dev_get_drvdata(d);
1852 int channel, pos = 0;
1853 const char *p = buf;
1854
1855
1856 while ((channel = simple_strtol(p, NULL, 0))) {
1857 if (pos == MAX_SPEED_SCAN - 1) {
1858 priv->speed_scan[pos] = 0;
1859 break;
1860 }
1861
1862 if (libipw_is_valid_channel(priv->ieee, channel))
1863 priv->speed_scan[pos++] = channel;
1864 else
1865 IPW_WARNING("Skipping invalid channel request: %d\n",
1866 channel);
1867 p = strchr(p, ' ');
1868 if (!p)
1869 break;
1870 while (*p == ' ' || *p == '\t')
1871 p++;
1872 }
1873
1874 if (pos == 0)
1875 priv->config &= ~CFG_SPEED_SCAN;
1876 else {
1877 priv->speed_scan_pos = 0;
1878 priv->config |= CFG_SPEED_SCAN;
1879 }
1880
1881 return count;
1882}
1883
1884static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan,
1885 store_speed_scan);
1886
1887static ssize_t show_net_stats(struct device *d, struct device_attribute *attr,
1888 char *buf)
1889{
1890 struct ipw_priv *priv = dev_get_drvdata(d);
1891 return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0');
1892}
1893
1894static ssize_t store_net_stats(struct device *d, struct device_attribute *attr,
1895 const char *buf, size_t count)
1896{
1897 struct ipw_priv *priv = dev_get_drvdata(d);
1898 if (buf[0] == '1')
1899 priv->config |= CFG_NET_STATS;
1900 else
1901 priv->config &= ~CFG_NET_STATS;
1902
1903 return count;
1904}
1905
1906static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO,
1907 show_net_stats, store_net_stats);
1908
1909static ssize_t show_channels(struct device *d,
1910 struct device_attribute *attr,
1911 char *buf)
1912{
1913 struct ipw_priv *priv = dev_get_drvdata(d);
1914 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
1915 int len = 0, i;
1916
1917 len = sprintf(&buf[len],
1918 "Displaying %d channels in 2.4Ghz band "
1919 "(802.11bg):\n", geo->bg_channels);
1920
1921 for (i = 0; i < geo->bg_channels; i++) {
1922 len += sprintf(&buf[len], "%d: BSS%s%s, %s, Band %s.\n",
1923 geo->bg[i].channel,
1924 geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT ?
1925 " (radar spectrum)" : "",
1926 ((geo->bg[i].flags & LIBIPW_CH_NO_IBSS) ||
1927 (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT))
1928 ? "" : ", IBSS",
1929 geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY ?
1930 "passive only" : "active/passive",
1931 geo->bg[i].flags & LIBIPW_CH_B_ONLY ?
1932 "B" : "B/G");
1933 }
1934
1935 len += sprintf(&buf[len],
1936 "Displaying %d channels in 5.2Ghz band "
1937 "(802.11a):\n", geo->a_channels);
1938 for (i = 0; i < geo->a_channels; i++) {
1939 len += sprintf(&buf[len], "%d: BSS%s%s, %s.\n",
1940 geo->a[i].channel,
1941 geo->a[i].flags & LIBIPW_CH_RADAR_DETECT ?
1942 " (radar spectrum)" : "",
1943 ((geo->a[i].flags & LIBIPW_CH_NO_IBSS) ||
1944 (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT))
1945 ? "" : ", IBSS",
1946 geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY ?
1947 "passive only" : "active/passive");
1948 }
1949
1950 return len;
1951}
1952
1953static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
1954
1955static void notify_wx_assoc_event(struct ipw_priv *priv)
1956{
1957 union iwreq_data wrqu;
1958 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1959 if (priv->status & STATUS_ASSOCIATED)
1960 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
1961 else
1962 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1963 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1964}
1965
1966static void ipw_irq_tasklet(struct ipw_priv *priv)
1967{
1968 u32 inta, inta_mask, handled = 0;
1969 unsigned long flags;
1970 int rc = 0;
1971
1972 spin_lock_irqsave(&priv->irq_lock, flags);
1973
1974 inta = ipw_read32(priv, IPW_INTA_RW);
1975 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
1976 inta &= (IPW_INTA_MASK_ALL & inta_mask);
1977
1978
1979 inta |= priv->isr_inta;
1980
1981 spin_unlock_irqrestore(&priv->irq_lock, flags);
1982
1983 spin_lock_irqsave(&priv->lock, flags);
1984
1985
1986 if (inta & IPW_INTA_BIT_RX_TRANSFER) {
1987 ipw_rx(priv);
1988 handled |= IPW_INTA_BIT_RX_TRANSFER;
1989 }
1990
1991 if (inta & IPW_INTA_BIT_TX_CMD_QUEUE) {
1992 IPW_DEBUG_HC("Command completed.\n");
1993 rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1);
1994 priv->status &= ~STATUS_HCMD_ACTIVE;
1995 wake_up_interruptible(&priv->wait_command_queue);
1996 handled |= IPW_INTA_BIT_TX_CMD_QUEUE;
1997 }
1998
1999 if (inta & IPW_INTA_BIT_TX_QUEUE_1) {
2000 IPW_DEBUG_TX("TX_QUEUE_1\n");
2001 rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0);
2002 handled |= IPW_INTA_BIT_TX_QUEUE_1;
2003 }
2004
2005 if (inta & IPW_INTA_BIT_TX_QUEUE_2) {
2006 IPW_DEBUG_TX("TX_QUEUE_2\n");
2007 rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1);
2008 handled |= IPW_INTA_BIT_TX_QUEUE_2;
2009 }
2010
2011 if (inta & IPW_INTA_BIT_TX_QUEUE_3) {
2012 IPW_DEBUG_TX("TX_QUEUE_3\n");
2013 rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2);
2014 handled |= IPW_INTA_BIT_TX_QUEUE_3;
2015 }
2016
2017 if (inta & IPW_INTA_BIT_TX_QUEUE_4) {
2018 IPW_DEBUG_TX("TX_QUEUE_4\n");
2019 rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3);
2020 handled |= IPW_INTA_BIT_TX_QUEUE_4;
2021 }
2022
2023 if (inta & IPW_INTA_BIT_STATUS_CHANGE) {
2024 IPW_WARNING("STATUS_CHANGE\n");
2025 handled |= IPW_INTA_BIT_STATUS_CHANGE;
2026 }
2027
2028 if (inta & IPW_INTA_BIT_BEACON_PERIOD_EXPIRED) {
2029 IPW_WARNING("TX_PERIOD_EXPIRED\n");
2030 handled |= IPW_INTA_BIT_BEACON_PERIOD_EXPIRED;
2031 }
2032
2033 if (inta & IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) {
2034 IPW_WARNING("HOST_CMD_DONE\n");
2035 handled |= IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE;
2036 }
2037
2038 if (inta & IPW_INTA_BIT_FW_INITIALIZATION_DONE) {
2039 IPW_WARNING("FW_INITIALIZATION_DONE\n");
2040 handled |= IPW_INTA_BIT_FW_INITIALIZATION_DONE;
2041 }
2042
2043 if (inta & IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) {
2044 IPW_WARNING("PHY_OFF_DONE\n");
2045 handled |= IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE;
2046 }
2047
2048 if (inta & IPW_INTA_BIT_RF_KILL_DONE) {
2049 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
2050 priv->status |= STATUS_RF_KILL_HW;
2051 wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true);
2052 wake_up_interruptible(&priv->wait_command_queue);
2053 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
2054 cancel_delayed_work(&priv->request_scan);
2055 cancel_delayed_work(&priv->request_direct_scan);
2056 cancel_delayed_work(&priv->request_passive_scan);
2057 cancel_delayed_work(&priv->scan_event);
2058 schedule_work(&priv->link_down);
2059 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
2060 handled |= IPW_INTA_BIT_RF_KILL_DONE;
2061 }
2062
2063 if (inta & IPW_INTA_BIT_FATAL_ERROR) {
2064 IPW_WARNING("Firmware error detected. Restarting.\n");
2065 if (priv->error) {
2066 IPW_DEBUG_FW("Sysfs 'error' log already exists.\n");
2067 if (ipw_debug_level & IPW_DL_FW_ERRORS) {
2068 struct ipw_fw_error *error =
2069 ipw_alloc_error_log(priv);
2070 ipw_dump_error_log(priv, error);
2071 kfree(error);
2072 }
2073 } else {
2074 priv->error = ipw_alloc_error_log(priv);
2075 if (priv->error)
2076 IPW_DEBUG_FW("Sysfs 'error' log captured.\n");
2077 else
2078 IPW_DEBUG_FW("Error allocating sysfs 'error' "
2079 "log.\n");
2080 if (ipw_debug_level & IPW_DL_FW_ERRORS)
2081 ipw_dump_error_log(priv, priv->error);
2082 }
2083
2084
2085
2086 if (priv->ieee->sec.encrypt) {
2087 priv->status &= ~STATUS_ASSOCIATED;
2088 notify_wx_assoc_event(priv);
2089 }
2090
2091
2092
2093 priv->status &= ~STATUS_INIT;
2094
2095
2096 priv->status &= ~STATUS_HCMD_ACTIVE;
2097 wake_up_interruptible(&priv->wait_command_queue);
2098
2099 queue_work(priv->workqueue, &priv->adapter_restart);
2100 handled |= IPW_INTA_BIT_FATAL_ERROR;
2101 }
2102
2103 if (inta & IPW_INTA_BIT_PARITY_ERROR) {
2104 IPW_ERROR("Parity error\n");
2105 handled |= IPW_INTA_BIT_PARITY_ERROR;
2106 }
2107
2108 if (handled != inta) {
2109 IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
2110 }
2111
2112 spin_unlock_irqrestore(&priv->lock, flags);
2113
2114
2115 ipw_enable_interrupts(priv);
2116}
2117
2118#define IPW_CMD(x) case IPW_CMD_ ## x : return #x
2119static char *get_cmd_string(u8 cmd)
2120{
2121 switch (cmd) {
2122 IPW_CMD(HOST_COMPLETE);
2123 IPW_CMD(POWER_DOWN);
2124 IPW_CMD(SYSTEM_CONFIG);
2125 IPW_CMD(MULTICAST_ADDRESS);
2126 IPW_CMD(SSID);
2127 IPW_CMD(ADAPTER_ADDRESS);
2128 IPW_CMD(PORT_TYPE);
2129 IPW_CMD(RTS_THRESHOLD);
2130 IPW_CMD(FRAG_THRESHOLD);
2131 IPW_CMD(POWER_MODE);
2132 IPW_CMD(WEP_KEY);
2133 IPW_CMD(TGI_TX_KEY);
2134 IPW_CMD(SCAN_REQUEST);
2135 IPW_CMD(SCAN_REQUEST_EXT);
2136 IPW_CMD(ASSOCIATE);
2137 IPW_CMD(SUPPORTED_RATES);
2138 IPW_CMD(SCAN_ABORT);
2139 IPW_CMD(TX_FLUSH);
2140 IPW_CMD(QOS_PARAMETERS);
2141 IPW_CMD(DINO_CONFIG);
2142 IPW_CMD(RSN_CAPABILITIES);
2143 IPW_CMD(RX_KEY);
2144 IPW_CMD(CARD_DISABLE);
2145 IPW_CMD(SEED_NUMBER);
2146 IPW_CMD(TX_POWER);
2147 IPW_CMD(COUNTRY_INFO);
2148 IPW_CMD(AIRONET_INFO);
2149 IPW_CMD(AP_TX_POWER);
2150 IPW_CMD(CCKM_INFO);
2151 IPW_CMD(CCX_VER_INFO);
2152 IPW_CMD(SET_CALIBRATION);
2153 IPW_CMD(SENSITIVITY_CALIB);
2154 IPW_CMD(RETRY_LIMIT);
2155 IPW_CMD(IPW_PRE_POWER_DOWN);
2156 IPW_CMD(VAP_BEACON_TEMPLATE);
2157 IPW_CMD(VAP_DTIM_PERIOD);
2158 IPW_CMD(EXT_SUPPORTED_RATES);
2159 IPW_CMD(VAP_LOCAL_TX_PWR_CONSTRAINT);
2160 IPW_CMD(VAP_QUIET_INTERVALS);
2161 IPW_CMD(VAP_CHANNEL_SWITCH);
2162 IPW_CMD(VAP_MANDATORY_CHANNELS);
2163 IPW_CMD(VAP_CELL_PWR_LIMIT);
2164 IPW_CMD(VAP_CF_PARAM_SET);
2165 IPW_CMD(VAP_SET_BEACONING_STATE);
2166 IPW_CMD(MEASUREMENT);
2167 IPW_CMD(POWER_CAPABILITY);
2168 IPW_CMD(SUPPORTED_CHANNELS);
2169 IPW_CMD(TPC_REPORT);
2170 IPW_CMD(WME_INFO);
2171 IPW_CMD(PRODUCTION_COMMAND);
2172 default:
2173 return "UNKNOWN";
2174 }
2175}
2176
2177#define HOST_COMPLETE_TIMEOUT HZ
2178
2179static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
2180{
2181 int rc = 0;
2182 unsigned long flags;
2183
2184 spin_lock_irqsave(&priv->lock, flags);
2185 if (priv->status & STATUS_HCMD_ACTIVE) {
2186 IPW_ERROR("Failed to send %s: Already sending a command.\n",
2187 get_cmd_string(cmd->cmd));
2188 spin_unlock_irqrestore(&priv->lock, flags);
2189 return -EAGAIN;
2190 }
2191
2192 priv->status |= STATUS_HCMD_ACTIVE;
2193
2194 if (priv->cmdlog) {
2195 priv->cmdlog[priv->cmdlog_pos].jiffies = jiffies;
2196 priv->cmdlog[priv->cmdlog_pos].cmd.cmd = cmd->cmd;
2197 priv->cmdlog[priv->cmdlog_pos].cmd.len = cmd->len;
2198 memcpy(priv->cmdlog[priv->cmdlog_pos].cmd.param, cmd->param,
2199 cmd->len);
2200 priv->cmdlog[priv->cmdlog_pos].retcode = -1;
2201 }
2202
2203 IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",
2204 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,
2205 priv->status);
2206
2207#ifndef DEBUG_CMD_WEP_KEY
2208 if (cmd->cmd == IPW_CMD_WEP_KEY)
2209 IPW_DEBUG_HC("WEP_KEY command masked out for secure.\n");
2210 else
2211#endif
2212 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
2213
2214 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, cmd->param, cmd->len, 0);
2215 if (rc) {
2216 priv->status &= ~STATUS_HCMD_ACTIVE;
2217 IPW_ERROR("Failed to send %s: Reason %d\n",
2218 get_cmd_string(cmd->cmd), rc);
2219 spin_unlock_irqrestore(&priv->lock, flags);
2220 goto exit;
2221 }
2222 spin_unlock_irqrestore(&priv->lock, flags);
2223
2224 rc = wait_event_interruptible_timeout(priv->wait_command_queue,
2225 !(priv->
2226 status & STATUS_HCMD_ACTIVE),
2227 HOST_COMPLETE_TIMEOUT);
2228 if (rc == 0) {
2229 spin_lock_irqsave(&priv->lock, flags);
2230 if (priv->status & STATUS_HCMD_ACTIVE) {
2231 IPW_ERROR("Failed to send %s: Command timed out.\n",
2232 get_cmd_string(cmd->cmd));
2233 priv->status &= ~STATUS_HCMD_ACTIVE;
2234 spin_unlock_irqrestore(&priv->lock, flags);
2235 rc = -EIO;
2236 goto exit;
2237 }
2238 spin_unlock_irqrestore(&priv->lock, flags);
2239 } else
2240 rc = 0;
2241
2242 if (priv->status & STATUS_RF_KILL_HW) {
2243 IPW_ERROR("Failed to send %s: Aborted due to RF kill switch.\n",
2244 get_cmd_string(cmd->cmd));
2245 rc = -EIO;
2246 goto exit;
2247 }
2248
2249 exit:
2250 if (priv->cmdlog) {
2251 priv->cmdlog[priv->cmdlog_pos++].retcode = rc;
2252 priv->cmdlog_pos %= priv->cmdlog_len;
2253 }
2254 return rc;
2255}
2256
2257static int ipw_send_cmd_simple(struct ipw_priv *priv, u8 command)
2258{
2259 struct host_cmd cmd = {
2260 .cmd = command,
2261 };
2262
2263 return __ipw_send_cmd(priv, &cmd);
2264}
2265
2266static int ipw_send_cmd_pdu(struct ipw_priv *priv, u8 command, u8 len,
2267 void *data)
2268{
2269 struct host_cmd cmd = {
2270 .cmd = command,
2271 .len = len,
2272 .param = data,
2273 };
2274
2275 return __ipw_send_cmd(priv, &cmd);
2276}
2277
2278static int ipw_send_host_complete(struct ipw_priv *priv)
2279{
2280 if (!priv) {
2281 IPW_ERROR("Invalid args\n");
2282 return -1;
2283 }
2284
2285 return ipw_send_cmd_simple(priv, IPW_CMD_HOST_COMPLETE);
2286}
2287
2288static int ipw_send_system_config(struct ipw_priv *priv)
2289{
2290 return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG,
2291 sizeof(priv->sys_config),
2292 &priv->sys_config);
2293}
2294
2295static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
2296{
2297 if (!priv || !ssid) {
2298 IPW_ERROR("Invalid args\n");
2299 return -1;
2300 }
2301
2302 return ipw_send_cmd_pdu(priv, IPW_CMD_SSID, min(len, IW_ESSID_MAX_SIZE),
2303 ssid);
2304}
2305
2306static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
2307{
2308 if (!priv || !mac) {
2309 IPW_ERROR("Invalid args\n");
2310 return -1;
2311 }
2312
2313 IPW_DEBUG_INFO("%s: Setting MAC to %pM\n",
2314 priv->net_dev->name, mac);
2315
2316 return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac);
2317}
2318
2319
2320
2321
2322
2323
2324static void ipw_adapter_restart(void *adapter)
2325{
2326 struct ipw_priv *priv = adapter;
2327
2328 if (priv->status & STATUS_RF_KILL_MASK)
2329 return;
2330
2331 ipw_down(priv);
2332
2333 if (priv->assoc_network &&
2334 (priv->assoc_network->capability & WLAN_CAPABILITY_IBSS))
2335 ipw_remove_current_network(priv);
2336
2337 if (ipw_up(priv)) {
2338 IPW_ERROR("Failed to up device\n");
2339 return;
2340 }
2341}
2342
2343static void ipw_bg_adapter_restart(struct work_struct *work)
2344{
2345 struct ipw_priv *priv =
2346 container_of(work, struct ipw_priv, adapter_restart);
2347 mutex_lock(&priv->mutex);
2348 ipw_adapter_restart(priv);
2349 mutex_unlock(&priv->mutex);
2350}
2351
2352static void ipw_abort_scan(struct ipw_priv *priv);
2353
2354#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
2355
2356static void ipw_scan_check(void *data)
2357{
2358 struct ipw_priv *priv = data;
2359
2360 if (priv->status & STATUS_SCAN_ABORTING) {
2361 IPW_DEBUG_SCAN("Scan completion watchdog resetting "
2362 "adapter after (%dms).\n",
2363 jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
2364 queue_work(priv->workqueue, &priv->adapter_restart);
2365 } else if (priv->status & STATUS_SCANNING) {
2366 IPW_DEBUG_SCAN("Scan completion watchdog aborting scan "
2367 "after (%dms).\n",
2368 jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));
2369 ipw_abort_scan(priv);
2370 queue_delayed_work(priv->workqueue, &priv->scan_check, HZ);
2371 }
2372}
2373
2374static void ipw_bg_scan_check(struct work_struct *work)
2375{
2376 struct ipw_priv *priv =
2377 container_of(work, struct ipw_priv, scan_check.work);
2378 mutex_lock(&priv->mutex);
2379 ipw_scan_check(priv);
2380 mutex_unlock(&priv->mutex);
2381}
2382
2383static int ipw_send_scan_request_ext(struct ipw_priv *priv,
2384 struct ipw_scan_request_ext *request)
2385{
2386 return ipw_send_cmd_pdu(priv, IPW_CMD_SCAN_REQUEST_EXT,
2387 sizeof(*request), request);
2388}
2389
2390static int ipw_send_scan_abort(struct ipw_priv *priv)
2391{
2392 if (!priv) {
2393 IPW_ERROR("Invalid args\n");
2394 return -1;
2395 }
2396
2397 return ipw_send_cmd_simple(priv, IPW_CMD_SCAN_ABORT);
2398}
2399
2400static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
2401{
2402 struct ipw_sensitivity_calib calib = {
2403 .beacon_rssi_raw = cpu_to_le16(sens),
2404 };
2405
2406 return ipw_send_cmd_pdu(priv, IPW_CMD_SENSITIVITY_CALIB, sizeof(calib),
2407 &calib);
2408}
2409
2410static int ipw_send_associate(struct ipw_priv *priv,
2411 struct ipw_associate *associate)
2412{
2413 if (!priv || !associate) {
2414 IPW_ERROR("Invalid args\n");
2415 return -1;
2416 }
2417
2418 return ipw_send_cmd_pdu(priv, IPW_CMD_ASSOCIATE, sizeof(*associate),
2419 associate);
2420}
2421
2422static int ipw_send_supported_rates(struct ipw_priv *priv,
2423 struct ipw_supported_rates *rates)
2424{
2425 if (!priv || !rates) {
2426 IPW_ERROR("Invalid args\n");
2427 return -1;
2428 }
2429
2430 return ipw_send_cmd_pdu(priv, IPW_CMD_SUPPORTED_RATES, sizeof(*rates),
2431 rates);
2432}
2433
2434static int ipw_set_random_seed(struct ipw_priv *priv)
2435{
2436 u32 val;
2437
2438 if (!priv) {
2439 IPW_ERROR("Invalid args\n");
2440 return -1;
2441 }
2442
2443 get_random_bytes(&val, sizeof(val));
2444
2445 return ipw_send_cmd_pdu(priv, IPW_CMD_SEED_NUMBER, sizeof(val), &val);
2446}
2447
2448static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
2449{
2450 __le32 v = cpu_to_le32(phy_off);
2451 if (!priv) {
2452 IPW_ERROR("Invalid args\n");
2453 return -1;
2454 }
2455
2456 return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(v), &v);
2457}
2458
2459static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
2460{
2461 if (!priv || !power) {
2462 IPW_ERROR("Invalid args\n");
2463 return -1;
2464 }
2465
2466 return ipw_send_cmd_pdu(priv, IPW_CMD_TX_POWER, sizeof(*power), power);
2467}
2468
2469static int ipw_set_tx_power(struct ipw_priv *priv)
2470{
2471 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
2472 struct ipw_tx_power tx_power;
2473 s8 max_power;
2474 int i;
2475
2476 memset(&tx_power, 0, sizeof(tx_power));
2477
2478
2479 tx_power.ieee_mode = IPW_G_MODE;
2480 tx_power.num_channels = geo->bg_channels;
2481 for (i = 0; i < geo->bg_channels; i++) {
2482 max_power = geo->bg[i].max_power;
2483 tx_power.channels_tx_power[i].channel_number =
2484 geo->bg[i].channel;
2485 tx_power.channels_tx_power[i].tx_power = max_power ?
2486 min(max_power, priv->tx_power) : priv->tx_power;
2487 }
2488 if (ipw_send_tx_power(priv, &tx_power))
2489 return -EIO;
2490
2491
2492 tx_power.ieee_mode = IPW_B_MODE;
2493 if (ipw_send_tx_power(priv, &tx_power))
2494 return -EIO;
2495
2496
2497 if (priv->ieee->abg_true) {
2498 tx_power.ieee_mode = IPW_A_MODE;
2499 tx_power.num_channels = geo->a_channels;
2500 for (i = 0; i < tx_power.num_channels; i++) {
2501 max_power = geo->a[i].max_power;
2502 tx_power.channels_tx_power[i].channel_number =
2503 geo->a[i].channel;
2504 tx_power.channels_tx_power[i].tx_power = max_power ?
2505 min(max_power, priv->tx_power) : priv->tx_power;
2506 }
2507 if (ipw_send_tx_power(priv, &tx_power))
2508 return -EIO;
2509 }
2510 return 0;
2511}
2512
2513static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
2514{
2515 struct ipw_rts_threshold rts_threshold = {
2516 .rts_threshold = cpu_to_le16(rts),
2517 };
2518
2519 if (!priv) {
2520 IPW_ERROR("Invalid args\n");
2521 return -1;
2522 }
2523
2524 return ipw_send_cmd_pdu(priv, IPW_CMD_RTS_THRESHOLD,
2525 sizeof(rts_threshold), &rts_threshold);
2526}
2527
2528static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
2529{
2530 struct ipw_frag_threshold frag_threshold = {
2531 .frag_threshold = cpu_to_le16(frag),
2532 };
2533
2534 if (!priv) {
2535 IPW_ERROR("Invalid args\n");
2536 return -1;
2537 }
2538
2539 return ipw_send_cmd_pdu(priv, IPW_CMD_FRAG_THRESHOLD,
2540 sizeof(frag_threshold), &frag_threshold);
2541}
2542
2543static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
2544{
2545 __le32 param;
2546
2547 if (!priv) {
2548 IPW_ERROR("Invalid args\n");
2549 return -1;
2550 }
2551
2552
2553
2554 switch (mode) {
2555 case IPW_POWER_BATTERY:
2556 param = cpu_to_le32(IPW_POWER_INDEX_3);
2557 break;
2558 case IPW_POWER_AC:
2559 param = cpu_to_le32(IPW_POWER_MODE_CAM);
2560 break;
2561 default:
2562 param = cpu_to_le32(mode);
2563 break;
2564 }
2565
2566 return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param),
2567 ¶m);
2568}
2569
2570static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
2571{
2572 struct ipw_retry_limit retry_limit = {
2573 .short_retry_limit = slimit,
2574 .long_retry_limit = llimit
2575 };
2576
2577 if (!priv) {
2578 IPW_ERROR("Invalid args\n");
2579 return -1;
2580 }
2581
2582 return ipw_send_cmd_pdu(priv, IPW_CMD_RETRY_LIMIT, sizeof(retry_limit),
2583 &retry_limit);
2584}
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604static inline void eeprom_write_reg(struct ipw_priv *p, u32 data)
2605{
2606 ipw_write_reg32(p, FW_MEM_REG_EEPROM_ACCESS, data);
2607
2608
2609 udelay(p->eeprom_delay);
2610}
2611
2612
2613static void eeprom_cs(struct ipw_priv *priv)
2614{
2615 eeprom_write_reg(priv, 0);
2616 eeprom_write_reg(priv, EEPROM_BIT_CS);
2617 eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK);
2618 eeprom_write_reg(priv, EEPROM_BIT_CS);
2619}
2620
2621
2622static void eeprom_disable_cs(struct ipw_priv *priv)
2623{
2624 eeprom_write_reg(priv, EEPROM_BIT_CS);
2625 eeprom_write_reg(priv, 0);
2626 eeprom_write_reg(priv, EEPROM_BIT_SK);
2627}
2628
2629
2630static inline void eeprom_write_bit(struct ipw_priv *p, u8 bit)
2631{
2632 int d = (bit ? EEPROM_BIT_DI : 0);
2633 eeprom_write_reg(p, EEPROM_BIT_CS | d);
2634 eeprom_write_reg(p, EEPROM_BIT_CS | d | EEPROM_BIT_SK);
2635}
2636
2637
2638static void eeprom_op(struct ipw_priv *priv, u8 op, u8 addr)
2639{
2640 int i;
2641
2642 eeprom_cs(priv);
2643 eeprom_write_bit(priv, 1);
2644 eeprom_write_bit(priv, op & 2);
2645 eeprom_write_bit(priv, op & 1);
2646 for (i = 7; i >= 0; i--) {
2647 eeprom_write_bit(priv, addr & (1 << i));
2648 }
2649}
2650
2651
2652static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr)
2653{
2654 int i;
2655 u16 r = 0;
2656
2657
2658 eeprom_op(priv, EEPROM_CMD_READ, addr);
2659
2660
2661 eeprom_write_reg(priv, EEPROM_BIT_CS);
2662
2663
2664 for (i = 0; i < 16; i++) {
2665 u32 data = 0;
2666 eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK);
2667 eeprom_write_reg(priv, EEPROM_BIT_CS);
2668 data = ipw_read_reg32(priv, FW_MEM_REG_EEPROM_ACCESS);
2669 r = (r << 1) | ((data & EEPROM_BIT_DO) ? 1 : 0);
2670 }
2671
2672
2673 eeprom_write_reg(priv, 0);
2674 eeprom_disable_cs(priv);
2675
2676 return r;
2677}
2678
2679
2680
2681static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac)
2682{
2683 memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6);
2684}
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694static void ipw_eeprom_init_sram(struct ipw_priv *priv)
2695{
2696 int i;
2697 __le16 *eeprom = (__le16 *) priv->eeprom;
2698
2699 IPW_DEBUG_TRACE(">>\n");
2700
2701
2702 for (i = 0; i < 128; i++)
2703 eeprom[i] = cpu_to_le16(eeprom_read_u16(priv, (u8) i));
2704
2705
2706
2707
2708
2709
2710 if (priv->eeprom[EEPROM_VERSION] != 0) {
2711 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
2712
2713
2714 for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
2715 ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]);
2716
2717
2718 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
2719 } else {
2720 IPW_DEBUG_INFO("Enabling FW initializationg of SRAM\n");
2721
2722
2723 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 1);
2724 }
2725
2726 IPW_DEBUG_TRACE("<<\n");
2727}
2728
2729static void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count)
2730{
2731 count >>= 2;
2732 if (!count)
2733 return;
2734 _ipw_write32(priv, IPW_AUTOINC_ADDR, start);
2735 while (count--)
2736 _ipw_write32(priv, IPW_AUTOINC_DATA, 0);
2737}
2738
2739static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)
2740{
2741 ipw_zero_memory(priv, IPW_SHARED_SRAM_DMA_CONTROL,
2742 CB_NUMBER_OF_ELEMENTS_SMALL *
2743 sizeof(struct command_block));
2744}
2745
2746static int ipw_fw_dma_enable(struct ipw_priv *priv)
2747{
2748
2749 IPW_DEBUG_FW(">> :\n");
2750
2751
2752 ipw_fw_dma_reset_command_blocks(priv);
2753
2754
2755 ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL);
2756
2757 IPW_DEBUG_FW("<< :\n");
2758 return 0;
2759}
2760
2761static void ipw_fw_dma_abort(struct ipw_priv *priv)
2762{
2763 u32 control = 0;
2764
2765 IPW_DEBUG_FW(">> :\n");
2766
2767
2768 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT;
2769 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
2770 priv->sram_desc.last_cb_index = 0;
2771
2772 IPW_DEBUG_FW("<<\n");
2773}
2774
2775static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index,
2776 struct command_block *cb)
2777{
2778 u32 address =
2779 IPW_SHARED_SRAM_DMA_CONTROL +
2780 (sizeof(struct command_block) * index);
2781 IPW_DEBUG_FW(">> :\n");
2782
2783 ipw_write_indirect(priv, address, (u8 *) cb,
2784 (int)sizeof(struct command_block));
2785
2786 IPW_DEBUG_FW("<< :\n");
2787 return 0;
2788
2789}
2790
2791static int ipw_fw_dma_kick(struct ipw_priv *priv)
2792{
2793 u32 control = 0;
2794 u32 index = 0;
2795
2796 IPW_DEBUG_FW(">> :\n");
2797
2798 for (index = 0; index < priv->sram_desc.last_cb_index; index++)
2799 ipw_fw_dma_write_command_block(priv, index,
2800 &priv->sram_desc.cb_list[index]);
2801
2802
2803 ipw_clear_bit(priv, IPW_RESET_REG,
2804 IPW_RESET_REG_MASTER_DISABLED |
2805 IPW_RESET_REG_STOP_MASTER);
2806
2807
2808 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START;
2809 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
2810
2811 IPW_DEBUG_FW("<< :\n");
2812 return 0;
2813}
2814
2815static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)
2816{
2817 u32 address;
2818 u32 register_value = 0;
2819 u32 cb_fields_address = 0;
2820
2821 IPW_DEBUG_FW(">> :\n");
2822 address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
2823 IPW_DEBUG_FW_INFO("Current CB is 0x%x\n", address);
2824
2825
2826 register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL);
2827 IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x\n", register_value);
2828
2829
2830 cb_fields_address = address;
2831 register_value = ipw_read_reg32(priv, cb_fields_address);
2832 IPW_DEBUG_FW_INFO("Current CB Control Field is 0x%x\n", register_value);
2833
2834 cb_fields_address += sizeof(u32);
2835 register_value = ipw_read_reg32(priv, cb_fields_address);
2836 IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x\n", register_value);
2837
2838 cb_fields_address += sizeof(u32);
2839 register_value = ipw_read_reg32(priv, cb_fields_address);
2840 IPW_DEBUG_FW_INFO("Current CB Destination Field is 0x%x\n",
2841 register_value);
2842
2843 cb_fields_address += sizeof(u32);
2844 register_value = ipw_read_reg32(priv, cb_fields_address);
2845 IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x\n", register_value);
2846
2847 IPW_DEBUG_FW(">> :\n");
2848}
2849
2850static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)
2851{
2852 u32 current_cb_address = 0;
2853 u32 current_cb_index = 0;
2854
2855 IPW_DEBUG_FW("<< :\n");
2856 current_cb_address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
2857
2858 current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) /
2859 sizeof(struct command_block);
2860
2861 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X\n",
2862 current_cb_index, current_cb_address);
2863
2864 IPW_DEBUG_FW(">> :\n");
2865 return current_cb_index;
2866
2867}
2868
2869static int ipw_fw_dma_add_command_block(struct ipw_priv *priv,
2870 u32 src_address,
2871 u32 dest_address,
2872 u32 length,
2873 int interrupt_enabled, int is_last)
2874{
2875
2876 u32 control = CB_VALID | CB_SRC_LE | CB_DEST_LE | CB_SRC_AUTOINC |
2877 CB_SRC_IO_GATED | CB_DEST_AUTOINC | CB_SRC_SIZE_LONG |
2878 CB_DEST_SIZE_LONG;
2879 struct command_block *cb;
2880 u32 last_cb_element = 0;
2881
2882 IPW_DEBUG_FW_INFO("src_address=0x%x dest_address=0x%x length=0x%x\n",
2883 src_address, dest_address, length);
2884
2885 if (priv->sram_desc.last_cb_index >= CB_NUMBER_OF_ELEMENTS_SMALL)
2886 return -1;
2887
2888 last_cb_element = priv->sram_desc.last_cb_index;
2889 cb = &priv->sram_desc.cb_list[last_cb_element];
2890 priv->sram_desc.last_cb_index++;
2891
2892
2893 if (interrupt_enabled)
2894 control |= CB_INT_ENABLED;
2895
2896 if (is_last)
2897 control |= CB_LAST_VALID;
2898
2899 control |= length;
2900
2901
2902 cb->status = control ^ src_address ^ dest_address;
2903
2904
2905 cb->dest_addr = dest_address;
2906 cb->source_addr = src_address;
2907
2908
2909 cb->control = control;
2910
2911 return 0;
2912}
2913
2914static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, dma_addr_t *src_address,
2915 int nr, u32 dest_address, u32 len)
2916{
2917 int ret, i;
2918 u32 size;
2919
2920 IPW_DEBUG_FW(">>\n");
2921 IPW_DEBUG_FW_INFO("nr=%d dest_address=0x%x len=0x%x\n",
2922 nr, dest_address, len);
2923
2924 for (i = 0; i < nr; i++) {
2925 size = min_t(u32, len - i * CB_MAX_LENGTH, CB_MAX_LENGTH);
2926 ret = ipw_fw_dma_add_command_block(priv, src_address[i],
2927 dest_address +
2928 i * CB_MAX_LENGTH, size,
2929 0, 0);
2930 if (ret) {
2931 IPW_DEBUG_FW_INFO(": Failed\n");
2932 return -1;
2933 } else
2934 IPW_DEBUG_FW_INFO(": Added new cb\n");
2935 }
2936
2937 IPW_DEBUG_FW("<<\n");
2938 return 0;
2939}
2940
2941static int ipw_fw_dma_wait(struct ipw_priv *priv)
2942{
2943 u32 current_index = 0, previous_index;
2944 u32 watchdog = 0;
2945
2946 IPW_DEBUG_FW(">> :\n");
2947
2948 current_index = ipw_fw_dma_command_block_index(priv);
2949 IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%08X\n",
2950 (int)priv->sram_desc.last_cb_index);
2951
2952 while (current_index < priv->sram_desc.last_cb_index) {
2953 udelay(50);
2954 previous_index = current_index;
2955 current_index = ipw_fw_dma_command_block_index(priv);
2956
2957 if (previous_index < current_index) {
2958 watchdog = 0;
2959 continue;
2960 }
2961 if (++watchdog > 400) {
2962 IPW_DEBUG_FW_INFO("Timeout\n");
2963 ipw_fw_dma_dump_command_block(priv);
2964 ipw_fw_dma_abort(priv);
2965 return -1;
2966 }
2967 }
2968
2969 ipw_fw_dma_abort(priv);
2970
2971
2972 ipw_set_bit(priv, IPW_RESET_REG,
2973 IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER);
2974
2975 IPW_DEBUG_FW("<< dmaWaitSync\n");
2976 return 0;
2977}
2978
2979static void ipw_remove_current_network(struct ipw_priv *priv)
2980{
2981 struct list_head *element, *safe;
2982 struct libipw_network *network = NULL;
2983 unsigned long flags;
2984
2985 spin_lock_irqsave(&priv->ieee->lock, flags);
2986 list_for_each_safe(element, safe, &priv->ieee->network_list) {
2987 network = list_entry(element, struct libipw_network, list);
2988 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
2989 list_del(element);
2990 list_add_tail(&network->list,
2991 &priv->ieee->network_free_list);
2992 }
2993 }
2994 spin_unlock_irqrestore(&priv->ieee->lock, flags);
2995}
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006static inline int ipw_alive(struct ipw_priv *priv)
3007{
3008 return ipw_read32(priv, 0x90) == 0xd55555d5;
3009}
3010
3011
3012static int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask,
3013 int timeout)
3014{
3015 int i = 0;
3016
3017 do {
3018 if ((ipw_read32(priv, addr) & mask) == mask)
3019 return i;
3020 mdelay(10);
3021 i += 10;
3022 } while (i < timeout);
3023
3024 return -ETIME;
3025}
3026
3027
3028
3029
3030
3031
3032static int ipw_stop_master(struct ipw_priv *priv)
3033{
3034 int rc;
3035
3036 IPW_DEBUG_TRACE(">>\n");
3037
3038 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
3039
3040
3041 rc = ipw_poll_bit(priv, IPW_RESET_REG,
3042 IPW_RESET_REG_MASTER_DISABLED, 100);
3043 if (rc < 0) {
3044 IPW_ERROR("wait for stop master failed after 100ms\n");
3045 return -1;
3046 }
3047
3048 IPW_DEBUG_INFO("stop master %dms\n", rc);
3049
3050 return rc;
3051}
3052
3053static void ipw_arc_release(struct ipw_priv *priv)
3054{
3055 IPW_DEBUG_TRACE(">>\n");
3056 mdelay(5);
3057
3058 ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
3059
3060
3061 mdelay(5);
3062}
3063
3064struct fw_chunk {
3065 __le32 address;
3066 __le32 length;
3067};
3068
3069static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
3070{
3071 int rc = 0, i, addr;
3072 u8 cr = 0;
3073 __le16 *image;
3074
3075 image = (__le16 *) data;
3076
3077 IPW_DEBUG_TRACE(">>\n");
3078
3079 rc = ipw_stop_master(priv);
3080
3081 if (rc < 0)
3082 return rc;
3083
3084 for (addr = IPW_SHARED_LOWER_BOUND;
3085 addr < IPW_REGISTER_DOMAIN1_END; addr += 4) {
3086 ipw_write32(priv, addr, 0);
3087 }
3088
3089
3090 memset(&priv->dino_alive, 0, sizeof(priv->dino_alive));
3091
3092
3093
3094 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_ON);
3095 ipw_arc_release(priv);
3096 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_OFF);
3097 mdelay(1);
3098
3099
3100 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, IPW_BASEBAND_POWER_DOWN);
3101 mdelay(1);
3102
3103 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, 0);
3104 mdelay(1);
3105
3106
3107 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0x0);
3108 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_CS);
3109 mdelay(1);
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120 for (i = 0; i < len / 2; i++)
3121 ipw_write_reg16(priv, IPW_BASEBAND_CONTROL_STORE,
3122 le16_to_cpu(image[i]));
3123
3124
3125 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
3126 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM);
3127
3128
3129
3130
3131 for (i = 0; i < 100; i++) {
3132
3133 cr = ipw_read_reg8(priv, IPW_BASEBAND_CONTROL_STATUS);
3134 if (cr & DINO_RXFIFO_DATA)
3135 break;
3136 mdelay(1);
3137 }
3138
3139 if (cr & DINO_RXFIFO_DATA) {
3140
3141 __le32 response_buffer[(sizeof(priv->dino_alive) + 3) / 4];
3142
3143 for (i = 0; i < ARRAY_SIZE(response_buffer); i++)
3144 response_buffer[i] =
3145 cpu_to_le32(ipw_read_reg32(priv,
3146 IPW_BASEBAND_RX_FIFO_READ));
3147 memcpy(&priv->dino_alive, response_buffer,
3148 sizeof(priv->dino_alive));
3149 if (priv->dino_alive.alive_command == 1
3150 && priv->dino_alive.ucode_valid == 1) {
3151 rc = 0;
3152 IPW_DEBUG_INFO
3153 ("Microcode OK, rev. %d (0x%x) dev. %d (0x%x) "
3154 "of %02d/%02d/%02d %02d:%02d\n",
3155 priv->dino_alive.software_revision,
3156 priv->dino_alive.software_revision,
3157 priv->dino_alive.device_identifier,
3158 priv->dino_alive.device_identifier,
3159 priv->dino_alive.time_stamp[0],
3160 priv->dino_alive.time_stamp[1],
3161 priv->dino_alive.time_stamp[2],
3162 priv->dino_alive.time_stamp[3],
3163 priv->dino_alive.time_stamp[4]);
3164 } else {
3165 IPW_DEBUG_INFO("Microcode is not alive\n");
3166 rc = -EINVAL;
3167 }
3168 } else {
3169 IPW_DEBUG_INFO("No alive response from DINO\n");
3170 rc = -ETIME;
3171 }
3172
3173
3174
3175 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
3176
3177 return rc;
3178}
3179
3180static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
3181{
3182 int ret = -1;
3183 int offset = 0;
3184 struct fw_chunk *chunk;
3185 int total_nr = 0;
3186 int i;
3187 struct pci_pool *pool;
3188 void **virts;
3189 dma_addr_t *phys;
3190
3191 IPW_DEBUG_TRACE("<< :\n");
3192
3193 virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL,
3194 GFP_KERNEL);
3195 if (!virts)
3196 return -ENOMEM;
3197
3198 phys = kmalloc(sizeof(dma_addr_t) * CB_NUMBER_OF_ELEMENTS_SMALL,
3199 GFP_KERNEL);
3200 if (!phys) {
3201 kfree(virts);
3202 return -ENOMEM;
3203 }
3204 pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0);
3205 if (!pool) {
3206 IPW_ERROR("pci_pool_create failed\n");
3207 kfree(phys);
3208 kfree(virts);
3209 return -ENOMEM;
3210 }
3211
3212
3213 ret = ipw_fw_dma_enable(priv);
3214
3215
3216 BUG_ON(priv->sram_desc.last_cb_index > 0);
3217
3218 do {
3219 u32 chunk_len;
3220 u8 *start;
3221 int size;
3222 int nr = 0;
3223
3224 chunk = (struct fw_chunk *)(data + offset);
3225 offset += sizeof(struct fw_chunk);
3226 chunk_len = le32_to_cpu(chunk->length);
3227 start = data + offset;
3228
3229 nr = (chunk_len + CB_MAX_LENGTH - 1) / CB_MAX_LENGTH;
3230 for (i = 0; i < nr; i++) {
3231 virts[total_nr] = pci_pool_alloc(pool, GFP_KERNEL,
3232 &phys[total_nr]);
3233 if (!virts[total_nr]) {
3234 ret = -ENOMEM;
3235 goto out;
3236 }
3237 size = min_t(u32, chunk_len - i * CB_MAX_LENGTH,
3238 CB_MAX_LENGTH);
3239 memcpy(virts[total_nr], start, size);
3240 start += size;
3241 total_nr++;
3242
3243 BUG_ON(total_nr > CB_NUMBER_OF_ELEMENTS_SMALL);
3244 }
3245
3246
3247
3248
3249
3250 ret = ipw_fw_dma_add_buffer(priv, &phys[total_nr - nr],
3251 nr, le32_to_cpu(chunk->address),
3252 chunk_len);
3253 if (ret) {
3254 IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
3255 goto out;
3256 }
3257
3258 offset += chunk_len;
3259 } while (offset < len);
3260
3261
3262 ret = ipw_fw_dma_kick(priv);
3263 if (ret) {
3264 IPW_ERROR("dmaKick Failed\n");
3265 goto out;
3266 }
3267
3268 ret = ipw_fw_dma_wait(priv);
3269 if (ret) {
3270 IPW_ERROR("dmaWaitSync Failed\n");
3271 goto out;
3272 }
3273 out:
3274 for (i = 0; i < total_nr; i++)
3275 pci_pool_free(pool, virts[i], phys[i]);
3276
3277 pci_pool_destroy(pool);
3278 kfree(phys);
3279 kfree(virts);
3280
3281 return ret;
3282}
3283
3284
3285static int ipw_stop_nic(struct ipw_priv *priv)
3286{
3287 int rc = 0;
3288
3289
3290 ipw_write32(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
3291
3292 rc = ipw_poll_bit(priv, IPW_RESET_REG,
3293 IPW_RESET_REG_MASTER_DISABLED, 500);
3294 if (rc < 0) {
3295 IPW_ERROR("wait for reg master disabled failed after 500ms\n");
3296 return rc;
3297 }
3298
3299 ipw_set_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
3300
3301 return rc;
3302}
3303
3304static void ipw_start_nic(struct ipw_priv *priv)
3305{
3306 IPW_DEBUG_TRACE(">>\n");
3307
3308
3309 ipw_clear_bit(priv, IPW_RESET_REG,
3310 IPW_RESET_REG_MASTER_DISABLED |
3311 IPW_RESET_REG_STOP_MASTER |
3312 CBD_RESET_REG_PRINCETON_RESET);
3313
3314
3315 ipw_set_bit(priv, IPW_GP_CNTRL_RW,
3316 IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
3317
3318 IPW_DEBUG_TRACE("<<\n");
3319}
3320
3321static int ipw_init_nic(struct ipw_priv *priv)
3322{
3323 int rc;
3324
3325 IPW_DEBUG_TRACE(">>\n");
3326
3327
3328
3329 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
3330
3331
3332 ipw_write32(priv, IPW_READ_INT_REGISTER,
3333 IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER);
3334
3335
3336 rc = ipw_poll_bit(priv, IPW_GP_CNTRL_RW,
3337 IPW_GP_CNTRL_BIT_CLOCK_READY, 250);
3338 if (rc < 0)
3339 IPW_DEBUG_INFO("FAILED wait for clock stablization\n");
3340
3341
3342 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_SW_RESET);
3343
3344 udelay(10);
3345
3346
3347 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
3348
3349 IPW_DEBUG_TRACE(">>\n");
3350 return 0;
3351}
3352
3353
3354
3355
3356static int ipw_reset_nic(struct ipw_priv *priv)
3357{
3358 int rc = 0;
3359 unsigned long flags;
3360
3361 IPW_DEBUG_TRACE(">>\n");
3362
3363 rc = ipw_init_nic(priv);
3364
3365 spin_lock_irqsave(&priv->lock, flags);
3366
3367 priv->status &= ~STATUS_HCMD_ACTIVE;
3368 wake_up_interruptible(&priv->wait_command_queue);
3369 priv->status &= ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
3370 wake_up_interruptible(&priv->wait_state);
3371 spin_unlock_irqrestore(&priv->lock, flags);
3372
3373 IPW_DEBUG_TRACE("<<\n");
3374 return rc;
3375}
3376
3377
3378struct ipw_fw {
3379 __le32 ver;
3380 __le32 boot_size;
3381 __le32 ucode_size;
3382 __le32 fw_size;
3383 u8 data[0];
3384};
3385
3386static int ipw_get_fw(struct ipw_priv *priv,
3387 const struct firmware **raw, const char *name)
3388{
3389 struct ipw_fw *fw;
3390 int rc;
3391
3392
3393 rc = request_firmware(raw, name, &priv->pci_dev->dev);
3394 if (rc < 0) {
3395 IPW_ERROR("%s request_firmware failed: Reason %d\n", name, rc);
3396 return rc;
3397 }
3398
3399 if ((*raw)->size < sizeof(*fw)) {
3400 IPW_ERROR("%s is too small (%zd)\n", name, (*raw)->size);
3401 return -EINVAL;
3402 }
3403
3404 fw = (void *)(*raw)->data;
3405
3406 if ((*raw)->size < sizeof(*fw) + le32_to_cpu(fw->boot_size) +
3407 le32_to_cpu(fw->ucode_size) + le32_to_cpu(fw->fw_size)) {
3408 IPW_ERROR("%s is too small or corrupt (%zd)\n",
3409 name, (*raw)->size);
3410 return -EINVAL;
3411 }
3412
3413 IPW_DEBUG_INFO("Read firmware '%s' image v%d.%d (%zd bytes)\n",
3414 name,
3415 le32_to_cpu(fw->ver) >> 16,
3416 le32_to_cpu(fw->ver) & 0xff,
3417 (*raw)->size - sizeof(*fw));
3418 return 0;
3419}
3420
3421#define IPW_RX_BUF_SIZE (3000)
3422
3423static void ipw_rx_queue_reset(struct ipw_priv *priv,
3424 struct ipw_rx_queue *rxq)
3425{
3426 unsigned long flags;
3427 int i;
3428
3429 spin_lock_irqsave(&rxq->lock, flags);
3430
3431 INIT_LIST_HEAD(&rxq->rx_free);
3432 INIT_LIST_HEAD(&rxq->rx_used);
3433
3434
3435 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
3436
3437
3438 if (rxq->pool[i].skb != NULL) {
3439 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
3440 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
3441 dev_kfree_skb(rxq->pool[i].skb);
3442 rxq->pool[i].skb = NULL;
3443 }
3444 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
3445 }
3446
3447
3448
3449 rxq->read = rxq->write = 0;
3450 rxq->free_count = 0;
3451 spin_unlock_irqrestore(&rxq->lock, flags);
3452}
3453
3454#ifdef CONFIG_PM
3455static int fw_loaded = 0;
3456static const struct firmware *raw = NULL;
3457
3458static void free_firmware(void)
3459{
3460 if (fw_loaded) {
3461 release_firmware(raw);
3462 raw = NULL;
3463 fw_loaded = 0;
3464 }
3465}
3466#else
3467#define free_firmware() do {} while (0)
3468#endif
3469
3470static int ipw_load(struct ipw_priv *priv)
3471{
3472#ifndef CONFIG_PM
3473 const struct firmware *raw = NULL;
3474#endif
3475 struct ipw_fw *fw;
3476 u8 *boot_img, *ucode_img, *fw_img;
3477 u8 *name = NULL;
3478 int rc = 0, retries = 3;
3479
3480 switch (priv->ieee->iw_mode) {
3481 case IW_MODE_ADHOC:
3482 name = "ipw2200-ibss.fw";
3483 break;
3484#ifdef CONFIG_IPW2200_MONITOR
3485 case IW_MODE_MONITOR:
3486 name = "ipw2200-sniffer.fw";
3487 break;
3488#endif
3489 case IW_MODE_INFRA:
3490 name = "ipw2200-bss.fw";
3491 break;
3492 }
3493
3494 if (!name) {
3495 rc = -EINVAL;
3496 goto error;
3497 }
3498
3499#ifdef CONFIG_PM
3500 if (!fw_loaded) {
3501#endif
3502 rc = ipw_get_fw(priv, &raw, name);
3503 if (rc < 0)
3504 goto error;
3505#ifdef CONFIG_PM
3506 }
3507#endif
3508
3509 fw = (void *)raw->data;
3510 boot_img = &fw->data[0];
3511 ucode_img = &fw->data[le32_to_cpu(fw->boot_size)];
3512 fw_img = &fw->data[le32_to_cpu(fw->boot_size) +
3513 le32_to_cpu(fw->ucode_size)];
3514
3515 if (rc < 0)
3516 goto error;
3517
3518 if (!priv->rxq)
3519 priv->rxq = ipw_rx_queue_alloc(priv);
3520 else
3521 ipw_rx_queue_reset(priv, priv->rxq);
3522 if (!priv->rxq) {
3523 IPW_ERROR("Unable to initialize Rx queue\n");
3524 goto error;
3525 }
3526
3527 retry:
3528
3529 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
3530 priv->status &= ~STATUS_INT_ENABLED;
3531
3532
3533 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
3534
3535 ipw_stop_nic(priv);
3536
3537 rc = ipw_reset_nic(priv);
3538 if (rc < 0) {
3539 IPW_ERROR("Unable to reset NIC\n");
3540 goto error;
3541 }
3542
3543 ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
3544 IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
3545
3546
3547 rc = ipw_load_firmware(priv, boot_img, le32_to_cpu(fw->boot_size));
3548 if (rc < 0) {
3549 IPW_ERROR("Unable to load boot firmware: %d\n", rc);
3550 goto error;
3551 }
3552
3553
3554 ipw_start_nic(priv);
3555
3556
3557 rc = ipw_poll_bit(priv, IPW_INTA_RW,
3558 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
3559 if (rc < 0) {
3560 IPW_ERROR("device failed to boot initial fw image\n");
3561 goto error;
3562 }
3563 IPW_DEBUG_INFO("initial device response after %dms\n", rc);
3564
3565
3566 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
3567
3568
3569 rc = ipw_load_ucode(priv, ucode_img, le32_to_cpu(fw->ucode_size));
3570 if (rc < 0) {
3571 IPW_ERROR("Unable to load ucode: %d\n", rc);
3572 goto error;
3573 }
3574
3575
3576 ipw_stop_nic(priv);
3577
3578
3579 rc = ipw_load_firmware(priv, fw_img, le32_to_cpu(fw->fw_size));
3580 if (rc < 0) {
3581 IPW_ERROR("Unable to load firmware: %d\n", rc);
3582 goto error;
3583 }
3584#ifdef CONFIG_PM
3585 fw_loaded = 1;
3586#endif
3587
3588 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);
3589
3590 rc = ipw_queue_reset(priv);
3591 if (rc < 0) {
3592 IPW_ERROR("Unable to initialize queues\n");
3593 goto error;
3594 }
3595
3596
3597 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
3598
3599 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
3600
3601
3602 ipw_start_nic(priv);
3603
3604 if (ipw_read32(priv, IPW_INTA_RW) & IPW_INTA_BIT_PARITY_ERROR) {
3605 if (retries > 0) {
3606 IPW_WARNING("Parity error. Retrying init.\n");
3607 retries--;
3608 goto retry;
3609 }
3610
3611 IPW_ERROR("TODO: Handle parity error -- schedule restart?\n");
3612 rc = -EIO;
3613 goto error;
3614 }
3615
3616
3617 rc = ipw_poll_bit(priv, IPW_INTA_RW,
3618 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
3619 if (rc < 0) {
3620 IPW_ERROR("device failed to start within 500ms\n");
3621 goto error;
3622 }
3623 IPW_DEBUG_INFO("device response after %dms\n", rc);
3624
3625
3626 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
3627
3628
3629 priv->eeprom_delay = 1;
3630 ipw_eeprom_init_sram(priv);
3631
3632
3633 ipw_enable_interrupts(priv);
3634
3635
3636 ipw_rx_queue_replenish(priv);
3637
3638 ipw_write32(priv, IPW_RX_READ_INDEX, priv->rxq->read);
3639
3640
3641 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
3642
3643#ifndef CONFIG_PM
3644 release_firmware(raw);
3645#endif
3646 return 0;
3647
3648 error:
3649 if (priv->rxq) {
3650 ipw_rx_queue_free(priv, priv->rxq);
3651 priv->rxq = NULL;
3652 }
3653 ipw_tx_queue_free(priv);
3654 if (raw)
3655 release_firmware(raw);
3656#ifdef CONFIG_PM
3657 fw_loaded = 0;
3658 raw = NULL;
3659#endif
3660
3661 return rc;
3662}
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694static int ipw_rx_queue_space(const struct ipw_rx_queue *q)
3695{
3696 int s = q->read - q->write;
3697 if (s <= 0)
3698 s += RX_QUEUE_SIZE;
3699
3700 s -= 2;
3701 if (s < 0)
3702 s = 0;
3703 return s;
3704}
3705
3706static inline int ipw_tx_queue_space(const struct clx2_queue *q)
3707{
3708 int s = q->last_used - q->first_empty;
3709 if (s <= 0)
3710 s += q->n_bd;
3711 s -= 2;
3712 if (s < 0)
3713 s = 0;
3714 return s;
3715}
3716
3717static inline int ipw_queue_inc_wrap(int index, int n_bd)
3718{
3719 return (++index == n_bd) ? 0 : index;
3720}
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736static void ipw_queue_init(struct ipw_priv *priv, struct clx2_queue *q,
3737 int count, u32 read, u32 write, u32 base, u32 size)
3738{
3739 q->n_bd = count;
3740
3741 q->low_mark = q->n_bd / 4;
3742 if (q->low_mark < 4)
3743 q->low_mark = 4;
3744
3745 q->high_mark = q->n_bd / 8;
3746 if (q->high_mark < 2)
3747 q->high_mark = 2;
3748
3749 q->first_empty = q->last_used = 0;
3750 q->reg_r = read;
3751 q->reg_w = write;
3752
3753 ipw_write32(priv, base, q->dma_addr);
3754 ipw_write32(priv, size, count);
3755 ipw_write32(priv, read, 0);
3756 ipw_write32(priv, write, 0);
3757
3758 _ipw_read32(priv, 0x90);
3759}
3760
3761static int ipw_queue_tx_init(struct ipw_priv *priv,
3762 struct clx2_tx_queue *q,
3763 int count, u32 read, u32 write, u32 base, u32 size)
3764{
3765 struct pci_dev *dev = priv->pci_dev;
3766
3767 q->txb = kmalloc(sizeof(q->txb[0]) * count, GFP_KERNEL);
3768 if (!q->txb) {
3769 IPW_ERROR("vmalloc for auxilary BD structures failed\n");
3770 return -ENOMEM;
3771 }
3772
3773 q->bd =
3774 pci_alloc_consistent(dev, sizeof(q->bd[0]) * count, &q->q.dma_addr);
3775 if (!q->bd) {
3776 IPW_ERROR("pci_alloc_consistent(%zd) failed\n",
3777 sizeof(q->bd[0]) * count);
3778 kfree(q->txb);
3779 q->txb = NULL;
3780 return -ENOMEM;
3781 }
3782
3783 ipw_queue_init(priv, &q->q, count, read, write, base, size);
3784 return 0;
3785}
3786
3787
3788
3789
3790
3791
3792
3793
3794static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,
3795 struct clx2_tx_queue *txq)
3796{
3797 struct tfd_frame *bd = &txq->bd[txq->q.last_used];
3798 struct pci_dev *dev = priv->pci_dev;
3799 int i;
3800
3801
3802 if (bd->control_flags.message_type == TX_HOST_COMMAND_TYPE)
3803
3804 return;
3805
3806
3807 if (le32_to_cpu(bd->u.data.num_chunks) > NUM_TFD_CHUNKS) {
3808 IPW_ERROR("Too many chunks: %i\n",
3809 le32_to_cpu(bd->u.data.num_chunks));
3810
3811 return;
3812 }
3813
3814
3815 for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) {
3816 pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]),
3817 le16_to_cpu(bd->u.data.chunk_len[i]),
3818 PCI_DMA_TODEVICE);
3819 if (txq->txb[txq->q.last_used]) {
3820 libipw_txb_free(txq->txb[txq->q.last_used]);
3821 txq->txb[txq->q.last_used] = NULL;
3822 }
3823 }
3824}
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835static void ipw_queue_tx_free(struct ipw_priv *priv, struct clx2_tx_queue *txq)
3836{
3837 struct clx2_queue *q = &txq->q;
3838 struct pci_dev *dev = priv->pci_dev;
3839
3840 if (q->n_bd == 0)
3841 return;
3842
3843
3844 for (; q->first_empty != q->last_used;
3845 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {
3846 ipw_queue_tx_free_tfd(priv, txq);
3847 }
3848
3849
3850 pci_free_consistent(dev, sizeof(txq->bd[0]) * q->n_bd, txq->bd,
3851 q->dma_addr);
3852 kfree(txq->txb);
3853
3854
3855 memset(txq, 0, sizeof(*txq));
3856}
3857
3858
3859
3860
3861
3862
3863static void ipw_tx_queue_free(struct ipw_priv *priv)
3864{
3865
3866 ipw_queue_tx_free(priv, &priv->txq_cmd);
3867
3868
3869 ipw_queue_tx_free(priv, &priv->txq[0]);
3870 ipw_queue_tx_free(priv, &priv->txq[1]);
3871 ipw_queue_tx_free(priv, &priv->txq[2]);
3872 ipw_queue_tx_free(priv, &priv->txq[3]);
3873}
3874
3875static void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)
3876{
3877
3878 bssid[0] = priv->mac_addr[0];
3879 bssid[1] = priv->mac_addr[1];
3880 bssid[2] = priv->mac_addr[2];
3881
3882
3883 get_random_bytes(&bssid[3], ETH_ALEN - 3);
3884
3885 bssid[0] &= 0xfe;
3886 bssid[0] |= 0x02;
3887}
3888
3889static u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid)
3890{
3891 struct ipw_station_entry entry;
3892 int i;
3893
3894 for (i = 0; i < priv->num_stations; i++) {
3895 if (!memcmp(priv->stations[i], bssid, ETH_ALEN)) {
3896
3897 priv->missed_adhoc_beacons = 0;
3898 if (!(priv->config & CFG_STATIC_CHANNEL))
3899
3900 priv->config &= ~CFG_ADHOC_PERSIST;
3901
3902 return i;
3903 }
3904 }
3905
3906 if (i == MAX_STATIONS)
3907 return IPW_INVALID_STATION;
3908
3909 IPW_DEBUG_SCAN("Adding AdHoc station: %pM\n", bssid);
3910
3911 entry.reserved = 0;
3912 entry.support_mode = 0;
3913 memcpy(entry.mac_addr, bssid, ETH_ALEN);
3914 memcpy(priv->stations[i], bssid, ETH_ALEN);
3915 ipw_write_direct(priv, IPW_STATION_TABLE_LOWER + i * sizeof(entry),
3916 &entry, sizeof(entry));
3917 priv->num_stations++;
3918
3919 return i;
3920}
3921
3922static u8 ipw_find_station(struct ipw_priv *priv, u8 * bssid)
3923{
3924 int i;
3925
3926 for (i = 0; i < priv->num_stations; i++)
3927 if (!memcmp(priv->stations[i], bssid, ETH_ALEN))
3928 return i;
3929
3930 return IPW_INVALID_STATION;
3931}
3932
3933static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
3934{
3935 int err;
3936
3937 if (priv->status & STATUS_ASSOCIATING) {
3938 IPW_DEBUG_ASSOC("Disassociating while associating.\n");
3939 queue_work(priv->workqueue, &priv->disassociate);
3940 return;
3941 }
3942
3943 if (!(priv->status & STATUS_ASSOCIATED)) {
3944 IPW_DEBUG_ASSOC("Disassociating while not associated.\n");
3945 return;
3946 }
3947
3948 IPW_DEBUG_ASSOC("Disassocation attempt from %pM "
3949 "on channel %d.\n",
3950 priv->assoc_request.bssid,
3951 priv->assoc_request.channel);
3952
3953 priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
3954 priv->status |= STATUS_DISASSOCIATING;
3955
3956 if (quiet)
3957 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
3958 else
3959 priv->assoc_request.assoc_type = HC_DISASSOCIATE;
3960
3961 err = ipw_send_associate(priv, &priv->assoc_request);
3962 if (err) {
3963 IPW_DEBUG_HC("Attempt to send [dis]associate command "
3964 "failed.\n");
3965 return;
3966 }
3967
3968}
3969
3970static int ipw_disassociate(void *data)
3971{
3972 struct ipw_priv *priv = data;
3973 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
3974 return 0;
3975 ipw_send_disassociate(data, 0);
3976 netif_carrier_off(priv->net_dev);
3977 return 1;
3978}
3979
3980static void ipw_bg_disassociate(struct work_struct *work)
3981{
3982 struct ipw_priv *priv =
3983 container_of(work, struct ipw_priv, disassociate);
3984 mutex_lock(&priv->mutex);
3985 ipw_disassociate(priv);
3986 mutex_unlock(&priv->mutex);
3987}
3988
3989static void ipw_system_config(struct work_struct *work)
3990{
3991 struct ipw_priv *priv =
3992 container_of(work, struct ipw_priv, system_config);
3993
3994#ifdef CONFIG_IPW2200_PROMISCUOUS
3995 if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {
3996 priv->sys_config.accept_all_data_frames = 1;
3997 priv->sys_config.accept_non_directed_frames = 1;
3998 priv->sys_config.accept_all_mgmt_bcpr = 1;
3999 priv->sys_config.accept_all_mgmt_frames = 1;
4000 }
4001#endif
4002
4003 ipw_send_system_config(priv);
4004}
4005
4006struct ipw_status_code {
4007 u16 status;
4008 const char *reason;
4009};
4010
4011static const struct ipw_status_code ipw_status_codes[] = {
4012 {0x00, "Successful"},
4013 {0x01, "Unspecified failure"},
4014 {0x0A, "Cannot support all requested capabilities in the "
4015 "Capability information field"},
4016 {0x0B, "Reassociation denied due to inability to confirm that "
4017 "association exists"},
4018 {0x0C, "Association denied due to reason outside the scope of this "
4019 "standard"},
4020 {0x0D,
4021 "Responding station does not support the specified authentication "
4022 "algorithm"},
4023 {0x0E,
4024 "Received an Authentication frame with authentication sequence "
4025 "transaction sequence number out of expected sequence"},
4026 {0x0F, "Authentication rejected because of challenge failure"},
4027 {0x10, "Authentication rejected due to timeout waiting for next "
4028 "frame in sequence"},
4029 {0x11, "Association denied because AP is unable to handle additional "
4030 "associated stations"},
4031 {0x12,
4032 "Association denied due to requesting station not supporting all "
4033 "of the datarates in the BSSBasicServiceSet Parameter"},
4034 {0x13,
4035 "Association denied due to requesting station not supporting "
4036 "short preamble operation"},
4037 {0x14,
4038 "Association denied due to requesting station not supporting "
4039 "PBCC encoding"},
4040 {0x15,
4041 "Association denied due to requesting station not supporting "
4042 "channel agility"},
4043 {0x19,
4044 "Association denied due to requesting station not supporting "
4045 "short slot operation"},
4046 {0x1A,
4047 "Association denied due to requesting station not supporting "
4048 "DSSS-OFDM operation"},
4049 {0x28, "Invalid Information Element"},
4050 {0x29, "Group Cipher is not valid"},
4051 {0x2A, "Pairwise Cipher is not valid"},
4052 {0x2B, "AKMP is not valid"},
4053 {0x2C, "Unsupported RSN IE version"},
4054 {0x2D, "Invalid RSN IE Capabilities"},
4055 {0x2E, "Cipher suite is rejected per security policy"},
4056};
4057
4058static const char *ipw_get_status_code(u16 status)
4059{
4060 int i;
4061 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++)
4062 if (ipw_status_codes[i].status == (status & 0xff))
4063 return ipw_status_codes[i].reason;
4064 return "Unknown status value.";
4065}
4066
4067static void inline average_init(struct average *avg)
4068{
4069 memset(avg, 0, sizeof(*avg));
4070}
4071
4072#define DEPTH_RSSI 8
4073#define DEPTH_NOISE 16
4074static s16 exponential_average(s16 prev_avg, s16 val, u8 depth)
4075{
4076 return ((depth-1)*prev_avg + val)/depth;
4077}
4078
4079static void average_add(struct average *avg, s16 val)
4080{
4081 avg->sum -= avg->entries[avg->pos];
4082 avg->sum += val;
4083 avg->entries[avg->pos++] = val;
4084 if (unlikely(avg->pos == AVG_ENTRIES)) {
4085 avg->init = 1;
4086 avg->pos = 0;
4087 }
4088}
4089
4090static s16 average_value(struct average *avg)
4091{
4092 if (!unlikely(avg->init)) {
4093 if (avg->pos)
4094 return avg->sum / avg->pos;
4095 return 0;
4096 }
4097
4098 return avg->sum / AVG_ENTRIES;
4099}
4100
4101static void ipw_reset_stats(struct ipw_priv *priv)
4102{
4103 u32 len = sizeof(u32);
4104
4105 priv->quality = 0;
4106
4107 average_init(&priv->average_missed_beacons);
4108 priv->exp_avg_rssi = -60;
4109 priv->exp_avg_noise = -85 + 0x100;
4110
4111 priv->last_rate = 0;
4112 priv->last_missed_beacons = 0;
4113 priv->last_rx_packets = 0;
4114 priv->last_tx_packets = 0;
4115 priv->last_tx_failures = 0;
4116
4117
4118
4119 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC,
4120 &priv->last_rx_err, &len);
4121 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE,
4122 &priv->last_tx_failures, &len);
4123
4124
4125 priv->missed_adhoc_beacons = 0;
4126 priv->missed_beacons = 0;
4127 priv->tx_packets = 0;
4128 priv->rx_packets = 0;
4129
4130}
4131
4132static u32 ipw_get_max_rate(struct ipw_priv *priv)
4133{
4134 u32 i = 0x80000000;
4135 u32 mask = priv->rates_mask;
4136
4137
4138 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
4139 mask &= LIBIPW_CCK_RATES_MASK;
4140
4141
4142
4143
4144 while (i && !(mask & i))
4145 i >>= 1;
4146 switch (i) {
4147 case LIBIPW_CCK_RATE_1MB_MASK:
4148 return 1000000;
4149 case LIBIPW_CCK_RATE_2MB_MASK:
4150 return 2000000;
4151 case LIBIPW_CCK_RATE_5MB_MASK:
4152 return 5500000;
4153 case LIBIPW_OFDM_RATE_6MB_MASK:
4154 return 6000000;
4155 case LIBIPW_OFDM_RATE_9MB_MASK:
4156 return 9000000;
4157 case LIBIPW_CCK_RATE_11MB_MASK:
4158 return 11000000;
4159 case LIBIPW_OFDM_RATE_12MB_MASK:
4160 return 12000000;
4161 case LIBIPW_OFDM_RATE_18MB_MASK:
4162 return 18000000;
4163 case LIBIPW_OFDM_RATE_24MB_MASK:
4164 return 24000000;
4165 case LIBIPW_OFDM_RATE_36MB_MASK:
4166 return 36000000;
4167 case LIBIPW_OFDM_RATE_48MB_MASK:
4168 return 48000000;
4169 case LIBIPW_OFDM_RATE_54MB_MASK:
4170 return 54000000;
4171 }
4172
4173 if (priv->ieee->mode == IEEE_B)
4174 return 11000000;
4175 else
4176 return 54000000;
4177}
4178
4179static u32 ipw_get_current_rate(struct ipw_priv *priv)
4180{
4181 u32 rate, len = sizeof(rate);
4182 int err;
4183
4184 if (!(priv->status & STATUS_ASSOCIATED))
4185 return 0;
4186
4187 if (priv->tx_packets > IPW_REAL_RATE_RX_PACKET_THRESHOLD) {
4188 err = ipw_get_ordinal(priv, IPW_ORD_STAT_TX_CURR_RATE, &rate,
4189 &len);
4190 if (err) {
4191 IPW_DEBUG_INFO("failed querying ordinals.\n");
4192 return 0;
4193 }
4194 } else
4195 return ipw_get_max_rate(priv);
4196
4197 switch (rate) {
4198 case IPW_TX_RATE_1MB:
4199 return 1000000;
4200 case IPW_TX_RATE_2MB:
4201 return 2000000;
4202 case IPW_TX_RATE_5MB:
4203 return 5500000;
4204 case IPW_TX_RATE_6MB:
4205 return 6000000;
4206 case IPW_TX_RATE_9MB:
4207 return 9000000;
4208 case IPW_TX_RATE_11MB:
4209 return 11000000;
4210 case IPW_TX_RATE_12MB:
4211 return 12000000;
4212 case IPW_TX_RATE_18MB:
4213 return 18000000;
4214 case IPW_TX_RATE_24MB:
4215 return 24000000;
4216 case IPW_TX_RATE_36MB:
4217 return 36000000;
4218 case IPW_TX_RATE_48MB:
4219 return 48000000;
4220 case IPW_TX_RATE_54MB:
4221 return 54000000;
4222 }
4223
4224 return 0;
4225}
4226
4227#define IPW_STATS_INTERVAL (2 * HZ)
4228static void ipw_gather_stats(struct ipw_priv *priv)
4229{
4230 u32 rx_err, rx_err_delta, rx_packets_delta;
4231 u32 tx_failures, tx_failures_delta, tx_packets_delta;
4232 u32 missed_beacons_percent, missed_beacons_delta;
4233 u32 quality = 0;
4234 u32 len = sizeof(u32);
4235 s16 rssi;
4236 u32 beacon_quality, signal_quality, tx_quality, rx_quality,
4237 rate_quality;
4238 u32 max_rate;
4239
4240 if (!(priv->status & STATUS_ASSOCIATED)) {
4241 priv->quality = 0;
4242 return;
4243 }
4244
4245
4246 ipw_get_ordinal(priv, IPW_ORD_STAT_MISSED_BEACONS,
4247 &priv->missed_beacons, &len);
4248 missed_beacons_delta = priv->missed_beacons - priv->last_missed_beacons;
4249 priv->last_missed_beacons = priv->missed_beacons;
4250 if (priv->assoc_request.beacon_interval) {
4251 missed_beacons_percent = missed_beacons_delta *
4252 (HZ * le16_to_cpu(priv->assoc_request.beacon_interval)) /
4253 (IPW_STATS_INTERVAL * 10);
4254 } else {
4255 missed_beacons_percent = 0;
4256 }
4257 average_add(&priv->average_missed_beacons, missed_beacons_percent);
4258
4259 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC, &rx_err, &len);
4260 rx_err_delta = rx_err - priv->last_rx_err;
4261 priv->last_rx_err = rx_err;
4262
4263 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE, &tx_failures, &len);
4264 tx_failures_delta = tx_failures - priv->last_tx_failures;
4265 priv->last_tx_failures = tx_failures;
4266
4267 rx_packets_delta = priv->rx_packets - priv->last_rx_packets;
4268 priv->last_rx_packets = priv->rx_packets;
4269
4270 tx_packets_delta = priv->tx_packets - priv->last_tx_packets;
4271 priv->last_tx_packets = priv->tx_packets;
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284#define BEACON_THRESHOLD 5
4285 beacon_quality = 100 - missed_beacons_percent;
4286 if (beacon_quality < BEACON_THRESHOLD)
4287 beacon_quality = 0;
4288 else
4289 beacon_quality = (beacon_quality - BEACON_THRESHOLD) * 100 /
4290 (100 - BEACON_THRESHOLD);
4291 IPW_DEBUG_STATS("Missed beacon: %3d%% (%d%%)\n",
4292 beacon_quality, missed_beacons_percent);
4293
4294 priv->last_rate = ipw_get_current_rate(priv);
4295 max_rate = ipw_get_max_rate(priv);
4296 rate_quality = priv->last_rate * 40 / max_rate + 60;
4297 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n",
4298 rate_quality, priv->last_rate / 1000000);
4299
4300 if (rx_packets_delta > 100 && rx_packets_delta + rx_err_delta)
4301 rx_quality = 100 - (rx_err_delta * 100) /
4302 (rx_packets_delta + rx_err_delta);
4303 else
4304 rx_quality = 100;
4305 IPW_DEBUG_STATS("Rx quality : %3d%% (%u errors, %u packets)\n",
4306 rx_quality, rx_err_delta, rx_packets_delta);
4307
4308 if (tx_packets_delta > 100 && tx_packets_delta + tx_failures_delta)
4309 tx_quality = 100 - (tx_failures_delta * 100) /
4310 (tx_packets_delta + tx_failures_delta);
4311 else
4312 tx_quality = 100;
4313 IPW_DEBUG_STATS("Tx quality : %3d%% (%u errors, %u packets)\n",
4314 tx_quality, tx_failures_delta, tx_packets_delta);
4315
4316 rssi = priv->exp_avg_rssi;
4317 signal_quality =
4318 (100 *
4319 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4320 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) -
4321 (priv->ieee->perfect_rssi - rssi) *
4322 (15 * (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) +
4323 62 * (priv->ieee->perfect_rssi - rssi))) /
4324 ((priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4325 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi));
4326 if (signal_quality > 100)
4327 signal_quality = 100;
4328 else if (signal_quality < 1)
4329 signal_quality = 0;
4330
4331 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
4332 signal_quality, rssi);
4333
4334 quality = min(rx_quality, signal_quality);
4335 quality = min(tx_quality, quality);
4336 quality = min(rate_quality, quality);
4337 quality = min(beacon_quality, quality);
4338 if (quality == beacon_quality)
4339 IPW_DEBUG_STATS("Quality (%d%%): Clamped to missed beacons.\n",
4340 quality);
4341 if (quality == rate_quality)
4342 IPW_DEBUG_STATS("Quality (%d%%): Clamped to rate quality.\n",
4343 quality);
4344 if (quality == tx_quality)
4345 IPW_DEBUG_STATS("Quality (%d%%): Clamped to Tx quality.\n",
4346 quality);
4347 if (quality == rx_quality)
4348 IPW_DEBUG_STATS("Quality (%d%%): Clamped to Rx quality.\n",
4349 quality);
4350 if (quality == signal_quality)
4351 IPW_DEBUG_STATS("Quality (%d%%): Clamped to signal quality.\n",
4352 quality);
4353
4354 priv->quality = quality;
4355
4356 queue_delayed_work(priv->workqueue, &priv->gather_stats,
4357 IPW_STATS_INTERVAL);
4358}
4359
4360static void ipw_bg_gather_stats(struct work_struct *work)
4361{
4362 struct ipw_priv *priv =
4363 container_of(work, struct ipw_priv, gather_stats.work);
4364 mutex_lock(&priv->mutex);
4365 ipw_gather_stats(priv);
4366 mutex_unlock(&priv->mutex);
4367}
4368
4369
4370
4371
4372
4373
4374static void ipw_handle_missed_beacon(struct ipw_priv *priv,
4375 int missed_count)
4376{
4377 priv->notif_missed_beacons = missed_count;
4378
4379 if (missed_count > priv->disassociate_threshold &&
4380 priv->status & STATUS_ASSOCIATED) {
4381
4382
4383
4384 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
4385 IPW_DL_STATE | IPW_DL_ASSOC,
4386 "Missed beacon: %d - disassociate\n", missed_count);
4387 priv->status &= ~STATUS_ROAMING;
4388 if (priv->status & STATUS_SCANNING) {
4389 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
4390 IPW_DL_STATE,
4391 "Aborting scan with missed beacon.\n");
4392 queue_work(priv->workqueue, &priv->abort_scan);
4393 }
4394
4395 queue_work(priv->workqueue, &priv->disassociate);
4396 return;
4397 }
4398
4399 if (priv->status & STATUS_ROAMING) {
4400
4401
4402 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4403 "Missed beacon: %d - roam in progress\n",
4404 missed_count);
4405 return;
4406 }
4407
4408 if (roaming &&
4409 (missed_count > priv->roaming_threshold &&
4410 missed_count <= priv->disassociate_threshold)) {
4411
4412
4413
4414
4415 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4416 "Missed beacon: %d - initiate "
4417 "roaming\n", missed_count);
4418 if (!(priv->status & STATUS_ROAMING)) {
4419 priv->status |= STATUS_ROAMING;
4420 if (!(priv->status & STATUS_SCANNING))
4421 queue_delayed_work(priv->workqueue,
4422 &priv->request_scan, 0);
4423 }
4424 return;
4425 }
4426
4427 if (priv->status & STATUS_SCANNING &&
4428 missed_count > IPW_MB_SCAN_CANCEL_THRESHOLD) {
4429
4430
4431
4432
4433 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE,
4434 "Aborting scan with missed beacon.\n");
4435 queue_work(priv->workqueue, &priv->abort_scan);
4436 }
4437
4438 IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
4439}
4440
4441static void ipw_scan_event(struct work_struct *work)
4442{
4443 union iwreq_data wrqu;
4444
4445 struct ipw_priv *priv =
4446 container_of(work, struct ipw_priv, scan_event.work);
4447
4448 wrqu.data.length = 0;
4449 wrqu.data.flags = 0;
4450 wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);
4451}
4452
4453static void handle_scan_event(struct ipw_priv *priv)
4454{
4455
4456 if (!priv->user_requested_scan) {
4457 if (!delayed_work_pending(&priv->scan_event))
4458 queue_delayed_work(priv->workqueue, &priv->scan_event,
4459 round_jiffies_relative(msecs_to_jiffies(4000)));
4460 } else {
4461 union iwreq_data wrqu;
4462
4463 priv->user_requested_scan = 0;
4464 cancel_delayed_work(&priv->scan_event);
4465
4466 wrqu.data.length = 0;
4467 wrqu.data.flags = 0;
4468 wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);
4469 }
4470}
4471
4472
4473
4474
4475
4476static void ipw_rx_notification(struct ipw_priv *priv,
4477 struct ipw_rx_notification *notif)
4478{
4479 DECLARE_SSID_BUF(ssid);
4480 u16 size = le16_to_cpu(notif->size);
4481
4482 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size);
4483
4484 switch (notif->subtype) {
4485 case HOST_NOTIFICATION_STATUS_ASSOCIATED:{
4486 struct notif_association *assoc = ¬if->u.assoc;
4487
4488 switch (assoc->state) {
4489 case CMAS_ASSOCIATED:{
4490 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4491 IPW_DL_ASSOC,
4492 "associated: '%s' %pM\n",
4493 print_ssid(ssid, priv->essid,
4494 priv->essid_len),
4495 priv->bssid);
4496
4497 switch (priv->ieee->iw_mode) {
4498 case IW_MODE_INFRA:
4499 memcpy(priv->ieee->bssid,
4500 priv->bssid, ETH_ALEN);
4501 break;
4502
4503 case IW_MODE_ADHOC:
4504 memcpy(priv->ieee->bssid,
4505 priv->bssid, ETH_ALEN);
4506
4507
4508 priv->num_stations = 0;
4509
4510 IPW_DEBUG_ASSOC
4511 ("queueing adhoc check\n");
4512 queue_delayed_work(priv->
4513 workqueue,
4514 &priv->
4515 adhoc_check,
4516 le16_to_cpu(priv->
4517 assoc_request.
4518 beacon_interval));
4519 break;
4520 }
4521
4522 priv->status &= ~STATUS_ASSOCIATING;
4523 priv->status |= STATUS_ASSOCIATED;
4524 queue_work(priv->workqueue,
4525 &priv->system_config);
4526
4527#ifdef CONFIG_IPW2200_QOS
4528#define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
4529 le16_to_cpu(((struct ieee80211_hdr *)(x))->frame_control))
4530 if ((priv->status & STATUS_AUTH) &&
4531 (IPW_GET_PACKET_STYPE(¬if->u.raw)
4532 == IEEE80211_STYPE_ASSOC_RESP)) {
4533 if ((sizeof
4534 (struct
4535 libipw_assoc_response)
4536 <= size)
4537 && (size <= 2314)) {
4538 struct
4539 libipw_rx_stats
4540 stats = {
4541 .len = size - 1,
4542 };
4543
4544 IPW_DEBUG_QOS
4545 ("QoS Associate "
4546 "size %d\n", size);
4547 libipw_rx_mgt(priv->
4548 ieee,
4549 (struct
4550 libipw_hdr_4addr
4551 *)
4552 ¬if->u.raw, &stats);
4553 }
4554 }
4555#endif
4556
4557 schedule_work(&priv->link_up);
4558
4559 break;
4560 }
4561
4562 case CMAS_AUTHENTICATED:{
4563 if (priv->
4564 status & (STATUS_ASSOCIATED |
4565 STATUS_AUTH)) {
4566 struct notif_authenticate *auth
4567 = ¬if->u.auth;
4568 IPW_DEBUG(IPW_DL_NOTIF |
4569 IPW_DL_STATE |
4570 IPW_DL_ASSOC,
4571 "deauthenticated: '%s' "
4572 "%pM"
4573 ": (0x%04X) - %s\n",
4574 print_ssid(ssid,
4575 priv->
4576 essid,
4577 priv->
4578 essid_len),
4579 priv->bssid,
4580 le16_to_cpu(auth->status),
4581 ipw_get_status_code
4582 (le16_to_cpu
4583 (auth->status)));
4584
4585 priv->status &=
4586 ~(STATUS_ASSOCIATING |
4587 STATUS_AUTH |
4588 STATUS_ASSOCIATED);
4589
4590 schedule_work(&priv->link_down);
4591 break;
4592 }
4593
4594 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4595 IPW_DL_ASSOC,
4596 "authenticated: '%s' %pM\n",
4597 print_ssid(ssid, priv->essid,
4598 priv->essid_len),
4599 priv->bssid);
4600 break;
4601 }
4602
4603 case CMAS_INIT:{
4604 if (priv->status & STATUS_AUTH) {
4605 struct
4606 libipw_assoc_response
4607 *resp;
4608 resp =
4609 (struct
4610 libipw_assoc_response
4611 *)¬if->u.raw;
4612 IPW_DEBUG(IPW_DL_NOTIF |
4613 IPW_DL_STATE |
4614 IPW_DL_ASSOC,
4615 "association failed (0x%04X): %s\n",
4616 le16_to_cpu(resp->status),
4617 ipw_get_status_code
4618 (le16_to_cpu
4619 (resp->status)));
4620 }
4621
4622 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4623 IPW_DL_ASSOC,
4624 "disassociated: '%s' %pM\n",
4625 print_ssid(ssid, priv->essid,
4626 priv->essid_len),
4627 priv->bssid);
4628
4629 priv->status &=
4630 ~(STATUS_DISASSOCIATING |
4631 STATUS_ASSOCIATING |
4632 STATUS_ASSOCIATED | STATUS_AUTH);
4633 if (priv->assoc_network
4634 && (priv->assoc_network->
4635 capability &
4636 WLAN_CAPABILITY_IBSS))
4637 ipw_remove_current_network
4638 (priv);
4639
4640 schedule_work(&priv->link_down);
4641
4642 break;
4643 }
4644
4645 case CMAS_RX_ASSOC_RESP:
4646 break;
4647
4648 default:
4649 IPW_ERROR("assoc: unknown (%d)\n",
4650 assoc->state);
4651 break;
4652 }
4653
4654 break;
4655 }
4656
4657 case HOST_NOTIFICATION_STATUS_AUTHENTICATE:{
4658 struct notif_authenticate *auth = ¬if->u.auth;
4659 switch (auth->state) {
4660 case CMAS_AUTHENTICATED:
4661 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4662 "authenticated: '%s' %pM\n",
4663 print_ssid(ssid, priv->essid,
4664 priv->essid_len),
4665 priv->bssid);
4666 priv->status |= STATUS_AUTH;
4667 break;
4668
4669 case CMAS_INIT:
4670 if (priv->status & STATUS_AUTH) {
4671 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4672 IPW_DL_ASSOC,
4673 "authentication failed (0x%04X): %s\n",
4674 le16_to_cpu(auth->status),
4675 ipw_get_status_code(le16_to_cpu
4676 (auth->
4677 status)));
4678 }
4679 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4680 IPW_DL_ASSOC,
4681 "deauthenticated: '%s' %pM\n",
4682 print_ssid(ssid, priv->essid,
4683 priv->essid_len),
4684 priv->bssid);
4685
4686 priv->status &= ~(STATUS_ASSOCIATING |
4687 STATUS_AUTH |
4688 STATUS_ASSOCIATED);
4689
4690 schedule_work(&priv->link_down);
4691 break;
4692
4693 case CMAS_TX_AUTH_SEQ_1:
4694 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4695 IPW_DL_ASSOC, "AUTH_SEQ_1\n");
4696 break;
4697 case CMAS_RX_AUTH_SEQ_2:
4698 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4699 IPW_DL_ASSOC, "AUTH_SEQ_2\n");
4700 break;
4701 case CMAS_AUTH_SEQ_1_PASS:
4702 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4703 IPW_DL_ASSOC, "AUTH_SEQ_1_PASS\n");
4704 break;
4705 case CMAS_AUTH_SEQ_1_FAIL:
4706 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4707 IPW_DL_ASSOC, "AUTH_SEQ_1_FAIL\n");
4708 break;
4709 case CMAS_TX_AUTH_SEQ_3:
4710 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4711 IPW_DL_ASSOC, "AUTH_SEQ_3\n");
4712 break;
4713 case CMAS_RX_AUTH_SEQ_4:
4714 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4715 IPW_DL_ASSOC, "RX_AUTH_SEQ_4\n");
4716 break;
4717 case CMAS_AUTH_SEQ_2_PASS:
4718 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4719 IPW_DL_ASSOC, "AUTH_SEQ_2_PASS\n");
4720 break;
4721 case CMAS_AUTH_SEQ_2_FAIL:
4722 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4723 IPW_DL_ASSOC, "AUT_SEQ_2_FAIL\n");
4724 break;
4725 case CMAS_TX_ASSOC:
4726 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4727 IPW_DL_ASSOC, "TX_ASSOC\n");
4728 break;
4729 case CMAS_RX_ASSOC_RESP:
4730 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4731 IPW_DL_ASSOC, "RX_ASSOC_RESP\n");
4732
4733 break;
4734 case CMAS_ASSOCIATED:
4735 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
4736 IPW_DL_ASSOC, "ASSOCIATED\n");
4737 break;
4738 default:
4739 IPW_DEBUG_NOTIF("auth: failure - %d\n",
4740 auth->state);
4741 break;
4742 }
4743 break;
4744 }
4745
4746 case HOST_NOTIFICATION_STATUS_SCAN_CHANNEL_RESULT:{
4747 struct notif_channel_result *x =
4748 ¬if->u.channel_result;
4749
4750 if (size == sizeof(*x)) {
4751 IPW_DEBUG_SCAN("Scan result for channel %d\n",
4752 x->channel_num);
4753 } else {
4754 IPW_DEBUG_SCAN("Scan result of wrong size %d "
4755 "(should be %zd)\n",
4756 size, sizeof(*x));
4757 }
4758 break;
4759 }
4760
4761 case HOST_NOTIFICATION_STATUS_SCAN_COMPLETED:{
4762 struct notif_scan_complete *x = ¬if->u.scan_complete;
4763 if (size == sizeof(*x)) {
4764 IPW_DEBUG_SCAN
4765 ("Scan completed: type %d, %d channels, "
4766 "%d status\n", x->scan_type,
4767 x->num_channels, x->status);
4768 } else {
4769 IPW_ERROR("Scan completed of wrong size %d "
4770 "(should be %zd)\n",
4771 size, sizeof(*x));
4772 }
4773
4774 priv->status &=
4775 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
4776
4777 wake_up_interruptible(&priv->wait_state);
4778 cancel_delayed_work(&priv->scan_check);
4779
4780 if (priv->status & STATUS_EXIT_PENDING)
4781 break;
4782
4783 priv->ieee->scans++;
4784
4785#ifdef CONFIG_IPW2200_MONITOR
4786 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
4787 priv->status |= STATUS_SCAN_FORCED;
4788 queue_delayed_work(priv->workqueue,
4789 &priv->request_scan, 0);
4790 break;
4791 }
4792 priv->status &= ~STATUS_SCAN_FORCED;
4793#endif
4794
4795
4796 if (priv->status & STATUS_DIRECT_SCAN_PENDING) {
4797 queue_delayed_work(priv->workqueue,
4798 &priv->request_direct_scan, 0);
4799 }
4800
4801 if (!(priv->status & (STATUS_ASSOCIATED |
4802 STATUS_ASSOCIATING |
4803 STATUS_ROAMING |
4804 STATUS_DISASSOCIATING)))
4805 queue_work(priv->workqueue, &priv->associate);
4806 else if (priv->status & STATUS_ROAMING) {
4807 if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
4808
4809
4810
4811
4812 queue_work(priv->workqueue,
4813 &priv->roam);
4814 else
4815
4816 priv->status &= ~STATUS_ROAMING;
4817 } else if (priv->status & STATUS_SCAN_PENDING)
4818 queue_delayed_work(priv->workqueue,
4819 &priv->request_scan, 0);
4820 else if (priv->config & CFG_BACKGROUND_SCAN
4821 && priv->status & STATUS_ASSOCIATED)
4822 queue_delayed_work(priv->workqueue,
4823 &priv->request_scan,
4824 round_jiffies_relative(HZ));
4825
4826
4827