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