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#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/init.h>
34#include <linux/pci.h>
35#include <linux/dma-mapping.h>
36#include <linux/delay.h>
37#include <linux/skbuff.h>
38#include <linux/netdevice.h>
39#include <linux/wireless.h>
40#include <linux/firmware.h>
41#include <linux/etherdevice.h>
42#include <linux/if_arp.h>
43
44#include <net/ieee80211_radiotap.h>
45#include <net/mac80211.h>
46
47#include <asm/div64.h>
48
49#include "iwl-3945.h"
50#include "iwl-helpers.h"
51
52#ifdef CONFIG_IWL3945_DEBUG
53u32 iwl3945_debug_level;
54#endif
55
56static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
57 struct iwl3945_tx_queue *txq);
58
59
60
61
62
63
64
65
66static int iwl3945_param_disable_hw_scan;
67static int iwl3945_param_debug;
68static int iwl3945_param_disable;
69static int iwl3945_param_antenna;
70int iwl3945_param_hwcrypto;
71static int iwl3945_param_qos_enable = 1;
72int iwl3945_param_queues_num = IWL_MAX_NUM_QUEUES;
73
74
75
76
77
78
79#define DRV_DESCRIPTION \
80"Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux"
81
82#ifdef CONFIG_IWL3945_DEBUG
83#define VD "d"
84#else
85#define VD
86#endif
87
88#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
89#define VS "s"
90#else
91#define VS
92#endif
93
94#define IWLWIFI_VERSION "1.2.23k" VD VS
95#define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation"
96#define DRV_VERSION IWLWIFI_VERSION
97
98
99
100
101
102#define IWL3945_UCODE_API "-1"
103
104MODULE_DESCRIPTION(DRV_DESCRIPTION);
105MODULE_VERSION(DRV_VERSION);
106MODULE_AUTHOR(DRV_COPYRIGHT);
107MODULE_LICENSE("GPL");
108
109static __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr)
110{
111 u16 fc = le16_to_cpu(hdr->frame_control);
112 int hdr_len = ieee80211_get_hdrlen(fc);
113
114 if ((fc & 0x00cc) == (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA))
115 return (__le16 *) ((u8 *) hdr + hdr_len - QOS_CONTROL_LEN);
116 return NULL;
117}
118
119static const struct ieee80211_hw_mode *iwl3945_get_hw_mode(
120 struct iwl3945_priv *priv, int mode)
121{
122 int i;
123
124 for (i = 0; i < 3; i++)
125 if (priv->modes[i].mode == mode)
126 return &priv->modes[i];
127
128 return NULL;
129}
130
131static int iwl3945_is_empty_essid(const char *essid, int essid_len)
132{
133
134 if (essid_len == 1 && essid[0] == ' ')
135 return 1;
136
137
138 while (essid_len) {
139 essid_len--;
140 if (essid[essid_len] != '\0')
141 return 0;
142 }
143
144 return 1;
145}
146
147static const char *iwl3945_escape_essid(const char *essid, u8 essid_len)
148{
149 static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
150 const char *s = essid;
151 char *d = escaped;
152
153 if (iwl3945_is_empty_essid(essid, essid_len)) {
154 memcpy(escaped, "<hidden>", sizeof("<hidden>"));
155 return escaped;
156 }
157
158 essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
159 while (essid_len--) {
160 if (*s == '\0') {
161 *d++ = '\\';
162 *d++ = '0';
163 s++;
164 } else
165 *d++ = *s++;
166 }
167 *d = '\0';
168 return escaped;
169}
170
171static void iwl3945_print_hex_dump(int level, void *p, u32 len)
172{
173#ifdef CONFIG_IWL3945_DEBUG
174 if (!(iwl3945_debug_level & level))
175 return;
176
177 print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
178 p, len, 1);
179#endif
180}
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207static int iwl3945_queue_space(const struct iwl3945_queue *q)
208{
209 int s = q->read_ptr - q->write_ptr;
210
211 if (q->read_ptr > q->write_ptr)
212 s -= q->n_bd;
213
214 if (s <= 0)
215 s += q->n_window;
216
217 s -= 2;
218 if (s < 0)
219 s = 0;
220 return s;
221}
222
223
224
225
226
227
228static inline int iwl3945_queue_inc_wrap(int index, int n_bd)
229{
230 return ++index & (n_bd - 1);
231}
232
233
234
235
236
237
238static inline int iwl3945_queue_dec_wrap(int index, int n_bd)
239{
240 return --index & (n_bd - 1);
241}
242
243static inline int x2_queue_used(const struct iwl3945_queue *q, int i)
244{
245 return q->write_ptr > q->read_ptr ?
246 (i >= q->read_ptr && i < q->write_ptr) :
247 !(i < q->read_ptr && i >= q->write_ptr);
248}
249
250static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge)
251{
252
253 if (is_huge)
254 return q->n_window;
255
256
257 return index & (q->n_window - 1);
258}
259
260
261
262
263static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *q,
264 int count, int slots_num, u32 id)
265{
266 q->n_bd = count;
267 q->n_window = slots_num;
268 q->id = id;
269
270
271
272 BUG_ON(!is_power_of_2(count));
273
274
275
276 BUG_ON(!is_power_of_2(slots_num));
277
278 q->low_mark = q->n_window / 4;
279 if (q->low_mark < 4)
280 q->low_mark = 4;
281
282 q->high_mark = q->n_window / 8;
283 if (q->high_mark < 2)
284 q->high_mark = 2;
285
286 q->write_ptr = q->read_ptr = 0;
287
288 return 0;
289}
290
291
292
293
294static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv,
295 struct iwl3945_tx_queue *txq, u32 id)
296{
297 struct pci_dev *dev = priv->pci_dev;
298
299
300
301 if (id != IWL_CMD_QUEUE_NUM) {
302 txq->txb = kmalloc(sizeof(txq->txb[0]) *
303 TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
304 if (!txq->txb) {
305 IWL_ERROR("kmalloc for auxiliary BD "
306 "structures failed\n");
307 goto error;
308 }
309 } else
310 txq->txb = NULL;
311
312
313
314 txq->bd = pci_alloc_consistent(dev,
315 sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX,
316 &txq->q.dma_addr);
317
318 if (!txq->bd) {
319 IWL_ERROR("pci_alloc_consistent(%zd) failed\n",
320 sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX);
321 goto error;
322 }
323 txq->q.id = id;
324
325 return 0;
326
327 error:
328 if (txq->txb) {
329 kfree(txq->txb);
330 txq->txb = NULL;
331 }
332
333 return -ENOMEM;
334}
335
336
337
338
339int iwl3945_tx_queue_init(struct iwl3945_priv *priv,
340 struct iwl3945_tx_queue *txq, int slots_num, u32 txq_id)
341{
342 struct pci_dev *dev = priv->pci_dev;
343 int len;
344 int rc = 0;
345
346
347
348
349
350
351
352
353
354 len = sizeof(struct iwl3945_cmd) * slots_num;
355 if (txq_id == IWL_CMD_QUEUE_NUM)
356 len += IWL_MAX_SCAN_SIZE;
357 txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd);
358 if (!txq->cmd)
359 return -ENOMEM;
360
361
362 rc = iwl3945_tx_queue_alloc(priv, txq, txq_id);
363 if (rc) {
364 pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
365
366 return -ENOMEM;
367 }
368 txq->need_update = 0;
369
370
371
372 BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
373
374
375 iwl3945_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
376
377
378 iwl3945_hw_tx_queue_init(priv, txq);
379
380 return 0;
381}
382
383
384
385
386
387
388
389
390
391void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
392{
393 struct iwl3945_queue *q = &txq->q;
394 struct pci_dev *dev = priv->pci_dev;
395 int len;
396
397 if (q->n_bd == 0)
398 return;
399
400
401 for (; q->write_ptr != q->read_ptr;
402 q->read_ptr = iwl3945_queue_inc_wrap(q->read_ptr, q->n_bd))
403 iwl3945_hw_txq_free_tfd(priv, txq);
404
405 len = sizeof(struct iwl3945_cmd) * q->n_window;
406 if (q->id == IWL_CMD_QUEUE_NUM)
407 len += IWL_MAX_SCAN_SIZE;
408
409
410 pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
411
412
413 if (txq->q.n_bd)
414 pci_free_consistent(dev, sizeof(struct iwl3945_tfd_frame) *
415 txq->q.n_bd, txq->bd, txq->q.dma_addr);
416
417
418 if (txq->txb) {
419 kfree(txq->txb);
420 txq->txb = NULL;
421 }
422
423
424 memset(txq, 0, sizeof(*txq));
425}
426
427const u8 iwl3945_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
428
429
430
431
432
433
434
435#if 0
436
437
438
439
440
441static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap)
442{
443 int index = IWL_INVALID_STATION;
444 int i;
445 unsigned long flags;
446
447 spin_lock_irqsave(&priv->sta_lock, flags);
448
449 if (is_ap)
450 index = IWL_AP_ID;
451 else if (is_broadcast_ether_addr(addr))
452 index = priv->hw_setting.bcast_sta_id;
453 else
454 for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++)
455 if (priv->stations[i].used &&
456 !compare_ether_addr(priv->stations[i].sta.sta.addr,
457 addr)) {
458 index = i;
459 break;
460 }
461
462 if (unlikely(index == IWL_INVALID_STATION))
463 goto out;
464
465 if (priv->stations[index].used) {
466 priv->stations[index].used = 0;
467 priv->num_stations--;
468 }
469
470 BUG_ON(priv->num_stations < 0);
471
472out:
473 spin_unlock_irqrestore(&priv->sta_lock, flags);
474 return 0;
475}
476#endif
477
478
479
480
481
482
483static void iwl3945_clear_stations_table(struct iwl3945_priv *priv)
484{
485 unsigned long flags;
486
487 spin_lock_irqsave(&priv->sta_lock, flags);
488
489 priv->num_stations = 0;
490 memset(priv->stations, 0, sizeof(priv->stations));
491
492 spin_unlock_irqrestore(&priv->sta_lock, flags);
493}
494
495
496
497
498u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 flags)
499{
500 int i;
501 int index = IWL_INVALID_STATION;
502 struct iwl3945_station_entry *station;
503 unsigned long flags_spin;
504 DECLARE_MAC_BUF(mac);
505 u8 rate;
506
507 spin_lock_irqsave(&priv->sta_lock, flags_spin);
508 if (is_ap)
509 index = IWL_AP_ID;
510 else if (is_broadcast_ether_addr(addr))
511 index = priv->hw_setting.bcast_sta_id;
512 else
513 for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++) {
514 if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
515 addr)) {
516 index = i;
517 break;
518 }
519
520 if (!priv->stations[i].used &&
521 index == IWL_INVALID_STATION)
522 index = i;
523 }
524
525
526
527 if (unlikely(index == IWL_INVALID_STATION)) {
528 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
529 return index;
530 }
531
532 if (priv->stations[index].used &&
533 !compare_ether_addr(priv->stations[index].sta.sta.addr, addr)) {
534 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
535 return index;
536 }
537
538 IWL_DEBUG_ASSOC("Add STA ID %d: %s\n", index, print_mac(mac, addr));
539 station = &priv->stations[index];
540 station->used = 1;
541 priv->num_stations++;
542
543
544 memset(&station->sta, 0, sizeof(struct iwl3945_addsta_cmd));
545 memcpy(station->sta.sta.addr, addr, ETH_ALEN);
546 station->sta.mode = 0;
547 station->sta.sta.sta_id = index;
548 station->sta.station_flags = 0;
549
550 if (priv->phymode == MODE_IEEE80211A)
551 rate = IWL_RATE_6M_PLCP;
552 else
553 rate = IWL_RATE_1M_PLCP;
554
555
556 station->sta.rate_n_flags =
557 iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
558 station->current_rate.rate_n_flags =
559 le16_to_cpu(station->sta.rate_n_flags);
560
561 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
562
563
564 iwl3945_send_add_station(priv, &station->sta, flags);
565 return index;
566
567}
568
569
570
571static inline int iwl3945_is_ready(struct iwl3945_priv *priv)
572{
573
574
575 return test_bit(STATUS_READY, &priv->status) &&
576 test_bit(STATUS_GEO_CONFIGURED, &priv->status) &&
577 !test_bit(STATUS_EXIT_PENDING, &priv->status);
578}
579
580static inline int iwl3945_is_alive(struct iwl3945_priv *priv)
581{
582 return test_bit(STATUS_ALIVE, &priv->status);
583}
584
585static inline int iwl3945_is_init(struct iwl3945_priv *priv)
586{
587 return test_bit(STATUS_INIT, &priv->status);
588}
589
590static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv)
591{
592 return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
593 test_bit(STATUS_RF_KILL_SW, &priv->status);
594}
595
596static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv)
597{
598
599 if (iwl3945_is_rfkill(priv))
600 return 0;
601
602 return iwl3945_is_ready(priv);
603}
604
605
606
607#define IWL_CMD(x) case x : return #x
608
609static const char *get_cmd_string(u8 cmd)
610{
611 switch (cmd) {
612 IWL_CMD(REPLY_ALIVE);
613 IWL_CMD(REPLY_ERROR);
614 IWL_CMD(REPLY_RXON);
615 IWL_CMD(REPLY_RXON_ASSOC);
616 IWL_CMD(REPLY_QOS_PARAM);
617 IWL_CMD(REPLY_RXON_TIMING);
618 IWL_CMD(REPLY_ADD_STA);
619 IWL_CMD(REPLY_REMOVE_STA);
620 IWL_CMD(REPLY_REMOVE_ALL_STA);
621 IWL_CMD(REPLY_3945_RX);
622 IWL_CMD(REPLY_TX);
623 IWL_CMD(REPLY_RATE_SCALE);
624 IWL_CMD(REPLY_LEDS_CMD);
625 IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
626 IWL_CMD(RADAR_NOTIFICATION);
627 IWL_CMD(REPLY_QUIET_CMD);
628 IWL_CMD(REPLY_CHANNEL_SWITCH);
629 IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
630 IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD);
631 IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION);
632 IWL_CMD(POWER_TABLE_CMD);
633 IWL_CMD(PM_SLEEP_NOTIFICATION);
634 IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC);
635 IWL_CMD(REPLY_SCAN_CMD);
636 IWL_CMD(REPLY_SCAN_ABORT_CMD);
637 IWL_CMD(SCAN_START_NOTIFICATION);
638 IWL_CMD(SCAN_RESULTS_NOTIFICATION);
639 IWL_CMD(SCAN_COMPLETE_NOTIFICATION);
640 IWL_CMD(BEACON_NOTIFICATION);
641 IWL_CMD(REPLY_TX_BEACON);
642 IWL_CMD(WHO_IS_AWAKE_NOTIFICATION);
643 IWL_CMD(QUIET_NOTIFICATION);
644 IWL_CMD(REPLY_TX_PWR_TABLE_CMD);
645 IWL_CMD(MEASURE_ABORT_NOTIFICATION);
646 IWL_CMD(REPLY_BT_CONFIG);
647 IWL_CMD(REPLY_STATISTICS_CMD);
648 IWL_CMD(STATISTICS_NOTIFICATION);
649 IWL_CMD(REPLY_CARD_STATE_CMD);
650 IWL_CMD(CARD_STATE_NOTIFICATION);
651 IWL_CMD(MISSED_BEACONS_NOTIFICATION);
652 default:
653 return "UNKNOWN";
654
655 }
656}
657
658#define HOST_COMPLETE_TIMEOUT (HZ / 2)
659
660
661
662
663
664
665
666
667
668
669static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
670{
671 struct iwl3945_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
672 struct iwl3945_queue *q = &txq->q;
673 struct iwl3945_tfd_frame *tfd;
674 u32 *control_flags;
675 struct iwl3945_cmd *out_cmd;
676 u32 idx;
677 u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
678 dma_addr_t phys_addr;
679 int pad;
680 u16 count;
681 int ret;
682 unsigned long flags;
683
684
685
686
687 BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
688 !(cmd->meta.flags & CMD_SIZE_HUGE));
689
690
691 if (iwl3945_is_rfkill(priv)) {
692 IWL_DEBUG_INFO("Not sending command - RF KILL");
693 return -EIO;
694 }
695
696 if (iwl3945_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
697 IWL_ERROR("No space for Tx\n");
698 return -ENOSPC;
699 }
700
701 spin_lock_irqsave(&priv->hcmd_lock, flags);
702
703 tfd = &txq->bd[q->write_ptr];
704 memset(tfd, 0, sizeof(*tfd));
705
706 control_flags = (u32 *) tfd;
707
708 idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
709 out_cmd = &txq->cmd[idx];
710
711 out_cmd->hdr.cmd = cmd->id;
712 memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta));
713 memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
714
715
716
717
718 out_cmd->hdr.flags = 0;
719 out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
720 INDEX_TO_SEQ(q->write_ptr));
721 if (out_cmd->meta.flags & CMD_SIZE_HUGE)
722 out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME);
723
724 phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx +
725 offsetof(struct iwl3945_cmd, hdr);
726 iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
727
728 pad = U32_PAD(cmd->len);
729 count = TFD_CTL_COUNT_GET(*control_flags);
730 *control_flags = TFD_CTL_COUNT_SET(count) | TFD_CTL_PAD_SET(pad);
731
732 IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
733 "%d bytes at %d[%d]:%d\n",
734 get_cmd_string(out_cmd->hdr.cmd),
735 out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
736 fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
737
738 txq->need_update = 1;
739
740
741 q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd);
742 ret = iwl3945_tx_queue_update_write_ptr(priv, txq);
743
744 spin_unlock_irqrestore(&priv->hcmd_lock, flags);
745 return ret ? ret : idx;
746}
747
748static int iwl3945_send_cmd_async(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
749{
750 int ret;
751
752 BUG_ON(!(cmd->meta.flags & CMD_ASYNC));
753
754
755 BUG_ON(cmd->meta.flags & CMD_WANT_SKB);
756
757
758 BUG_ON(!cmd->meta.u.callback);
759
760 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
761 return -EBUSY;
762
763 ret = iwl3945_enqueue_hcmd(priv, cmd);
764 if (ret < 0) {
765 IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n",
766 get_cmd_string(cmd->id), ret);
767 return ret;
768 }
769 return 0;
770}
771
772static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
773{
774 int cmd_idx;
775 int ret;
776 static atomic_t entry = ATOMIC_INIT(0);
777
778 BUG_ON(cmd->meta.flags & CMD_ASYNC);
779
780
781 BUG_ON(cmd->meta.u.callback != NULL);
782
783 if (atomic_xchg(&entry, 1)) {
784 IWL_ERROR("Error sending %s: Already sending a host command\n",
785 get_cmd_string(cmd->id));
786 return -EBUSY;
787 }
788
789 set_bit(STATUS_HCMD_ACTIVE, &priv->status);
790
791 if (cmd->meta.flags & CMD_WANT_SKB)
792 cmd->meta.source = &cmd->meta;
793
794 cmd_idx = iwl3945_enqueue_hcmd(priv, cmd);
795 if (cmd_idx < 0) {
796 ret = cmd_idx;
797 IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n",
798 get_cmd_string(cmd->id), ret);
799 goto out;
800 }
801
802 ret = wait_event_interruptible_timeout(priv->wait_command_queue,
803 !test_bit(STATUS_HCMD_ACTIVE, &priv->status),
804 HOST_COMPLETE_TIMEOUT);
805 if (!ret) {
806 if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) {
807 IWL_ERROR("Error sending %s: time out after %dms.\n",
808 get_cmd_string(cmd->id),
809 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
810
811 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
812 ret = -ETIMEDOUT;
813 goto cancel;
814 }
815 }
816
817 if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
818 IWL_DEBUG_INFO("Command %s aborted: RF KILL Switch\n",
819 get_cmd_string(cmd->id));
820 ret = -ECANCELED;
821 goto fail;
822 }
823 if (test_bit(STATUS_FW_ERROR, &priv->status)) {
824 IWL_DEBUG_INFO("Command %s failed: FW Error\n",
825 get_cmd_string(cmd->id));
826 ret = -EIO;
827 goto fail;
828 }
829 if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) {
830 IWL_ERROR("Error: Response NULL in '%s'\n",
831 get_cmd_string(cmd->id));
832 ret = -EIO;
833 goto out;
834 }
835
836 ret = 0;
837 goto out;
838
839cancel:
840 if (cmd->meta.flags & CMD_WANT_SKB) {
841 struct iwl3945_cmd *qcmd;
842
843
844
845
846
847 qcmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx];
848 qcmd->meta.flags &= ~CMD_WANT_SKB;
849 }
850fail:
851 if (cmd->meta.u.skb) {
852 dev_kfree_skb_any(cmd->meta.u.skb);
853 cmd->meta.u.skb = NULL;
854 }
855out:
856 atomic_set(&entry, 0);
857 return ret;
858}
859
860int iwl3945_send_cmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
861{
862 if (cmd->meta.flags & CMD_ASYNC)
863 return iwl3945_send_cmd_async(priv, cmd);
864
865 return iwl3945_send_cmd_sync(priv, cmd);
866}
867
868int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len, const void *data)
869{
870 struct iwl3945_host_cmd cmd = {
871 .id = id,
872 .len = len,
873 .data = data,
874 };
875
876 return iwl3945_send_cmd_sync(priv, &cmd);
877}
878
879static int __must_check iwl3945_send_cmd_u32(struct iwl3945_priv *priv, u8 id, u32 val)
880{
881 struct iwl3945_host_cmd cmd = {
882 .id = id,
883 .len = sizeof(val),
884 .data = &val,
885 };
886
887 return iwl3945_send_cmd_sync(priv, &cmd);
888}
889
890int iwl3945_send_statistics_request(struct iwl3945_priv *priv)
891{
892 return iwl3945_send_cmd_u32(priv, REPLY_STATISTICS_CMD, 0);
893}
894
895
896
897
898
899
900
901
902
903
904
905static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv, u8 phymode, u16 channel)
906{
907 if (!iwl3945_get_channel_info(priv, phymode, channel)) {
908 IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
909 channel, phymode);
910 return -EINVAL;
911 }
912
913 if ((le16_to_cpu(priv->staging_rxon.channel) == channel) &&
914 (priv->phymode == phymode))
915 return 0;
916
917 priv->staging_rxon.channel = cpu_to_le16(channel);
918 if (phymode == MODE_IEEE80211A)
919 priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK;
920 else
921 priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
922
923 priv->phymode = phymode;
924
925 IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, phymode);
926
927 return 0;
928}
929
930
931
932
933
934
935
936
937static int iwl3945_check_rxon_cmd(struct iwl3945_rxon_cmd *rxon)
938{
939 int error = 0;
940 int counter = 1;
941
942 if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
943 error |= le32_to_cpu(rxon->flags &
944 (RXON_FLG_TGJ_NARROW_BAND_MSK |
945 RXON_FLG_RADAR_DETECT_MSK));
946 if (error)
947 IWL_WARNING("check 24G fields %d | %d\n",
948 counter++, error);
949 } else {
950 error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ?
951 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK);
952 if (error)
953 IWL_WARNING("check 52 fields %d | %d\n",
954 counter++, error);
955 error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK);
956 if (error)
957 IWL_WARNING("check 52 CCK %d | %d\n",
958 counter++, error);
959 }
960 error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1;
961 if (error)
962 IWL_WARNING("check mac addr %d | %d\n", counter++, error);
963
964
965 error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) &&
966 ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0));
967 if (error)
968 IWL_WARNING("check basic rate %d | %d\n", counter++, error);
969
970 error |= (le16_to_cpu(rxon->assoc_id) > 2007);
971 if (error)
972 IWL_WARNING("check assoc id %d | %d\n", counter++, error);
973
974 error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
975 == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK));
976 if (error)
977 IWL_WARNING("check CCK and short slot %d | %d\n",
978 counter++, error);
979
980 error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
981 == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK));
982 if (error)
983 IWL_WARNING("check CCK & auto detect %d | %d\n",
984 counter++, error);
985
986 error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
987 RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK);
988 if (error)
989 IWL_WARNING("check TGG and auto detect %d | %d\n",
990 counter++, error);
991
992 if ((rxon->flags & RXON_FLG_DIS_DIV_MSK))
993 error |= ((rxon->flags & (RXON_FLG_ANT_B_MSK |
994 RXON_FLG_ANT_A_MSK)) == 0);
995 if (error)
996 IWL_WARNING("check antenna %d %d\n", counter++, error);
997
998 if (error)
999 IWL_WARNING("Tuning to channel %d\n",
1000 le16_to_cpu(rxon->channel));
1001
1002 if (error) {
1003 IWL_ERROR("Not a valid iwl3945_rxon_assoc_cmd field values\n");
1004 return -1;
1005 }
1006 return 0;
1007}
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017static int iwl3945_full_rxon_required(struct iwl3945_priv *priv)
1018{
1019
1020
1021 if (!(priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ||
1022 compare_ether_addr(priv->staging_rxon.bssid_addr,
1023 priv->active_rxon.bssid_addr) ||
1024 compare_ether_addr(priv->staging_rxon.node_addr,
1025 priv->active_rxon.node_addr) ||
1026 compare_ether_addr(priv->staging_rxon.wlap_bssid_addr,
1027 priv->active_rxon.wlap_bssid_addr) ||
1028 (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) ||
1029 (priv->staging_rxon.channel != priv->active_rxon.channel) ||
1030 (priv->staging_rxon.air_propagation !=
1031 priv->active_rxon.air_propagation) ||
1032 (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
1033 return 1;
1034
1035
1036
1037
1038
1039
1040 if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) !=
1041 (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK))
1042 return 1;
1043
1044
1045 if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) !=
1046 (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK))
1047 return 1;
1048
1049 return 0;
1050}
1051
1052static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
1053{
1054 int rc = 0;
1055 struct iwl3945_rx_packet *res = NULL;
1056 struct iwl3945_rxon_assoc_cmd rxon_assoc;
1057 struct iwl3945_host_cmd cmd = {
1058 .id = REPLY_RXON_ASSOC,
1059 .len = sizeof(rxon_assoc),
1060 .meta.flags = CMD_WANT_SKB,
1061 .data = &rxon_assoc,
1062 };
1063 const struct iwl3945_rxon_cmd *rxon1 = &priv->staging_rxon;
1064 const struct iwl3945_rxon_cmd *rxon2 = &priv->active_rxon;
1065
1066 if ((rxon1->flags == rxon2->flags) &&
1067 (rxon1->filter_flags == rxon2->filter_flags) &&
1068 (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
1069 (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
1070 IWL_DEBUG_INFO("Using current RXON_ASSOC. Not resending.\n");
1071 return 0;
1072 }
1073
1074 rxon_assoc.flags = priv->staging_rxon.flags;
1075 rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
1076 rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
1077 rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
1078 rxon_assoc.reserved = 0;
1079
1080 rc = iwl3945_send_cmd_sync(priv, &cmd);
1081 if (rc)
1082 return rc;
1083
1084 res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
1085 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
1086 IWL_ERROR("Bad return from REPLY_RXON_ASSOC command\n");
1087 rc = -EIO;
1088 }
1089
1090 priv->alloc_rxb_skb--;
1091 dev_kfree_skb_any(cmd.meta.u.skb);
1092
1093 return rc;
1094}
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
1105{
1106
1107 struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
1108 int rc = 0;
1109 DECLARE_MAC_BUF(mac);
1110
1111 if (!iwl3945_is_alive(priv))
1112 return -1;
1113
1114
1115 priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
1116
1117
1118 priv->staging_rxon.flags &=
1119 ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
1120 priv->staging_rxon.flags |= iwl3945_get_antenna_flags(priv);
1121
1122 rc = iwl3945_check_rxon_cmd(&priv->staging_rxon);
1123 if (rc) {
1124 IWL_ERROR("Invalid RXON configuration. Not committing.\n");
1125 return -EINVAL;
1126 }
1127
1128
1129
1130
1131 if (!iwl3945_full_rxon_required(priv)) {
1132 rc = iwl3945_send_rxon_assoc(priv);
1133 if (rc) {
1134 IWL_ERROR("Error setting RXON_ASSOC "
1135 "configuration (%d).\n", rc);
1136 return rc;
1137 }
1138
1139 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
1140
1141 return 0;
1142 }
1143
1144
1145
1146
1147
1148 if (iwl3945_is_associated(priv) &&
1149 (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) {
1150 IWL_DEBUG_INFO("Toggling associated bit on current RXON\n");
1151 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1152
1153 rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON,
1154 sizeof(struct iwl3945_rxon_cmd),
1155 &priv->active_rxon);
1156
1157
1158
1159 if (rc) {
1160 active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
1161 IWL_ERROR("Error clearing ASSOC_MSK on current "
1162 "configuration (%d).\n", rc);
1163 return rc;
1164 }
1165 }
1166
1167 IWL_DEBUG_INFO("Sending RXON\n"
1168 "* with%s RXON_FILTER_ASSOC_MSK\n"
1169 "* channel = %d\n"
1170 "* bssid = %s\n",
1171 ((priv->staging_rxon.filter_flags &
1172 RXON_FILTER_ASSOC_MSK) ? "" : "out"),
1173 le16_to_cpu(priv->staging_rxon.channel),
1174 print_mac(mac, priv->staging_rxon.bssid_addr));
1175
1176
1177 rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON,
1178 sizeof(struct iwl3945_rxon_cmd), &priv->staging_rxon);
1179 if (rc) {
1180 IWL_ERROR("Error setting new configuration (%d).\n", rc);
1181 return rc;
1182 }
1183
1184 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
1185
1186 iwl3945_clear_stations_table(priv);
1187
1188
1189
1190 rc = iwl3945_hw_reg_send_txpower(priv);
1191 if (rc) {
1192 IWL_ERROR("Error setting Tx power (%d).\n", rc);
1193 return rc;
1194 }
1195
1196
1197 if (iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0) ==
1198 IWL_INVALID_STATION) {
1199 IWL_ERROR("Error adding BROADCAST address for transmit.\n");
1200 return -EIO;
1201 }
1202
1203
1204
1205 if (iwl3945_is_associated(priv) &&
1206 (priv->iw_mode == IEEE80211_IF_TYPE_STA))
1207 if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, 1, 0)
1208 == IWL_INVALID_STATION) {
1209 IWL_ERROR("Error adding AP address for transmit.\n");
1210 return -EIO;
1211 }
1212
1213
1214
1215 rc = iwl3945_init_hw_rate_table(priv);
1216 if (rc) {
1217 IWL_ERROR("Error setting HW rate table: %02X\n", rc);
1218 return -EIO;
1219 }
1220
1221 return 0;
1222}
1223
1224static int iwl3945_send_bt_config(struct iwl3945_priv *priv)
1225{
1226 struct iwl3945_bt_cmd bt_cmd = {
1227 .flags = 3,
1228 .lead_time = 0xAA,
1229 .max_kill = 1,
1230 .kill_ack_mask = 0,
1231 .kill_cts_mask = 0,
1232 };
1233
1234 return iwl3945_send_cmd_pdu(priv, REPLY_BT_CONFIG,
1235 sizeof(struct iwl3945_bt_cmd), &bt_cmd);
1236}
1237
1238static int iwl3945_send_scan_abort(struct iwl3945_priv *priv)
1239{
1240 int rc = 0;
1241 struct iwl3945_rx_packet *res;
1242 struct iwl3945_host_cmd cmd = {
1243 .id = REPLY_SCAN_ABORT_CMD,
1244 .meta.flags = CMD_WANT_SKB,
1245 };
1246
1247
1248
1249
1250 if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
1251 clear_bit(STATUS_SCAN_ABORTING, &priv->status);
1252 return 0;
1253 }
1254
1255 rc = iwl3945_send_cmd_sync(priv, &cmd);
1256 if (rc) {
1257 clear_bit(STATUS_SCAN_ABORTING, &priv->status);
1258 return rc;
1259 }
1260
1261 res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
1262 if (res->u.status != CAN_ABORT_STATUS) {
1263
1264
1265
1266
1267
1268
1269 IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status);
1270 clear_bit(STATUS_SCAN_ABORTING, &priv->status);
1271 clear_bit(STATUS_SCAN_HW, &priv->status);
1272 }
1273
1274 dev_kfree_skb_any(cmd.meta.u.skb);
1275
1276 return rc;
1277}
1278
1279static int iwl3945_card_state_sync_callback(struct iwl3945_priv *priv,
1280 struct iwl3945_cmd *cmd,
1281 struct sk_buff *skb)
1282{
1283 return 1;
1284}
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296static int iwl3945_send_card_state(struct iwl3945_priv *priv, u32 flags, u8 meta_flag)
1297{
1298 struct iwl3945_host_cmd cmd = {
1299 .id = REPLY_CARD_STATE_CMD,
1300 .len = sizeof(u32),
1301 .data = &flags,
1302 .meta.flags = meta_flag,
1303 };
1304
1305 if (meta_flag & CMD_ASYNC)
1306 cmd.meta.u.callback = iwl3945_card_state_sync_callback;
1307
1308 return iwl3945_send_cmd(priv, &cmd);
1309}
1310
1311static int iwl3945_add_sta_sync_callback(struct iwl3945_priv *priv,
1312 struct iwl3945_cmd *cmd, struct sk_buff *skb)
1313{
1314 struct iwl3945_rx_packet *res = NULL;
1315
1316 if (!skb) {
1317 IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n");
1318 return 1;
1319 }
1320
1321 res = (struct iwl3945_rx_packet *)skb->data;
1322 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
1323 IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
1324 res->hdr.flags);
1325 return 1;
1326 }
1327
1328 switch (res->u.add_sta.status) {
1329 case ADD_STA_SUCCESS_MSK:
1330 break;
1331 default:
1332 break;
1333 }
1334
1335
1336 return 1;
1337}
1338
1339int iwl3945_send_add_station(struct iwl3945_priv *priv,
1340 struct iwl3945_addsta_cmd *sta, u8 flags)
1341{
1342 struct iwl3945_rx_packet *res = NULL;
1343 int rc = 0;
1344 struct iwl3945_host_cmd cmd = {
1345 .id = REPLY_ADD_STA,
1346 .len = sizeof(struct iwl3945_addsta_cmd),
1347 .meta.flags = flags,
1348 .data = sta,
1349 };
1350
1351 if (flags & CMD_ASYNC)
1352 cmd.meta.u.callback = iwl3945_add_sta_sync_callback;
1353 else
1354 cmd.meta.flags |= CMD_WANT_SKB;
1355
1356 rc = iwl3945_send_cmd(priv, &cmd);
1357
1358 if (rc || (flags & CMD_ASYNC))
1359 return rc;
1360
1361 res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
1362 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
1363 IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
1364 res->hdr.flags);
1365 rc = -EIO;
1366 }
1367
1368 if (rc == 0) {
1369 switch (res->u.add_sta.status) {
1370 case ADD_STA_SUCCESS_MSK:
1371 IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n");
1372 break;
1373 default:
1374 rc = -EIO;
1375 IWL_WARNING("REPLY_ADD_STA failed\n");
1376 break;
1377 }
1378 }
1379
1380 priv->alloc_rxb_skb--;
1381 dev_kfree_skb_any(cmd.meta.u.skb);
1382
1383 return rc;
1384}
1385
1386static int iwl3945_update_sta_key_info(struct iwl3945_priv *priv,
1387 struct ieee80211_key_conf *keyconf,
1388 u8 sta_id)
1389{
1390 unsigned long flags;
1391 __le16 key_flags = 0;
1392
1393 switch (keyconf->alg) {
1394 case ALG_CCMP:
1395 key_flags |= STA_KEY_FLG_CCMP;
1396 key_flags |= cpu_to_le16(
1397 keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
1398 key_flags &= ~STA_KEY_FLG_INVALID;
1399 break;
1400 case ALG_TKIP:
1401 case ALG_WEP:
1402 default:
1403 return -EINVAL;
1404 }
1405 spin_lock_irqsave(&priv->sta_lock, flags);
1406 priv->stations[sta_id].keyinfo.alg = keyconf->alg;
1407 priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
1408 memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
1409 keyconf->keylen);
1410
1411 memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
1412 keyconf->keylen);
1413 priv->stations[sta_id].sta.key.key_flags = key_flags;
1414 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
1415 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1416
1417 spin_unlock_irqrestore(&priv->sta_lock, flags);
1418
1419 IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n");
1420 iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0);
1421 return 0;
1422}
1423
1424static int iwl3945_clear_sta_key_info(struct iwl3945_priv *priv, u8 sta_id)
1425{
1426 unsigned long flags;
1427
1428 spin_lock_irqsave(&priv->sta_lock, flags);
1429 memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key));
1430 memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl3945_keyinfo));
1431 priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
1432 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
1433 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1434 spin_unlock_irqrestore(&priv->sta_lock, flags);
1435
1436 IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
1437 iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0);
1438 return 0;
1439}
1440
1441static void iwl3945_clear_free_frames(struct iwl3945_priv *priv)
1442{
1443 struct list_head *element;
1444
1445 IWL_DEBUG_INFO("%d frames on pre-allocated heap on clear.\n",
1446 priv->frames_count);
1447
1448 while (!list_empty(&priv->free_frames)) {
1449 element = priv->free_frames.next;
1450 list_del(element);
1451 kfree(list_entry(element, struct iwl3945_frame, list));
1452 priv->frames_count--;
1453 }
1454
1455 if (priv->frames_count) {
1456 IWL_WARNING("%d frames still in use. Did we lose one?\n",
1457 priv->frames_count);
1458 priv->frames_count = 0;
1459 }
1460}
1461
1462static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl3945_priv *priv)
1463{
1464 struct iwl3945_frame *frame;
1465 struct list_head *element;
1466 if (list_empty(&priv->free_frames)) {
1467 frame = kzalloc(sizeof(*frame), GFP_KERNEL);
1468 if (!frame) {
1469 IWL_ERROR("Could not allocate frame!\n");
1470 return NULL;
1471 }
1472
1473 priv->frames_count++;
1474 return frame;
1475 }
1476
1477 element = priv->free_frames.next;
1478 list_del(element);
1479 return list_entry(element, struct iwl3945_frame, list);
1480}
1481
1482static void iwl3945_free_frame(struct iwl3945_priv *priv, struct iwl3945_frame *frame)
1483{
1484 memset(frame, 0, sizeof(*frame));
1485 list_add(&frame->list, &priv->free_frames);
1486}
1487
1488unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
1489 struct ieee80211_hdr *hdr,
1490 const u8 *dest, int left)
1491{
1492
1493 if (!iwl3945_is_associated(priv) || !priv->ibss_beacon ||
1494 ((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) &&
1495 (priv->iw_mode != IEEE80211_IF_TYPE_AP)))
1496 return 0;
1497
1498 if (priv->ibss_beacon->len > left)
1499 return 0;
1500
1501 memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len);
1502
1503 return priv->ibss_beacon->len;
1504}
1505
1506static u8 iwl3945_rate_get_lowest_plcp(int rate_mask)
1507{
1508 u8 i;
1509
1510 for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
1511 i = iwl3945_rates[i].next_ieee) {
1512 if (rate_mask & (1 << i))
1513 return iwl3945_rates[i].plcp;
1514 }
1515
1516 return IWL_RATE_INVALID;
1517}
1518
1519static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
1520{
1521 struct iwl3945_frame *frame;
1522 unsigned int frame_size;
1523 int rc;
1524 u8 rate;
1525
1526 frame = iwl3945_get_free_frame(priv);
1527
1528 if (!frame) {
1529 IWL_ERROR("Could not obtain free frame buffer for beacon "
1530 "command.\n");
1531 return -ENOMEM;
1532 }
1533
1534 if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) {
1535 rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic &
1536 0xFF0);
1537 if (rate == IWL_INVALID_RATE)
1538 rate = IWL_RATE_6M_PLCP;
1539 } else {
1540 rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic & 0xF);
1541 if (rate == IWL_INVALID_RATE)
1542 rate = IWL_RATE_1M_PLCP;
1543 }
1544
1545 frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
1546
1547 rc = iwl3945_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
1548 &frame->u.cmd[0]);
1549
1550 iwl3945_free_frame(priv, frame);
1551
1552 return rc;
1553}
1554
1555
1556
1557
1558
1559
1560
1561static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac)
1562{
1563 memcpy(mac, priv->eeprom.mac_address, 6);
1564}
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574static inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
1575{
1576 _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
1577 return 0;
1578}
1579
1580
1581
1582
1583
1584
1585
1586
1587int iwl3945_eeprom_init(struct iwl3945_priv *priv)
1588{
1589 u16 *e = (u16 *)&priv->eeprom;
1590 u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP);
1591 u32 r;
1592 int sz = sizeof(priv->eeprom);
1593 int rc;
1594 int i;
1595 u16 addr;
1596
1597
1598
1599
1600
1601 BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
1602
1603 if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
1604 IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
1605 return -ENOENT;
1606 }
1607
1608
1609 rc = iwl3945_eeprom_acquire_semaphore(priv);
1610 if (rc < 0) {
1611 IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
1612 return -ENOENT;
1613 }
1614
1615
1616 for (addr = 0; addr < sz; addr += sizeof(u16)) {
1617 _iwl3945_write32(priv, CSR_EEPROM_REG, addr << 1);
1618 _iwl3945_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
1619
1620 for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT;
1621 i += IWL_EEPROM_ACCESS_DELAY) {
1622 r = _iwl3945_read_direct32(priv, CSR_EEPROM_REG);
1623 if (r & CSR_EEPROM_REG_READ_VALID_MSK)
1624 break;
1625 udelay(IWL_EEPROM_ACCESS_DELAY);
1626 }
1627
1628 if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
1629 IWL_ERROR("Time out reading EEPROM[%d]", addr);
1630 return -ETIMEDOUT;
1631 }
1632 e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
1633 }
1634
1635 return 0;
1636}
1637
1638
1639
1640
1641
1642
1643#ifdef CONFIG_IWL3945_DEBUG
1644
1645
1646
1647
1648
1649
1650
1651
1652void iwl3945_report_frame(struct iwl3945_priv *priv,
1653 struct iwl3945_rx_packet *pkt,
1654 struct ieee80211_hdr *header, int group100)
1655{
1656 u32 to_us;
1657 u32 print_summary = 0;
1658 u32 print_dump = 0;
1659 u32 hundred = 0;
1660 u32 dataframe = 0;
1661 u16 fc;
1662 u16 seq_ctl;
1663 u16 channel;
1664 u16 phy_flags;
1665 int rate_sym;
1666 u16 length;
1667 u16 status;
1668 u16 bcn_tmr;
1669 u32 tsf_low;
1670 u64 tsf;
1671 u8 rssi;
1672 u8 agc;
1673 u16 sig_avg;
1674 u16 noise_diff;
1675 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
1676 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
1677 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
1678 u8 *data = IWL_RX_DATA(pkt);
1679
1680
1681 fc = le16_to_cpu(header->frame_control);
1682 seq_ctl = le16_to_cpu(header->seq_ctrl);
1683
1684
1685 channel = le16_to_cpu(rx_hdr->channel);
1686 phy_flags = le16_to_cpu(rx_hdr->phy_flags);
1687 rate_sym = rx_hdr->rate;
1688 length = le16_to_cpu(rx_hdr->len);
1689
1690
1691 status = le32_to_cpu(rx_end->status);
1692 bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
1693 tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
1694 tsf = le64_to_cpu(rx_end->timestamp);
1695
1696
1697 rssi = rx_stats->rssi;
1698 agc = rx_stats->agc;
1699 sig_avg = le16_to_cpu(rx_stats->sig_avg);
1700 noise_diff = le16_to_cpu(rx_stats->noise_diff);
1701
1702 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
1703
1704
1705
1706 if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) ==
1707 (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
1708 dataframe = 1;
1709 if (!group100)
1710 print_summary = 1;
1711 else if (priv->framecnt_to_us < 100) {
1712 priv->framecnt_to_us++;
1713 print_summary = 0;
1714 } else {
1715 priv->framecnt_to_us = 0;
1716 print_summary = 1;
1717 hundred = 1;
1718 }
1719 } else {
1720
1721 print_summary = 1;
1722 }
1723
1724 if (print_summary) {
1725 char *title;
1726 u32 rate;
1727
1728 if (hundred)
1729 title = "100Frames";
1730 else if (fc & IEEE80211_FCTL_RETRY)
1731 title = "Retry";
1732 else if (ieee80211_is_assoc_response(fc))
1733 title = "AscRsp";
1734 else if (ieee80211_is_reassoc_response(fc))
1735 title = "RasRsp";
1736 else if (ieee80211_is_probe_response(fc)) {
1737 title = "PrbRsp";
1738 print_dump = 1;
1739 } else if (ieee80211_is_beacon(fc)) {
1740 title = "Beacon";
1741 print_dump = 1;
1742 } else if (ieee80211_is_atim(fc))
1743 title = "ATIM";
1744 else if (ieee80211_is_auth(fc))
1745 title = "Auth";
1746 else if (ieee80211_is_deauth(fc))
1747 title = "DeAuth";
1748 else if (ieee80211_is_disassoc(fc))
1749 title = "DisAssoc";
1750 else
1751 title = "Frame";
1752
1753 rate = iwl3945_rate_index_from_plcp(rate_sym);
1754 if (rate == -1)
1755 rate = 0;
1756 else
1757 rate = iwl3945_rates[rate].ieee / 2;
1758
1759
1760
1761
1762 if (dataframe)
1763 IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
1764 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
1765 title, fc, header->addr1[5],
1766 length, rssi, channel, rate);
1767 else {
1768
1769 IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
1770 "src=0x%02x, rssi=%u, tim=%lu usec, "
1771 "phy=0x%02x, chnl=%d\n",
1772 title, fc, header->addr1[5],
1773 header->addr3[5], rssi,
1774 tsf_low - priv->scan_start_tsf,
1775 phy_flags, channel);
1776 }
1777 }
1778 if (print_dump)
1779 iwl3945_print_hex_dump(IWL_DL_RX, data, length);
1780}
1781#endif
1782
1783static void iwl3945_unset_hw_setting(struct iwl3945_priv *priv)
1784{
1785 if (priv->hw_setting.shared_virt)
1786 pci_free_consistent(priv->pci_dev,
1787 sizeof(struct iwl3945_shared),
1788 priv->hw_setting.shared_virt,
1789 priv->hw_setting.shared_phys);
1790}
1791
1792
1793
1794
1795
1796
1797static u16 iwl3945_supported_rate_to_ie(u8 *ie, u16 supported_rate,
1798 u16 basic_rate, int *left)
1799{
1800 u16 ret_rates = 0, bit;
1801 int i;
1802 u8 *cnt = ie;
1803 u8 *rates = ie + 1;
1804
1805 for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
1806 if (bit & supported_rate) {
1807 ret_rates |= bit;
1808 rates[*cnt] = iwl3945_rates[i].ieee |
1809 ((bit & basic_rate) ? 0x80 : 0x00);
1810 (*cnt)++;
1811 (*left)--;
1812 if ((*left <= 0) ||
1813 (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
1814 break;
1815 }
1816 }
1817
1818 return ret_rates;
1819}
1820
1821
1822
1823
1824static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv,
1825 struct ieee80211_mgmt *frame,
1826 int left, int is_direct)
1827{
1828 int len = 0;
1829 u8 *pos = NULL;
1830 u16 active_rates, ret_rates, cck_rates;
1831
1832
1833
1834 left -= 24;
1835 if (left < 0)
1836 return 0;
1837 len += 24;
1838
1839 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
1840 memcpy(frame->da, iwl3945_broadcast_addr, ETH_ALEN);
1841 memcpy(frame->sa, priv->mac_addr, ETH_ALEN);
1842 memcpy(frame->bssid, iwl3945_broadcast_addr, ETH_ALEN);
1843 frame->seq_ctrl = 0;
1844
1845
1846
1847
1848 left -= 2;
1849 if (left < 0)
1850 return 0;
1851 len += 2;
1852 pos = &(frame->u.probe_req.variable[0]);
1853 *pos++ = WLAN_EID_SSID;
1854 *pos++ = 0;
1855
1856
1857 if (is_direct) {
1858
1859 left -= 2 + priv->essid_len;
1860 if (left < 0)
1861 return 0;
1862
1863 *pos++ = WLAN_EID_SSID;
1864 *pos++ = priv->essid_len;
1865 memcpy(pos, priv->essid, priv->essid_len);
1866 pos += priv->essid_len;
1867 len += 2 + priv->essid_len;
1868 }
1869
1870
1871
1872 left -= 2;
1873 if (left < 0)
1874 return 0;
1875
1876
1877 *pos++ = WLAN_EID_SUPP_RATES;
1878 *pos = 0;
1879
1880 priv->active_rate = priv->rates_mask;
1881 active_rates = priv->active_rate;
1882 priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
1883
1884 cck_rates = IWL_CCK_RATES_MASK & active_rates;
1885 ret_rates = iwl3945_supported_rate_to_ie(pos, cck_rates,
1886 priv->active_rate_basic, &left);
1887 active_rates &= ~ret_rates;
1888
1889 ret_rates = iwl3945_supported_rate_to_ie(pos, active_rates,
1890 priv->active_rate_basic, &left);
1891 active_rates &= ~ret_rates;
1892
1893 len += 2 + *pos;
1894 pos += (*pos) + 1;
1895 if (active_rates == 0)
1896 goto fill_end;
1897
1898
1899
1900 left -= 2;
1901 if (left < 0)
1902 return 0;
1903
1904 *pos++ = WLAN_EID_EXT_SUPP_RATES;
1905 *pos = 0;
1906 iwl3945_supported_rate_to_ie(pos, active_rates,
1907 priv->active_rate_basic, &left);
1908 if (*pos > 0)
1909 len += 2 + *pos;
1910
1911 fill_end:
1912 return (u16)len;
1913}
1914
1915
1916
1917
1918#ifdef CONFIG_IWL3945_QOS
1919static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv,
1920 struct iwl3945_qosparam_cmd *qos)
1921{
1922
1923 return iwl3945_send_cmd_pdu(priv, REPLY_QOS_PARAM,
1924 sizeof(struct iwl3945_qosparam_cmd), qos);
1925}
1926
1927static void iwl3945_reset_qos(struct iwl3945_priv *priv)
1928{
1929 u16 cw_min = 15;
1930 u16 cw_max = 1023;
1931 u8 aifs = 2;
1932 u8 is_legacy = 0;
1933 unsigned long flags;
1934 int i;
1935
1936 spin_lock_irqsave(&priv->lock, flags);
1937 priv->qos_data.qos_active = 0;
1938
1939 if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) {
1940 if (priv->qos_data.qos_enable)
1941 priv->qos_data.qos_active = 1;
1942 if (!(priv->active_rate & 0xfff0)) {
1943 cw_min = 31;
1944 is_legacy = 1;
1945 }
1946 } else if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
1947 if (priv->qos_data.qos_enable)
1948 priv->qos_data.qos_active = 1;
1949 } else if (!(priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK)) {
1950 cw_min = 31;
1951 is_legacy = 1;
1952 }
1953
1954 if (priv->qos_data.qos_active)
1955 aifs = 3;
1956
1957 priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min);
1958 priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max);
1959 priv->qos_data.def_qos_parm.ac[0].aifsn = aifs;
1960 priv->qos_data.def_qos_parm.ac[0].edca_txop = 0;
1961 priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;
1962
1963 if (priv->qos_data.qos_active) {
1964 i = 1;
1965 priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min);
1966 priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max);
1967 priv->qos_data.def_qos_parm.ac[i].aifsn = 7;
1968 priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
1969 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
1970
1971 i = 2;
1972 priv->qos_data.def_qos_parm.ac[i].cw_min =
1973 cpu_to_le16((cw_min + 1) / 2 - 1);
1974 priv->qos_data.def_qos_parm.ac[i].cw_max =
1975 cpu_to_le16(cw_max);
1976 priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
1977 if (is_legacy)
1978 priv->qos_data.def_qos_parm.ac[i].edca_txop =
1979 cpu_to_le16(6016);
1980 else
1981 priv->qos_data.def_qos_parm.ac[i].edca_txop =
1982 cpu_to_le16(3008);
1983 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
1984
1985 i = 3;
1986 priv->qos_data.def_qos_parm.ac[i].cw_min =
1987 cpu_to_le16((cw_min + 1) / 4 - 1);
1988 priv->qos_data.def_qos_parm.ac[i].cw_max =
1989 cpu_to_le16((cw_max + 1) / 2 - 1);
1990 priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
1991 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
1992 if (is_legacy)
1993 priv->qos_data.def_qos_parm.ac[i].edca_txop =
1994 cpu_to_le16(3264);
1995 else
1996 priv->qos_data.def_qos_parm.ac[i].edca_txop =
1997 cpu_to_le16(1504);
1998 } else {
1999 for (i = 1; i < 4; i++) {
2000 priv->qos_data.def_qos_parm.ac[i].cw_min =
2001 cpu_to_le16(cw_min);
2002 priv->qos_data.def_qos_parm.ac[i].cw_max =
2003 cpu_to_le16(cw_max);
2004 priv->qos_data.def_qos_parm.ac[i].aifsn = aifs;
2005 priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
2006 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
2007 }
2008 }
2009 IWL_DEBUG_QOS("set QoS to default \n");
2010
2011 spin_unlock_irqrestore(&priv->lock, flags);
2012}
2013
2014static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
2015{
2016 unsigned long flags;
2017
2018 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2019 return;
2020
2021 if (!priv->qos_data.qos_enable)
2022 return;
2023
2024 spin_lock_irqsave(&priv->lock, flags);
2025 priv->qos_data.def_qos_parm.qos_flags = 0;
2026
2027 if (priv->qos_data.qos_cap.q_AP.queue_request &&
2028 !priv->qos_data.qos_cap.q_AP.txop_request)
2029 priv->qos_data.def_qos_parm.qos_flags |=
2030 QOS_PARAM_FLG_TXOP_TYPE_MSK;
2031
2032 if (priv->qos_data.qos_active)
2033 priv->qos_data.def_qos_parm.qos_flags |=
2034 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
2035
2036 spin_unlock_irqrestore(&priv->lock, flags);
2037
2038 if (force || iwl3945_is_associated(priv)) {
2039 IWL_DEBUG_QOS("send QoS cmd with Qos active %d \n",
2040 priv->qos_data.qos_active);
2041
2042 iwl3945_send_qos_params_command(priv,
2043 &(priv->qos_data.def_qos_parm));
2044 }
2045}
2046
2047#endif
2048
2049
2050
2051#define MSEC_TO_USEC 1024
2052
2053#define NOSLP __constant_cpu_to_le32(0)
2054#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK
2055#define SLP_TIMEOUT(T) __constant_cpu_to_le32((T) * MSEC_TO_USEC)
2056#define SLP_VEC(X0, X1, X2, X3, X4) {__constant_cpu_to_le32(X0), \
2057 __constant_cpu_to_le32(X1), \
2058 __constant_cpu_to_le32(X2), \
2059 __constant_cpu_to_le32(X3), \
2060 __constant_cpu_to_le32(X4)}
2061
2062
2063
2064
2065static struct iwl3945_power_vec_entry range_0[IWL_POWER_AC] = {
2066 {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
2067 {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
2068 {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0},
2069 {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100), SLP_VEC(2, 6, 9, 9, 10)}, 0},
2070 {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 10)}, 1},
2071 {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25), SLP_VEC(4, 7, 10, 10, 10)}, 1}
2072};
2073
2074
2075static struct iwl3945_power_vec_entry range_1[IWL_POWER_AC] = {
2076 {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
2077 {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500),
2078 SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
2079 {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300),
2080 SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
2081 {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(100),
2082 SLP_VEC(2, 6, 9, 9, 0xFF)}, 0},
2083 {{SLP, SLP_TIMEOUT(50), SLP_TIMEOUT(25), SLP_VEC(2, 7, 9, 9, 0xFF)}, 0},
2084 {{SLP, SLP_TIMEOUT(25), SLP_TIMEOUT(25),
2085 SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
2086};
2087
2088int iwl3945_power_init_handle(struct iwl3945_priv *priv)
2089{
2090 int rc = 0, i;
2091 struct iwl3945_power_mgr *pow_data;
2092 int size = sizeof(struct iwl3945_power_vec_entry) * IWL_POWER_AC;
2093 u16 pci_pm;
2094
2095 IWL_DEBUG_POWER("Initialize power \n");
2096
2097 pow_data = &(priv->power_data);
2098
2099 memset(pow_data, 0, sizeof(*pow_data));
2100
2101 pow_data->active_index = IWL_POWER_RANGE_0;
2102 pow_data->dtim_val = 0xffff;
2103
2104 memcpy(&pow_data->pwr_range_0[0], &range_0[0], size);
2105 memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
2106
2107 rc = pci_read_config_word(priv->pci_dev, PCI_LINK_CTRL, &pci_pm);
2108 if (rc != 0)
2109 return 0;
2110 else {
2111 struct iwl3945_powertable_cmd *cmd;
2112
2113 IWL_DEBUG_POWER("adjust power command flags\n");
2114
2115 for (i = 0; i < IWL_POWER_AC; i++) {
2116 cmd = &pow_data->pwr_range_0[i].cmd;
2117
2118 if (pci_pm & 0x1)
2119 cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
2120 else
2121 cmd->flags |= IWL_POWER_PCI_PM_MSK;
2122 }
2123 }
2124 return rc;
2125}
2126
2127static int iwl3945_update_power_cmd(struct iwl3945_priv *priv,
2128 struct iwl3945_powertable_cmd *cmd, u32 mode)
2129{
2130 int rc = 0, i;
2131 u8 skip;
2132 u32 max_sleep = 0;
2133 struct iwl3945_power_vec_entry *range;
2134 u8 period = 0;
2135 struct iwl3945_power_mgr *pow_data;
2136
2137 if (mode > IWL_POWER_INDEX_5) {
2138 IWL_DEBUG_POWER("Error invalid power mode \n");
2139 return -1;
2140 }
2141 pow_data = &(priv->power_data);
2142
2143 if (pow_data->active_index == IWL_POWER_RANGE_0)
2144 range = &pow_data->pwr_range_0[0];
2145 else
2146 range = &pow_data->pwr_range_1[1];
2147
2148 memcpy(cmd, &range[mode].cmd, sizeof(struct iwl3945_powertable_cmd));
2149
2150#ifdef IWL_MAC80211_DISABLE
2151 if (priv->assoc_network != NULL) {
2152 unsigned long flags;
2153
2154 period = priv->assoc_network->tim.tim_period;
2155 }
2156#endif
2157 skip = range[mode].no_dtim;
2158
2159 if (period == 0) {
2160 period = 1;
2161 skip = 0;
2162 }
2163
2164 if (skip == 0) {
2165 max_sleep = period;
2166 cmd->flags &= ~IWL_POWER_SLEEP_OVER_DTIM_MSK;
2167 } else {
2168 __le32 slp_itrvl = cmd->sleep_interval[IWL_POWER_VEC_SIZE - 1];
2169 max_sleep = (le32_to_cpu(slp_itrvl) / period) * period;
2170 cmd->flags |= IWL_POWER_SLEEP_OVER_DTIM_MSK;
2171 }
2172
2173 for (i = 0; i < IWL_POWER_VEC_SIZE; i++) {
2174 if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
2175 cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
2176 }
2177
2178 IWL_DEBUG_POWER("Flags value = 0x%08X\n", cmd->flags);
2179 IWL_DEBUG_POWER("Tx timeout = %u\n", le32_to_cpu(cmd->tx_data_timeout));
2180 IWL_DEBUG_POWER("Rx timeout = %u\n", le32_to_cpu(cmd->rx_data_timeout));
2181 IWL_DEBUG_POWER("Sleep interval vector = { %d , %d , %d , %d , %d }\n",
2182 le32_to_cpu(cmd->sleep_interval[0]),
2183 le32_to_cpu(cmd->sleep_interval[1]),
2184 le32_to_cpu(cmd->sleep_interval[2]),
2185 le32_to_cpu(cmd->sleep_interval[3]),
2186 le32_to_cpu(cmd->sleep_interval[4]));
2187
2188 return rc;
2189}
2190
2191static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode)
2192{
2193 u32 uninitialized_var(final_mode);
2194 int rc;
2195 struct iwl3945_powertable_cmd cmd;
2196
2197
2198
2199
2200 switch (mode) {
2201 case IWL_POWER_BATTERY:
2202 final_mode = IWL_POWER_INDEX_3;
2203 break;
2204 case IWL_POWER_AC:
2205 final_mode = IWL_POWER_MODE_CAM;
2206 break;
2207 default:
2208 final_mode = mode;
2209 break;
2210 }
2211
2212 iwl3945_update_power_cmd(priv, &cmd, final_mode);
2213
2214 rc = iwl3945_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd);
2215
2216 if (final_mode == IWL_POWER_MODE_CAM)
2217 clear_bit(STATUS_POWER_PMI, &priv->status);
2218 else
2219 set_bit(STATUS_POWER_PMI, &priv->status);
2220
2221 return rc;
2222}
2223
2224int iwl3945_is_network_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header)
2225{
2226
2227
2228 switch (priv->iw_mode) {
2229 case IEEE80211_IF_TYPE_IBSS:
2230
2231 if (!compare_ether_addr(header->addr2, priv->mac_addr))
2232 return 0;
2233
2234 if (is_multicast_ether_addr(header->addr1))
2235 return !compare_ether_addr(header->addr3, priv->bssid);
2236
2237 return !compare_ether_addr(header->addr1, priv->mac_addr);
2238 case IEEE80211_IF_TYPE_STA:
2239
2240 if (!compare_ether_addr(header->addr3, priv->mac_addr))
2241 return 0;
2242
2243 if (is_multicast_ether_addr(header->addr1))
2244 return !compare_ether_addr(header->addr2, priv->bssid);
2245
2246 return !compare_ether_addr(header->addr1, priv->mac_addr);
2247 }
2248
2249 return 1;
2250}
2251
2252#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
2253
2254static const char *iwl3945_get_tx_fail_reason(u32 status)
2255{
2256 switch (status & TX_STATUS_MSK) {
2257 case TX_STATUS_SUCCESS:
2258 return "SUCCESS";
2259 TX_STATUS_ENTRY(SHORT_LIMIT);
2260 TX_STATUS_ENTRY(LONG_LIMIT);
2261 TX_STATUS_ENTRY(FIFO_UNDERRUN);
2262 TX_STATUS_ENTRY(MGMNT_ABORT);
2263 TX_STATUS_ENTRY(NEXT_FRAG);
2264 TX_STATUS_ENTRY(LIFE_EXPIRE);
2265 TX_STATUS_ENTRY(DEST_PS);
2266 TX_STATUS_ENTRY(ABORTED);
2267 TX_STATUS_ENTRY(BT_RETRY);
2268 TX_STATUS_ENTRY(STA_INVALID);
2269 TX_STATUS_ENTRY(FRAG_DROPPED);
2270 TX_STATUS_ENTRY(TID_DISABLE);
2271 TX_STATUS_ENTRY(FRAME_FLUSHED);
2272 TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL);
2273 TX_STATUS_ENTRY(TX_LOCKED);
2274 TX_STATUS_ENTRY(NO_BEACON_ON_RADAR);
2275 }
2276
2277 return "UNKNOWN";
2278}
2279
2280
2281
2282
2283
2284
2285static int iwl3945_scan_cancel(struct iwl3945_priv *priv)
2286{
2287 if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
2288 clear_bit(STATUS_SCANNING, &priv->status);
2289 return 0;
2290 }
2291
2292 if (test_bit(STATUS_SCANNING, &priv->status)) {
2293 if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
2294 IWL_DEBUG_SCAN("Queuing scan abort.\n");
2295 set_bit(STATUS_SCAN_ABORTING, &priv->status);
2296 queue_work(priv->workqueue, &priv->abort_scan);
2297
2298 } else
2299 IWL_DEBUG_SCAN("Scan abort already in progress.\n");
2300
2301 return test_bit(STATUS_SCANNING, &priv->status);
2302 }
2303
2304 return 0;
2305}
2306
2307
2308
2309
2310
2311
2312
2313static int iwl3945_scan_cancel_timeout(struct iwl3945_priv *priv, unsigned long ms)
2314{
2315 unsigned long now = jiffies;
2316 int ret;
2317
2318 ret = iwl3945_scan_cancel(priv);
2319 if (ret && ms) {
2320 mutex_unlock(&priv->mutex);
2321 while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&
2322 test_bit(STATUS_SCANNING, &priv->status))
2323 msleep(1);
2324 mutex_lock(&priv->mutex);
2325
2326 return test_bit(STATUS_SCANNING, &priv->status);
2327 }
2328
2329 return ret;
2330}
2331
2332static void iwl3945_sequence_reset(struct iwl3945_priv *priv)
2333{
2334
2335
2336
2337
2338
2339 priv->last_seq_num = -1;
2340 priv->last_frag_num = -1;
2341 priv->last_packet_time = 0;
2342
2343 iwl3945_scan_cancel(priv);
2344}
2345
2346#define MAX_UCODE_BEACON_INTERVAL 1024
2347#define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA)
2348
2349static __le16 iwl3945_adjust_beacon_interval(u16 beacon_val)
2350{
2351 u16 new_val = 0;
2352 u16 beacon_factor = 0;
2353
2354 beacon_factor =
2355 (beacon_val + MAX_UCODE_BEACON_INTERVAL)
2356 / MAX_UCODE_BEACON_INTERVAL;
2357 new_val = beacon_val / beacon_factor;
2358
2359 return cpu_to_le16(new_val);
2360}
2361
2362static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
2363{
2364 u64 interval_tm_unit;
2365 u64 tsf, result;
2366 unsigned long flags;
2367 struct ieee80211_conf *conf = NULL;
2368 u16 beacon_int = 0;
2369
2370 conf = ieee80211_get_hw_conf(priv->hw);
2371
2372 spin_lock_irqsave(&priv->lock, flags);
2373 priv->rxon_timing.timestamp.dw[1] = cpu_to_le32(priv->timestamp1);
2374 priv->rxon_timing.timestamp.dw[0] = cpu_to_le32(priv->timestamp0);
2375
2376 priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTERVAL;
2377
2378 tsf = priv->timestamp1;
2379 tsf = ((tsf << 32) | priv->timestamp0);
2380
2381 beacon_int = priv->beacon_int;
2382 spin_unlock_irqrestore(&priv->lock, flags);
2383
2384 if (priv->iw_mode == IEEE80211_IF_TYPE_STA) {
2385 if (beacon_int == 0) {
2386 priv->rxon_timing.beacon_interval = cpu_to_le16(100);
2387 priv->rxon_timing.beacon_init_val = cpu_to_le32(102400);
2388 } else {
2389 priv->rxon_timing.beacon_interval =
2390 cpu_to_le16(beacon_int);
2391 priv->rxon_timing.beacon_interval =
2392 iwl3945_adjust_beacon_interval(
2393 le16_to_cpu(priv->rxon_timing.beacon_interval));
2394 }
2395
2396 priv->rxon_timing.atim_window = 0;
2397 } else {
2398 priv->rxon_timing.beacon_interval =
2399 iwl3945_adjust_beacon_interval(conf->beacon_int);
2400
2401
2402 priv->rxon_timing.atim_window = 0;
2403 }
2404
2405 interval_tm_unit =
2406 (le16_to_cpu(priv->rxon_timing.beacon_interval) * 1024);
2407 result = do_div(tsf, interval_tm_unit);
2408 priv->rxon_timing.beacon_init_val =
2409 cpu_to_le32((u32) ((u64) interval_tm_unit - result));
2410
2411 IWL_DEBUG_ASSOC
2412 ("beacon interval %d beacon timer %d beacon tim %d\n",
2413 le16_to_cpu(priv->rxon_timing.beacon_interval),
2414 le32_to_cpu(priv->rxon_timing.beacon_init_val),
2415 le16_to_cpu(priv->rxon_timing.atim_window));
2416}
2417
2418static int iwl3945_scan_initiate(struct iwl3945_priv *priv)
2419{
2420 if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
2421 IWL_ERROR("APs don't scan.\n");
2422 return 0;
2423 }
2424
2425 if (!iwl3945_is_ready_rf(priv)) {
2426 IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
2427 return -EIO;
2428 }
2429
2430 if (test_bit(STATUS_SCANNING, &priv->status)) {
2431 IWL_DEBUG_SCAN("Scan already in progress.\n");
2432 return -EAGAIN;
2433 }
2434
2435 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
2436 IWL_DEBUG_SCAN("Scan request while abort pending. "
2437 "Queuing.\n");
2438 return -EAGAIN;
2439 }
2440
2441 IWL_DEBUG_INFO("Starting scan...\n");
2442 priv->scan_bands = 2;
2443 set_bit(STATUS_SCANNING, &priv->status);
2444 priv->scan_start = jiffies;
2445 priv->scan_pass_start = priv->scan_start;
2446
2447 queue_work(priv->workqueue, &priv->request_scan);
2448
2449 return 0;
2450}
2451
2452static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt)
2453{
2454 struct iwl3945_rxon_cmd *rxon = &priv->staging_rxon;
2455
2456 if (hw_decrypt)
2457 rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
2458 else
2459 rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK;
2460
2461 return 0;
2462}
2463
2464static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode)
2465{
2466 if (phymode == MODE_IEEE80211A) {
2467 priv->staging_rxon.flags &=
2468 ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
2469 | RXON_FLG_CCK_MSK);
2470 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
2471 } else {
2472
2473 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
2474 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
2475 else
2476 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
2477
2478 if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
2479 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
2480
2481 priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
2482 priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
2483 priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
2484 }
2485}
2486
2487
2488
2489
2490static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
2491{
2492 const struct iwl3945_channel_info *ch_info;
2493
2494 memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
2495
2496 switch (priv->iw_mode) {
2497 case IEEE80211_IF_TYPE_AP:
2498 priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
2499 break;
2500
2501 case IEEE80211_IF_TYPE_STA:
2502 priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS;
2503 priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
2504 break;
2505
2506 case IEEE80211_IF_TYPE_IBSS:
2507 priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS;
2508 priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
2509 priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
2510 RXON_FILTER_ACCEPT_GRP_MSK;
2511 break;
2512
2513 case IEEE80211_IF_TYPE_MNTR:
2514 priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
2515 priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
2516 RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
2517 break;
2518 }
2519
2520#if 0
2521
2522
2523 if (!hw_to_local(priv->hw)->short_preamble)
2524 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
2525 else
2526 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
2527#endif
2528
2529 ch_info = iwl3945_get_channel_info(priv, priv->phymode,
2530 le16_to_cpu(priv->staging_rxon.channel));
2531
2532 if (!ch_info)
2533 ch_info = &priv->channel_info[0];
2534
2535
2536
2537
2538
2539 if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
2540 !(is_channel_ibss(ch_info)))
2541 ch_info = &priv->channel_info[0];
2542
2543 priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
2544 if (is_channel_a_band(ch_info))
2545 priv->phymode = MODE_IEEE80211A;
2546 else
2547 priv->phymode = MODE_IEEE80211G;
2548
2549 iwl3945_set_flags_for_phymode(priv, priv->phymode);
2550
2551 priv->staging_rxon.ofdm_basic_rates =
2552 (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
2553 priv->staging_rxon.cck_basic_rates =
2554 (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
2555}
2556
2557static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
2558{
2559 if (mode == IEEE80211_IF_TYPE_IBSS) {
2560 const struct iwl3945_channel_info *ch_info;
2561
2562 ch_info = iwl3945_get_channel_info(priv,
2563 priv->phymode,
2564 le16_to_cpu(priv->staging_rxon.channel));
2565
2566 if (!ch_info || !is_channel_ibss(ch_info)) {
2567 IWL_ERROR("channel %d not IBSS channel\n",
2568 le16_to_cpu(priv->staging_rxon.channel));
2569 return -EINVAL;
2570 }
2571 }
2572
2573 priv->iw_mode = mode;
2574
2575 iwl3945_connection_init_rx_config(priv);
2576 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
2577
2578 iwl3945_clear_stations_table(priv);
2579
2580
2581 if (!iwl3945_is_ready_rf(priv))
2582 return -EAGAIN;
2583
2584 cancel_delayed_work(&priv->scan_check);
2585 if (iwl3945_scan_cancel_timeout(priv, 100)) {
2586 IWL_WARNING("Aborted scan still in progress after 100ms\n");
2587 IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
2588 return -EAGAIN;
2589 }
2590
2591 iwl3945_commit_rxon(priv);
2592
2593 return 0;
2594}
2595
2596static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
2597 struct ieee80211_tx_control *ctl,
2598 struct iwl3945_cmd *cmd,
2599 struct sk_buff *skb_frag,
2600 int last_frag)
2601{
2602 struct iwl3945_hw_key *keyinfo = &priv->stations[ctl->key_idx].keyinfo;
2603
2604 switch (keyinfo->alg) {
2605 case ALG_CCMP:
2606 cmd->cmd.tx.sec_ctl = TX_CMD_SEC_CCM;
2607 memcpy(cmd->cmd.tx.key, keyinfo->key, keyinfo->keylen);
2608 IWL_DEBUG_TX("tx_cmd with aes hwcrypto\n");
2609 break;
2610
2611 case ALG_TKIP:
2612#if 0
2613 cmd->cmd.tx.sec_ctl = TX_CMD_SEC_TKIP;
2614
2615 if (last_frag)
2616 memcpy(cmd->cmd.tx.tkip_mic.byte, skb_frag->tail - 8,
2617 8);
2618 else
2619 memset(cmd->cmd.tx.tkip_mic.byte, 0, 8);
2620#endif
2621 break;
2622
2623 case ALG_WEP:
2624 cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP |
2625 (ctl->key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT;
2626
2627 if (keyinfo->keylen == 13)
2628 cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128;
2629
2630 memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen);
2631
2632 IWL_DEBUG_TX("Configuring packet for WEP encryption "
2633 "with key %d\n", ctl->key_idx);
2634 break;
2635
2636 default:
2637 printk(KERN_ERR "Unknown encode alg %d\n", keyinfo->alg);
2638 break;
2639 }
2640}
2641
2642
2643
2644
2645static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
2646 struct iwl3945_cmd *cmd,
2647 struct ieee80211_tx_control *ctrl,
2648 struct ieee80211_hdr *hdr,
2649 int is_unicast, u8 std_id)
2650{
2651 __le16 *qc;
2652 u16 fc = le16_to_cpu(hdr->frame_control);
2653 __le32 tx_flags = cmd->cmd.tx.tx_flags;
2654
2655 cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
2656 if (!(ctrl->flags & IEEE80211_TXCTL_NO_ACK)) {
2657 tx_flags |= TX_CMD_FLG_ACK_MSK;
2658 if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
2659 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
2660 if (ieee80211_is_probe_response(fc) &&
2661 !(le16_to_cpu(hdr->seq_ctrl) & 0xf))
2662 tx_flags |= TX_CMD_FLG_TSF_MSK;
2663 } else {
2664 tx_flags &= (~TX_CMD_FLG_ACK_MSK);
2665 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
2666 }
2667
2668 cmd->cmd.tx.sta_id = std_id;
2669 if (ieee80211_get_morefrag(hdr))
2670 tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
2671
2672 qc = ieee80211_get_qos_ctrl(hdr);
2673 if (qc) {
2674 cmd->cmd.tx.tid_tspec = (u8) (le16_to_cpu(*qc) & 0xf);
2675 tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
2676 } else
2677 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
2678
2679 if (ctrl->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
2680 tx_flags |= TX_CMD_FLG_RTS_MSK;
2681 tx_flags &= ~TX_CMD_FLG_CTS_MSK;
2682 } else if (ctrl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
2683 tx_flags &= ~TX_CMD_FLG_RTS_MSK;
2684 tx_flags |= TX_CMD_FLG_CTS_MSK;
2685 }
2686
2687 if ((tx_flags & TX_CMD_FLG_RTS_MSK) || (tx_flags & TX_CMD_FLG_CTS_MSK))
2688 tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
2689
2690 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
2691 if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
2692 if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ ||
2693 (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
2694 cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3);
2695 else
2696 cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2);
2697 } else
2698 cmd->cmd.tx.timeout.pm_frame_timeout = 0;
2699
2700 cmd->cmd.tx.driver_txop = 0;
2701 cmd->cmd.tx.tx_flags = tx_flags;
2702 cmd->cmd.tx.next_frame_len = 0;
2703}
2704
2705
2706
2707
2708static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *hdr)
2709{
2710 int sta_id;
2711 u16 fc = le16_to_cpu(hdr->frame_control);
2712
2713
2714 if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
2715 is_multicast_ether_addr(hdr->addr1))
2716 return priv->hw_setting.bcast_sta_id;
2717
2718 switch (priv->iw_mode) {
2719
2720
2721
2722 case IEEE80211_IF_TYPE_STA:
2723 return IWL_AP_ID;
2724
2725
2726 case IEEE80211_IF_TYPE_AP:
2727 sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
2728 if (sta_id != IWL_INVALID_STATION)
2729 return sta_id;
2730 return priv->hw_setting.bcast_sta_id;
2731
2732
2733
2734 case IEEE80211_IF_TYPE_IBSS: {
2735 DECLARE_MAC_BUF(mac);
2736
2737
2738 sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
2739 if (sta_id != IWL_INVALID_STATION)
2740 return sta_id;
2741
2742 sta_id = iwl3945_add_station(priv, hdr->addr1, 0, CMD_ASYNC);
2743
2744 if (sta_id != IWL_INVALID_STATION)
2745 return sta_id;
2746
2747 IWL_DEBUG_DROP("Station %s not in station map. "
2748 "Defaulting to broadcast...\n",
2749 print_mac(mac, hdr->addr1));
2750 iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
2751 return priv->hw_setting.bcast_sta_id;
2752 }
2753 default:
2754 IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
2755 return priv->hw_setting.bcast_sta_id;
2756 }
2757}
2758
2759
2760
2761
2762static int iwl3945_tx_skb(struct iwl3945_priv *priv,
2763 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
2764{
2765 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
2766 struct iwl3945_tfd_frame *tfd;
2767 u32 *control_flags;
2768 int txq_id = ctl->queue;
2769 struct iwl3945_tx_queue *txq = NULL;
2770 struct iwl3945_queue *q = NULL;
2771 dma_addr_t phys_addr;
2772 dma_addr_t txcmd_phys;
2773 struct iwl3945_cmd *out_cmd = NULL;
2774 u16 len, idx, len_org;
2775 u8 id, hdr_len, unicast;
2776 u8 sta_id;
2777 u16 seq_number = 0;
2778 u16 fc;
2779 __le16 *qc;
2780 u8 wait_write_ptr = 0;
2781 unsigned long flags;
2782 int rc;
2783
2784 spin_lock_irqsave(&priv->lock, flags);
2785 if (iwl3945_is_rfkill(priv)) {
2786 IWL_DEBUG_DROP("Dropping - RF KILL\n");
2787 goto drop_unlock;
2788 }
2789
2790 if (!priv->vif) {
2791 IWL_DEBUG_DROP("Dropping - !priv->vif\n");
2792 goto drop_unlock;
2793 }
2794
2795 if ((ctl->tx_rate & 0xFF) == IWL_INVALID_RATE) {
2796 IWL_ERROR("ERROR: No TX rate available.\n");
2797 goto drop_unlock;
2798 }
2799
2800 unicast = !is_multicast_ether_addr(hdr->addr1);
2801 id = 0;
2802
2803 fc = le16_to_cpu(hdr->frame_control);
2804
2805#ifdef CONFIG_IWL3945_DEBUG
2806 if (ieee80211_is_auth(fc))
2807 IWL_DEBUG_TX("Sending AUTH frame\n");
2808 else if (ieee80211_is_assoc_request(fc))
2809 IWL_DEBUG_TX("Sending ASSOC frame\n");
2810 else if (ieee80211_is_reassoc_request(fc))
2811 IWL_DEBUG_TX("Sending REASSOC frame\n");
2812#endif
2813
2814
2815 if ((!iwl3945_is_associated(priv) ||
2816 ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) &&
2817 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
2818 IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
2819 goto drop_unlock;
2820 }
2821
2822 spin_unlock_irqrestore(&priv->lock, flags);
2823
2824 hdr_len = ieee80211_get_hdrlen(fc);
2825
2826
2827 sta_id = iwl3945_get_sta_id(priv, hdr);
2828 if (sta_id == IWL_INVALID_STATION) {
2829 DECLARE_MAC_BUF(mac);
2830
2831 IWL_DEBUG_DROP("Dropping - INVALID STATION: %s\n",
2832 print_mac(mac, hdr->addr1));
2833 goto drop;
2834 }
2835
2836 IWL_DEBUG_RATE("station Id %d\n", sta_id);
2837
2838 qc = ieee80211_get_qos_ctrl(hdr);
2839 if (qc) {
2840 u8 tid = (u8)(le16_to_cpu(*qc) & 0xf);
2841 seq_number = priv->stations[sta_id].tid[tid].seq_number &
2842 IEEE80211_SCTL_SEQ;
2843 hdr->seq_ctrl = cpu_to_le16(seq_number) |
2844 (hdr->seq_ctrl &
2845 __constant_cpu_to_le16(IEEE80211_SCTL_FRAG));
2846 seq_number += 0x10;
2847 }
2848
2849
2850 txq = &priv->txq[txq_id];
2851 q = &txq->q;
2852
2853 spin_lock_irqsave(&priv->lock, flags);
2854
2855
2856 tfd = &txq->bd[q->write_ptr];
2857 memset(tfd, 0, sizeof(*tfd));
2858 control_flags = (u32 *) tfd;
2859 idx = get_cmd_index(q, q->write_ptr, 0);
2860
2861
2862 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl3945_tx_info));
2863 txq->txb[q->write_ptr].skb[0] = skb;
2864 memcpy(&(txq->txb[q->write_ptr].status.control),
2865 ctl, sizeof(struct ieee80211_tx_control));
2866
2867
2868 out_cmd = &txq->cmd[idx];
2869 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
2870 memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx));
2871
2872
2873
2874
2875
2876
2877
2878 out_cmd->hdr.cmd = REPLY_TX;
2879 out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
2880 INDEX_TO_SEQ(q->write_ptr)));
2881
2882
2883 memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len);
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894 len = priv->hw_setting.tx_cmd_len +
2895 sizeof(struct iwl3945_cmd_header) + hdr_len;
2896
2897 len_org = len;
2898 len = (len + 3) & ~3;
2899
2900 if (len_org != len)
2901 len_org = 1;
2902 else
2903 len_org = 0;
2904
2905
2906
2907 txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl3945_cmd) * idx +
2908 offsetof(struct iwl3945_cmd, hdr);
2909
2910
2911
2912 iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
2913
2914 if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT))
2915 iwl3945_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0);
2916
2917
2918
2919 len = skb->len - hdr_len;
2920 if (len) {
2921 phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
2922 len, PCI_DMA_TODEVICE);
2923 iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
2924 }
2925
2926 if (!len)
2927
2928 *control_flags = TFD_CTL_COUNT_SET(1);
2929 else
2930
2931
2932 *control_flags = TFD_CTL_COUNT_SET(2) |
2933 TFD_CTL_PAD_SET(U32_PAD(len));
2934
2935
2936 len = (u16)skb->len;
2937 out_cmd->cmd.tx.len = cpu_to_le16(len);
2938
2939
2940 iwl3945_build_tx_cmd_basic(priv, out_cmd, ctl, hdr, unicast, sta_id);
2941
2942
2943 iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, ctl, hdr, sta_id, 0);
2944
2945 out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
2946 out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
2947
2948 if (!ieee80211_get_morefrag(hdr)) {
2949 txq->need_update = 1;
2950 if (qc) {
2951 u8 tid = (u8)(le16_to_cpu(*qc) & 0xf);
2952 priv->stations[sta_id].tid[tid].seq_number = seq_number;
2953 }
2954 } else {
2955 wait_write_ptr = 1;
2956 txq->need_update = 0;
2957 }
2958
2959 iwl3945_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload,
2960 sizeof(out_cmd->cmd.tx));
2961
2962 iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
2963 ieee80211_get_hdrlen(fc));
2964
2965
2966 q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd);
2967 rc = iwl3945_tx_queue_update_write_ptr(priv, txq);
2968 spin_unlock_irqrestore(&priv->lock, flags);
2969
2970 if (rc)
2971 return rc;
2972
2973 if ((iwl3945_queue_space(q) < q->high_mark)
2974 && priv->mac80211_registered) {
2975 if (wait_write_ptr) {
2976 spin_lock_irqsave(&priv->lock, flags);
2977 txq->need_update = 1;
2978 iwl3945_tx_queue_update_write_ptr(priv, txq);
2979 spin_unlock_irqrestore(&priv->lock, flags);
2980 }
2981
2982 ieee80211_stop_queue(priv->hw, ctl->queue);
2983 }
2984
2985 return 0;
2986
2987drop_unlock:
2988 spin_unlock_irqrestore(&priv->lock, flags);
2989drop:
2990 return -1;
2991}
2992
2993static void iwl3945_set_rate(struct iwl3945_priv *priv)
2994{
2995 const struct ieee80211_hw_mode *hw = NULL;
2996 struct ieee80211_rate *rate;
2997 int i;
2998
2999 hw = iwl3945_get_hw_mode(priv, priv->phymode);
3000 if (!hw) {
3001 IWL_ERROR("Failed to set rate: unable to get hw mode\n");
3002 return;
3003 }
3004
3005 priv->active_rate = 0;
3006 priv->active_rate_basic = 0;
3007
3008 IWL_DEBUG_RATE("Setting rates for 802.11%c\n",
3009 hw->mode == MODE_IEEE80211A ?
3010 'a' : ((hw->mode == MODE_IEEE80211B) ? 'b' : 'g'));
3011
3012 for (i = 0; i < hw->num_rates; i++) {
3013 rate = &(hw->rates[i]);
3014 if ((rate->val < IWL_RATE_COUNT) &&
3015 (rate->flags & IEEE80211_RATE_SUPPORTED)) {
3016 IWL_DEBUG_RATE("Adding rate index %d (plcp %d)%s\n",
3017 rate->val, iwl3945_rates[rate->val].plcp,
3018 (rate->flags & IEEE80211_RATE_BASIC) ?
3019 "*" : "");
3020 priv->active_rate |= (1 << rate->val);
3021 if (rate->flags & IEEE80211_RATE_BASIC)
3022 priv->active_rate_basic |= (1 << rate->val);
3023 } else
3024 IWL_DEBUG_RATE("Not adding rate %d (plcp %d)\n",
3025 rate->val, iwl3945_rates[rate->val].plcp);
3026 }
3027
3028 IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n",
3029 priv->active_rate, priv->active_rate_basic);
3030
3031
3032
3033
3034
3035
3036 if (priv->active_rate_basic & IWL_CCK_BASIC_RATES_MASK)
3037 priv->staging_rxon.cck_basic_rates =
3038 ((priv->active_rate_basic &
3039 IWL_CCK_RATES_MASK) >> IWL_FIRST_CCK_RATE) & 0xF;
3040 else
3041 priv->staging_rxon.cck_basic_rates =
3042 (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
3043
3044 if (priv->active_rate_basic & IWL_OFDM_BASIC_RATES_MASK)
3045 priv->staging_rxon.ofdm_basic_rates =
3046 ((priv->active_rate_basic &
3047 (IWL_OFDM_BASIC_RATES_MASK | IWL_RATE_6M_MASK)) >>
3048 IWL_FIRST_OFDM_RATE) & 0xFF;
3049 else
3050 priv->staging_rxon.ofdm_basic_rates =
3051 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
3052}
3053
3054static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio)
3055{
3056 unsigned long flags;
3057
3058 if (!!disable_radio == test_bit(STATUS_RF_KILL_SW, &priv->status))
3059 return;
3060
3061 IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO %s\n",
3062 disable_radio ? "OFF" : "ON");
3063
3064 if (disable_radio) {
3065 iwl3945_scan_cancel(priv);
3066
3067 if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
3068 spin_lock_irqsave(&priv->lock, flags);
3069 iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET,
3070 CSR_UCODE_SW_BIT_RFKILL);
3071 spin_unlock_irqrestore(&priv->lock, flags);
3072 iwl3945_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0);
3073 set_bit(STATUS_RF_KILL_SW, &priv->status);
3074 }
3075 return;
3076 }
3077
3078 spin_lock_irqsave(&priv->lock, flags);
3079 iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
3080
3081 clear_bit(STATUS_RF_KILL_SW, &priv->status);
3082 spin_unlock_irqrestore(&priv->lock, flags);
3083
3084
3085 msleep(10);
3086
3087 spin_lock_irqsave(&priv->lock, flags);
3088 iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
3089 if (!iwl3945_grab_nic_access(priv))
3090 iwl3945_release_nic_access(priv);
3091 spin_unlock_irqrestore(&priv->lock, flags);
3092
3093 if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
3094 IWL_DEBUG_RF_KILL("Can not turn radio back on - "
3095 "disabled by HW switch\n");
3096 return;
3097 }
3098
3099 queue_work(priv->workqueue, &priv->restart);
3100 return;
3101}
3102
3103void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb,
3104 u32 decrypt_res, struct ieee80211_rx_status *stats)
3105{
3106 u16 fc =
3107 le16_to_cpu(((struct ieee80211_hdr *)skb->data)->frame_control);
3108
3109 if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
3110 return;
3111
3112 if (!(fc & IEEE80211_FCTL_PROTECTED))
3113 return;
3114
3115 IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
3116 switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
3117 case RX_RES_STATUS_SEC_TYPE_TKIP:
3118 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
3119 RX_RES_STATUS_BAD_ICV_MIC)
3120 stats->flag |= RX_FLAG_MMIC_ERROR;
3121 case RX_RES_STATUS_SEC_TYPE_WEP:
3122 case RX_RES_STATUS_SEC_TYPE_CCMP:
3123 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
3124 RX_RES_STATUS_DECRYPT_OK) {
3125 IWL_DEBUG_RX("hw decrypt successfully!!!\n");
3126 stats->flag |= RX_FLAG_DECRYPTED;
3127 }
3128 break;
3129
3130 default:
3131 break;
3132 }
3133}
3134
3135#define IWL_PACKET_RETRY_TIME HZ
3136
3137int iwl3945_is_duplicate_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header)
3138{
3139 u16 sc = le16_to_cpu(header->seq_ctrl);
3140 u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
3141 u16 frag = sc & IEEE80211_SCTL_FRAG;
3142 u16 *last_seq, *last_frag;
3143 unsigned long *last_time;
3144
3145 switch (priv->iw_mode) {
3146 case IEEE80211_IF_TYPE_IBSS:{
3147 struct list_head *p;
3148 struct iwl3945_ibss_seq *entry = NULL;
3149 u8 *mac = header->addr2;
3150 int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1);
3151
3152 __list_for_each(p, &priv->ibss_mac_hash[index]) {
3153 entry = list_entry(p, struct iwl3945_ibss_seq, list);
3154 if (!compare_ether_addr(entry->mac, mac))
3155 break;
3156 }
3157 if (p == &priv->ibss_mac_hash[index]) {
3158 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
3159 if (!entry) {
3160 IWL_ERROR("Cannot malloc new mac entry\n");
3161 return 0;
3162 }
3163 memcpy(entry->mac, mac, ETH_ALEN);
3164 entry->seq_num = seq;
3165 entry->frag_num = frag;
3166 entry->packet_time = jiffies;
3167 list_add(&entry->list, &priv->ibss_mac_hash[index]);
3168 return 0;
3169 }
3170 last_seq = &entry->seq_num;
3171 last_frag = &entry->frag_num;
3172 last_time = &entry->packet_time;
3173 break;
3174 }
3175 case IEEE80211_IF_TYPE_STA:
3176 last_seq = &priv->last_seq_num;
3177 last_frag = &priv->last_frag_num;
3178 last_time = &priv->last_packet_time;
3179 break;
3180 default:
3181 return 0;
3182 }
3183 if ((*last_seq == seq) &&
3184 time_after(*last_time + IWL_PACKET_RETRY_TIME, jiffies)) {
3185 if (*last_frag == frag)
3186 goto drop;
3187 if (*last_frag + 1 != frag)
3188
3189 goto drop;
3190 } else
3191 *last_seq = seq;
3192
3193 *last_frag = frag;
3194 *last_time = jiffies;
3195 return 0;
3196
3197 drop:
3198 return 1;
3199}
3200
3201#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
3202
3203#include "iwl-spectrum.h"
3204
3205#define BEACON_TIME_MASK_LOW 0x00FFFFFF
3206#define BEACON_TIME_MASK_HIGH 0xFF000000
3207#define TIME_UNIT 1024
3208
3209
3210
3211
3212
3213
3214
3215
3216static u32 iwl3945_usecs_to_beacons(u32 usec, u32 beacon_interval)
3217{
3218 u32 quot;
3219 u32 rem;
3220 u32 interval = beacon_interval * 1024;
3221
3222 if (!interval || !usec)
3223 return 0;
3224
3225 quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
3226 rem = (usec % interval) & BEACON_TIME_MASK_LOW;
3227
3228 return (quot << 24) + rem;
3229}
3230
3231
3232
3233
3234
3235static __le32 iwl3945_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
3236{
3237 u32 base_low = base & BEACON_TIME_MASK_LOW;
3238 u32 addon_low = addon & BEACON_TIME_MASK_LOW;
3239 u32 interval = beacon_interval * TIME_UNIT;
3240 u32 res = (base & BEACON_TIME_MASK_HIGH) +
3241 (addon & BEACON_TIME_MASK_HIGH);
3242
3243 if (base_low > addon_low)
3244 res += base_low - addon_low;
3245 else if (base_low < addon_low) {
3246 res += interval + base_low - addon_low;
3247 res += (1 << 24);
3248 } else
3249 res += (1 << 24);
3250
3251 return cpu_to_le32(res);
3252}
3253
3254static int iwl3945_get_measurement(struct iwl3945_priv *priv,
3255 struct ieee80211_measurement_params *params,
3256 u8 type)
3257{
3258 struct iwl3945_spectrum_cmd spectrum;
3259 struct iwl3945_rx_packet *res;
3260 struct iwl3945_host_cmd cmd = {
3261 .id = REPLY_SPECTRUM_MEASUREMENT_CMD,
3262 .data = (void *)&spectrum,
3263 .meta.flags = CMD_WANT_SKB,
3264 };
3265 u32 add_time = le64_to_cpu(params->start_time);
3266 int rc;
3267 int spectrum_resp_status;
3268 int duration = le16_to_cpu(params->duration);
3269
3270 if (iwl3945_is_associated(priv))
3271 add_time =
3272 iwl3945_usecs_to_beacons(
3273 le64_to_cpu(params->start_time) - priv->last_tsf,
3274 le16_to_cpu(priv->rxon_timing.beacon_interval));
3275
3276 memset(&spectrum, 0, sizeof(spectrum));
3277
3278 spectrum.channel_count = cpu_to_le16(1);
3279 spectrum.flags =
3280 RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK;
3281 spectrum.filter_flags = MEASUREMENT_FILTER_FLAG;
3282 cmd.len = sizeof(spectrum);
3283 spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
3284
3285 if (iwl3945_is_associated(priv))
3286 spectrum.start_time =
3287 iwl3945_add_beacon_time(priv->last_beacon_time,
3288 add_time,
3289 le16_to_cpu(priv->rxon_timing.beacon_interval));
3290 else
3291 spectrum.start_time = 0;
3292
3293 spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
3294 spectrum.channels[0].channel = params->channel;
3295 spectrum.channels[0].type = type;
3296 if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
3297 spectrum.flags |= RXON_FLG_BAND_24G_MSK |
3298 RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
3299
3300 rc = iwl3945_send_cmd_sync(priv, &cmd);
3301 if (rc)
3302 return rc;
3303
3304 res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
3305 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
3306 IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
3307 rc = -EIO;
3308 }
3309
3310 spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
3311 switch (spectrum_resp_status) {
3312 case 0:
3313 if (res->u.spectrum.id != 0xff) {
3314 IWL_DEBUG_INFO("Replaced existing measurement: %d\n",
3315 res->u.spectrum.id);
3316 priv->measurement_status &= ~MEASUREMENT_READY;
3317 }
3318 priv->measurement_status |= MEASUREMENT_ACTIVE;
3319 rc = 0;
3320 break;
3321
3322 case 1:
3323 rc = -EAGAIN;
3324 break;
3325 }
3326
3327 dev_kfree_skb_any(cmd.meta.u.skb);
3328
3329 return rc;
3330}
3331#endif
3332
3333static void iwl3945_txstatus_to_ieee(struct iwl3945_priv *priv,
3334 struct iwl3945_tx_info *tx_sta)
3335{
3336
3337 tx_sta->status.ack_signal = 0;
3338 tx_sta->status.excessive_retries = 0;
3339 tx_sta->status.queue_length = 0;
3340 tx_sta->status.queue_number = 0;
3341
3342 if (in_interrupt())
3343 ieee80211_tx_status_irqsafe(priv->hw,
3344 tx_sta->skb[0], &(tx_sta->status));
3345 else
3346 ieee80211_tx_status(priv->hw,
3347 tx_sta->skb[0], &(tx_sta->status));
3348
3349 tx_sta->skb[0] = NULL;
3350}
3351
3352
3353
3354
3355
3356
3357
3358
3359static int iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv, int txq_id, int index)
3360{
3361 struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
3362 struct iwl3945_queue *q = &txq->q;
3363 int nfreed = 0;
3364
3365 if ((index >= q->n_bd) || (x2_queue_used(q, index) == 0)) {
3366 IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
3367 "is out of range [0-%d] %d %d.\n", txq_id,
3368 index, q->n_bd, q->write_ptr, q->read_ptr);
3369 return 0;
3370 }
3371
3372 for (index = iwl3945_queue_inc_wrap(index, q->n_bd);
3373 q->read_ptr != index;
3374 q->read_ptr = iwl3945_queue_inc_wrap(q->read_ptr, q->n_bd)) {
3375 if (txq_id != IWL_CMD_QUEUE_NUM) {
3376 iwl3945_txstatus_to_ieee(priv,
3377 &(txq->txb[txq->q.read_ptr]));
3378 iwl3945_hw_txq_free_tfd(priv, txq);
3379 } else if (nfreed > 1) {
3380 IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
3381 q->write_ptr, q->read_ptr);
3382 queue_work(priv->workqueue, &priv->restart);
3383 }
3384 nfreed++;
3385 }
3386
3387 if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) &&
3388 (txq_id != IWL_CMD_QUEUE_NUM) &&
3389 priv->mac80211_registered)
3390 ieee80211_wake_queue(priv->hw, txq_id);
3391
3392
3393 return nfreed;
3394}
3395
3396static int iwl3945_is_tx_success(u32 status)
3397{
3398 return (status & 0xFF) == 0x1;
3399}
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
3410 struct iwl3945_rx_mem_buffer *rxb)
3411{
3412 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3413 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
3414 int txq_id = SEQ_TO_QUEUE(sequence);
3415 int index = SEQ_TO_INDEX(sequence);
3416 struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
3417 struct ieee80211_tx_status *tx_status;
3418 struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
3419 u32 status = le32_to_cpu(tx_resp->status);
3420
3421 if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) {
3422 IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
3423 "is out of range [0-%d] %d %d\n", txq_id,
3424 index, txq->q.n_bd, txq->q.write_ptr,
3425 txq->q.read_ptr);
3426 return;
3427 }
3428
3429 tx_status = &(txq->txb[txq->q.read_ptr].status);
3430
3431 tx_status->retry_count = tx_resp->failure_frame;
3432 tx_status->queue_number = status;
3433 tx_status->queue_length = tx_resp->bt_kill_count;
3434 tx_status->queue_length |= tx_resp->failure_rts;
3435
3436 tx_status->flags =
3437 iwl3945_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0;
3438
3439 tx_status->control.tx_rate = iwl3945_rate_index_from_plcp(tx_resp->rate);
3440
3441 IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
3442 txq_id, iwl3945_get_tx_fail_reason(status), status,
3443 tx_resp->rate, tx_resp->failure_frame);
3444
3445 IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
3446 if (index != -1)
3447 iwl3945_tx_queue_reclaim(priv, txq_id, index);
3448
3449 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
3450 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
3451}
3452
3453
3454static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv,
3455 struct iwl3945_rx_mem_buffer *rxb)
3456{
3457 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3458 struct iwl3945_alive_resp *palive;
3459 struct delayed_work *pwork;
3460
3461 palive = &pkt->u.alive_frame;
3462
3463 IWL_DEBUG_INFO("Alive ucode status 0x%08X revision "
3464 "0x%01X 0x%01X\n",
3465 palive->is_valid, palive->ver_type,
3466 palive->ver_subtype);
3467
3468 if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
3469 IWL_DEBUG_INFO("Initialization Alive received.\n");
3470 memcpy(&priv->card_alive_init,
3471 &pkt->u.alive_frame,
3472 sizeof(struct iwl3945_init_alive_resp));
3473 pwork = &priv->init_alive_start;
3474 } else {
3475 IWL_DEBUG_INFO("Runtime Alive received.\n");
3476 memcpy(&priv->card_alive, &pkt->u.alive_frame,
3477 sizeof(struct iwl3945_alive_resp));
3478 pwork = &priv->alive_start;
3479 iwl3945_disable_events(priv);
3480 }
3481
3482
3483
3484 if (palive->is_valid == UCODE_VALID_OK)
3485 queue_delayed_work(priv->workqueue, pwork,
3486 msecs_to_jiffies(5));
3487 else
3488 IWL_WARNING("uCode did not respond OK.\n");
3489}
3490
3491static void iwl3945_rx_reply_add_sta(struct iwl3945_priv *priv,
3492 struct iwl3945_rx_mem_buffer *rxb)
3493{
3494 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3495
3496 IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
3497 return;
3498}
3499
3500static void iwl3945_rx_reply_error(struct iwl3945_priv *priv,
3501 struct iwl3945_rx_mem_buffer *rxb)
3502{
3503 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3504
3505 IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) "
3506 "seq 0x%04X ser 0x%08X\n",
3507 le32_to_cpu(pkt->u.err_resp.error_type),
3508 get_cmd_string(pkt->u.err_resp.cmd_id),
3509 pkt->u.err_resp.cmd_id,
3510 le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
3511 le32_to_cpu(pkt->u.err_resp.error_info));
3512}
3513
3514#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
3515
3516static void iwl3945_rx_csa(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
3517{
3518 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3519 struct iwl3945_rxon_cmd *rxon = (void *)&priv->active_rxon;
3520 struct iwl3945_csa_notification *csa = &(pkt->u.csa_notif);
3521 IWL_DEBUG_11H("CSA notif: channel %d, status %d\n",
3522 le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
3523 rxon->channel = csa->channel;
3524 priv->staging_rxon.channel = csa->channel;
3525}
3526
3527static void iwl3945_rx_spectrum_measure_notif(struct iwl3945_priv *priv,
3528 struct iwl3945_rx_mem_buffer *rxb)
3529{
3530#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
3531 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3532 struct iwl3945_spectrum_notification *report = &(pkt->u.spectrum_notif);
3533
3534 if (!report->state) {
3535 IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO,
3536 "Spectrum Measure Notification: Start\n");
3537 return;
3538 }
3539
3540 memcpy(&priv->measure_report, report, sizeof(*report));
3541 priv->measurement_status |= MEASUREMENT_READY;
3542#endif
3543}
3544
3545static void iwl3945_rx_pm_sleep_notif(struct iwl3945_priv *priv,
3546 struct iwl3945_rx_mem_buffer *rxb)
3547{
3548#ifdef CONFIG_IWL3945_DEBUG
3549 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3550 struct iwl3945_sleep_notification *sleep = &(pkt->u.sleep_notif);
3551 IWL_DEBUG_RX("sleep mode: %d, src: %d\n",
3552 sleep->pm_sleep_mode, sleep->pm_wakeup_src);
3553#endif
3554}
3555
3556static void iwl3945_rx_pm_debug_statistics_notif(struct iwl3945_priv *priv,
3557 struct iwl3945_rx_mem_buffer *rxb)
3558{
3559 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3560 IWL_DEBUG_RADIO("Dumping %d bytes of unhandled "
3561 "notification for %s:\n",
3562 le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
3563 iwl3945_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
3564}
3565
3566static void iwl3945_bg_beacon_update(struct work_struct *work)
3567{
3568 struct iwl3945_priv *priv =
3569 container_of(work, struct iwl3945_priv, beacon_update);
3570 struct sk_buff *beacon;
3571
3572
3573 beacon = ieee80211_beacon_get(priv->hw, priv->vif, NULL);
3574
3575 if (!beacon) {
3576 IWL_ERROR("update beacon failed\n");
3577 return;
3578 }
3579
3580 mutex_lock(&priv->mutex);
3581
3582 if (priv->ibss_beacon)
3583 dev_kfree_skb(priv->ibss_beacon);
3584
3585 priv->ibss_beacon = beacon;
3586 mutex_unlock(&priv->mutex);
3587
3588 iwl3945_send_beacon_cmd(priv);
3589}
3590
3591static void iwl3945_rx_beacon_notif(struct iwl3945_priv *priv,
3592 struct iwl3945_rx_mem_buffer *rxb)
3593{
3594#ifdef CONFIG_IWL3945_DEBUG
3595 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3596 struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status);
3597 u8 rate = beacon->beacon_notify_hdr.rate;
3598
3599 IWL_DEBUG_RX("beacon status %x retries %d iss %d "
3600 "tsf %d %d rate %d\n",
3601 le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK,
3602 beacon->beacon_notify_hdr.failure_frame,
3603 le32_to_cpu(beacon->ibss_mgr_status),
3604 le32_to_cpu(beacon->high_tsf),
3605 le32_to_cpu(beacon->low_tsf), rate);
3606#endif
3607
3608 if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&
3609 (!test_bit(STATUS_EXIT_PENDING, &priv->status)))
3610 queue_work(priv->workqueue, &priv->beacon_update);
3611}
3612
3613
3614static void iwl3945_rx_reply_scan(struct iwl3945_priv *priv,
3615 struct iwl3945_rx_mem_buffer *rxb)
3616{
3617#ifdef CONFIG_IWL3945_DEBUG
3618 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3619 struct iwl3945_scanreq_notification *notif =
3620 (struct iwl3945_scanreq_notification *)pkt->u.raw;
3621
3622 IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);
3623#endif
3624}
3625
3626
3627static void iwl3945_rx_scan_start_notif(struct iwl3945_priv *priv,
3628 struct iwl3945_rx_mem_buffer *rxb)
3629{
3630 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3631 struct iwl3945_scanstart_notification *notif =
3632 (struct iwl3945_scanstart_notification *)pkt->u.raw;
3633 priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
3634 IWL_DEBUG_SCAN("Scan start: "
3635 "%d [802.11%s] "
3636 "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n",
3637 notif->channel,
3638 notif->band ? "bg" : "a",
3639 notif->tsf_high,
3640 notif->tsf_low, notif->status, notif->beacon_timer);
3641}
3642
3643
3644static void iwl3945_rx_scan_results_notif(struct iwl3945_priv *priv,
3645 struct iwl3945_rx_mem_buffer *rxb)
3646{
3647 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3648 struct iwl3945_scanresults_notification *notif =
3649 (struct iwl3945_scanresults_notification *)pkt->u.raw;
3650
3651 IWL_DEBUG_SCAN("Scan ch.res: "
3652 "%d [802.11%s] "
3653 "(TSF: 0x%08X:%08X) - %d "
3654 "elapsed=%lu usec (%dms since last)\n",
3655 notif->channel,
3656 notif->band ? "bg" : "a",
3657 le32_to_cpu(notif->tsf_high),
3658 le32_to_cpu(notif->tsf_low),
3659 le32_to_cpu(notif->statistics[0]),
3660 le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf,
3661 jiffies_to_msecs(elapsed_jiffies
3662 (priv->last_scan_jiffies, jiffies)));
3663
3664 priv->last_scan_jiffies = jiffies;
3665 priv->next_scan_jiffies = 0;
3666}
3667
3668
3669static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv,
3670 struct iwl3945_rx_mem_buffer *rxb)
3671{
3672 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3673 struct iwl3945_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
3674
3675 IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
3676 scan_notif->scanned_channels,
3677 scan_notif->tsf_low,
3678 scan_notif->tsf_high, scan_notif->status);
3679
3680
3681 clear_bit(STATUS_SCAN_HW, &priv->status);
3682
3683
3684 cancel_delayed_work(&priv->scan_check);
3685
3686 IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
3687 (priv->scan_bands == 2) ? "2.4" : "5.2",
3688 jiffies_to_msecs(elapsed_jiffies
3689 (priv->scan_pass_start, jiffies)));
3690
3691
3692
3693 priv->scan_bands--;
3694
3695
3696
3697
3698 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
3699 IWL_DEBUG_INFO("Aborted scan completed.\n");
3700 clear_bit(STATUS_SCAN_ABORTING, &priv->status);
3701 } else {
3702
3703 if (priv->scan_bands > 0)
3704 goto reschedule;
3705 }
3706
3707 priv->last_scan_jiffies = jiffies;
3708 priv->next_scan_jiffies = 0;
3709 IWL_DEBUG_INFO("Setting scan to off\n");
3710
3711 clear_bit(STATUS_SCANNING, &priv->status);
3712
3713 IWL_DEBUG_INFO("Scan took %dms\n",
3714 jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));
3715
3716 queue_work(priv->workqueue, &priv->scan_completed);
3717
3718 return;
3719
3720reschedule:
3721 priv->scan_pass_start = jiffies;
3722 queue_work(priv->workqueue, &priv->request_scan);
3723}
3724
3725
3726
3727static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv,
3728 struct iwl3945_rx_mem_buffer *rxb)
3729{
3730 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
3731 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
3732 unsigned long status = priv->status;
3733
3734 IWL_DEBUG_RF_KILL("Card state received: HW:%s SW:%s\n",
3735 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
3736 (flags & SW_CARD_DISABLED) ? "Kill" : "On");
3737
3738 iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET,
3739 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
3740
3741 if (flags & HW_CARD_DISABLED)
3742 set_bit(STATUS_RF_KILL_HW, &priv->status);
3743 else
3744 clear_bit(STATUS_RF_KILL_HW, &priv->status);
3745
3746
3747 if (flags & SW_CARD_DISABLED)
3748 set_bit(STATUS_RF_KILL_SW, &priv->status);
3749 else
3750 clear_bit(STATUS_RF_KILL_SW, &priv->status);
3751
3752 iwl3945_scan_cancel(priv);
3753
3754 if ((test_bit(STATUS_RF_KILL_HW, &status) !=
3755 test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
3756 (test_bit(STATUS_RF_KILL_SW, &status) !=
3757 test_bit(STATUS_RF_KILL_SW, &priv->status)))
3758 queue_work(priv->workqueue, &priv->rf_kill);
3759 else
3760 wake_up_interruptible(&priv->wait_command_queue);
3761}
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv)
3773{
3774 priv->rx_handlers[REPLY_ALIVE] = iwl3945_rx_reply_alive;
3775 priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta;
3776 priv->rx_handlers[REPLY_ERROR] = iwl3945_rx_reply_error;
3777 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl3945_rx_csa;
3778 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
3779 iwl3945_rx_spectrum_measure_notif;
3780 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl3945_rx_pm_sleep_notif;
3781 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
3782 iwl3945_rx_pm_debug_statistics_notif;
3783 priv->rx_handlers[BEACON_NOTIFICATION] = iwl3945_rx_beacon_notif;
3784
3785
3786
3787
3788
3789
3790 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics;
3791 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics;
3792
3793 priv->rx_handlers[REPLY_SCAN_CMD] = iwl3945_rx_reply_scan;
3794 priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl3945_rx_scan_start_notif;
3795 priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] =
3796 iwl3945_rx_scan_results_notif;
3797 priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
3798 iwl3945_rx_scan_complete_notif;
3799 priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
3800 priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx;
3801
3802
3803 iwl3945_hw_rx_handler_setup(priv);
3804}
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
3815 struct iwl3945_rx_mem_buffer *rxb)
3816{
3817 struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
3818 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
3819 int txq_id = SEQ_TO_QUEUE(sequence);
3820 int index = SEQ_TO_INDEX(sequence);
3821 int huge = sequence & SEQ_HUGE_FRAME;
3822 int cmd_index;
3823 struct iwl3945_cmd *cmd;
3824
3825
3826
3827
3828 if (txq_id != IWL_CMD_QUEUE_NUM)
3829 IWL_ERROR("Error wrong command queue %d command id 0x%X\n",
3830 txq_id, pkt->hdr.cmd);
3831 BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
3832
3833 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
3834 cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
3835
3836
3837 if (cmd->meta.flags & CMD_WANT_SKB) {
3838 cmd->meta.source->u.skb = rxb->skb;
3839 rxb->skb = NULL;
3840 } else if (cmd->meta.u.callback &&
3841 !cmd->meta.u.callback(priv, cmd, rxb->skb))
3842 rxb->skb = NULL;
3843
3844 iwl3945_tx_queue_reclaim(priv, txq_id, index);
3845
3846 if (!(cmd->meta.flags & CMD_ASYNC)) {
3847 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
3848 wake_up_interruptible(&priv->wait_command_queue);
3849 }
3850}
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920static int iwl3945_rx_queue_space(const struct iwl3945_rx_queue *q)
3921{
3922 int s = q->read - q->write;
3923 if (s <= 0)
3924 s += RX_QUEUE_SIZE;
3925
3926 s -= 2;
3927 if (s < 0)
3928 s = 0;
3929 return s;
3930}
3931
3932
3933
3934
3935int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv, struct iwl3945_rx_queue *q)
3936{
3937 u32 reg = 0;
3938 int rc = 0;
3939 unsigned long flags;
3940
3941 spin_lock_irqsave(&q->lock, flags);
3942
3943 if (q->need_update == 0)
3944 goto exit_unlock;
3945
3946
3947 if (test_bit(STATUS_POWER_PMI, &priv->status)) {
3948 reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
3949
3950 if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
3951 iwl3945_set_bit(priv, CSR_GP_CNTRL,
3952 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
3953 goto exit_unlock;
3954 }
3955
3956 rc = iwl3945_grab_nic_access(priv);
3957 if (rc)
3958 goto exit_unlock;
3959
3960
3961 iwl3945_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
3962 q->write & ~0x7);
3963 iwl3945_release_nic_access(priv);
3964
3965
3966 } else
3967
3968 iwl3945_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
3969
3970
3971 q->need_update = 0;
3972
3973 exit_unlock:
3974 spin_unlock_irqrestore(&q->lock, flags);
3975 return rc;
3976}
3977
3978
3979
3980
3981static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl3945_priv *priv,
3982 dma_addr_t dma_addr)
3983{
3984 return cpu_to_le32((u32)dma_addr);
3985}
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)
3999{
4000 struct iwl3945_rx_queue *rxq = &priv->rxq;
4001 struct list_head *element;
4002 struct iwl3945_rx_mem_buffer *rxb;
4003 unsigned long flags;
4004 int write, rc;
4005
4006 spin_lock_irqsave(&rxq->lock, flags);
4007 write = rxq->write & ~0x7;
4008 while ((iwl3945_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
4009
4010 element = rxq->rx_free.next;
4011 rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list);
4012 list_del(element);
4013
4014
4015 rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->dma_addr);
4016 rxq->queue[rxq->write] = rxb;
4017 rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
4018 rxq->free_count--;
4019 }
4020 spin_unlock_irqrestore(&rxq->lock, flags);
4021
4022
4023 if (rxq->free_count <= RX_LOW_WATERMARK)
4024 queue_work(priv->workqueue, &priv->rx_replenish);
4025
4026
4027
4028
4029 if ((write != (rxq->write & ~0x7))
4030 || (abs(rxq->write - rxq->read) > 7)) {
4031 spin_lock_irqsave(&rxq->lock, flags);
4032 rxq->need_update = 1;
4033 spin_unlock_irqrestore(&rxq->lock, flags);
4034 rc = iwl3945_rx_queue_update_write_ptr(priv, rxq);
4035 if (rc)
4036 return rc;
4037 }
4038
4039 return 0;
4040}
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050static void iwl3945_rx_allocate(struct iwl3945_priv *priv)
4051{
4052 struct iwl3945_rx_queue *rxq = &priv->rxq;
4053 struct list_head *element;
4054 struct iwl3945_rx_mem_buffer *rxb;
4055 unsigned long flags;
4056 spin_lock_irqsave(&rxq->lock, flags);
4057 while (!list_empty(&rxq->rx_used)) {
4058 element = rxq->rx_used.next;
4059 rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list);
4060
4061
4062 rxb->skb =
4063 alloc_skb(IWL_RX_BUF_SIZE, __GFP_NOWARN | GFP_ATOMIC);
4064 if (!rxb->skb) {
4065 if (net_ratelimit())
4066 printk(KERN_CRIT DRV_NAME
4067 ": Can not allocate SKB buffers\n");
4068
4069
4070
4071 break;
4072 }
4073
4074
4075
4076
4077
4078
4079
4080 skb_reserve(rxb->skb, 4);
4081
4082 priv->alloc_rxb_skb++;
4083 list_del(element);
4084
4085
4086 rxb->dma_addr =
4087 pci_map_single(priv->pci_dev, rxb->skb->data,
4088 IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
4089 list_add_tail(&rxb->list, &rxq->rx_free);
4090 rxq->free_count++;
4091 }
4092 spin_unlock_irqrestore(&rxq->lock, flags);
4093}
4094
4095
4096
4097
4098static void __iwl3945_rx_replenish(void *data)
4099{
4100 struct iwl3945_priv *priv = data;
4101
4102 iwl3945_rx_allocate(priv);
4103 iwl3945_rx_queue_restock(priv);
4104}
4105
4106
4107void iwl3945_rx_replenish(void *data)
4108{
4109 struct iwl3945_priv *priv = data;
4110 unsigned long flags;
4111
4112 iwl3945_rx_allocate(priv);
4113
4114 spin_lock_irqsave(&priv->lock, flags);
4115 iwl3945_rx_queue_restock(priv);
4116 spin_unlock_irqrestore(&priv->lock, flags);
4117}
4118
4119
4120
4121
4122
4123
4124static void iwl3945_rx_queue_free(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
4125{
4126 int i;
4127 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
4128 if (rxq->pool[i].skb != NULL) {
4129 pci_unmap_single(priv->pci_dev,
4130 rxq->pool[i].dma_addr,
4131 IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
4132 dev_kfree_skb(rxq->pool[i].skb);
4133 }
4134 }
4135
4136 pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
4137 rxq->dma_addr);
4138 rxq->bd = NULL;
4139}
4140
4141int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv)
4142{
4143 struct iwl3945_rx_queue *rxq = &priv->rxq;
4144 struct pci_dev *dev = priv->pci_dev;
4145 int i;
4146
4147 spin_lock_init(&rxq->lock);
4148 INIT_LIST_HEAD(&rxq->rx_free);
4149 INIT_LIST_HEAD(&rxq->rx_used);
4150
4151
4152 rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
4153 if (!rxq->bd)
4154 return -ENOMEM;
4155
4156
4157 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
4158 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
4159
4160
4161
4162 rxq->read = rxq->write = 0;
4163 rxq->free_count = 0;
4164 rxq->need_update = 0;
4165 return 0;
4166}
4167
4168void iwl3945_rx_queue_reset(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
4169{
4170 unsigned long flags;
4171 int i;
4172 spin_lock_irqsave(&rxq->lock, flags);
4173 INIT_LIST_HEAD(&rxq->rx_free);
4174 INIT_LIST_HEAD(&rxq->rx_used);
4175
4176 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
4177
4178
4179 if (rxq->pool[i].skb != NULL) {
4180 pci_unmap_single(priv->pci_dev,
4181 rxq->pool[i].dma_addr,
4182 IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
4183 priv->alloc_rxb_skb--;
4184 dev_kfree_skb(rxq->pool[i].skb);
4185 rxq->pool[i].skb = NULL;
4186 }
4187 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
4188 }
4189
4190
4191
4192 rxq->read = rxq->write = 0;
4193 rxq->free_count = 0;
4194 spin_unlock_irqrestore(&rxq->lock, flags);
4195}
4196
4197
4198static u8 ratio2dB[100] = {
4199
4200 0, 0, 6, 10, 12, 14, 16, 17, 18, 19,
4201 20, 21, 22, 22, 23, 23, 24, 25, 26, 26,
4202 26, 26, 26, 27, 27, 28, 28, 28, 29, 29,
4203 29, 30, 30, 30, 31, 31, 31, 31, 32, 32,
4204 32, 32, 32, 33, 33, 33, 33, 33, 34, 34,
4205 34, 34, 34, 34, 35, 35, 35, 35, 35, 35,
4206 36, 36, 36, 36, 36, 36, 36, 37, 37, 37,
4207 37, 37, 37, 37, 37, 38, 38, 38, 38, 38,
4208 38, 38, 38, 38, 38, 39, 39, 39, 39, 39,
4209 39, 39, 39, 39, 39, 40, 40, 40, 40, 40
4210};
4211
4212
4213
4214
4215int iwl3945_calc_db_from_ratio(int sig_ratio)
4216{
4217
4218 if (sig_ratio >= 1000)
4219 return 60;
4220
4221
4222
4223 if (sig_ratio >= 100)
4224 return (20 + (int)ratio2dB[sig_ratio/10]);
4225
4226
4227 if (sig_ratio < 1)
4228 return 0;
4229
4230
4231 return (int)ratio2dB[sig_ratio];
4232}
4233
4234#define PERFECT_RSSI (-20)
4235#define WORST_RSSI (-95)
4236#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI)
4237
4238
4239
4240
4241int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm)
4242{
4243 int sig_qual;
4244 int degradation = PERFECT_RSSI - rssi_dbm;
4245
4246
4247
4248
4249
4250
4251 if (noise_dbm) {
4252 if (rssi_dbm - noise_dbm >= 40)
4253 return 100;
4254 else if (rssi_dbm < noise_dbm)
4255 return 0;
4256 sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2;
4257
4258
4259
4260
4261
4262 } else
4263 sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation *
4264 (15 * RSSI_RANGE + 62 * degradation)) /
4265 (RSSI_RANGE * RSSI_RANGE);
4266
4267 if (sig_qual > 100)
4268 sig_qual = 100;
4269 else if (sig_qual < 1)
4270 sig_qual = 0;
4271
4272 return sig_qual;
4273}
4274
4275
4276
4277
4278
4279
4280
4281
4282static void iwl3945_rx_handle(struct iwl3945_priv *priv)
4283{
4284 struct iwl3945_rx_mem_buffer *rxb;
4285 struct iwl3945_rx_packet *pkt;
4286 struct iwl3945_rx_queue *rxq = &priv->rxq;
4287 u32 r, i;
4288 int reclaim;
4289 unsigned long flags;
4290 u8 fill_rx = 0;
4291 u32 count = 8;
4292
4293
4294
4295 r = iwl3945_hw_get_rx_read(priv);
4296 i = rxq->read;
4297
4298 if (iwl3945_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
4299 fill_rx = 1;
4300
4301 if (i == r)
4302 IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i);
4303
4304 while (i != r) {
4305 rxb = rxq->queue[i];
4306
4307
4308
4309
4310 BUG_ON(rxb == NULL);
4311
4312 rxq->queue[i] = NULL;
4313
4314 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
4315 IWL_RX_BUF_SIZE,
4316 PCI_DMA_FROMDEVICE);
4317 pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
4318
4319
4320
4321
4322
4323
4324
4325 reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
4326 (pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
4327 (pkt->hdr.cmd != REPLY_TX);
4328
4329
4330
4331
4332 if (priv->rx_handlers[pkt->hdr.cmd]) {
4333 IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR,
4334 "r = %d, i = %d, %s, 0x%02x\n", r, i,
4335 get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
4336 priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
4337 } else {
4338
4339 IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR,
4340 "r %d i %d No handler needed for %s, 0x%02x\n",
4341 r, i, get_cmd_string(pkt->hdr.cmd),
4342 pkt->hdr.cmd);
4343 }
4344
4345 if (reclaim) {
4346
4347
4348
4349 if (rxb && rxb->skb)
4350 iwl3945_tx_cmd_complete(priv, rxb);
4351 else
4352 IWL_WARNING("Claim null rxb?\n");
4353 }
4354
4355
4356
4357
4358 if (rxb->skb != NULL) {
4359 priv->alloc_rxb_skb--;
4360 dev_kfree_skb_any(rxb->skb);
4361 rxb->skb = NULL;
4362 }
4363
4364 pci_unmap_single(priv->pci_dev, rxb->dma_addr,
4365 IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
4366 spin_lock_irqsave(&rxq->lock, flags);
4367 list_add_tail(&rxb->list, &priv->rxq.rx_used);
4368 spin_unlock_irqrestore(&rxq->lock, flags);
4369 i = (i + 1) & RX_QUEUE_MASK;
4370
4371
4372 if (fill_rx) {
4373 count++;
4374 if (count >= 8) {
4375 priv->rxq.read = i;
4376 __iwl3945_rx_replenish(priv);
4377 count = 0;
4378 }
4379 }
4380 }
4381
4382
4383 priv->rxq.read = i;
4384 iwl3945_rx_queue_restock(priv);
4385}
4386
4387
4388
4389
4390static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
4391 struct iwl3945_tx_queue *txq)
4392{
4393 u32 reg = 0;
4394 int rc = 0;
4395 int txq_id = txq->q.id;
4396
4397 if (txq->need_update == 0)
4398 return rc;
4399
4400
4401 if (test_bit(STATUS_POWER_PMI, &priv->status)) {
4402
4403
4404
4405 reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
4406
4407 if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
4408 IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg);
4409 iwl3945_set_bit(priv, CSR_GP_CNTRL,
4410 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
4411 return rc;
4412 }
4413
4414
4415 rc = iwl3945_grab_nic_access(priv);
4416 if (rc)
4417 return rc;
4418 iwl3945_write_direct32(priv, HBUS_TARG_WRPTR,
4419 txq->q.write_ptr | (txq_id << 8));
4420 iwl3945_release_nic_access(priv);
4421
4422
4423
4424 } else
4425 iwl3945_write32(priv, HBUS_TARG_WRPTR,
4426 txq->q.write_ptr | (txq_id << 8));
4427
4428 txq->need_update = 0;
4429
4430 return rc;
4431}
4432
4433#ifdef CONFIG_IWL3945_DEBUG
4434static void iwl3945_print_rx_config_cmd(struct iwl3945_rxon_cmd *rxon)
4435{
4436 DECLARE_MAC_BUF(mac);
4437
4438 IWL_DEBUG_RADIO("RX CONFIG:\n");
4439 iwl3945_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
4440 IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
4441 IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
4442 IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n",
4443 le32_to_cpu(rxon->filter_flags));
4444 IWL_DEBUG_RADIO("u8 dev_type: 0x%x\n", rxon->dev_type);
4445 IWL_DEBUG_RADIO("u8 ofdm_basic_rates: 0x%02x\n",
4446 rxon->ofdm_basic_rates);
4447 IWL_DEBUG_RADIO("u8 cck_basic_rates: 0x%02x\n", rxon->cck_basic_rates);
4448 IWL_DEBUG_RADIO("u8[6] node_addr: %s\n",
4449 print_mac(mac, rxon->node_addr));
4450 IWL_DEBUG_RADIO("u8[6] bssid_addr: %s\n",
4451 print_mac(mac, rxon->bssid_addr));
4452 IWL_DEBUG_RADIO("u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
4453}
4454#endif
4455
4456static void iwl3945_enable_interrupts(struct iwl3945_priv *priv)
4457{
4458 IWL_DEBUG_ISR("Enabling interrupts\n");
4459 set_bit(STATUS_INT_ENABLED, &priv->status);
4460 iwl3945_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
4461}
4462
4463static inline void iwl3945_disable_interrupts(struct iwl3945_priv *priv)
4464{
4465 clear_bit(STATUS_INT_ENABLED, &priv->status);
4466
4467
4468 iwl3945_write32(priv, CSR_INT_MASK, 0x00000000);
4469
4470
4471
4472 iwl3945_write32(priv, CSR_INT, 0xffffffff);
4473 iwl3945_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
4474 IWL_DEBUG_ISR("Disabled interrupts\n");
4475}
4476
4477static const char *desc_lookup(int i)
4478{
4479 switch (i) {
4480 case 1:
4481 return "FAIL";
4482 case 2:
4483 return "BAD_PARAM";
4484 case 3:
4485 return "BAD_CHECKSUM";
4486 case 4:
4487 return "NMI_INTERRUPT";
4488 case 5:
4489 return "SYSASSERT";
4490 case 6:
4491 return "FATAL_ERROR";
4492 }
4493
4494 return "UNKNOWN";
4495}
4496
4497#define ERROR_START_OFFSET (1 * sizeof(u32))
4498#define ERROR_ELEM_SIZE (7 * sizeof(u32))
4499
4500static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv)
4501{
4502 u32 i;
4503 u32 desc, time, count, base, data1;
4504 u32 blink1, blink2, ilink1, ilink2;
4505 int rc;
4506
4507 base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
4508
4509 if (!iwl3945_hw_valid_rtc_data_addr(base)) {
4510 IWL_ERROR("Not valid error log pointer 0x%08X\n", base);
4511 return;
4512 }
4513
4514 rc = iwl3945_grab_nic_access(priv);
4515 if (rc) {
4516 IWL_WARNING("Can not read from adapter at this time.\n");
4517 return;
4518 }
4519
4520 count = iwl3945_read_targ_mem(priv, base);
4521
4522 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
4523 IWL_ERROR("Start IWL Error Log Dump:\n");
4524 IWL_ERROR("Status: 0x%08lX, Config: %08X count: %d\n",
4525 priv->status, priv->config, count);
4526 }
4527
4528 IWL_ERROR("Desc Time asrtPC blink2 "
4529 "ilink1 nmiPC Line\n");
4530 for (i = ERROR_START_OFFSET;
4531 i < (count * ERROR_ELEM_SIZE) + ERROR_START_OFFSET;
4532 i += ERROR_ELEM_SIZE) {
4533 desc = iwl3945_read_targ_mem(priv, base + i);
4534 time =
4535 iwl3945_read_targ_mem(priv, base + i + 1 * sizeof(u32));
4536 blink1 =
4537 iwl3945_read_targ_mem(priv, base + i + 2 * sizeof(u32));
4538 blink2 =
4539 iwl3945_read_targ_mem(priv, base + i + 3 * sizeof(u32));
4540 ilink1 =
4541 iwl3945_read_targ_mem(priv, base + i + 4 * sizeof(u32));
4542 ilink2 =
4543 iwl3945_read_targ_mem(priv, base + i + 5 * sizeof(u32));
4544 data1 =
4545 iwl3945_read_targ_mem(priv, base + i + 6 * sizeof(u32));
4546
4547 IWL_ERROR
4548 ("%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n",
4549 desc_lookup(desc), desc, time, blink1, blink2,
4550 ilink1, ilink2, data1);
4551 }
4552
4553 iwl3945_release_nic_access(priv);
4554
4555}
4556
4557#define EVENT_START_OFFSET (6 * sizeof(u32))
4558
4559
4560
4561
4562
4563
4564static void iwl3945_print_event_log(struct iwl3945_priv *priv, u32 start_idx,
4565 u32 num_events, u32 mode)
4566{
4567 u32 i;
4568 u32 base;
4569 u32 event_size;
4570 u32 ptr;
4571 u32 ev, time, data;
4572
4573 if (num_events == 0)
4574 return;
4575
4576 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
4577
4578 if (mode == 0)
4579 event_size = 2 * sizeof(u32);
4580 else
4581 event_size = 3 * sizeof(u32);
4582
4583 ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
4584
4585
4586
4587 for (i = 0; i < num_events; i++) {
4588 ev = iwl3945_read_targ_mem(priv, ptr);
4589 ptr += sizeof(u32);
4590 time = iwl3945_read_targ_mem(priv, ptr);
4591 ptr += sizeof(u32);
4592 if (mode == 0)
4593 IWL_ERROR("0x%08x\t%04u\n", time, ev);
4594 else {
4595 data = iwl3945_read_targ_mem(priv, ptr);
4596 ptr += sizeof(u32);
4597 IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev);
4598 }
4599 }
4600}
4601
4602static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv)
4603{
4604 int rc;
4605 u32 base;
4606 u32 capacity;
4607 u32 mode;
4608 u32 num_wraps;
4609 u32 next_entry;
4610 u32 size;
4611
4612 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
4613 if (!iwl3945_hw_valid_rtc_data_addr(base)) {
4614 IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
4615 return;
4616 }
4617
4618 rc = iwl3945_grab_nic_access(priv);
4619 if (rc) {
4620 IWL_WARNING("Can not read from adapter at this time.\n");
4621 return;
4622 }
4623
4624
4625 capacity = iwl3945_read_targ_mem(priv, base);
4626 mode = iwl3945_read_targ_mem(priv, base + (1 * sizeof(u32)));
4627 num_wraps = iwl3945_read_targ_mem(priv, base + (2 * sizeof(u32)));
4628 next_entry