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