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#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/slab.h>
31#include <linux/pci.h>
32#include <linux/dma-mapping.h>
33#include <linux/delay.h>
34#include <linux/sched.h>
35#include <linux/skbuff.h>
36#include <linux/netdevice.h>
37#include <linux/wireless.h>
38#include <linux/firmware.h>
39#include <linux/etherdevice.h>
40#include <asm/unaligned.h>
41#include <net/mac80211.h>
42
43#include "iwl-fh.h"
44#include "iwl-3945-fh.h"
45#include "iwl-commands.h"
46#include "iwl-sta.h"
47#include "iwl-3945.h"
48#include "iwl-eeprom.h"
49#include "iwl-core.h"
50#include "iwl-helpers.h"
51#include "iwl-led.h"
52#include "iwl-3945-led.h"
53
54#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \
55 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
56 IWL_RATE_##r##M_IEEE, \
57 IWL_RATE_##ip##M_INDEX, \
58 IWL_RATE_##in##M_INDEX, \
59 IWL_RATE_##rp##M_INDEX, \
60 IWL_RATE_##rn##M_INDEX, \
61 IWL_RATE_##pp##M_INDEX, \
62 IWL_RATE_##np##M_INDEX, \
63 IWL_RATE_##r##M_INDEX_TABLE, \
64 IWL_RATE_##ip##M_INDEX_TABLE }
65
66
67
68
69
70
71
72
73
74const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = {
75 IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2),
76 IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5),
77 IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11),
78 IWL_DECLARE_RATE_INFO(11, 9, 12, 5, 12, 5, 18),
79 IWL_DECLARE_RATE_INFO(6, 5, 9, 5, 11, 5, 11),
80 IWL_DECLARE_RATE_INFO(9, 6, 11, 5, 11, 5, 11),
81 IWL_DECLARE_RATE_INFO(12, 11, 18, 11, 18, 11, 18),
82 IWL_DECLARE_RATE_INFO(18, 12, 24, 12, 24, 11, 24),
83 IWL_DECLARE_RATE_INFO(24, 18, 36, 18, 36, 18, 36),
84 IWL_DECLARE_RATE_INFO(36, 24, 48, 24, 48, 24, 48),
85 IWL_DECLARE_RATE_INFO(48, 36, 54, 36, 54, 36, 54),
86 IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),
87};
88
89
90#define IWL_EVT_DISABLE (0)
91#define IWL_EVT_DISABLE_SIZE (1532/32)
92
93
94
95
96
97
98
99
100
101
102void iwl3945_disable_events(struct iwl_priv *priv)
103{
104 int i;
105 u32 base;
106 u32 disable_ptr;
107 u32 array_size;
108 u32 evt_disable[IWL_EVT_DISABLE_SIZE] = {
109 0x00000000,
110 0x00000000,
111 0x00000000,
112 0x00000000,
113 0x00000000,
114 0x00000000,
115 0x00000000,
116 0x00000000,
117 0x00000000,
118 0x00000000,
119 0x00000000,
120 0x00000000,
121 0x00000000,
122 0x00000000,
123 0x00000000,
124 0x00000000,
125 0x00000000,
126 0x00000000,
127 0x00000000,
128 0x00000000,
129 0x00000000,
130 0x00000000,
131 0x00000000,
132 0x00000000,
133 0x00000000,
134 0x00000000,
135 0x00000000,
136 0x00000000,
137 0x00000000,
138 0x00000000,
139 0x00000000,
140 0x00000000,
141 0x00000000,
142 0x00000000,
143 0x00000000,
144 0x00000000,
145 0x00000000,
146 0x00000000,
147 0x00000000,
148 0x00000000,
149 0x00000000,
150 0x00000000,
151 0x00000000,
152 0x00000000,
153 0x00000000,
154 0x00000000,
155 0x00000000,
156 };
157
158 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
159 if (!iwl3945_hw_valid_rtc_data_addr(base)) {
160 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
161 return;
162 }
163
164 disable_ptr = iwl_read_targ_mem(priv, base + (4 * sizeof(u32)));
165 array_size = iwl_read_targ_mem(priv, base + (5 * sizeof(u32)));
166
167 if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) {
168 IWL_DEBUG_INFO(priv, "Disabling selected uCode log events at 0x%x\n",
169 disable_ptr);
170 for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++)
171 iwl_write_targ_mem(priv,
172 disable_ptr + (i * sizeof(u32)),
173 evt_disable[i]);
174
175 } else {
176 IWL_DEBUG_INFO(priv, "Selected uCode log events may be disabled\n");
177 IWL_DEBUG_INFO(priv, " by writing \"1\"s into disable bitmap\n");
178 IWL_DEBUG_INFO(priv, " in SRAM at 0x%x, size %d u32s\n",
179 disable_ptr, array_size);
180 }
181
182}
183
184static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
185{
186 int idx;
187
188 for (idx = 0; idx < IWL_RATE_COUNT_3945; idx++)
189 if (iwl3945_rates[idx].plcp == plcp)
190 return idx;
191 return -1;
192}
193
194#ifdef CONFIG_IWLWIFI_DEBUG
195#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
196
197static const char *iwl3945_get_tx_fail_reason(u32 status)
198{
199 switch (status & TX_STATUS_MSK) {
200 case TX_STATUS_SUCCESS:
201 return "SUCCESS";
202 TX_STATUS_ENTRY(SHORT_LIMIT);
203 TX_STATUS_ENTRY(LONG_LIMIT);
204 TX_STATUS_ENTRY(FIFO_UNDERRUN);
205 TX_STATUS_ENTRY(MGMNT_ABORT);
206 TX_STATUS_ENTRY(NEXT_FRAG);
207 TX_STATUS_ENTRY(LIFE_EXPIRE);
208 TX_STATUS_ENTRY(DEST_PS);
209 TX_STATUS_ENTRY(ABORTED);
210 TX_STATUS_ENTRY(BT_RETRY);
211 TX_STATUS_ENTRY(STA_INVALID);
212 TX_STATUS_ENTRY(FRAG_DROPPED);
213 TX_STATUS_ENTRY(TID_DISABLE);
214 TX_STATUS_ENTRY(FRAME_FLUSHED);
215 TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL);
216 TX_STATUS_ENTRY(TX_LOCKED);
217 TX_STATUS_ENTRY(NO_BEACON_ON_RADAR);
218 }
219
220 return "UNKNOWN";
221}
222#else
223static inline const char *iwl3945_get_tx_fail_reason(u32 status)
224{
225 return "";
226}
227#endif
228
229
230
231
232
233
234int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate)
235{
236 int next_rate = iwl3945_get_prev_ieee_rate(rate);
237
238 switch (priv->band) {
239 case IEEE80211_BAND_5GHZ:
240 if (rate == IWL_RATE_12M_INDEX)
241 next_rate = IWL_RATE_9M_INDEX;
242 else if (rate == IWL_RATE_6M_INDEX)
243 next_rate = IWL_RATE_6M_INDEX;
244 break;
245 case IEEE80211_BAND_2GHZ:
246 if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
247 iwl_is_associated(priv)) {
248 if (rate == IWL_RATE_11M_INDEX)
249 next_rate = IWL_RATE_5M_INDEX;
250 }
251 break;
252
253 default:
254 break;
255 }
256
257 return next_rate;
258}
259
260
261
262
263
264
265
266
267
268static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
269 int txq_id, int index)
270{
271 struct iwl_tx_queue *txq = &priv->txq[txq_id];
272 struct iwl_queue *q = &txq->q;
273 struct iwl_tx_info *tx_info;
274
275 BUG_ON(txq_id == IWL_CMD_QUEUE_NUM);
276
277 for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
278 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
279
280 tx_info = &txq->txb[txq->q.read_ptr];
281 ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]);
282 tx_info->skb[0] = NULL;
283 priv->cfg->ops->lib->txq_free_tfd(priv, txq);
284 }
285
286 if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
287 (txq_id != IWL_CMD_QUEUE_NUM) &&
288 priv->mac80211_registered)
289 iwl_wake_queue(priv, txq_id);
290}
291
292
293
294
295static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
296 struct iwl_rx_mem_buffer *rxb)
297{
298 struct iwl_rx_packet *pkt = rxb_addr(rxb);
299 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
300 int txq_id = SEQ_TO_QUEUE(sequence);
301 int index = SEQ_TO_INDEX(sequence);
302 struct iwl_tx_queue *txq = &priv->txq[txq_id];
303 struct ieee80211_tx_info *info;
304 struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
305 u32 status = le32_to_cpu(tx_resp->status);
306 int rate_idx;
307 int fail;
308
309 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
310 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
311 "is out of range [0-%d] %d %d\n", txq_id,
312 index, txq->q.n_bd, txq->q.write_ptr,
313 txq->q.read_ptr);
314 return;
315 }
316
317 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
318 ieee80211_tx_info_clear_status(info);
319
320
321 rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate);
322 if (info->band == IEEE80211_BAND_5GHZ)
323 rate_idx -= IWL_FIRST_OFDM_RATE;
324
325 fail = tx_resp->failure_frame;
326
327 info->status.rates[0].idx = rate_idx;
328 info->status.rates[0].count = fail + 1;
329
330
331 info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ?
332 IEEE80211_TX_STAT_ACK : 0;
333
334 IWL_DEBUG_TX(priv, "Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
335 txq_id, iwl3945_get_tx_fail_reason(status), status,
336 tx_resp->rate, tx_resp->failure_frame);
337
338 IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index);
339 iwl3945_tx_queue_reclaim(priv, txq_id, index);
340
341 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
342 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
343}
344
345
346
347
348
349
350
351
352
353
354
355void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
356 struct iwl_rx_mem_buffer *rxb)
357{
358 struct iwl_rx_packet *pkt = rxb_addr(rxb);
359 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
360 (int)sizeof(struct iwl3945_notif_statistics),
361 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
362
363 memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39));
364}
365
366
367
368
369
370
371#ifdef CONFIG_IWLWIFI_DEBUG
372
373
374
375
376
377
378
379
380static void _iwl3945_dbg_report_frame(struct iwl_priv *priv,
381 struct iwl_rx_packet *pkt,
382 struct ieee80211_hdr *header, int group100)
383{
384 u32 to_us;
385 u32 print_summary = 0;
386 u32 print_dump = 0;
387 u32 hundred = 0;
388 u32 dataframe = 0;
389 __le16 fc;
390 u16 seq_ctl;
391 u16 channel;
392 u16 phy_flags;
393 u16 length;
394 u16 status;
395 u16 bcn_tmr;
396 u32 tsf_low;
397 u64 tsf;
398 u8 rssi;
399 u8 agc;
400 u16 sig_avg;
401 u16 noise_diff;
402 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
403 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
404 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
405 u8 *data = IWL_RX_DATA(pkt);
406
407
408 fc = header->frame_control;
409 seq_ctl = le16_to_cpu(header->seq_ctrl);
410
411
412 channel = le16_to_cpu(rx_hdr->channel);
413 phy_flags = le16_to_cpu(rx_hdr->phy_flags);
414 length = le16_to_cpu(rx_hdr->len);
415
416
417 status = le32_to_cpu(rx_end->status);
418 bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
419 tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
420 tsf = le64_to_cpu(rx_end->timestamp);
421
422
423 rssi = rx_stats->rssi;
424 agc = rx_stats->agc;
425 sig_avg = le16_to_cpu(rx_stats->sig_avg);
426 noise_diff = le16_to_cpu(rx_stats->noise_diff);
427
428 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
429
430
431
432 if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
433 cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
434 dataframe = 1;
435 if (!group100)
436 print_summary = 1;
437 else if (priv->framecnt_to_us < 100) {
438 priv->framecnt_to_us++;
439 print_summary = 0;
440 } else {
441 priv->framecnt_to_us = 0;
442 print_summary = 1;
443 hundred = 1;
444 }
445 } else {
446
447 print_summary = 1;
448 }
449
450 if (print_summary) {
451 char *title;
452 int rate;
453
454 if (hundred)
455 title = "100Frames";
456 else if (ieee80211_has_retry(fc))
457 title = "Retry";
458 else if (ieee80211_is_assoc_resp(fc))
459 title = "AscRsp";
460 else if (ieee80211_is_reassoc_resp(fc))
461 title = "RasRsp";
462 else if (ieee80211_is_probe_resp(fc)) {
463 title = "PrbRsp";
464 print_dump = 1;
465 } else if (ieee80211_is_beacon(fc)) {
466 title = "Beacon";
467 print_dump = 1;
468 } else if (ieee80211_is_atim(fc))
469 title = "ATIM";
470 else if (ieee80211_is_auth(fc))
471 title = "Auth";
472 else if (ieee80211_is_deauth(fc))
473 title = "DeAuth";
474 else if (ieee80211_is_disassoc(fc))
475 title = "DisAssoc";
476 else
477 title = "Frame";
478
479 rate = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate);
480 if (rate == -1)
481 rate = 0;
482 else
483 rate = iwl3945_rates[rate].ieee / 2;
484
485
486
487
488 if (dataframe)
489 IWL_DEBUG_RX(priv, "%s: mhd=0x%04x, dst=0x%02x, "
490 "len=%u, rssi=%d, chnl=%d, rate=%d, \n",
491 title, le16_to_cpu(fc), header->addr1[5],
492 length, rssi, channel, rate);
493 else {
494
495 IWL_DEBUG_RX(priv, "%s: 0x%04x, dst=0x%02x, "
496 "src=0x%02x, rssi=%u, tim=%lu usec, "
497 "phy=0x%02x, chnl=%d\n",
498 title, le16_to_cpu(fc), header->addr1[5],
499 header->addr3[5], rssi,
500 tsf_low - priv->scan_start_tsf,
501 phy_flags, channel);
502 }
503 }
504 if (print_dump)
505 iwl_print_hex_dump(priv, IWL_DL_RX, data, length);
506}
507
508static void iwl3945_dbg_report_frame(struct iwl_priv *priv,
509 struct iwl_rx_packet *pkt,
510 struct ieee80211_hdr *header, int group100)
511{
512 if (iwl_get_debug_level(priv) & IWL_DL_RX)
513 _iwl3945_dbg_report_frame(priv, pkt, header, group100);
514}
515
516#else
517static inline void iwl3945_dbg_report_frame(struct iwl_priv *priv,
518 struct iwl_rx_packet *pkt,
519 struct ieee80211_hdr *header, int group100)
520{
521}
522#endif
523
524
525static int iwl3945_is_network_packet(struct iwl_priv *priv,
526 struct ieee80211_hdr *header)
527{
528
529
530 switch (priv->iw_mode) {
531 case NL80211_IFTYPE_ADHOC:
532
533 return !compare_ether_addr(header->addr3, priv->bssid);
534 case NL80211_IFTYPE_STATION:
535
536 return !compare_ether_addr(header->addr2, priv->bssid);
537 default:
538 return 1;
539 }
540}
541
542static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
543 struct iwl_rx_mem_buffer *rxb,
544 struct ieee80211_rx_status *stats)
545{
546 struct iwl_rx_packet *pkt = rxb_addr(rxb);
547 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
548 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
549 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
550 u16 len = le16_to_cpu(rx_hdr->len);
551 struct sk_buff *skb;
552 int ret;
553 __le16 fc = hdr->frame_control;
554
555
556 if (unlikely(len + IWL39_RX_FRAME_SIZE >
557 PAGE_SIZE << priv->hw_params.rx_page_order)) {
558 IWL_DEBUG_DROP(priv, "Corruption detected!\n");
559 return;
560 }
561
562
563 if (unlikely(!priv->is_open)) {
564 IWL_DEBUG_DROP_LIMIT(priv,
565 "Dropping packet while interface is not open.\n");
566 return;
567 }
568
569 skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC);
570 if (!skb) {
571 IWL_ERR(priv, "alloc_skb failed\n");
572 return;
573 }
574
575 if (!iwl3945_mod_params.sw_crypto)
576 iwl_set_decrypted_flag(priv,
577 (struct ieee80211_hdr *)rxb_addr(rxb),
578 le32_to_cpu(rx_end->status), stats);
579
580 skb_reserve(skb, IWL_LINK_HDR_MAX);
581 skb_add_rx_frag(skb, 0, rxb->page,
582 (void *)rx_hdr->payload - (void *)pkt, len);
583
584
585
586
587 if (ieee80211_is_mgmt(fc) ||
588 ieee80211_has_protected(fc) ||
589 ieee80211_has_morefrags(fc) ||
590 le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)
591 ret = skb_linearize(skb);
592 else
593 ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ?
594 0 : -ENOMEM;
595
596 if (ret) {
597 kfree_skb(skb);
598 goto out;
599 }
600
601
602
603
604
605
606 iwl_update_stats(priv, false, fc, len);
607 memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
608
609 ieee80211_rx(priv->hw, skb);
610 out:
611 priv->alloc_rxb_page--;
612 rxb->page = NULL;
613}
614
615#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
616
617static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
618 struct iwl_rx_mem_buffer *rxb)
619{
620 struct ieee80211_hdr *header;
621 struct ieee80211_rx_status rx_status;
622 struct iwl_rx_packet *pkt = rxb_addr(rxb);
623 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
624 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
625 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
626 int snr;
627 u16 rx_stats_sig_avg = le16_to_cpu(rx_stats->sig_avg);
628 u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff);
629 u8 network_packet;
630
631 rx_status.flag = 0;
632 rx_status.mactime = le64_to_cpu(rx_end->timestamp);
633 rx_status.freq =
634 ieee80211_channel_to_frequency(le16_to_cpu(rx_hdr->channel));
635 rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
636 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
637
638 rx_status.rate_idx = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate);
639 if (rx_status.band == IEEE80211_BAND_5GHZ)
640 rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
641
642 rx_status.antenna = (le16_to_cpu(rx_hdr->phy_flags) &
643 RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4;
644
645
646 if (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
647 rx_status.flag |= RX_FLAG_SHORTPRE;
648
649 if ((unlikely(rx_stats->phy_count > 20))) {
650 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
651 rx_stats->phy_count);
652 return;
653 }
654
655 if (!(rx_end->status & RX_RES_STATUS_NO_CRC32_ERROR)
656 || !(rx_end->status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
657 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n", rx_end->status);
658 return;
659 }
660
661
662
663
664 rx_status.signal = rx_stats->rssi - IWL39_RSSI_OFFSET;
665
666
667 if (priv->last_rx_noise == 0)
668 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
669
670
671
672
673
674
675
676
677
678
679
680
681 if (rx_stats_noise_diff) {
682 snr = rx_stats_sig_avg / rx_stats_noise_diff;
683 rx_status.noise = rx_status.signal -
684 iwl3945_calc_db_from_ratio(snr);
685 } else {
686 rx_status.noise = priv->last_rx_noise;
687 }
688
689
690 IWL_DEBUG_STATS(priv, "Rssi %d noise %d sig_avg %d noise_diff %d\n",
691 rx_status.signal, rx_status.noise,
692 rx_stats_sig_avg, rx_stats_noise_diff);
693
694 header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
695
696 network_packet = iwl3945_is_network_packet(priv, header);
697
698 IWL_DEBUG_STATS_LIMIT(priv, "[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n",
699 network_packet ? '*' : ' ',
700 le16_to_cpu(rx_hdr->channel),
701 rx_status.signal, rx_status.signal,
702 rx_status.noise, rx_status.rate_idx);
703
704
705 iwl3945_dbg_report_frame(priv, pkt, header, 1);
706 iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header);
707
708 if (network_packet) {
709 priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
710 priv->last_tsf = le64_to_cpu(rx_end->timestamp);
711 priv->last_rx_rssi = rx_status.signal;
712 priv->last_rx_noise = rx_status.noise;
713 }
714
715 iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
716}
717
718int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
719 struct iwl_tx_queue *txq,
720 dma_addr_t addr, u16 len, u8 reset, u8 pad)
721{
722 int count;
723 struct iwl_queue *q;
724 struct iwl3945_tfd *tfd, *tfd_tmp;
725
726 q = &txq->q;
727 tfd_tmp = (struct iwl3945_tfd *)txq->tfds;
728 tfd = &tfd_tmp[q->write_ptr];
729
730 if (reset)
731 memset(tfd, 0, sizeof(*tfd));
732
733 count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));
734
735 if ((count >= NUM_TFD_CHUNKS) || (count < 0)) {
736 IWL_ERR(priv, "Error can not send more than %d chunks\n",
737 NUM_TFD_CHUNKS);
738 return -EINVAL;
739 }
740
741 tfd->tbs[count].addr = cpu_to_le32(addr);
742 tfd->tbs[count].len = cpu_to_le32(len);
743
744 count++;
745
746 tfd->control_flags = cpu_to_le32(TFD_CTL_COUNT_SET(count) |
747 TFD_CTL_PAD_SET(pad));
748
749 return 0;
750}
751
752
753
754
755
756
757void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
758{
759 struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)txq->tfds;
760 int index = txq->q.read_ptr;
761 struct iwl3945_tfd *tfd = &tfd_tmp[index];
762 struct pci_dev *dev = priv->pci_dev;
763 int i;
764 int counter;
765
766
767 counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));
768 if (counter > NUM_TFD_CHUNKS) {
769 IWL_ERR(priv, "Too many chunks: %i\n", counter);
770
771 return;
772 }
773
774
775 if (counter)
776 pci_unmap_single(dev,
777 pci_unmap_addr(&txq->meta[index], mapping),
778 pci_unmap_len(&txq->meta[index], len),
779 PCI_DMA_TODEVICE);
780
781
782
783 for (i = 1; i < counter; i++) {
784 pci_unmap_single(dev, le32_to_cpu(tfd->tbs[i].addr),
785 le32_to_cpu(tfd->tbs[i].len), PCI_DMA_TODEVICE);
786 if (txq->txb[txq->q.read_ptr].skb[0]) {
787 struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[0];
788 if (txq->txb[txq->q.read_ptr].skb[0]) {
789
790 dev_kfree_skb_any(skb);
791 txq->txb[txq->q.read_ptr].skb[0] = NULL;
792 }
793 }
794 }
795 return ;
796}
797
798
799
800
801
802void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
803 struct iwl_device_cmd *cmd,
804 struct ieee80211_tx_info *info,
805 struct ieee80211_hdr *hdr,
806 int sta_id, int tx_id)
807{
808 u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
809 u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT_3945);
810 u16 rate_mask;
811 int rate;
812 u8 rts_retry_limit;
813 u8 data_retry_limit;
814 __le32 tx_flags;
815 __le16 fc = hdr->frame_control;
816 struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
817
818 rate = iwl3945_rates[rate_index].plcp;
819 tx_flags = tx_cmd->tx_flags;
820
821
822
823 rate_mask = IWL_RATES_MASK;
824
825
826
827 if (ieee80211_is_probe_resp(fc))
828 data_retry_limit = 3;
829 else
830 data_retry_limit = IWL_DEFAULT_TX_RETRY;
831 tx_cmd->data_retry_limit = data_retry_limit;
832
833 if (tx_id >= IWL_CMD_QUEUE_NUM)
834 rts_retry_limit = 3;
835 else
836 rts_retry_limit = 7;
837
838 if (data_retry_limit < rts_retry_limit)
839 rts_retry_limit = data_retry_limit;
840 tx_cmd->rts_retry_limit = rts_retry_limit;
841
842 if (ieee80211_is_mgmt(fc)) {
843 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
844 case cpu_to_le16(IEEE80211_STYPE_AUTH):
845 case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
846 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
847 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
848 if (tx_flags & TX_CMD_FLG_RTS_MSK) {
849 tx_flags &= ~TX_CMD_FLG_RTS_MSK;
850 tx_flags |= TX_CMD_FLG_CTS_MSK;
851 }
852 break;
853 default:
854 break;
855 }
856 }
857
858 tx_cmd->rate = rate;
859 tx_cmd->tx_flags = tx_flags;
860
861
862 tx_cmd->supp_rates[0] =
863 ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF;
864
865
866 tx_cmd->supp_rates[1] = (rate_mask & 0xF);
867
868 IWL_DEBUG_RATE(priv, "Tx sta id: %d, rate: %d (plcp), flags: 0x%4X "
869 "cck/ofdm mask: 0x%x/0x%x\n", sta_id,
870 tx_cmd->rate, le32_to_cpu(tx_cmd->tx_flags),
871 tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]);
872}
873
874u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
875{
876 unsigned long flags_spin;
877 struct iwl_station_entry *station;
878
879 if (sta_id == IWL_INVALID_STATION)
880 return IWL_INVALID_STATION;
881
882 spin_lock_irqsave(&priv->sta_lock, flags_spin);
883 station = &priv->stations[sta_id];
884
885 station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
886 station->sta.rate_n_flags = cpu_to_le16(tx_rate);
887 station->sta.mode = STA_CONTROL_MODIFY_MSK;
888
889 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
890
891 iwl_send_add_sta(priv, &station->sta, flags);
892 IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n",
893 sta_id, tx_rate);
894 return sta_id;
895}
896
897static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
898{
899 if (src == IWL_PWR_SRC_VAUX) {
900 if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) {
901 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
902 APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
903 ~APMG_PS_CTRL_MSK_PWR_SRC);
904
905 iwl_poll_bit(priv, CSR_GPIO_IN,
906 CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
907 CSR_GPIO_IN_BIT_AUX_POWER, 5000);
908 }
909 } else {
910 iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
911 APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
912 ~APMG_PS_CTRL_MSK_PWR_SRC);
913
914 iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
915 CSR_GPIO_IN_BIT_AUX_POWER, 5000);
916 }
917
918 return 0;
919}
920
921static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
922{
923 iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->dma_addr);
924 iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma);
925 iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0);
926 iwl_write_direct32(priv, FH39_RCSR_CONFIG(0),
927 FH39_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE |
928 FH39_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE |
929 FH39_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN |
930 FH39_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 |
931 (RX_QUEUE_SIZE_LOG << FH39_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) |
932 FH39_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST |
933 (1 << FH39_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) |
934 FH39_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH);
935
936
937 iwl_read_direct32(priv, FH39_RSSR_CTRL);
938
939 return 0;
940}
941
942static int iwl3945_tx_reset(struct iwl_priv *priv)
943{
944
945
946 iwl_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
947
948
949 iwl_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01);
950
951
952 iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f);
953
954 iwl_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000);
955 iwl_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002);
956 iwl_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004);
957 iwl_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
958
959 iwl_write_direct32(priv, FH39_TSSR_CBB_BASE,
960 priv->shared_phys);
961
962 iwl_write_direct32(priv, FH39_TSSR_MSG_CONFIG,
963 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |
964 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON |
965 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B |
966 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON |
967 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON |
968 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH |
969 FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH);
970
971
972 return 0;
973}
974
975
976
977
978
979
980static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
981{
982 int rc;
983 int txq_id, slots_num;
984
985 iwl3945_hw_txq_ctx_free(priv);
986
987
988 rc = iwl_alloc_txq_mem(priv);
989 if (rc)
990 return rc;
991
992
993 rc = iwl3945_tx_reset(priv);
994 if (rc)
995 goto error;
996
997
998 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
999 slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
1000 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
1001 rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
1002 txq_id);
1003 if (rc) {
1004 IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
1005 goto error;
1006 }
1007 }
1008
1009 return rc;
1010
1011 error:
1012 iwl3945_hw_txq_ctx_free(priv);
1013 return rc;
1014}
1015
1016
1017
1018
1019
1020
1021
1022static int iwl3945_apm_init(struct iwl_priv *priv)
1023{
1024 int ret = iwl_apm_init(priv);
1025
1026
1027 iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
1028 iwl_write_prph(priv, APMG_RTC_INT_STT_REG, 0xFFFFFFFF);
1029
1030
1031 iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ);
1032 udelay(5);
1033 iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ);
1034
1035 return ret;
1036}
1037
1038static void iwl3945_nic_config(struct iwl_priv *priv)
1039{
1040 struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
1041 unsigned long flags;
1042 u8 rev_id = 0;
1043
1044 spin_lock_irqsave(&priv->lock, flags);
1045
1046
1047 pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
1048
1049 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
1050
1051 if (rev_id & PCI_CFG_REV_ID_BIT_RTP)
1052 IWL_DEBUG_INFO(priv, "RTP type \n");
1053 else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
1054 IWL_DEBUG_INFO(priv, "3945 RADIO-MB type\n");
1055 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
1056 CSR39_HW_IF_CONFIG_REG_BIT_3945_MB);
1057 } else {
1058 IWL_DEBUG_INFO(priv, "3945 RADIO-MM type\n");
1059 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
1060 CSR39_HW_IF_CONFIG_REG_BIT_3945_MM);
1061 }
1062
1063 if (EEPROM_SKU_CAP_OP_MODE_MRC == eeprom->sku_cap) {
1064 IWL_DEBUG_INFO(priv, "SKU OP mode is mrc\n");
1065 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
1066 CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC);
1067 } else
1068 IWL_DEBUG_INFO(priv, "SKU OP mode is basic\n");
1069
1070 if ((eeprom->board_revision & 0xF0) == 0xD0) {
1071 IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n",
1072 eeprom->board_revision);
1073 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
1074 CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
1075 } else {
1076 IWL_DEBUG_INFO(priv, "3945ABG revision is 0x%X\n",
1077 eeprom->board_revision);
1078 iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
1079 CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
1080 }
1081
1082 if (eeprom->almgor_m_version <= 1) {
1083 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
1084 CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A);
1085 IWL_DEBUG_INFO(priv, "Card M type A version is 0x%X\n",
1086 eeprom->almgor_m_version);
1087 } else {
1088 IWL_DEBUG_INFO(priv, "Card M type B version is 0x%X\n",
1089 eeprom->almgor_m_version);
1090 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
1091 CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B);
1092 }
1093 spin_unlock_irqrestore(&priv->lock, flags);
1094
1095 if (eeprom->sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)
1096 IWL_DEBUG_RF_KILL(priv, "SW RF KILL supported in EEPROM.\n");
1097
1098 if (eeprom->sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)
1099 IWL_DEBUG_RF_KILL(priv, "HW RF KILL supported in EEPROM.\n");
1100}
1101
1102int iwl3945_hw_nic_init(struct iwl_priv *priv)
1103{
1104 int rc;
1105 unsigned long flags;
1106 struct iwl_rx_queue *rxq = &priv->rxq;
1107
1108 spin_lock_irqsave(&priv->lock, flags);
1109 priv->cfg->ops->lib->apm_ops.init(priv);
1110 spin_unlock_irqrestore(&priv->lock, flags);
1111
1112 rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
1113 if (rc)
1114 return rc;
1115
1116 priv->cfg->ops->lib->apm_ops.config(priv);
1117
1118
1119 if (!rxq->bd) {
1120 rc = iwl_rx_queue_alloc(priv);
1121 if (rc) {
1122 IWL_ERR(priv, "Unable to initialize Rx queue\n");
1123 return -ENOMEM;
1124 }
1125 } else
1126 iwl3945_rx_queue_reset(priv, rxq);
1127
1128 iwl3945_rx_replenish(priv);
1129
1130 iwl3945_rx_init(priv, rxq);
1131
1132
1133
1134
1135
1136
1137
1138 iwl_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7);
1139
1140 rc = iwl3945_txq_ctx_reset(priv);
1141 if (rc)
1142 return rc;
1143
1144 set_bit(STATUS_INIT, &priv->status);
1145
1146 return 0;
1147}
1148
1149
1150
1151
1152
1153
1154void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
1155{
1156 int txq_id;
1157
1158
1159 if (priv->txq)
1160 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
1161 txq_id++)
1162 if (txq_id == IWL_CMD_QUEUE_NUM)
1163 iwl_cmd_queue_free(priv);
1164 else
1165 iwl_tx_queue_free(priv, txq_id);
1166
1167
1168 iwl_free_txq_mem(priv);
1169}
1170
1171void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
1172{
1173 int txq_id;
1174
1175
1176 iwl_write_prph(priv, ALM_SCD_MODE_REG, 0);
1177 iwl_write_prph(priv, ALM_SCD_TXFACT_REG, 0);
1178
1179
1180 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
1181 iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0);
1182 iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS,
1183 FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
1184 1000);
1185 }
1186
1187 iwl3945_hw_txq_ctx_free(priv);
1188}
1189
1190
1191
1192
1193
1194static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading)
1195{
1196 return (new_reading - old_reading) * (-11) / 100;
1197}
1198
1199
1200
1201
1202static inline int iwl3945_hw_reg_temp_out_of_range(int temperature)
1203{
1204 return ((temperature < -260) || (temperature > 25)) ? 1 : 0;
1205}
1206
1207int iwl3945_hw_get_temperature(struct iwl_priv *priv)
1208{
1209 return iwl_read32(priv, CSR_UCODE_DRV_GP2);
1210}
1211
1212
1213
1214
1215
1216static int iwl3945_hw_reg_txpower_get_temperature(struct iwl_priv *priv)
1217{
1218 struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
1219 int temperature;
1220
1221 temperature = iwl3945_hw_get_temperature(priv);
1222
1223
1224
1225 IWL_DEBUG_INFO(priv, "Temperature: %d\n", temperature + IWL_TEMP_CONVERT);
1226
1227
1228 if (iwl3945_hw_reg_temp_out_of_range(temperature)) {
1229 IWL_ERR(priv, "Error bad temperature value %d\n", temperature);
1230
1231
1232
1233 if (priv->last_temperature > 100)
1234 temperature = eeprom->groups[2].temperature;
1235 else
1236 temperature = priv->last_temperature;
1237 }
1238
1239 return temperature;
1240}
1241
1242
1243
1244
1245#define IWL_TEMPERATURE_LIMIT_TIMER 6
1246
1247
1248
1249
1250
1251
1252
1253static int is_temp_calib_needed(struct iwl_priv *priv)
1254{
1255 int temp_diff;
1256
1257 priv->temperature = iwl3945_hw_reg_txpower_get_temperature(priv);
1258 temp_diff = priv->temperature - priv->last_temperature;
1259
1260
1261 if (temp_diff < 0) {
1262 IWL_DEBUG_POWER(priv, "Getting cooler, delta %d,\n", temp_diff);
1263 temp_diff = -temp_diff;
1264 } else if (temp_diff == 0)
1265 IWL_DEBUG_POWER(priv, "Same temp,\n");
1266 else
1267 IWL_DEBUG_POWER(priv, "Getting warmer, delta %d,\n", temp_diff);
1268
1269
1270 if (temp_diff < IWL_TEMPERATURE_LIMIT_TIMER) {
1271 IWL_DEBUG_POWER(priv, "Timed thermal calib not needed\n");
1272 return 0;
1273 }
1274
1275 IWL_DEBUG_POWER(priv, "Timed thermal calib needed\n");
1276
1277
1278
1279 priv->last_temperature = priv->temperature;
1280 return 1;
1281}
1282
1283#define IWL_MAX_GAIN_ENTRIES 78
1284#define IWL_CCK_FROM_OFDM_POWER_DIFF -5
1285#define IWL_CCK_FROM_OFDM_INDEX_DIFF (10)
1286
1287
1288
1289static struct iwl3945_tx_power power_gain_table[2][IWL_MAX_GAIN_ENTRIES] = {
1290 {
1291 {251, 127},
1292 {251, 127},
1293 {251, 127},
1294 {251, 127},
1295 {251, 125},
1296 {251, 110},
1297 {251, 105},
1298 {251, 98},
1299 {187, 125},
1300 {187, 115},
1301 {187, 108},
1302 {187, 99},
1303 {243, 119},
1304 {243, 111},
1305 {243, 105},
1306 {243, 97},
1307 {243, 92},
1308 {211, 106},
1309 {211, 100},
1310 {179, 120},
1311 {179, 113},
1312 {179, 107},
1313 {147, 125},
1314 {147, 119},
1315 {147, 112},
1316 {147, 106},
1317 {147, 101},
1318 {147, 97},
1319 {147, 91},
1320 {115, 107},
1321 {235, 121},
1322 {235, 115},
1323 {235, 109},
1324 {203, 127},
1325 {203, 121},
1326 {203, 115},
1327 {203, 108},
1328 {203, 102},
1329 {203, 96},
1330 {203, 92},
1331 {171, 110},
1332 {171, 104},
1333 {171, 98},
1334 {139, 116},
1335 {227, 125},
1336 {227, 119},
1337 {227, 113},
1338 {227, 107},
1339 {227, 101},
1340 {227, 96},
1341 {195, 113},
1342 {195, 106},
1343 {195, 102},
1344 {195, 95},
1345 {163, 113},
1346 {163, 106},
1347 {163, 102},
1348 {163, 95},
1349 {131, 113},
1350 {131, 106},
1351 {131, 102},
1352 {131, 95},
1353 {99, 113},
1354 {99, 106},
1355 {99, 102},
1356 {99, 95},
1357 {67, 113},
1358 {67, 106},
1359 {67, 102},
1360 {67, 95},
1361 {35, 113},
1362 {35, 106},
1363 {35, 102},
1364 {35, 95},
1365 {3, 113},
1366 {3, 106},
1367 {3, 102},
1368 {3, 95} },
1369 {
1370 {251, 127},
1371 {251, 120},
1372 {251, 114},
1373 {219, 119},
1374 {219, 101},
1375 {187, 113},
1376 {187, 102},
1377 {155, 114},
1378 {155, 103},
1379 {123, 117},
1380 {123, 107},
1381 {123, 99},
1382 {123, 92},
1383 {91, 108},
1384 {59, 125},
1385 {59, 118},
1386 {59, 109},
1387 {59, 102},
1388 {59, 96},
1389 {59, 90},
1390 {27, 104},
1391 {27, 98},
1392 {27, 92},
1393 {115, 118},
1394 {115, 111},
1395 {115, 104},
1396 {83, 126},
1397 {83, 121},
1398 {83, 113},
1399 {83, 105},
1400 {83, 99},
1401 {51, 118},
1402 {51, 111},
1403 {51, 104},
1404 {51, 98},
1405 {19, 116},
1406 {19, 109},
1407 {19, 102},
1408 {19, 98},
1409 {19, 93},
1410 {171, 113},
1411 {171, 107},
1412 {171, 99},
1413 {139, 120},
1414 {139, 113},
1415 {139, 107},
1416 {139, 99},
1417 {107, 120},
1418 {107, 113},
1419 {107, 107},
1420 {107, 99},
1421 {75, 120},
1422 {75, 113},
1423 {75, 107},
1424 {75, 99},
1425 {43, 120},
1426 {43, 113},
1427 {43, 107},
1428 {43, 99},
1429 {11, 120},
1430 {11, 113},
1431 {11, 107},
1432 {11, 99},
1433 {131, 107},
1434 {131, 99},
1435 {99, 120},
1436 {99, 113},
1437 {99, 107},
1438 {99, 99},
1439 {67, 120},
1440 {67, 113},
1441 {67, 107},
1442 {67, 99},
1443 {35, 120},
1444 {35, 113},
1445 {35, 107},
1446 {35, 99},
1447 {3, 120} }
1448};
1449
1450static inline u8 iwl3945_hw_reg_fix_power_index(int index)
1451{
1452 if (index < 0)
1453 return 0;
1454 if (index >= IWL_MAX_GAIN_ENTRIES)
1455 return IWL_MAX_GAIN_ENTRIES - 1;
1456 return (u8) index;
1457}
1458
1459
1460#define REG_RECALIB_PERIOD (60)
1461
1462
1463
1464
1465
1466
1467
1468static void iwl3945_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index,
1469 s32 rate_index, const s8 *clip_pwrs,
1470 struct iwl_channel_info *ch_info,
1471 int band_index)
1472{
1473 struct iwl3945_scan_power_info *scan_power_info;
1474 s8 power;
1475 u8 power_index;
1476
1477 scan_power_info = &ch_info->scan_pwr_info[scan_tbl_index];
1478
1479
1480
1481
1482 power = min(ch_info->scan_power, clip_pwrs[IWL_RATE_6M_INDEX_TABLE]);
1483
1484
1485
1486
1487 power = min(power, priv->tx_power_user_lmt);
1488 scan_power_info->requested_power = power;
1489
1490
1491
1492
1493
1494
1495 power_index = ch_info->power_info[rate_index].power_table_index
1496 - (power - ch_info->power_info
1497 [IWL_RATE_6M_INDEX_TABLE].requested_power) * 2;
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509 power_index = iwl3945_hw_reg_fix_power_index(power_index);
1510
1511 scan_power_info->power_table_index = power_index;
1512 scan_power_info->tpc.tx_gain =
1513 power_gain_table[band_index][power_index].tx_gain;
1514 scan_power_info->tpc.dsp_atten =
1515 power_gain_table[band_index][power_index].dsp_atten;
1516}
1517
1518
1519
1520
1521
1522
1523
1524static int iwl3945_send_tx_power(struct iwl_priv *priv)
1525{
1526 int rate_idx, i;
1527 const struct iwl_channel_info *ch_info = NULL;
1528 struct iwl3945_txpowertable_cmd txpower = {
1529 .channel = priv->active_rxon.channel,
1530 };
1531
1532 txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
1533 ch_info = iwl_get_channel_info(priv,
1534 priv->band,
1535 le16_to_cpu(priv->active_rxon.channel));
1536 if (!ch_info) {
1537 IWL_ERR(priv,
1538 "Failed to get channel info for channel %d [%d]\n",
1539 le16_to_cpu(priv->active_rxon.channel), priv->band);
1540 return -EINVAL;
1541 }
1542
1543 if (!is_channel_valid(ch_info)) {
1544 IWL_DEBUG_POWER(priv, "Not calling TX_PWR_TABLE_CMD on "
1545 "non-Tx channel.\n");
1546 return 0;
1547 }
1548
1549
1550
1551 for (rate_idx = IWL_FIRST_OFDM_RATE, i = 0;
1552 rate_idx <= IWL39_LAST_OFDM_RATE; rate_idx++, i++) {
1553
1554 txpower.power[i].tpc = ch_info->power_info[i].tpc;
1555 txpower.power[i].rate = iwl3945_rates[rate_idx].plcp;
1556
1557 IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
1558 le16_to_cpu(txpower.channel),
1559 txpower.band,
1560 txpower.power[i].tpc.tx_gain,
1561 txpower.power[i].tpc.dsp_atten,
1562 txpower.power[i].rate);
1563 }
1564
1565 for (rate_idx = IWL_FIRST_CCK_RATE;
1566 rate_idx <= IWL_LAST_CCK_RATE; rate_idx++, i++) {
1567 txpower.power[i].tpc = ch_info->power_info[i].tpc;
1568 txpower.power[i].rate = iwl3945_rates[rate_idx].plcp;
1569
1570 IWL_DEBUG_POWER(priv, "ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
1571 le16_to_cpu(txpower.channel),
1572 txpower.band,
1573 txpower.power[i].tpc.tx_gain,
1574 txpower.power[i].tpc.dsp_atten,
1575 txpower.power[i].rate);
1576 }
1577
1578 return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
1579 sizeof(struct iwl3945_txpowertable_cmd),
1580 &txpower);
1581
1582}
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600static int iwl3945_hw_reg_set_new_power(struct iwl_priv *priv,
1601 struct iwl_channel_info *ch_info)
1602{
1603 struct iwl3945_channel_power_info *power_info;
1604 int power_changed = 0;
1605 int i;
1606 const s8 *clip_pwrs;
1607 int power;
1608
1609
1610 clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
1611
1612
1613 power_info = ch_info->power_info;
1614
1615
1616 for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE;
1617 i++, ++power_info) {
1618 int delta_idx;
1619
1620
1621 power = min(ch_info->curr_txpow, clip_pwrs[i]);
1622 if (power == power_info->requested_power)
1623 continue;
1624
1625
1626
1627 delta_idx = (power - power_info->requested_power) * 2;
1628 power_info->base_power_index -= delta_idx;
1629
1630
1631 power_info->requested_power = power;
1632
1633 power_changed = 1;
1634 }
1635
1636
1637
1638 if (power_changed) {
1639 power =
1640 ch_info->power_info[IWL_RATE_12M_INDEX_TABLE].
1641 requested_power + IWL_CCK_FROM_OFDM_POWER_DIFF;
1642
1643
1644 for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++) {
1645 power_info->requested_power = power;
1646 power_info->base_power_index =
1647 ch_info->power_info[IWL_RATE_12M_INDEX_TABLE].
1648 base_power_index + IWL_CCK_FROM_OFDM_INDEX_DIFF;
1649 ++power_info;
1650 }
1651 }
1652
1653 return 0;
1654}
1655
1656
1657
1658
1659
1660
1661
1662
1663static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info)
1664{
1665 s8 max_power;
1666
1667#if 0
1668
1669 if (ch_info->tgd_data.max_power != 0)
1670 max_power = min(ch_info->tgd_data.max_power,
1671 ch_info->eeprom.max_power_avg);
1672
1673
1674 else
1675#endif
1676 max_power = ch_info->eeprom.max_power_avg;
1677
1678 return min(max_power, ch_info->max_power_avg);
1679}
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
1692{
1693 struct iwl_channel_info *ch_info = NULL;
1694 struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
1695 int delta_index;
1696 const s8 *clip_pwrs;
1697 u8 a_band;
1698 u8 rate_index;
1699 u8 scan_tbl_index;
1700 u8 i;
1701 int ref_temp;
1702 int temperature = priv->temperature;
1703
1704
1705 for (i = 0; i < priv->channel_count; i++) {
1706 ch_info = &priv->channel_info[i];
1707 a_band = is_channel_a_band(ch_info);
1708
1709
1710 ref_temp = (s16)eeprom->groups[ch_info->group_index].
1711 temperature;
1712
1713
1714
1715 delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature,
1716 ref_temp);
1717
1718
1719 for (rate_index = 0; rate_index < IWL_RATE_COUNT;
1720 rate_index++) {
1721 int power_idx =
1722 ch_info->power_info[rate_index].base_power_index;
1723
1724
1725 power_idx += delta_index;
1726
1727
1728 power_idx = iwl3945_hw_reg_fix_power_index(power_idx);
1729 ch_info->power_info[rate_index].
1730 power_table_index = (u8) power_idx;
1731 ch_info->power_info[rate_index].tpc =
1732 power_gain_table[a_band][power_idx];
1733 }
1734
1735
1736 clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
1737
1738
1739 for (scan_tbl_index = 0;
1740 scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) {
1741 s32 actual_index = (scan_tbl_index == 0) ?
1742 IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE;
1743 iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index,
1744 actual_index, clip_pwrs,
1745 ch_info, a_band);
1746 }
1747 }
1748
1749
1750 return priv->cfg->ops->lib->send_tx_power(priv);
1751}
1752
1753int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
1754{
1755 struct iwl_channel_info *ch_info;
1756 s8 max_power;
1757 u8 a_band;
1758 u8 i;
1759
1760 if (priv->tx_power_user_lmt == power) {
1761 IWL_DEBUG_POWER(priv, "Requested Tx power same as current "
1762 "limit: %ddBm.\n", power);
1763 return 0;
1764 }
1765
1766 IWL_DEBUG_POWER(priv, "Setting upper limit clamp to %ddBm.\n", power);
1767 priv->tx_power_user_lmt = power;
1768
1769
1770
1771 for (i = 0; i < priv->channel_count; i++) {
1772 ch_info = &priv->channel_info[i];
1773 a_band = is_channel_a_band(ch_info);
1774
1775
1776
1777 max_power = iwl3945_hw_reg_get_ch_txpower_limit(ch_info);
1778 max_power = min(power, max_power);
1779 if (max_power != ch_info->curr_txpow) {
1780 ch_info->curr_txpow = max_power;
1781
1782
1783 iwl3945_hw_reg_set_new_power(priv, ch_info);
1784 }
1785 }
1786
1787
1788
1789 is_temp_calib_needed(priv);
1790 iwl3945_hw_reg_comp_txpower_temp(priv);
1791
1792 return 0;
1793}
1794
1795static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
1796{
1797 int rc = 0;
1798 struct iwl_rx_packet *pkt;
1799 struct iwl3945_rxon_assoc_cmd rxon_assoc;
1800 struct iwl_host_cmd cmd = {
1801 .id = REPLY_RXON_ASSOC,
1802 .len = sizeof(rxon_assoc),
1803 .flags = CMD_WANT_SKB,
1804 .data = &rxon_assoc,
1805 };
1806 const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
1807 const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
1808
1809 if ((rxon1->flags == rxon2->flags) &&
1810 (rxon1->filter_flags == rxon2->filter_flags) &&
1811 (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
1812 (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
1813 IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
1814 return 0;
1815 }
1816
1817 rxon_assoc.flags = priv->staging_rxon.flags;
1818 rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
1819 rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
1820 rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
1821 rxon_assoc.reserved = 0;
1822
1823 rc = iwl_send_cmd_sync(priv, &cmd);
1824 if (rc)
1825 return rc;
1826
1827 pkt = (struct iwl_rx_packet *)cmd.reply_page;
1828 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
1829 IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
1830 rc = -EIO;
1831 }
1832
1833 iwl_free_pages(priv, cmd.reply_page);
1834
1835 return rc;
1836}
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846static int iwl3945_commit_rxon(struct iwl_priv *priv)
1847{
1848
1849 struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
1850 struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
1851 int rc = 0;
1852 bool new_assoc =
1853 !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
1854
1855 if (!iwl_is_alive(priv))
1856 return -1;
1857
1858
1859 staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;
1860
1861
1862 staging_rxon->flags &=
1863 ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
1864 staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
1865
1866 rc = iwl_check_rxon_cmd(priv);
1867 if (rc) {
1868 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
1869 return -EINVAL;
1870 }
1871
1872
1873
1874
1875 if (!iwl_full_rxon_required(priv)) {
1876 rc = iwl_send_rxon_assoc(priv);
1877 if (rc) {
1878 IWL_ERR(priv, "Error setting RXON_ASSOC "
1879 "configuration (%d).\n", rc);
1880 return rc;
1881 }
1882
1883 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
1884
1885 return 0;
1886 }
1887
1888
1889
1890
1891
1892 if (iwl_is_associated(priv) && new_assoc) {
1893 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
1894 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1895
1896
1897
1898
1899
1900 active_rxon->reserved4 = 0;
1901 active_rxon->reserved5 = 0;
1902 rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
1903 sizeof(struct iwl3945_rxon_cmd),
1904 &priv->active_rxon);
1905
1906
1907
1908 if (rc) {
1909 active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
1910 IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
1911 "configuration (%d).\n", rc);
1912 return rc;
1913 }
1914 }
1915
1916 IWL_DEBUG_INFO(priv, "Sending RXON\n"
1917 "* with%s RXON_FILTER_ASSOC_MSK\n"
1918 "* channel = %d\n"
1919 "* bssid = %pM\n",
1920 (new_assoc ? "" : "out"),
1921 le16_to_cpu(staging_rxon->channel),
1922 staging_rxon->bssid_addr);
1923
1924
1925
1926
1927
1928 staging_rxon->reserved4 = 0;
1929 staging_rxon->reserved5 = 0;
1930
1931 iwl_set_rxon_hwcrypto(priv, !iwl3945_mod_params.sw_crypto);
1932
1933
1934 rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
1935 sizeof(struct iwl3945_rxon_cmd),
1936 staging_rxon);
1937 if (rc) {
1938 IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
1939 return rc;
1940 }
1941
1942 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
1943
1944 iwl_clear_stations_table(priv);
1945
1946
1947
1948 rc = priv->cfg->ops->lib->send_tx_power(priv);
1949 if (rc) {
1950 IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
1951 return rc;
1952 }
1953
1954
1955 priv->cfg->ops->lib->add_bcast_station(priv);
1956
1957
1958
1959 if (iwl_is_associated(priv) &&
1960 (priv->iw_mode == NL80211_IFTYPE_STATION))
1961 if (iwl_add_station(priv, priv->active_rxon.bssid_addr,
1962 true, CMD_SYNC, NULL) == IWL_INVALID_STATION) {
1963 IWL_ERR(priv, "Error adding AP address for transmit\n");
1964 return -EIO;
1965 }
1966
1967
1968 rc = iwl3945_init_hw_rate_table(priv);
1969 if (rc) {
1970 IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
1971 return -EIO;
1972 }
1973
1974 return 0;
1975}
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987void iwl3945_reg_txpower_periodic(struct iwl_priv *priv)
1988{
1989
1990
1991 if (!is_temp_calib_needed(priv))
1992 goto reschedule;
1993
1994
1995
1996
1997 iwl3945_hw_reg_comp_txpower_temp(priv);
1998
1999 reschedule:
2000 queue_delayed_work(priv->workqueue,
2001 &priv->thermal_periodic, REG_RECALIB_PERIOD * HZ);
2002}
2003
2004static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
2005{
2006 struct iwl_priv *priv = container_of(work, struct iwl_priv,
2007 thermal_periodic.work);
2008
2009 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2010 return;
2011
2012 mutex_lock(&priv->mutex);
2013 iwl3945_reg_txpower_periodic(priv);
2014 mutex_unlock(&priv->mutex);
2015}
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl_priv *priv,
2029 const struct iwl_channel_info *ch_info)
2030{
2031 struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
2032 struct iwl3945_eeprom_txpower_group *ch_grp = &eeprom->groups[0];
2033 u8 group;
2034 u16 group_index = 0;
2035 u8 grp_channel;
2036
2037
2038 if (is_channel_a_band(ch_info)) {
2039 for (group = 1; group < 5; group++) {
2040 grp_channel = ch_grp[group].group_channel;
2041 if (ch_info->channel <= grp_channel) {
2042 group_index = group;
2043 break;
2044 }
2045 }
2046
2047 if (group == 5)
2048 group_index = 4;
2049 } else
2050 group_index = 0;
2051
2052 IWL_DEBUG_POWER(priv, "Chnl %d mapped to grp %d\n", ch_info->channel,
2053 group_index);
2054 return group_index;
2055}
2056
2057
2058
2059
2060
2061
2062
2063static int iwl3945_hw_reg_get_matched_power_index(struct iwl_priv *priv,
2064 s8 requested_power,
2065 s32 setting_index, s32 *new_index)
2066{
2067 const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL;
2068 struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
2069 s32 index0, index1;
2070 s32 power = 2 * requested_power;
2071 s32 i;
2072 const struct iwl3945_eeprom_txpower_sample *samples;
2073 s32 gains0, gains1;
2074 s32 res;
2075 s32 denominator;
2076
2077 chnl_grp = &eeprom->groups[setting_index];
2078 samples = chnl_grp->samples;
2079 for (i = 0; i < 5; i++) {
2080 if (power == samples[i].power) {
2081 *new_index = samples[i].gain_index;
2082 return 0;
2083 }
2084 }
2085
2086 if (power > samples[1].power) {
2087 index0 = 0;
2088 index1 = 1;
2089 } else if (power > samples[2].power) {
2090 index0 = 1;
2091 index1 = 2;
2092 } else if (power > samples[3].power) {
2093 index0 = 2;
2094 index1 = 3;
2095 } else {
2096 index0 = 3;
2097 index1 = 4;
2098 }
2099
2100 denominator = (s32) samples[index1].power - (s32) samples[index0].power;
2101 if (denominator == 0)
2102 return -EINVAL;
2103 gains0 = (s32) samples[index0].gain_index * (1 << 19);
2104 gains1 = (s32) samples[index1].gain_index * (1 << 19);
2105 res = gains0 + (gains1 - gains0) *
2106 ((s32) power - (s32) samples[index0].power) / denominator +
2107 (1 << 18);
2108 *new_index = res >> 19;
2109 return 0;
2110}
2111
2112static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv)
2113{
2114 u32 i;
2115 s32 rate_index;
2116 struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
2117 const struct iwl3945_eeprom_txpower_group *group;
2118
2119 IWL_DEBUG_POWER(priv, "Initializing factory calib info from EEPROM\n");
2120
2121 for (i = 0; i < IWL_NUM_TX_CALIB_GROUPS; i++) {
2122 s8 *clip_pwrs;
2123 s8 satur_pwr;
2124 group = &eeprom->groups[i];
2125
2126
2127 if (group->saturation_power < 40) {
2128 IWL_WARN(priv, "Error: saturation power is %d, "
2129 "less than minimum expected 40\n",
2130 group->saturation_power);
2131 return;
2132 }
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143 clip_pwrs = (s8 *) priv->clip39_groups[i].clip_powers;
2144
2145
2146 satur_pwr = (s8) (group->saturation_power >> 1);
2147
2148
2149 for (rate_index = 0;
2150 rate_index < IWL_RATE_COUNT_3945; rate_index++, clip_pwrs++) {
2151 switch (rate_index) {
2152 case IWL_RATE_36M_INDEX_TABLE:
2153 if (i == 0)
2154 *clip_pwrs = satur_pwr;
2155 else
2156 *clip_pwrs = satur_pwr - 5;
2157 break;
2158 case IWL_RATE_48M_INDEX_TABLE:
2159 if (i == 0)
2160 *clip_pwrs = satur_pwr - 7;
2161 else
2162 *clip_pwrs = satur_pwr - 10;
2163 break;
2164 case IWL_RATE_54M_INDEX_TABLE:
2165 if (i == 0)
2166 *clip_pwrs = satur_pwr - 9;
2167 else
2168 *clip_pwrs = satur_pwr - 12;
2169 break;
2170 default:
2171 *clip_pwrs = satur_pwr;
2172 break;
2173 }
2174 }
2175 }
2176}
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
2194{
2195 struct iwl_channel_info *ch_info = NULL;
2196 struct iwl3945_channel_power_info *pwr_info;
2197 struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
2198 int delta_index;
2199 u8 rate_index;
2200 u8 scan_tbl_index;
2201 const s8 *clip_pwrs;
2202 u8 gain, dsp_atten;
2203 s8 power;
2204 u8 pwr_index, base_pwr_index, a_band;
2205 u8 i;
2206 int temperature;
2207
2208
2209
2210 temperature = iwl3945_hw_reg_txpower_get_temperature(priv);
2211 priv->last_temperature = temperature;
2212
2213 iwl3945_hw_reg_init_channel_groups(priv);
2214
2215
2216 for (i = 0, ch_info = priv->channel_info; i < priv->channel_count;
2217 i++, ch_info++) {
2218 a_band = is_channel_a_band(ch_info);
2219 if (!is_channel_valid(ch_info))
2220 continue;
2221
2222
2223 ch_info->group_index =
2224 iwl3945_hw_reg_get_ch_grp_index(priv, ch_info);
2225
2226
2227 clip_pwrs = priv->clip39_groups[ch_info->group_index].clip_powers;
2228
2229
2230
2231 delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature,
2232 eeprom->groups[ch_info->group_index].
2233 temperature);
2234
2235 IWL_DEBUG_POWER(priv, "Delta index for channel %d: %d [%d]\n",
2236 ch_info->channel, delta_index, temperature +
2237 IWL_TEMP_CONVERT);
2238
2239
2240 for (rate_index = 0; rate_index < IWL_OFDM_RATES;
2241 rate_index++) {
2242 s32 uninitialized_var(power_idx);
2243 int rc;
2244
2245
2246
2247 s8 pwr = min(ch_info->max_power_avg,
2248 clip_pwrs[rate_index]);
2249
2250 pwr_info = &ch_info->power_info[rate_index];
2251
2252
2253
2254 rc = iwl3945_hw_reg_get_matched_power_index(priv, pwr,
2255 ch_info->group_index,
2256 &power_idx);
2257 if (rc) {
2258 IWL_ERR(priv, "Invalid power index\n");
2259 return rc;
2260 }
2261 pwr_info->base_power_index = (u8) power_idx;
2262
2263
2264 power_idx += delta_index;
2265
2266
2267 power_idx = iwl3945_hw_reg_fix_power_index(power_idx);
2268
2269
2270 pwr_info->requested_power = pwr;
2271 pwr_info->power_table_index = (u8) power_idx;
2272 pwr_info->tpc.tx_gain =
2273 power_gain_table[a_band][power_idx].tx_gain;
2274 pwr_info->tpc.dsp_atten =
2275 power_gain_table[a_band][power_idx].dsp_atten;
2276 }
2277
2278
2279 pwr_info = &ch_info->power_info[IWL_RATE_12M_INDEX_TABLE];
2280 power = pwr_info->requested_power +
2281 IWL_CCK_FROM_OFDM_POWER_DIFF;
2282 pwr_index = pwr_info->power_table_index +
2283 IWL_CCK_FROM_OFDM_INDEX_DIFF;
2284 base_pwr_index = pwr_info->base_power_index +
2285 IWL_CCK_FROM_OFDM_INDEX_DIFF;
2286
2287
2288 pwr_index = iwl3945_hw_reg_fix_power_index(pwr_index);
2289 gain = power_gain_table[a_band][pwr_index].tx_gain;
2290 dsp_atten = power_gain_table[a_band][pwr_index].dsp_atten;
2291
2292
2293
2294
2295 for (rate_index = 0;
2296 rate_index < IWL_CCK_RATES; rate_index++) {
2297 pwr_info = &ch_info->power_info[rate_index+IWL_OFDM_RATES];
2298 pwr_info->requested_power = power;
2299 pwr_info->power_table_index = pwr_index;
2300 pwr_info->base_power_index = base_pwr_index;
2301 pwr_info->tpc.tx_gain = gain;
2302 pwr_info->tpc.dsp_atten = dsp_atten;
2303 }
2304
2305
2306 for (scan_tbl_index = 0;
2307 scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) {
2308 s32 actual_index = (scan_tbl_index == 0) ?
2309 IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE;
2310 iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index,
2311 actual_index, clip_pwrs, ch_info, a_band);
2312 }
2313 }
2314
2315 return 0;
2316}
2317
2318int iwl3945_hw_rxq_stop(struct iwl_priv *priv)
2319{
2320 int rc;
2321
2322 iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 0);
2323 rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS,
2324 FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
2325 if (rc < 0)
2326 IWL_ERR(priv, "Can't stop Rx DMA.\n");
2327
2328 return 0;
2329}
2330
2331int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
2332{
2333 int txq_id = txq->q.id;
2334
2335 struct iwl3945_shared *shared_data = priv->shared_virt;
2336
2337 shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr);
2338
2339 iwl_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0);
2340 iwl_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0);
2341
2342 iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id),
2343 FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT |
2344 FH39_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF |
2345 FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |
2346 FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL |
2347 FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE);
2348
2349
2350 iwl_read32(priv, FH39_TSSR_CBB_BASE);
2351
2352 return 0;
2353}
2354
2355
2356
2357
2358static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len)
2359{
2360 switch (cmd_id) {
2361 case REPLY_RXON:
2362 return sizeof(struct iwl3945_rxon_cmd);
2363 case POWER_TABLE_CMD:
2364 return sizeof(struct iwl3945_powertable_cmd);
2365 default:
2366 return len;
2367 }
2368}
2369
2370
2371static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
2372{
2373 struct iwl3945_addsta_cmd *addsta = (struct iwl3945_addsta_cmd *)data;
2374 addsta->mode = cmd->mode;
2375 memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify));
2376 memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo));
2377 addsta->station_flags = cmd->station_flags;
2378 addsta->station_flags_msk = cmd->station_flags_msk;
2379 addsta->tid_disable_tx = cpu_to_le16(0);
2380 addsta->rate_n_flags = cmd->rate_n_flags;
2381 addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;
2382 addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;
2383 addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;
2384
2385 return (u16)sizeof(struct iwl3945_addsta_cmd);
2386}
2387
2388
2389
2390
2391
2392int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
2393{
2394 int rc, i, index, prev_index;
2395 struct iwl3945_rate_scaling_cmd rate_cmd = {
2396 .reserved = {0, 0, 0},
2397 };
2398 struct iwl3945_rate_scaling_info *table = rate_cmd.table;
2399
2400 for (i = 0; i < ARRAY_SIZE(iwl3945_rates); i++) {
2401 index = iwl3945_rates[i].table_rs_index;
2402
2403 table[index].rate_n_flags =
2404 iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0);
2405 table[index].try_cnt = priv->retry_rate;
2406 prev_index = iwl3945_get_prev_ieee_rate(i);
2407 table[index].next_rate_index =
2408 iwl3945_rates[prev_index].table_rs_index;
2409 }
2410
2411 switch (priv->band) {
2412 case IEEE80211_BAND_5GHZ:
2413 IWL_DEBUG_RATE(priv, "Select A mode rate scale\n");
2414
2415
2416 for (i = IWL_RATE_1M_INDEX_TABLE;
2417 i <= IWL_RATE_11M_INDEX_TABLE; i++)
2418 table[i].next_rate_index =
2419 iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
2420
2421
2422 table[IWL_RATE_12M_INDEX_TABLE].next_rate_index =
2423 IWL_RATE_9M_INDEX_TABLE;
2424
2425
2426 table[IWL_RATE_6M_INDEX_TABLE].next_rate_index =
2427 iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
2428 break;
2429
2430 case IEEE80211_BAND_2GHZ:
2431 IWL_DEBUG_RATE(priv, "Select B/G mode rate scale\n");
2432
2433
2434
2435 if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
2436 iwl_is_associated(priv)) {
2437
2438 index = IWL_FIRST_CCK_RATE;
2439 for (i = IWL_RATE_6M_INDEX_TABLE;
2440 i <= IWL_RATE_54M_INDEX_TABLE; i++)
2441 table[i].next_rate_index =
2442 iwl3945_rates[index].table_rs_index;
2443
2444 index = IWL_RATE_11M_INDEX_TABLE;
2445
2446 table[index].next_rate_index = IWL_RATE_5M_INDEX_TABLE;
2447 }
2448 break;
2449
2450 default:
2451 WARN_ON(1);
2452 break;
2453 }
2454
2455
2456 rate_cmd.table_id = 0;
2457 rc = iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
2458 &rate_cmd);
2459 if (rc)
2460 return rc;
2461
2462
2463 rate_cmd.table_id = 1;
2464 return iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
2465 &rate_cmd);
2466}
2467
2468
2469int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
2470{
2471 memset((void *)&priv->hw_params, 0,
2472 sizeof(struct iwl_hw_params));
2473
2474 priv->shared_virt = dma_alloc_coherent(&priv->pci_dev->dev,
2475 sizeof(struct iwl3945_shared),
2476 &priv->shared_phys, GFP_KERNEL);
2477 if (!priv->shared_virt) {
2478 IWL_ERR(priv, "failed to allocate pci memory\n");
2479 mutex_unlock(&priv->mutex);
2480 return -ENOMEM;
2481 }
2482
2483
2484 priv->hw_params.max_txq_num = priv->cfg->num_of_queues;
2485
2486 priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
2487 priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K);
2488 priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
2489 priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
2490 priv->hw_params.max_stations = IWL3945_STATION_COUNT;
2491 priv->hw_params.bcast_sta_id = IWL3945_BROADCAST_ID;
2492
2493 priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR;
2494 priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL;
2495
2496 return 0;
2497}
2498
2499unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
2500 struct iwl3945_frame *frame, u8 rate)
2501{
2502 struct iwl3945_tx_beacon_cmd *tx_beacon_cmd;
2503 unsigned int frame_size;
2504
2505 tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u;
2506 memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
2507
2508 tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
2509 tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
2510
2511 frame_size = iwl3945_fill_beacon_frame(priv,
2512 tx_beacon_cmd->frame,
2513 sizeof(frame->u) - sizeof(*tx_beacon_cmd));
2514
2515 BUG_ON(frame_size > MAX_MPDU_SIZE);
2516 tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
2517
2518 tx_beacon_cmd->tx.rate = rate;
2519 tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK |
2520 TX_CMD_FLG_TSF_MSK);
2521
2522
2523 tx_beacon_cmd->tx.supp_rates[0] =
2524 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
2525
2526 tx_beacon_cmd->tx.supp_rates[1] =
2527 (IWL_CCK_BASIC_RATES_MASK & 0xF);
2528
2529 return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size;
2530}
2531
2532void iwl3945_hw_rx_handler_setup(struct iwl_priv *priv)
2533{
2534 priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx;
2535 priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx;
2536}
2537
2538void iwl3945_hw_setup_deferred_work(struct iwl_priv *priv)
2539{
2540 INIT_DELAYED_WORK(&priv->thermal_periodic,
2541 iwl3945_bg_reg_txpower_periodic);
2542}
2543
2544void iwl3945_hw_cancel_deferred_work(struct iwl_priv *priv)
2545{
2546 cancel_delayed_work(&priv->thermal_periodic);
2547}
2548
2549
2550static int iwl3945_verify_bsm(struct iwl_priv *priv)
2551 {
2552 __le32 *image = priv->ucode_boot.v_addr;
2553 u32 len = priv->ucode_boot.len;
2554 u32 reg;
2555 u32 val;
2556
2557 IWL_DEBUG_INFO(priv, "Begin verify bsm\n");
2558
2559
2560 val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG);
2561 for (reg = BSM_SRAM_LOWER_BOUND;
2562 reg < BSM_SRAM_LOWER_BOUND + len;
2563 reg += sizeof(u32), image++) {
2564 val = iwl_read_prph(priv, reg);
2565 if (val != le32_to_cpu(*image)) {
2566 IWL_ERR(priv, "BSM uCode verification failed at "
2567 "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
2568 BSM_SRAM_LOWER_BOUND,
2569 reg - BSM_SRAM_LOWER_BOUND, len,
2570 val, le32_to_cpu(*image));
2571 return -EIO;
2572 }
2573 }
2574
2575 IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n");
2576
2577 return 0;
2578}
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595static int iwl3945_eeprom_acquire_semaphore(struct iwl_priv *priv)
2596{
2597 _iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
2598 return 0;
2599}
2600
2601
2602static void iwl3945_eeprom_release_semaphore(struct iwl_priv *priv)
2603{
2604 return;
2605}
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639static int iwl3945_load_bsm(struct iwl_priv *priv)
2640{
2641 __le32 *image = priv->ucode_boot.v_addr;
2642 u32 len = priv->ucode_boot.len;
2643 dma_addr_t pinst;
2644 dma_addr_t pdata;
2645 u32 inst_len;
2646 u32 data_len;
2647 int rc;
2648 int i;
2649 u32 done;
2650 u32 reg_offset;
2651
2652 IWL_DEBUG_INFO(priv, "Begin load bsm\n");
2653
2654
2655 if (len > IWL39_MAX_BSM_SIZE)
2656 return -EINVAL;
2657
2658
2659
2660
2661
2662
2663 pinst = priv->ucode_init.p_addr;
2664 pdata = priv->ucode_init_data.p_addr;
2665 inst_len = priv->ucode_init.len;
2666 data_len = priv->ucode_init_data.len;
2667
2668 iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
2669 iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
2670 iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
2671 iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
2672
2673
2674 for (reg_offset = BSM_SRAM_LOWER_BOUND;
2675 reg_offset < BSM_SRAM_LOWER_BOUND + len;
2676 reg_offset += sizeof(u32), image++)
2677 _iwl_write_prph(priv, reg_offset,
2678 le32_to_cpu(*image));
2679
2680 rc = iwl3945_verify_bsm(priv);
2681 if (rc)
2682 return rc;
2683
2684
2685 iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
2686 iwl_write_prph(priv, BSM_WR_MEM_DST_REG,
2687 IWL39_RTC_INST_LOWER_BOUND);
2688 iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
2689
2690
2691
2692 iwl_write_prph(priv, BSM_WR_CTRL_REG,
2693 BSM_WR_CTRL_REG_BIT_START);
2694
2695
2696 for (i = 0; i < 100; i++) {
2697 done = iwl_read_prph(priv, BSM_WR_CTRL_REG);
2698 if (!(done & BSM_WR_CTRL_REG_BIT_START))
2699 break;
2700 udelay(10);
2701 }
2702 if (i < 100)
2703 IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i);
2704 else {
2705 IWL_ERR(priv, "BSM write did not complete!\n");
2706 return -EIO;
2707 }
2708
2709
2710
2711 iwl_write_prph(priv, BSM_WR_CTRL_REG,
2712 BSM_WR_CTRL_REG_BIT_START_EN);
2713
2714 return 0;
2715}
2716
2717#define IWL3945_UCODE_GET(item) \
2718static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode,\
2719 u32 api_ver) \
2720{ \
2721 return le32_to_cpu(ucode->u.v1.item); \
2722}
2723
2724static u32 iwl3945_ucode_get_header_size(u32 api_ver)
2725{
2726 return UCODE_HEADER_SIZE(1);
2727}
2728static u32 iwl3945_ucode_get_build(const struct iwl_ucode_header *ucode,
2729 u32 api_ver)
2730{
2731 return 0;
2732}
2733static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode,
2734 u32 api_ver)
2735{
2736 return (u8 *) ucode->u.v1.data;
2737}
2738
2739IWL3945_UCODE_GET(inst_size);
2740IWL3945_UCODE_GET(data_size);
2741IWL3945_UCODE_GET(init_size);
2742IWL3945_UCODE_GET(init_data_size);
2743IWL3945_UCODE_GET(boot_size);
2744
2745static struct iwl_hcmd_ops iwl3945_hcmd = {
2746 .rxon_assoc = iwl3945_send_rxon_assoc,
2747 .commit_rxon = iwl3945_commit_rxon,
2748};
2749
2750static struct iwl_ucode_ops iwl3945_ucode = {
2751 .get_header_size = iwl3945_ucode_get_header_size,
2752 .get_build = iwl3945_ucode_get_build,
2753 .get_inst_size = iwl3945_ucode_get_inst_size,
2754 .get_data_size = iwl3945_ucode_get_data_size,
2755 .get_init_size = iwl3945_ucode_get_init_size,
2756 .get_init_data_size = iwl3945_ucode_get_init_data_size,
2757 .get_boot_size = iwl3945_ucode_get_boot_size,
2758 .get_data = iwl3945_ucode_get_data,
2759};
2760
2761static struct iwl_lib_ops iwl3945_lib = {
2762 .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
2763 .txq_free_tfd = iwl3945_hw_txq_free_tfd,
2764 .txq_init = iwl3945_hw_tx_queue_init,
2765 .load_ucode = iwl3945_load_bsm,
2766 .dump_nic_event_log = iwl3945_dump_nic_event_log,
2767 .dump_nic_error_log = iwl3945_dump_nic_error_log,
2768 .apm_ops = {
2769 .init = iwl3945_apm_init,
2770 .stop = iwl_apm_stop,
2771 .config = iwl3945_nic_config,
2772 .set_pwr_src = iwl3945_set_pwr_src,
2773 },
2774 .eeprom_ops = {
2775 .regulatory_bands = {
2776 EEPROM_REGULATORY_BAND_1_CHANNELS,
2777 EEPROM_REGULATORY_BAND_2_CHANNELS,
2778 EEPROM_REGULATORY_BAND_3_CHANNELS,
2779 EEPROM_REGULATORY_BAND_4_CHANNELS,
2780 EEPROM_REGULATORY_BAND_5_CHANNELS,
2781 EEPROM_REGULATORY_BAND_NO_HT40,
2782 EEPROM_REGULATORY_BAND_NO_HT40,
2783 },
2784 .verify_signature = iwlcore_eeprom_verify_signature,
2785 .acquire_semaphore = iwl3945_eeprom_acquire_semaphore,
2786 .release_semaphore = iwl3945_eeprom_release_semaphore,
2787 .query_addr = iwlcore_eeprom_query_addr,
2788 },
2789 .send_tx_power = iwl3945_send_tx_power,
2790 .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr,
2791 .post_associate = iwl3945_post_associate,
2792 .isr = iwl_isr_legacy,
2793 .config_ap = iwl3945_config_ap,
2794 .add_bcast_station = iwl3945_add_bcast_station,
2795};
2796
2797static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2798 .get_hcmd_size = iwl3945_get_hcmd_size,
2799 .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
2800 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
2801};
2802
2803static const struct iwl_ops iwl3945_ops = {
2804 .ucode = &iwl3945_ucode,
2805 .lib = &iwl3945_lib,
2806 .hcmd = &iwl3945_hcmd,
2807 .utils = &iwl3945_hcmd_utils,
2808 .led = &iwl3945_led_ops,
2809};
2810
2811static struct iwl_cfg iwl3945_bg_cfg = {
2812 .name = "3945BG",
2813 .fw_name_pre = IWL3945_FW_PRE,
2814 .ucode_api_max = IWL3945_UCODE_API_MAX,
2815 .ucode_api_min = IWL3945_UCODE_API_MIN,
2816 .sku = IWL_SKU_G,
2817 .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
2818 .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
2819 .ops = &iwl3945_ops,
2820 .num_of_queues = IWL39_NUM_QUEUES,
2821 .mod_params = &iwl3945_mod_params,
2822 .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
2823 .set_l0s = false,
2824 .use_bsm = true,
2825 .use_isr_legacy = true,
2826 .ht_greenfield_support = false,
2827 .led_compensation = 64,
2828 .broken_powersave = true,
2829 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2830};
2831
2832static struct iwl_cfg iwl3945_abg_cfg = {
2833 .name = "3945ABG",
2834 .fw_name_pre = IWL3945_FW_PRE,
2835 .ucode_api_max = IWL3945_UCODE_API_MAX,
2836 .ucode_api_min = IWL3945_UCODE_API_MIN,
2837 .sku = IWL_SKU_A|IWL_SKU_G,
2838 .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
2839 .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
2840 .ops = &iwl3945_ops,
2841 .num_of_queues = IWL39_NUM_QUEUES,
2842 .mod_params = &iwl3945_mod_params,
2843 .use_isr_legacy = true,
2844 .ht_greenfield_support = false,
2845 .led_compensation = 64,
2846 .broken_powersave = true,
2847 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2848};
2849
2850DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
2851 {IWL_PCI_DEVICE(0x4222, 0x1005, iwl3945_bg_cfg)},
2852 {IWL_PCI_DEVICE(0x4222, 0x1034, iwl3945_bg_cfg)},
2853 {IWL_PCI_DEVICE(0x4222, 0x1044, iwl3945_bg_cfg)},
2854 {IWL_PCI_DEVICE(0x4227, 0x1014, iwl3945_bg_cfg)},
2855 {IWL_PCI_DEVICE(0x4222, PCI_ANY_ID, iwl3945_abg_cfg)},
2856 {IWL_PCI_DEVICE(0x4227, PCI_ANY_ID, iwl3945_abg_cfg)},
2857 {0}
2858};
2859
2860MODULE_DEVICE_TABLE(pci, iwl3945_hw_card_ids);
2861