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/skbuff.h>
34#include <linux/netdevice.h>
35#include <linux/wireless.h>
36#include <net/mac80211.h>
37#include <linux/etherdevice.h>
38#include <asm/unaligned.h>
39
40#include "iwl-eeprom.h"
41#include "iwl-dev.h"
42#include "iwl-core.h"
43#include "iwl-io.h"
44#include "iwl-helpers.h"
45#include "iwl-calib.h"
46#include "iwl-sta.h"
47
48static int iwl4965_send_tx_power(struct iwl_priv *priv);
49static int iwl4965_hw_get_temperature(const struct iwl_priv *priv);
50
51
52
53
54
55#define IWL4965_UCODE_API "-2"
56
57
58
59static struct iwl_mod_params iwl4965_mod_params = {
60 .num_of_queues = IWL49_NUM_QUEUES,
61 .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
62 .enable_qos = 1,
63 .amsdu_size_8K = 1,
64 .restart_fw = 1,
65
66};
67
68
69static int iwl4965_verify_bsm(struct iwl_priv *priv)
70{
71 __le32 *image = priv->ucode_boot.v_addr;
72 u32 len = priv->ucode_boot.len;
73 u32 reg;
74 u32 val;
75
76 IWL_DEBUG_INFO("Begin verify bsm\n");
77
78
79 val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG);
80 for (reg = BSM_SRAM_LOWER_BOUND;
81 reg < BSM_SRAM_LOWER_BOUND + len;
82 reg += sizeof(u32), image++) {
83 val = iwl_read_prph(priv, reg);
84 if (val != le32_to_cpu(*image)) {
85 IWL_ERROR("BSM uCode verification failed at "
86 "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
87 BSM_SRAM_LOWER_BOUND,
88 reg - BSM_SRAM_LOWER_BOUND, len,
89 val, le32_to_cpu(*image));
90 return -EIO;
91 }
92 }
93
94 IWL_DEBUG_INFO("BSM bootstrap uCode image OK\n");
95
96 return 0;
97}
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131static int iwl4965_load_bsm(struct iwl_priv *priv)
132{
133 __le32 *image = priv->ucode_boot.v_addr;
134 u32 len = priv->ucode_boot.len;
135 dma_addr_t pinst;
136 dma_addr_t pdata;
137 u32 inst_len;
138 u32 data_len;
139 int i;
140 u32 done;
141 u32 reg_offset;
142 int ret;
143
144 IWL_DEBUG_INFO("Begin load bsm\n");
145
146 priv->ucode_type = UCODE_RT;
147
148
149 if (len > IWL_MAX_BSM_SIZE)
150 return -EINVAL;
151
152
153
154
155
156
157
158 pinst = priv->ucode_init.p_addr >> 4;
159 pdata = priv->ucode_init_data.p_addr >> 4;
160 inst_len = priv->ucode_init.len;
161 data_len = priv->ucode_init_data.len;
162
163 ret = iwl_grab_nic_access(priv);
164 if (ret)
165 return ret;
166
167 iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
168 iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
169 iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
170 iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
171
172
173 for (reg_offset = BSM_SRAM_LOWER_BOUND;
174 reg_offset < BSM_SRAM_LOWER_BOUND + len;
175 reg_offset += sizeof(u32), image++)
176 _iwl_write_prph(priv, reg_offset, le32_to_cpu(*image));
177
178 ret = iwl4965_verify_bsm(priv);
179 if (ret) {
180 iwl_release_nic_access(priv);
181 return ret;
182 }
183
184
185 iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
186 iwl_write_prph(priv, BSM_WR_MEM_DST_REG, RTC_INST_LOWER_BOUND);
187 iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
188
189
190
191 iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START);
192
193
194 for (i = 0; i < 100; i++) {
195 done = iwl_read_prph(priv, BSM_WR_CTRL_REG);
196 if (!(done & BSM_WR_CTRL_REG_BIT_START))
197 break;
198 udelay(10);
199 }
200 if (i < 100)
201 IWL_DEBUG_INFO("BSM write complete, poll %d iterations\n", i);
202 else {
203 IWL_ERROR("BSM write did not complete!\n");
204 return -EIO;
205 }
206
207
208
209 iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN);
210
211 iwl_release_nic_access(priv);
212
213 return 0;
214}
215
216
217
218
219
220
221
222
223
224
225static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
226{
227 dma_addr_t pinst;
228 dma_addr_t pdata;
229 unsigned long flags;
230 int ret = 0;
231
232
233 pinst = priv->ucode_code.p_addr >> 4;
234 pdata = priv->ucode_data_backup.p_addr >> 4;
235
236 spin_lock_irqsave(&priv->lock, flags);
237 ret = iwl_grab_nic_access(priv);
238 if (ret) {
239 spin_unlock_irqrestore(&priv->lock, flags);
240 return ret;
241 }
242
243
244 iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
245 iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
246 iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
247 priv->ucode_data.len);
248
249
250
251 iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
252 priv->ucode_code.len | BSM_DRAM_INST_LOAD);
253 iwl_release_nic_access(priv);
254
255 spin_unlock_irqrestore(&priv->lock, flags);
256
257 IWL_DEBUG_INFO("Runtime uCode pointers are set.\n");
258
259 return ret;
260}
261
262
263
264
265
266
267
268
269
270
271
272
273static void iwl4965_init_alive_start(struct iwl_priv *priv)
274{
275
276 if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
277
278
279 IWL_DEBUG_INFO("Initialize Alive failed.\n");
280 goto restart;
281 }
282
283
284
285
286 if (iwl_verify_ucode(priv)) {
287
288
289 IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
290 goto restart;
291 }
292
293
294 priv->temperature = iwl4965_hw_get_temperature(priv);
295
296
297
298
299 IWL_DEBUG_INFO("Initialization Alive received.\n");
300 if (iwl4965_set_ucode_ptrs(priv)) {
301
302
303 IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n");
304 goto restart;
305 }
306 return;
307
308restart:
309 queue_work(priv->workqueue, &priv->restart);
310}
311
312static int is_fat_channel(__le32 rxon_flags)
313{
314 return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) ||
315 (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK);
316}
317
318
319
320
321
322static int iwl4965_eeprom_check_version(struct iwl_priv *priv)
323{
324 u16 eeprom_ver;
325 u16 calib_ver;
326
327 eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
328
329 calib_ver = iwl_eeprom_query16(priv, EEPROM_4965_CALIB_VERSION_OFFSET);
330
331 if (eeprom_ver < EEPROM_4965_EEPROM_VERSION ||
332 calib_ver < EEPROM_4965_TX_POWER_VERSION)
333 goto err;
334
335 return 0;
336err:
337 IWL_ERROR("Unsuported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
338 eeprom_ver, EEPROM_4965_EEPROM_VERSION,
339 calib_ver, EEPROM_4965_TX_POWER_VERSION);
340 return -EINVAL;
341
342}
343
344
345
346
347
348static void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask)
349{
350 iwl_write_prph(priv, IWL49_SCD_TXFACT, mask);
351}
352
353static int iwl4965_apm_init(struct iwl_priv *priv)
354{
355 int ret = 0;
356
357 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
358 CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
359
360
361 iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
362 CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
363
364
365
366 iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
367
368
369 ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
370 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
371 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
372 if (ret < 0) {
373 IWL_DEBUG_INFO("Failed to init the card\n");
374 goto out;
375 }
376
377 ret = iwl_grab_nic_access(priv);
378 if (ret)
379 goto out;
380
381
382 iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
383 APMG_CLK_VAL_BSM_CLK_RQT);
384
385 udelay(20);
386
387
388 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
389 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
390
391 iwl_release_nic_access(priv);
392out:
393 return ret;
394}
395
396
397static void iwl4965_nic_config(struct iwl_priv *priv)
398{
399 unsigned long flags;
400 u32 val;
401 u16 radio_cfg;
402 u16 link;
403
404 spin_lock_irqsave(&priv->lock, flags);
405
406 if ((priv->rev_id & 0x80) == 0x80 && (priv->rev_id & 0x7f) < 8) {
407 pci_read_config_dword(priv->pci_dev, PCI_REG_WUM8, &val);
408
409 pci_write_config_dword(priv->pci_dev, PCI_REG_WUM8,
410 val & ~(1 << 11));
411 }
412
413 pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &link);
414
415
416 if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
417
418 iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
419 else
420
421 iwl_clear_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
422
423 radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
424
425
426 if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) == EEPROM_4965_RF_CFG_TYPE_MAX)
427 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
428 EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
429 EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
430 EEPROM_RF_CFG_DASH_MSK(radio_cfg));
431
432
433 iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
434 CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
435 CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
436
437 priv->calib_info = (struct iwl_eeprom_calib_info *)
438 iwl_eeprom_query_addr(priv, EEPROM_4965_CALIB_TXPOWER_OFFSET);
439
440 spin_unlock_irqrestore(&priv->lock, flags);
441}
442
443static int iwl4965_apm_stop_master(struct iwl_priv *priv)
444{
445 int ret = 0;
446 unsigned long flags;
447
448 spin_lock_irqsave(&priv->lock, flags);
449
450
451 iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
452
453 ret = iwl_poll_bit(priv, CSR_RESET,
454 CSR_RESET_REG_FLAG_MASTER_DISABLED,
455 CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
456 if (ret < 0)
457 goto out;
458
459out:
460 spin_unlock_irqrestore(&priv->lock, flags);
461 IWL_DEBUG_INFO("stop master\n");
462
463 return ret;
464}
465
466static void iwl4965_apm_stop(struct iwl_priv *priv)
467{
468 unsigned long flags;
469
470 iwl4965_apm_stop_master(priv);
471
472 spin_lock_irqsave(&priv->lock, flags);
473
474 iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
475
476 udelay(10);
477
478 iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
479 spin_unlock_irqrestore(&priv->lock, flags);
480}
481
482static int iwl4965_apm_reset(struct iwl_priv *priv)
483{
484 int ret = 0;
485 unsigned long flags;
486
487 iwl4965_apm_stop_master(priv);
488
489 spin_lock_irqsave(&priv->lock, flags);
490
491 iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
492
493 udelay(10);
494
495
496
497 iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
498
499 ret = iwl_poll_bit(priv, CSR_RESET,
500 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
501 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25);
502
503 if (ret)
504 goto out;
505
506 udelay(10);
507
508 ret = iwl_grab_nic_access(priv);
509 if (ret)
510 goto out;
511
512 iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT |
513 APMG_CLK_VAL_BSM_CLK_RQT);
514
515 udelay(10);
516
517
518 iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
519 APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
520
521 iwl_release_nic_access(priv);
522
523 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
524 wake_up_interruptible(&priv->wait_command_queue);
525
526out:
527 spin_unlock_irqrestore(&priv->lock, flags);
528
529 return ret;
530}
531
532
533
534
535static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
536{
537 struct iwl_chain_noise_data *data = &(priv->chain_noise_data);
538
539 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
540 struct iwl4965_calibration_cmd cmd;
541
542 memset(&cmd, 0, sizeof(cmd));
543 cmd.opCode = PHY_CALIBRATE_DIFF_GAIN_CMD;
544 cmd.diff_gain_a = 0;
545 cmd.diff_gain_b = 0;
546 cmd.diff_gain_c = 0;
547 if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
548 sizeof(cmd), &cmd))
549 IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
550 data->state = IWL_CHAIN_NOISE_ACCUMULATE;
551 IWL_DEBUG_CALIB("Run chain_noise_calibrate\n");
552 }
553}
554
555static void iwl4965_gain_computation(struct iwl_priv *priv,
556 u32 *average_noise,
557 u16 min_average_noise_antenna_i,
558 u32 min_average_noise)
559{
560 int i, ret;
561 struct iwl_chain_noise_data *data = &priv->chain_noise_data;
562
563 data->delta_gain_code[min_average_noise_antenna_i] = 0;
564
565 for (i = 0; i < NUM_RX_CHAINS; i++) {
566 s32 delta_g = 0;
567
568 if (!(data->disconn_array[i]) &&
569 (data->delta_gain_code[i] ==
570 CHAIN_NOISE_DELTA_GAIN_INIT_VAL)) {
571 delta_g = average_noise[i] - min_average_noise;
572 data->delta_gain_code[i] = (u8)((delta_g * 10) / 15);
573 data->delta_gain_code[i] =
574 min(data->delta_gain_code[i],
575 (u8) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
576
577 data->delta_gain_code[i] =
578 (data->delta_gain_code[i] | (1 << 2));
579 } else {
580 data->delta_gain_code[i] = 0;
581 }
582 }
583 IWL_DEBUG_CALIB("delta_gain_codes: a %d b %d c %d\n",
584 data->delta_gain_code[0],
585 data->delta_gain_code[1],
586 data->delta_gain_code[2]);
587
588
589 if (!data->radio_write) {
590 struct iwl4965_calibration_cmd cmd;
591 data->radio_write = 1;
592
593 memset(&cmd, 0, sizeof(cmd));
594 cmd.opCode = PHY_CALIBRATE_DIFF_GAIN_CMD;
595 cmd.diff_gain_a = data->delta_gain_code[0];
596 cmd.diff_gain_b = data->delta_gain_code[1];
597 cmd.diff_gain_c = data->delta_gain_code[2];
598 ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
599 sizeof(cmd), &cmd);
600 if (ret)
601 IWL_DEBUG_CALIB("fail sending cmd "
602 "REPLY_PHY_CALIBRATION_CMD \n");
603
604
605
606
607
608 data->state = IWL_CHAIN_NOISE_CALIBRATED;
609 }
610 data->chain_noise_a = 0;
611 data->chain_noise_b = 0;
612 data->chain_noise_c = 0;
613 data->chain_signal_a = 0;
614 data->chain_signal_b = 0;
615 data->chain_signal_c = 0;
616 data->beacon_count = 0;
617}
618
619static void iwl4965_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
620 __le32 *tx_flags)
621{
622 if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
623 *tx_flags |= TX_CMD_FLG_RTS_MSK;
624 *tx_flags &= ~TX_CMD_FLG_CTS_MSK;
625 } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
626 *tx_flags &= ~TX_CMD_FLG_RTS_MSK;
627 *tx_flags |= TX_CMD_FLG_CTS_MSK;
628 }
629}
630
631static void iwl4965_bg_txpower_work(struct work_struct *work)
632{
633 struct iwl_priv *priv = container_of(work, struct iwl_priv,
634 txpower_work);
635
636
637
638
639
640 if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
641 test_bit(STATUS_SCANNING, &priv->status))
642 return;
643
644 mutex_lock(&priv->mutex);
645
646
647
648
649 iwl4965_send_tx_power(priv);
650
651
652
653 priv->last_temperature = priv->temperature;
654
655 mutex_unlock(&priv->mutex);
656}
657
658
659
660
661static void iwl4965_set_wr_ptrs(struct iwl_priv *priv, int txq_id, u32 index)
662{
663 iwl_write_direct32(priv, HBUS_TARG_WRPTR,
664 (index & 0xff) | (txq_id << 8));
665 iwl_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(txq_id), index);
666}
667
668
669
670
671
672
673
674
675static void iwl4965_tx_queue_set_status(struct iwl_priv *priv,
676 struct iwl_tx_queue *txq,
677 int tx_fifo_id, int scd_retry)
678{
679 int txq_id = txq->q.id;
680
681
682 int active = test_bit(txq_id, &priv->txq_ctx_active_msk)?1:0;
683
684
685 iwl_write_prph(priv, IWL49_SCD_QUEUE_STATUS_BITS(txq_id),
686 (active << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
687 (tx_fifo_id << IWL49_SCD_QUEUE_STTS_REG_POS_TXF) |
688 (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_WSL) |
689 (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK) |
690 IWL49_SCD_QUEUE_STTS_REG_MSK);
691
692 txq->sched_retry = scd_retry;
693
694 IWL_DEBUG_INFO("%s %s Queue %d on AC %d\n",
695 active ? "Activate" : "Deactivate",
696 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
697}
698
699static const u16 default_queue_to_tx_fifo[] = {
700 IWL_TX_FIFO_AC3,
701 IWL_TX_FIFO_AC2,
702 IWL_TX_FIFO_AC1,
703 IWL_TX_FIFO_AC0,
704 IWL49_CMD_FIFO_NUM,
705 IWL_TX_FIFO_HCCA_1,
706 IWL_TX_FIFO_HCCA_2
707};
708
709static int iwl4965_alive_notify(struct iwl_priv *priv)
710{
711 u32 a;
712 int i = 0;
713 unsigned long flags;
714 int ret;
715
716 spin_lock_irqsave(&priv->lock, flags);
717
718 ret = iwl_grab_nic_access(priv);
719 if (ret) {
720 spin_unlock_irqrestore(&priv->lock, flags);
721 return ret;
722 }
723
724
725 priv->scd_base_addr = iwl_read_prph(priv, IWL49_SCD_SRAM_BASE_ADDR);
726 a = priv->scd_base_addr + IWL49_SCD_CONTEXT_DATA_OFFSET;
727 for (; a < priv->scd_base_addr + IWL49_SCD_TX_STTS_BITMAP_OFFSET; a += 4)
728 iwl_write_targ_mem(priv, a, 0);
729 for (; a < priv->scd_base_addr + IWL49_SCD_TRANSLATE_TBL_OFFSET; a += 4)
730 iwl_write_targ_mem(priv, a, 0);
731 for (; a < sizeof(u16) * priv->hw_params.max_txq_num; a += 4)
732 iwl_write_targ_mem(priv, a, 0);
733
734
735 iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR,
736 (priv->shared_phys +
737 offsetof(struct iwl4965_shared, queues_byte_cnt_tbls)) >> 10);
738
739
740 iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0);
741
742
743 for (i = 0; i < priv->hw_params.max_txq_num; i++) {
744
745
746 iwl_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(i), 0);
747 iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8));
748
749
750 iwl_write_targ_mem(priv, priv->scd_base_addr +
751 IWL49_SCD_CONTEXT_QUEUE_OFFSET(i),
752 (SCD_WIN_SIZE <<
753 IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
754 IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
755
756
757 iwl_write_targ_mem(priv, priv->scd_base_addr +
758 IWL49_SCD_CONTEXT_QUEUE_OFFSET(i) +
759 sizeof(u32),
760 (SCD_FRAME_LIMIT <<
761 IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
762 IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
763
764 }
765 iwl_write_prph(priv, IWL49_SCD_INTERRUPT_MASK,
766 (1 << priv->hw_params.max_txq_num) - 1);
767
768
769 priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7));
770
771 iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
772
773
774 for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
775 int ac = default_queue_to_tx_fifo[i];
776 iwl_txq_ctx_activate(priv, i);
777 iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
778 }
779
780 iwl_release_nic_access(priv);
781 spin_unlock_irqrestore(&priv->lock, flags);
782
783 return ret;
784}
785
786static struct iwl_sensitivity_ranges iwl4965_sensitivity = {
787 .min_nrg_cck = 97,
788 .max_nrg_cck = 0,
789
790 .auto_corr_min_ofdm = 85,
791 .auto_corr_min_ofdm_mrc = 170,
792 .auto_corr_min_ofdm_x1 = 105,
793 .auto_corr_min_ofdm_mrc_x1 = 220,
794
795 .auto_corr_max_ofdm = 120,
796 .auto_corr_max_ofdm_mrc = 210,
797 .auto_corr_max_ofdm_x1 = 140,
798 .auto_corr_max_ofdm_mrc_x1 = 270,
799
800 .auto_corr_min_cck = 125,
801 .auto_corr_max_cck = 200,
802 .auto_corr_min_cck_mrc = 200,
803 .auto_corr_max_cck_mrc = 400,
804
805 .nrg_th_cck = 100,
806 .nrg_th_ofdm = 100,
807};
808
809
810
811
812
813
814static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
815{
816
817 if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) ||
818 (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
819 IWL_ERROR("invalid queues_num, should be between %d and %d\n",
820 IWL_MIN_NUM_QUEUES, IWL49_NUM_QUEUES);
821 return -EINVAL;
822 }
823
824 priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
825 priv->hw_params.first_ampdu_q = IWL49_FIRST_AMPDU_QUEUE;
826 priv->hw_params.max_stations = IWL4965_STATION_COUNT;
827 priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
828 priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
829 priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE;
830 priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
831 priv->hw_params.fat_channel = BIT(IEEE80211_BAND_5GHZ);
832
833 priv->hw_params.tx_chains_num = 2;
834 priv->hw_params.rx_chains_num = 2;
835 priv->hw_params.valid_tx_ant = ANT_A | ANT_B;
836 priv->hw_params.valid_rx_ant = ANT_A | ANT_B;
837 priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
838
839 priv->hw_params.sens = &iwl4965_sensitivity;
840
841 return 0;
842}
843
844static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res)
845{
846 s32 sign = 1;
847
848 if (num < 0) {
849 sign = -sign;
850 num = -num;
851 }
852 if (denom < 0) {
853 sign = -sign;
854 denom = -denom;
855 }
856 *res = 1;
857 *res = ((num * 2 + denom) / (denom * 2)) * sign;
858
859 return 1;
860}
861
862
863
864
865
866
867
868
869
870
871
872
873static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage,
874 s32 current_voltage)
875{
876 s32 comp = 0;
877
878 if ((TX_POWER_IWL_ILLEGAL_VOLTAGE == eeprom_voltage) ||
879 (TX_POWER_IWL_ILLEGAL_VOLTAGE == current_voltage))
880 return 0;
881
882 iwl4965_math_div_round(current_voltage - eeprom_voltage,
883 TX_POWER_IWL_VOLTAGE_CODES_PER_03V, &comp);
884
885 if (current_voltage > eeprom_voltage)
886 comp *= 2;
887 if ((comp < -2) || (comp > 2))
888 comp = 0;
889
890 return comp;
891}
892
893static s32 iwl4965_get_tx_atten_grp(u16 channel)
894{
895 if (channel >= CALIB_IWL_TX_ATTEN_GR5_FCH &&
896 channel <= CALIB_IWL_TX_ATTEN_GR5_LCH)
897 return CALIB_CH_GROUP_5;
898
899 if (channel >= CALIB_IWL_TX_ATTEN_GR1_FCH &&
900 channel <= CALIB_IWL_TX_ATTEN_GR1_LCH)
901 return CALIB_CH_GROUP_1;
902
903 if (channel >= CALIB_IWL_TX_ATTEN_GR2_FCH &&
904 channel <= CALIB_IWL_TX_ATTEN_GR2_LCH)
905 return CALIB_CH_GROUP_2;
906
907 if (channel >= CALIB_IWL_TX_ATTEN_GR3_FCH &&
908 channel <= CALIB_IWL_TX_ATTEN_GR3_LCH)
909 return CALIB_CH_GROUP_3;
910
911 if (channel >= CALIB_IWL_TX_ATTEN_GR4_FCH &&
912 channel <= CALIB_IWL_TX_ATTEN_GR4_LCH)
913 return CALIB_CH_GROUP_4;
914
915 IWL_ERROR("Can't find txatten group for channel %d.\n", channel);
916 return -1;
917}
918
919static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel)
920{
921 s32 b = -1;
922
923 for (b = 0; b < EEPROM_TX_POWER_BANDS; b++) {
924 if (priv->calib_info->band_info[b].ch_from == 0)
925 continue;
926
927 if ((channel >= priv->calib_info->band_info[b].ch_from)
928 && (channel <= priv->calib_info->band_info[b].ch_to))
929 break;
930 }
931
932 return b;
933}
934
935static s32 iwl4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
936{
937 s32 val;
938
939 if (x2 == x1)
940 return y1;
941 else {
942 iwl4965_math_div_round((x2 - x) * (y1 - y2), (x2 - x1), &val);
943 return val + y2;
944 }
945}
946
947
948
949
950
951
952
953
954
955static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
956 struct iwl_eeprom_calib_ch_info *chan_info)
957{
958 s32 s = -1;
959 u32 c;
960 u32 m;
961 const struct iwl_eeprom_calib_measure *m1;
962 const struct iwl_eeprom_calib_measure *m2;
963 struct iwl_eeprom_calib_measure *omeas;
964 u32 ch_i1;
965 u32 ch_i2;
966
967 s = iwl4965_get_sub_band(priv, channel);
968 if (s >= EEPROM_TX_POWER_BANDS) {
969 IWL_ERROR("Tx Power can not find channel %d\n", channel);
970 return -1;
971 }
972
973 ch_i1 = priv->calib_info->band_info[s].ch1.ch_num;
974 ch_i2 = priv->calib_info->band_info[s].ch2.ch_num;
975 chan_info->ch_num = (u8) channel;
976
977 IWL_DEBUG_TXPOWER("channel %d subband %d factory cal ch %d & %d\n",
978 channel, s, ch_i1, ch_i2);
979
980 for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) {
981 for (m = 0; m < EEPROM_TX_POWER_MEASUREMENTS; m++) {
982 m1 = &(priv->calib_info->band_info[s].ch1.
983 measurements[c][m]);
984 m2 = &(priv->calib_info->band_info[s].ch2.
985 measurements[c][m]);
986 omeas = &(chan_info->measurements[c][m]);
987
988 omeas->actual_pow =
989 (u8) iwl4965_interpolate_value(channel, ch_i1,
990 m1->actual_pow,
991 ch_i2,
992 m2->actual_pow);
993 omeas->gain_idx =
994 (u8) iwl4965_interpolate_value(channel, ch_i1,
995 m1->gain_idx, ch_i2,
996 m2->gain_idx);
997 omeas->temperature =
998 (u8) iwl4965_interpolate_value(channel, ch_i1,
999 m1->temperature,
1000 ch_i2,
1001 m2->temperature);
1002 omeas->pa_det =
1003 (s8) iwl4965_interpolate_value(channel, ch_i1,
1004 m1->pa_det, ch_i2,
1005 m2->pa_det);
1006
1007 IWL_DEBUG_TXPOWER
1008 ("chain %d meas %d AP1=%d AP2=%d AP=%d\n", c, m,
1009 m1->actual_pow, m2->actual_pow, omeas->actual_pow);
1010 IWL_DEBUG_TXPOWER
1011 ("chain %d meas %d NI1=%d NI2=%d NI=%d\n", c, m,
1012 m1->gain_idx, m2->gain_idx, omeas->gain_idx);
1013 IWL_DEBUG_TXPOWER
1014 ("chain %d meas %d PA1=%d PA2=%d PA=%d\n", c, m,
1015 m1->pa_det, m2->pa_det, omeas->pa_det);
1016 IWL_DEBUG_TXPOWER
1017 ("chain %d meas %d T1=%d T2=%d T=%d\n", c, m,
1018 m1->temperature, m2->temperature,
1019 omeas->temperature);
1020 }
1021 }
1022
1023 return 0;
1024}
1025
1026
1027
1028static s32 back_off_table[] = {
1029 10, 10, 10, 10, 10, 15, 17, 20,
1030 10, 10, 10, 10, 10, 15, 17, 20,
1031 10, 10, 10, 10, 10, 15, 17, 20,
1032 10, 10, 10, 10, 10, 15, 17, 20,
1033 10
1034};
1035
1036
1037
1038static struct iwl4965_txpower_comp_entry {
1039 s32 degrees_per_05db_a;
1040 s32 degrees_per_05db_a_denom;
1041} tx_power_cmp_tble[CALIB_CH_GROUP_MAX] = {
1042 {9, 2},
1043 {4, 1},
1044 {4, 1},
1045 {4, 1},
1046 {3, 1}
1047};
1048
1049static s32 get_min_power_index(s32 rate_power_index, u32 band)
1050{
1051 if (!band) {
1052 if ((rate_power_index & 7) <= 4)
1053 return MIN_TX_GAIN_INDEX_52GHZ_EXT;
1054 }
1055 return MIN_TX_GAIN_INDEX;
1056}
1057
1058struct gain_entry {
1059 u8 dsp;
1060 u8 radio;
1061};
1062
1063static const struct gain_entry gain_table[2][108] = {
1064
1065 {
1066 {123, 0x3F},
1067 {117, 0x3F},
1068 {110, 0x3F},
1069 {104, 0x3F},
1070 {98, 0x3F},
1071 {110, 0x3E},
1072 {104, 0x3E},
1073 {98, 0x3E},
1074 {110, 0x3D},
1075 {104, 0x3D},
1076 {98, 0x3D},
1077 {110, 0x3C},
1078 {104, 0x3C},
1079 {98, 0x3C},
1080 {110, 0x3B},
1081 {104, 0x3B},
1082 {98, 0x3B},
1083 {110, 0x3A},
1084 {104, 0x3A},
1085 {98, 0x3A},
1086 {110, 0x39},
1087 {104, 0x39},
1088 {98, 0x39},
1089 {110, 0x38},
1090 {104, 0x38},
1091 {98, 0x38},
1092 {110, 0x37},
1093 {104, 0x37},
1094 {98, 0x37},
1095 {110, 0x36},
1096 {104, 0x36},
1097 {98, 0x36},
1098 {110, 0x35},
1099 {104, 0x35},
1100 {98, 0x35},
1101 {110, 0x34},
1102 {104, 0x34},
1103 {98, 0x34},
1104 {110, 0x33},
1105 {104, 0x33},
1106 {98, 0x33},
1107 {110, 0x32},
1108 {104, 0x32},
1109 {98, 0x32},
1110 {110, 0x31},
1111 {104, 0x31},
1112 {98, 0x31},
1113 {110, 0x30},
1114 {104, 0x30},
1115 {98, 0x30},
1116 {110, 0x25},
1117 {104, 0x25},
1118 {98, 0x25},
1119 {110, 0x24},
1120 {104, 0x24},
1121 {98, 0x24},
1122 {110, 0x23},
1123 {104, 0x23},
1124 {98, 0x23},
1125 {110, 0x22},
1126 {104, 0x18},
1127 {98, 0x18},
1128 {110, 0x17},
1129 {104, 0x17},
1130 {98, 0x17},
1131 {110, 0x16},
1132 {104, 0x16},
1133 {98, 0x16},
1134 {110, 0x15},
1135 {104, 0x15},
1136 {98, 0x15},
1137 {110, 0x14},
1138 {104, 0x14},
1139 {98, 0x14},
1140 {110, 0x13},
1141 {104, 0x13},
1142 {98, 0x13},
1143 {110, 0x12},
1144 {104, 0x08},
1145 {98, 0x08},
1146 {110, 0x07},
1147 {104, 0x07},
1148 {98, 0x07},
1149 {110, 0x06},
1150 {104, 0x06},
1151 {98, 0x06},
1152 {110, 0x05},
1153 {104, 0x05},
1154 {98, 0x05},
1155 {110, 0x04},
1156 {104, 0x04},
1157 {98, 0x04},
1158 {110, 0x03},
1159 {104, 0x03},
1160 {98, 0x03},
1161 {110, 0x02},
1162 {104, 0x02},
1163 {98, 0x02},
1164 {110, 0x01},
1165 {104, 0x01},
1166 {98, 0x01},
1167 {110, 0x00},
1168 {104, 0x00},
1169 {98, 0x00},
1170 {93, 0x00},
1171 {88, 0x00},
1172 {83, 0x00},
1173 {78, 0x00},
1174 },
1175
1176 {
1177 {110, 0x3f},
1178 {104, 0x3f},
1179 {98, 0x3f},
1180 {110, 0x3e},
1181 {104, 0x3e},
1182 {98, 0x3e},
1183 {110, 0x3d},
1184 {104, 0x3d},
1185 {98, 0x3d},
1186 {110, 0x3c},
1187 {104, 0x3c},
1188 {98, 0x3c},
1189 {110, 0x3b},
1190 {104, 0x3b},
1191 {98, 0x3b},
1192 {110, 0x3a},
1193 {104, 0x3a},
1194 {98, 0x3a},
1195 {110, 0x39},
1196 {104, 0x39},
1197 {98, 0x39},
1198 {110, 0x38},
1199 {104, 0x38},
1200 {98, 0x38},
1201 {110, 0x37},
1202 {104, 0x37},
1203 {98, 0x37},
1204 {110, 0x36},
1205 {104, 0x36},
1206 {98, 0x36},
1207 {110, 0x35},
1208 {104, 0x35},
1209 {98, 0x35},
1210 {110, 0x34},
1211 {104, 0x34},
1212 {98, 0x34},
1213 {110, 0x33},
1214 {104, 0x33},
1215 {98, 0x33},
1216 {110, 0x32},
1217 {104, 0x32},
1218 {98, 0x32},
1219 {110, 0x31},
1220 {104, 0x31},
1221 {98, 0x31},
1222 {110, 0x30},
1223 {104, 0x30},
1224 {98, 0x30},
1225 {110, 0x6},
1226 {104, 0x6},
1227 {98, 0x6},
1228 {110, 0x5},
1229 {104, 0x5},
1230 {98, 0x5},
1231 {110, 0x4},
1232 {104, 0x4},
1233 {98, 0x4},
1234 {110, 0x3},
1235 {104, 0x3},
1236 {98, 0x3},
1237 {110, 0x2},
1238 {104, 0x2},
1239 {98, 0x2},
1240 {110, 0x1},
1241 {104, 0x1},
1242 {98, 0x1},
1243 {110, 0x0},
1244 {104, 0x0},
1245 {98, 0x0},
1246 {97, 0},
1247 {96, 0},
1248 {95, 0},
1249 {94, 0},
1250 {93, 0},
1251 {92, 0},
1252 {91, 0},
1253 {90, 0},
1254 {89, 0},
1255 {88, 0},
1256 {87, 0},
1257 {86, 0},
1258 {85, 0},
1259 {84, 0},
1260 {83, 0},
1261 {82, 0},
1262 {81, 0},
1263 {80, 0},
1264 {79, 0},
1265 {78, 0},
1266 {77, 0},
1267 {76, 0},
1268 {75, 0},
1269 {74, 0},
1270 {73, 0},
1271 {72, 0},
1272 {71, 0},
1273 {70, 0},
1274 {69, 0},
1275 {68, 0},
1276 {67, 0},
1277 {66, 0},
1278 {65, 0},
1279 {64, 0},
1280 {63, 0},
1281 {62, 0},
1282 {61, 0},
1283 {60, 0},
1284 {59, 0},
1285 }
1286};
1287
1288static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
1289 u8 is_fat, u8 ctrl_chan_high,
1290 struct iwl4965_tx_power_db *tx_power_tbl)
1291{
1292 u8 saturation_power;
1293 s32 target_power;
1294 s32 user_target_power;
1295 s32 power_limit;
1296 s32 current_temp;
1297 s32 reg_limit;
1298 s32 current_regulatory;
1299 s32 txatten_grp = CALIB_CH_GROUP_MAX;
1300 int i;
1301 int c;
1302 const struct iwl_channel_info *ch_info = NULL;
1303 struct iwl_eeprom_calib_ch_info ch_eeprom_info;
1304 const struct iwl_eeprom_calib_measure *measurement;
1305 s16 voltage;
1306 s32 init_voltage;
1307 s32 voltage_compensation;
1308 s32 degrees_per_05db_num;
1309 s32 degrees_per_05db_denom;
1310 s32 factory_temp;
1311 s32 temperature_comp[2];
1312 s32 factory_gain_index[2];
1313 s32 factory_actual_pwr[2];
1314 s32 power_index;
1315
1316
1317
1318 user_target_power = 2 * priv->tx_power_user_lmt;
1319
1320
1321 IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band,
1322 is_fat);
1323
1324 ch_info = iwl_get_channel_info(priv, priv->band, channel);
1325
1326 if (!is_channel_valid(ch_info))
1327 return -EINVAL;
1328
1329
1330
1331 txatten_grp = iwl4965_get_tx_atten_grp(channel);
1332 if (txatten_grp < 0)
1333 return -EINVAL;
1334
1335 IWL_DEBUG_TXPOWER("channel %d belongs to txatten group %d\n",
1336 channel, txatten_grp);
1337
1338 if (is_fat) {
1339 if (ctrl_chan_high)
1340 channel -= 2;
1341 else
1342 channel += 2;
1343 }
1344
1345
1346
1347 if (band)
1348 saturation_power = priv->calib_info->saturation_power24;
1349 else
1350 saturation_power = priv->calib_info->saturation_power52;
1351
1352 if (saturation_power < IWL_TX_POWER_SATURATION_MIN ||
1353 saturation_power > IWL_TX_POWER_SATURATION_MAX) {
1354 if (band)
1355 saturation_power = IWL_TX_POWER_DEFAULT_SATURATION_24;
1356 else
1357 saturation_power = IWL_TX_POWER_DEFAULT_SATURATION_52;
1358 }
1359
1360
1361
1362 if (is_fat)
1363 reg_limit = ch_info->fat_max_power_avg * 2;
1364 else
1365 reg_limit = ch_info->max_power_avg * 2;
1366
1367 if ((reg_limit < IWL_TX_POWER_REGULATORY_MIN) ||
1368 (reg_limit > IWL_TX_POWER_REGULATORY_MAX)) {
1369 if (band)
1370 reg_limit = IWL_TX_POWER_DEFAULT_REGULATORY_24;
1371 else
1372 reg_limit = IWL_TX_POWER_DEFAULT_REGULATORY_52;
1373 }
1374
1375
1376
1377 iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info);
1378
1379
1380 voltage = priv->calib_info->voltage;
1381 init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage);
1382 voltage_compensation =
1383 iwl4965_get_voltage_compensation(voltage, init_voltage);
1384
1385 IWL_DEBUG_TXPOWER("curr volt %d eeprom volt %d volt comp %d\n",
1386 init_voltage,
1387 voltage, voltage_compensation);
1388
1389
1390 current_temp = max(priv->temperature, IWL_TX_POWER_TEMPERATURE_MIN);
1391 current_temp = min(priv->temperature, IWL_TX_POWER_TEMPERATURE_MAX);
1392 current_temp = KELVIN_TO_CELSIUS(current_temp);
1393
1394
1395
1396 degrees_per_05db_num =
1397 tx_power_cmp_tble[txatten_grp].degrees_per_05db_a;
1398 degrees_per_05db_denom =
1399 tx_power_cmp_tble[txatten_grp].degrees_per_05db_a_denom;
1400
1401
1402 for (c = 0; c < 2; c++) {
1403 measurement = &ch_eeprom_info.measurements[c][1];
1404
1405
1406
1407 factory_temp = measurement->temperature;
1408 iwl4965_math_div_round((current_temp - factory_temp) *
1409 degrees_per_05db_denom,
1410 degrees_per_05db_num,
1411 &temperature_comp[c]);
1412
1413 factory_gain_index[c] = measurement->gain_idx;
1414 factory_actual_pwr[c] = measurement->actual_pow;
1415
1416 IWL_DEBUG_TXPOWER("chain = %d\n", c);
1417 IWL_DEBUG_TXPOWER("fctry tmp %d, "
1418 "curr tmp %d, comp %d steps\n",
1419 factory_temp, current_temp,
1420 temperature_comp[c]);
1421
1422 IWL_DEBUG_TXPOWER("fctry idx %d, fctry pwr %d\n",
1423 factory_gain_index[c],
1424 factory_actual_pwr[c]);
1425 }
1426
1427
1428 for (i = 0; i < POWER_TABLE_NUM_ENTRIES; i++) {
1429 u8 is_mimo_rate;
1430 union iwl4965_tx_power_dual_stream tx_power;
1431
1432
1433
1434
1435 if (i & 0x8) {
1436 current_regulatory = reg_limit -
1437 IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION;
1438 is_mimo_rate = 1;
1439 } else {
1440 current_regulatory = reg_limit;
1441 is_mimo_rate = 0;
1442 }
1443
1444
1445 power_limit = saturation_power - back_off_table[i];
1446 if (power_limit > current_regulatory)
1447 power_limit = current_regulatory;
1448
1449
1450
1451 target_power = user_target_power;
1452 if (target_power > power_limit)
1453 target_power = power_limit;
1454
1455 IWL_DEBUG_TXPOWER("rate %d sat %d reg %d usr %d tgt %d\n",
1456 i, saturation_power - back_off_table[i],
1457 current_regulatory, user_target_power,
1458 target_power);
1459
1460
1461 for (c = 0; c < 2; c++) {
1462 s32 atten_value;
1463
1464 if (is_mimo_rate)
1465 atten_value =
1466 (s32)le32_to_cpu(priv->card_alive_init.
1467 tx_atten[txatten_grp][c]);
1468 else
1469 atten_value = 0;
1470
1471
1472 power_index = (u8) (factory_gain_index[c] -
1473 (target_power -
1474 factory_actual_pwr[c]) -
1475 temperature_comp[c] -
1476 voltage_compensation +
1477 atten_value);
1478
1479
1480
1481
1482 if (power_index < get_min_power_index(i, band))
1483 power_index = get_min_power_index(i, band);
1484
1485
1486 if (!band)
1487 power_index += 9;
1488
1489
1490 if (i == POWER_TABLE_CCK_ENTRY)
1491 power_index +=
1492 IWL_TX_POWER_CCK_COMPENSATION_C_STEP;
1493
1494
1495 if (power_index > 107) {
1496 IWL_WARNING("txpower index %d > 107\n",
1497 power_index);
1498 power_index = 107;
1499 }
1500 if (power_index < 0) {
1501 IWL_WARNING("txpower index %d < 0\n",
1502 power_index);
1503 power_index = 0;
1504 }
1505
1506
1507 tx_power.s.radio_tx_gain[c] =
1508 gain_table[band][power_index].radio;
1509 tx_power.s.dsp_predis_atten[c] =
1510 gain_table[band][power_index].dsp;
1511
1512 IWL_DEBUG_TXPOWER("chain %d mimo %d index %d "
1513 "gain 0x%02x dsp %d\n",
1514 c, atten_value, power_index,
1515 tx_power.s.radio_tx_gain[c],
1516 tx_power.s.dsp_predis_atten[c]);
1517 }
1518
1519 tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw);
1520
1521 }
1522
1523 return 0;
1524}
1525
1526
1527
1528
1529
1530
1531
1532static int iwl4965_send_tx_power(struct iwl_priv *priv)
1533{
1534 struct iwl4965_txpowertable_cmd cmd = { 0 };
1535 int ret;
1536 u8 band = 0;
1537 u8 is_fat = 0;
1538 u8 ctrl_chan_high = 0;
1539
1540 if (test_bit(STATUS_SCANNING, &priv->status)) {
1541
1542
1543
1544 IWL_WARNING("TX Power requested while scanning!\n");
1545 return -EAGAIN;
1546 }
1547
1548 band = priv->band == IEEE80211_BAND_2GHZ;
1549
1550 is_fat = is_fat_channel(priv->active_rxon.flags);
1551
1552 if (is_fat &&
1553 (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
1554 ctrl_chan_high = 1;
1555
1556 cmd.band = band;
1557 cmd.channel = priv->active_rxon.channel;
1558
1559 ret = iwl4965_fill_txpower_tbl(priv, band,
1560 le16_to_cpu(priv->active_rxon.channel),
1561 is_fat, ctrl_chan_high, &cmd.tx_power);
1562 if (ret)
1563 goto out;
1564
1565 ret = iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, sizeof(cmd), &cmd);
1566
1567out:
1568 return ret;
1569}
1570
1571static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
1572{
1573 int ret = 0;
1574 struct iwl4965_rxon_assoc_cmd rxon_assoc;
1575 const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
1576 const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
1577
1578 if ((rxon1->flags == rxon2->flags) &&
1579 (rxon1->filter_flags == rxon2->filter_flags) &&
1580 (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
1581 (rxon1->ofdm_ht_single_stream_basic_rates ==
1582 rxon2->ofdm_ht_single_stream_basic_rates) &&
1583 (rxon1->ofdm_ht_dual_stream_basic_rates ==
1584 rxon2->ofdm_ht_dual_stream_basic_rates) &&
1585 (rxon1->rx_chain == rxon2->rx_chain) &&
1586 (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
1587 IWL_DEBUG_INFO("Using current RXON_ASSOC. Not resending.\n");
1588 return 0;
1589 }
1590
1591 rxon_assoc.flags = priv->staging_rxon.flags;
1592 rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
1593 rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
1594 rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
1595 rxon_assoc.reserved = 0;
1596 rxon_assoc.ofdm_ht_single_stream_basic_rates =
1597 priv->staging_rxon.ofdm_ht_single_stream_basic_rates;
1598 rxon_assoc.ofdm_ht_dual_stream_basic_rates =
1599 priv->staging_rxon.ofdm_ht_dual_stream_basic_rates;
1600 rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain;
1601
1602 ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
1603 sizeof(rxon_assoc), &rxon_assoc, NULL);
1604 if (ret)
1605 return ret;
1606
1607 return ret;
1608}
1609
1610#ifdef IEEE80211_CONF_CHANNEL_SWITCH
1611static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
1612{
1613 int rc;
1614 u8 band = 0;
1615 u8 is_fat = 0;
1616 u8 ctrl_chan_high = 0;
1617 struct iwl4965_channel_switch_cmd cmd = { 0 };
1618 const struct iwl_channel_info *ch_info;
1619
1620 band = priv->band == IEEE80211_BAND_2GHZ;
1621
1622 ch_info = iwl_get_channel_info(priv, priv->band, channel);
1623
1624 is_fat = is_fat_channel(priv->staging_rxon.flags);
1625
1626 if (is_fat &&
1627 (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
1628 ctrl_chan_high = 1;
1629
1630 cmd.band = band;
1631 cmd.expect_beacon = 0;
1632 cmd.channel = cpu_to_le16(channel);
1633 cmd.rxon_flags = priv->active_rxon.flags;
1634 cmd.rxon_filter_flags = priv->active_rxon.filter_flags;
1635 cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
1636 if (ch_info)
1637 cmd.expect_beacon = is_channel_radar(ch_info);
1638 else
1639 cmd.expect_beacon = 1;
1640
1641 rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_fat,
1642 ctrl_chan_high, &cmd.tx_power);
1643 if (rc) {
1644 IWL_DEBUG_11H("error:%d fill txpower_tbl\n", rc);
1645 return rc;
1646 }
1647
1648 rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
1649 return rc;
1650}
1651#endif
1652
1653static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
1654{
1655 struct iwl4965_shared *s = priv->shared_virt;
1656 return le32_to_cpu(s->rb_closed) & 0xFFF;
1657}
1658
1659static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
1660{
1661 priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
1662 sizeof(struct iwl4965_shared),
1663 &priv->shared_phys);
1664 if (!priv->shared_virt)
1665 return -ENOMEM;
1666
1667 memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared));
1668
1669 priv->rb_closed_offset = offsetof(struct iwl4965_shared, rb_closed);
1670
1671 return 0;
1672}
1673
1674static void iwl4965_free_shared_mem(struct iwl_priv *priv)
1675{
1676 if (priv->shared_virt)
1677 pci_free_consistent(priv->pci_dev,
1678 sizeof(struct iwl4965_shared),
1679 priv->shared_virt,
1680 priv->shared_phys);
1681}
1682
1683
1684
1685
1686static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
1687 struct iwl_tx_queue *txq,
1688 u16 byte_cnt)
1689{
1690 int len;
1691 int txq_id = txq->q.id;
1692 struct iwl4965_shared *shared_data = priv->shared_virt;
1693
1694 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
1695
1696
1697 IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
1698 tfd_offset[txq->q.write_ptr], byte_cnt, len);
1699
1700
1701 if (txq->q.write_ptr < IWL49_MAX_WIN_SIZE)
1702 IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
1703 tfd_offset[IWL49_QUEUE_SIZE + txq->q.write_ptr],
1704 byte_cnt, len);
1705}
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716static s32 sign_extend(u32 oper, int index)
1717{
1718 u8 shift = 31 - index;
1719
1720 return (s32)(oper << shift) >> shift;
1721}
1722
1723
1724
1725
1726
1727
1728
1729static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)
1730{
1731 s32 temperature;
1732 s32 vt;
1733 s32 R1, R2, R3;
1734 u32 R4;
1735
1736 if (test_bit(STATUS_TEMPERATURE, &priv->status) &&
1737 (priv->statistics.flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK)) {
1738 IWL_DEBUG_TEMP("Running FAT temperature calibration\n");
1739 R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]);
1740 R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]);
1741 R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[1]);
1742 R4 = le32_to_cpu(priv->card_alive_init.therm_r4[1]);
1743 } else {
1744 IWL_DEBUG_TEMP("Running temperature calibration\n");
1745 R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[0]);
1746 R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[0]);
1747 R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[0]);
1748 R4 = le32_to_cpu(priv->card_alive_init.therm_r4[0]);
1749 }
1750
1751
1752
1753
1754
1755
1756
1757
1758 if (!test_bit(STATUS_TEMPERATURE, &priv->status))
1759 vt = sign_extend(R4, 23);
1760 else
1761 vt = sign_extend(
1762 le32_to_cpu(priv->statistics.general.temperature), 23);
1763
1764 IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
1765
1766 if (R3 == R1) {
1767 IWL_ERROR("Calibration conflict R1 == R3\n");
1768 return -1;
1769 }
1770
1771
1772
1773 temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2);
1774 temperature /= (R3 - R1);
1775 temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET;
1776
1777 IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n",
1778 temperature, KELVIN_TO_CELSIUS(temperature));
1779
1780 return temperature;
1781}
1782
1783
1784#define IWL_TEMPERATURE_THRESHOLD 3
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv)
1796{
1797 int temp_diff;
1798
1799 if (!test_bit(STATUS_STATISTICS, &priv->status)) {
1800 IWL_DEBUG_TEMP("Temperature not updated -- no statistics.\n");
1801 return 0;
1802 }
1803
1804 temp_diff = priv->temperature - priv->last_temperature;
1805
1806
1807 if (temp_diff < 0) {
1808 IWL_DEBUG_POWER("Getting cooler, delta %d, \n", temp_diff);
1809 temp_diff = -temp_diff;
1810 } else if (temp_diff == 0)
1811 IWL_DEBUG_POWER("Same temp, \n");
1812 else
1813 IWL_DEBUG_POWER("Getting warmer, delta %d, \n", temp_diff);
1814
1815 if (temp_diff < IWL_TEMPERATURE_THRESHOLD) {
1816 IWL_DEBUG_POWER("Thermal txpower calib not needed\n");
1817 return 0;
1818 }
1819
1820 IWL_DEBUG_POWER("Thermal txpower calib needed\n");
1821
1822 return 1;
1823}
1824
1825static void iwl4965_temperature_calib(struct iwl_priv *priv)
1826{
1827 s32 temp;
1828
1829 temp = iwl4965_hw_get_temperature(priv);
1830 if (temp < 0)
1831 return;
1832
1833 if (priv->temperature != temp) {
1834 if (priv->temperature)
1835 IWL_DEBUG_TEMP("Temperature changed "
1836 "from %dC to %dC\n",
1837 KELVIN_TO_CELSIUS(priv->temperature),
1838 KELVIN_TO_CELSIUS(temp));
1839 else
1840 IWL_DEBUG_TEMP("Temperature "
1841 "initialized to %dC\n",
1842 KELVIN_TO_CELSIUS(temp));
1843 }
1844
1845 priv->temperature = temp;
1846 set_bit(STATUS_TEMPERATURE, &priv->status);
1847
1848 if (!priv->disable_tx_power_cal &&
1849 unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
1850 iwl4965_is_temp_calib_needed(priv))
1851 queue_work(priv->workqueue, &priv->txpower_work);
1852}
1853
1854
1855
1856
1857static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv,
1858 u16 txq_id)
1859{
1860
1861
1862 iwl_write_prph(priv,
1863 IWL49_SCD_QUEUE_STATUS_BITS(txq_id),
1864 (0 << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
1865 (1 << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
1866}
1867
1868
1869
1870
1871
1872static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
1873 u16 ssn_idx, u8 tx_fifo)
1874{
1875 int ret = 0;
1876
1877 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
1878 (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
1879 IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
1880 txq_id, IWL49_FIRST_AMPDU_QUEUE,
1881 IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1);
1882 return -EINVAL;
1883 }
1884
1885 ret = iwl_grab_nic_access(priv);
1886 if (ret)
1887 return ret;
1888
1889 iwl4965_tx_queue_stop_scheduler(priv, txq_id);
1890
1891 iwl_clear_bits_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, (1 << txq_id));
1892
1893 priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
1894 priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
1895
1896 iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx);
1897
1898 iwl_clear_bits_prph(priv, IWL49_SCD_INTERRUPT_MASK, (1 << txq_id));
1899 iwl_txq_ctx_deactivate(priv, txq_id);
1900 iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
1901
1902 iwl_release_nic_access(priv);
1903
1904 return 0;
1905}
1906
1907
1908
1909
1910static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
1911 u16 txq_id)
1912{
1913 u32 tbl_dw_addr;
1914 u32 tbl_dw;
1915 u16 scd_q2ratid;
1916
1917 scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
1918
1919 tbl_dw_addr = priv->scd_base_addr +
1920 IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
1921
1922 tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
1923
1924 if (txq_id & 0x1)
1925 tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
1926 else
1927 tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
1928
1929 iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw);
1930
1931 return 0;
1932}
1933
1934
1935
1936
1937
1938
1939
1940
1941static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
1942 int tx_fifo, int sta_id, int tid, u16 ssn_idx)
1943{
1944 unsigned long flags;
1945 int ret;
1946 u16 ra_tid;
1947
1948 if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
1949 (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
1950 IWL_WARNING("queue number out of range: %d, must be %d to %d\n",
1951 txq_id, IWL49_FIRST_AMPDU_QUEUE,
1952 IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES - 1);
1953 return -EINVAL;
1954 }
1955
1956 ra_tid = BUILD_RAxTID(sta_id, tid);
1957
1958
1959 iwl_sta_modify_enable_tid_tx(priv, sta_id, tid);
1960
1961 spin_lock_irqsave(&priv->lock, flags);
1962 ret = iwl_grab_nic_access(priv);
1963 if (ret) {
1964 spin_unlock_irqrestore(&priv->lock, flags);
1965 return ret;
1966 }
1967
1968
1969 iwl4965_tx_queue_stop_scheduler(priv, txq_id);
1970
1971
1972 iwl4965_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
1973
1974
1975 iwl_set_bits_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, (1 << txq_id));
1976
1977
1978
1979 priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
1980 priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
1981 iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx);
1982
1983
1984 iwl_write_targ_mem(priv,
1985 priv->scd_base_addr + IWL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id),
1986 (SCD_WIN_SIZE << IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
1987 IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
1988
1989 iwl_write_targ_mem(priv, priv->scd_base_addr +
1990 IWL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32),
1991 (SCD_FRAME_LIMIT << IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS)
1992 & IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
1993
1994 iwl_set_bits_prph(priv, IWL49_SCD_INTERRUPT_MASK, (1 << txq_id));
1995
1996
1997 iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
1998
1999 iwl_release_nic_access(priv);
2000 spin_unlock_irqrestore(&priv->lock, flags);
2001
2002 return 0;
2003}
2004
2005
2006static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len)
2007{
2008 switch (cmd_id) {
2009 case REPLY_RXON:
2010 return (u16) sizeof(struct iwl4965_rxon_cmd);
2011 default:
2012 return len;
2013 }
2014}
2015
2016static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
2017{
2018 struct iwl4965_addsta_cmd *addsta = (struct iwl4965_addsta_cmd *)data;
2019 addsta->mode = cmd->mode;
2020 memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify));
2021 memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo));
2022 addsta->station_flags = cmd->station_flags;
2023 addsta->station_flags_msk = cmd->station_flags_msk;
2024 addsta->tid_disable_tx = cmd->tid_disable_tx;
2025 addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;
2026 addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;
2027 addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;
2028 addsta->reserved1 = __constant_cpu_to_le16(0);
2029 addsta->reserved2 = __constant_cpu_to_le32(0);
2030
2031 return (u16)sizeof(struct iwl4965_addsta_cmd);
2032}
2033
2034static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
2035{
2036 return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN;
2037}
2038
2039
2040
2041
2042static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
2043 struct iwl_ht_agg *agg,
2044 struct iwl4965_tx_resp *tx_resp,
2045 int txq_id, u16 start_idx)
2046{
2047 u16 status;
2048 struct agg_tx_status *frame_status = tx_resp->u.agg_status;
2049 struct ieee80211_tx_info *info = NULL;
2050 struct ieee80211_hdr *hdr = NULL;
2051 u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
2052 int i, sh, idx;
2053 u16 seq;
2054 if (agg->wait_for_ba)
2055 IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");
2056
2057 agg->frame_count = tx_resp->frame_count;
2058 agg->start_idx = start_idx;
2059 agg->rate_n_flags = rate_n_flags;
2060 agg->bitmap = 0;
2061
2062
2063 if (agg->frame_count == 1) {
2064
2065 status = le16_to_cpu(frame_status[0].status);
2066 idx = start_idx;
2067
2068
2069 IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
2070 agg->frame_count, agg->start_idx, idx);
2071
2072 info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
2073 info->status.retry_count = tx_resp->failure_frame;
2074 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
2075 info->flags |= iwl_is_tx_success(status)?
2076 IEEE80211_TX_STAT_ACK : 0;
2077 iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
2078
2079
2080 IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
2081 status & 0xff, tx_resp->failure_frame);
2082 IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
2083
2084 agg->wait_for_ba = 0;
2085 } else {
2086
2087 u64 bitmap = 0;
2088 int start = agg->start_idx;
2089
2090
2091 for (i = 0; i < agg->frame_count; i++) {
2092 u16 sc;
2093 status = le16_to_cpu(frame_status[i].status);
2094 seq = le16_to_cpu(frame_status[i].sequence);
2095 idx = SEQ_TO_INDEX(seq);
2096 txq_id = SEQ_TO_QUEUE(seq);
2097
2098 if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
2099 AGG_TX_STATE_ABORT_MSK))
2100 continue;
2101
2102 IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
2103 agg->frame_count, txq_id, idx);
2104
2105 hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
2106
2107 sc = le16_to_cpu(hdr->seq_ctrl);
2108 if (idx != (SEQ_TO_SN(sc) & 0xff)) {
2109 IWL_ERROR("BUG_ON idx doesn't match seq control"
2110 " idx=%d, seq_idx=%d, seq=%d\n",
2111 idx, SEQ_TO_SN(sc),
2112 hdr->seq_ctrl);
2113 return -1;
2114 }
2115
2116 IWL_DEBUG_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n",
2117 i, idx, SEQ_TO_SN(sc));
2118
2119 sh = idx - start;
2120 if (sh > 64) {
2121 sh = (start - idx) + 0xff;
2122 bitmap = bitmap << sh;
2123 sh = 0;
2124 start = idx;
2125 } else if (sh < -64)
2126 sh = 0xff - (start - idx);
2127 else if (sh < 0) {
2128 sh = start - idx;
2129 start = idx;
2130 bitmap = bitmap << sh;
2131 sh = 0;
2132 }
2133 bitmap |= 1ULL << sh;
2134 IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
2135 start, (unsigned long long)bitmap);
2136 }
2137
2138 agg->bitmap = bitmap;
2139 agg->start_idx = start;
2140 IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
2141 agg->frame_count, agg->start_idx,
2142 (unsigned long long)agg->bitmap);
2143
2144 if (bitmap)
2145 agg->wait_for_ba = 1;
2146 }
2147 return 0;
2148}
2149
2150
2151
2152
2153static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2154 struct iwl_rx_mem_buffer *rxb)
2155{
2156 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
2157 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
2158 int txq_id = SEQ_TO_QUEUE(sequence);
2159 int index = SEQ_TO_INDEX(sequence);
2160 struct iwl_tx_queue *txq = &priv->txq[txq_id];
2161 struct ieee80211_tx_info *info;
2162 struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
2163 u32 status = le32_to_cpu(tx_resp->u.status);
2164 int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
2165 __le16 fc;
2166 struct ieee80211_hdr *hdr;
2167 u8 *qc = NULL;
2168
2169 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
2170 IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
2171 "is out of range [0-%d] %d %d\n", txq_id,
2172 index, txq->q.n_bd, txq->q.write_ptr,
2173 txq->q.read_ptr);
2174 return;
2175 }
2176
2177 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
2178 memset(&info->status, 0, sizeof(info->status));
2179
2180 hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
2181 fc = hdr->frame_control;
2182 if (ieee80211_is_data_qos(fc)) {
2183 qc = ieee80211_get_qos_ctl(hdr);
2184 tid = qc[0] & 0xf;
2185 }
2186
2187 sta_id = iwl_get_ra_sta_id(priv, hdr);
2188 if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {
2189 IWL_ERROR("Station not known\n");
2190 return;
2191 }
2192
2193 if (txq->sched_retry) {
2194 const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
2195 struct iwl_ht_agg *agg = NULL;
2196
2197 if (!qc)
2198 return;
2199
2200 agg = &priv->stations[sta_id].tid[tid].agg;
2201
2202 iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
2203
2204
2205 if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status))
2206 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
2207
2208 if (txq->q.read_ptr != (scd_ssn & 0xff)) {
2209 int freed, ampdu_q;
2210 index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
2211 IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
2212 "%d index %d\n", scd_ssn , index);
2213 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
2214 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
2215
2216 if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
2217 txq_id >= 0 && priv->mac80211_registered &&
2218 agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) {
2219
2220 ampdu_q = txq_id - IWL49_FIRST_AMPDU_QUEUE +
2221 priv->hw->queues;
2222 if (agg->state == IWL_AGG_OFF)
2223 ieee80211_wake_queue(priv->hw, txq_id);
2224 else
2225 ieee80211_wake_queue(priv->hw, ampdu_q);
2226 }
2227 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
2228 }
2229 } else {
2230 info->status.retry_count = tx_resp->failure_frame;
2231 info->flags |=
2232 iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
2233 iwl_hwrate_to_tx_control(priv,
2234 le32_to_cpu(tx_resp->rate_n_flags),
2235 info);
2236
2237 IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags "
2238 "0x%x retries %d\n", txq_id,
2239 iwl_get_tx_fail_reason(status),
2240 status, le32_to_cpu(tx_resp->rate_n_flags),
2241 tx_resp->failure_frame);
2242
2243 IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
2244
2245 if (index != -1) {
2246 int freed = iwl_tx_queue_reclaim(priv, txq_id, index);
2247 if (tid != MAX_TID_COUNT)
2248 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
2249 if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
2250 (txq_id >= 0) && priv->mac80211_registered)
2251 ieee80211_wake_queue(priv->hw, txq_id);
2252 if (tid != MAX_TID_COUNT)
2253 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
2254 }
2255 }
2256
2257 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
2258 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
2259}
2260
2261static int iwl4965_calc_rssi(struct iwl_priv *priv,
2262 struct iwl_rx_phy_res *rx_resp)
2263{
2264
2265
2266 struct iwl4965_rx_non_cfg_phy *ncphy =
2267 (struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
2268 u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL49_AGC_DB_MASK)
2269 >> IWL49_AGC_DB_POS;
2270
2271 u32 valid_antennae =
2272 (le16_to_cpu(rx_resp->phy_flags) & IWL49_RX_PHY_FLAGS_ANTENNAE_MASK)
2273 >> IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET;
2274 u8 max_rssi = 0;
2275 u32 i;
2276
2277
2278
2279
2280
2281
2282 for (i = 0; i < 3; i++)
2283 if (valid_antennae & (1 << i))
2284 max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
2285
2286 IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
2287 ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
2288 max_rssi, agc);
2289
2290
2291
2292 return max_rssi - agc - IWL_RSSI_OFFSET;
2293}
2294
2295
2296
2297static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
2298{
2299
2300 priv->rx_handlers[REPLY_RX] = iwl_rx_reply_rx;
2301
2302 priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;
2303}
2304
2305static void iwl4965_setup_deferred_work(struct iwl_priv *priv)
2306{
2307 INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work);
2308}
2309
2310static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
2311{
2312 cancel_work_sync(&priv->txpower_work);
2313}
2314
2315
2316static struct iwl_hcmd_ops iwl4965_hcmd = {
2317 .rxon_assoc = iwl4965_send_rxon_assoc,
2318};
2319
2320static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
2321 .get_hcmd_size = iwl4965_get_hcmd_size,
2322 .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
2323 .chain_noise_reset = iwl4965_chain_noise_reset,
2324 .gain_computation = iwl4965_gain_computation,
2325 .rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag,
2326 .calc_rssi = iwl4965_calc_rssi,
2327};
2328
2329static struct iwl_lib_ops iwl4965_lib = {
2330 .set_hw_params = iwl4965_hw_set_hw_params,
2331 .alloc_shared_mem = iwl4965_alloc_shared_mem,
2332 .free_shared_mem = iwl4965_free_shared_mem,
2333 .shared_mem_rx_idx = iwl4965_shared_mem_rx_idx,
2334 .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl,
2335 .txq_set_sched = iwl4965_txq_set_sched,
2336 .txq_agg_enable = iwl4965_txq_agg_enable,
2337 .txq_agg_disable = iwl4965_txq_agg_disable,
2338 .rx_handler_setup = iwl4965_rx_handler_setup,
2339 .setup_deferred_work = iwl4965_setup_deferred_work,
2340 .cancel_deferred_work = iwl4965_cancel_deferred_work,
2341 .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr,
2342 .alive_notify = iwl4965_alive_notify,
2343 .init_alive_start = iwl4965_init_alive_start,
2344 .load_ucode = iwl4965_load_bsm,
2345 .apm_ops = {
2346 .init = iwl4965_apm_init,
2347 .reset = iwl4965_apm_reset,
2348 .stop = iwl4965_apm_stop,
2349 .config = iwl4965_nic_config,
2350 .set_pwr_src = iwl4965_set_pwr_src,
2351 },
2352 .eeprom_ops = {
2353 .regulatory_bands = {
2354 EEPROM_REGULATORY_BAND_1_CHANNELS,
2355 EEPROM_REGULATORY_BAND_2_CHANNELS,
2356 EEPROM_REGULATORY_BAND_3_CHANNELS,
2357 EEPROM_REGULATORY_BAND_4_CHANNELS,
2358 EEPROM_REGULATORY_BAND_5_CHANNELS,
2359 EEPROM_4965_REGULATORY_BAND_24_FAT_CHANNELS,
2360 EEPROM_4965_REGULATORY_BAND_52_FAT_CHANNELS
2361 },
2362 .verify_signature = iwlcore_eeprom_verify_signature,
2363 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
2364 .release_semaphore = iwlcore_eeprom_release_semaphore,
2365 .check_version = iwl4965_eeprom_check_version,
2366 .query_addr = iwlcore_eeprom_query_addr,
2367 },
2368 .send_tx_power = iwl4965_send_tx_power,
2369 .update_chain_flags = iwl4965_update_chain_flags,
2370 .temperature = iwl4965_temperature_calib,
2371};
2372
2373static struct iwl_ops iwl4965_ops = {
2374 .lib = &iwl4965_lib,
2375 .hcmd = &iwl4965_hcmd,
2376 .utils = &iwl4965_hcmd_utils,
2377};
2378
2379struct iwl_cfg iwl4965_agn_cfg = {
2380 .name = "4965AGN",
2381 .fw_name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode",
2382 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
2383 .eeprom_size = IWL4965_EEPROM_IMG_SIZE,
2384 .ops = &iwl4965_ops,
2385 .mod_params = &iwl4965_mod_params,
2386};
2387
2388
2389MODULE_FIRMWARE("iwlwifi-4965" IWL4965_UCODE_API ".ucode");
2390
2391module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444);
2392MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
2393module_param_named(disable, iwl4965_mod_params.disable, int, 0444);
2394MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
2395module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444);
2396MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
2397module_param_named(debug, iwl4965_mod_params.debug, int, 0444);
2398MODULE_PARM_DESC(debug, "debug output mask");
2399module_param_named(
2400 disable_hw_scan, iwl4965_mod_params.disable_hw_scan, int, 0444);
2401MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
2402
2403module_param_named(queues_num, iwl4965_mod_params.num_of_queues, int, 0444);
2404MODULE_PARM_DESC(queues_num, "number of hw queues.");
2405
2406module_param_named(qos_enable, iwl4965_mod_params.enable_qos, int, 0444);
2407MODULE_PARM_DESC(qos_enable, "enable all QoS functionality");
2408
2409module_param_named(11n_disable, iwl4965_mod_params.disable_11n, int, 0444);
2410MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
2411module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K, int, 0444);
2412MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
2413
2414module_param_named(fw_restart4965, iwl4965_mod_params.restart_fw, int, 0444);
2415MODULE_PARM_DESC(fw_restart4965, "restart firmware in case of error");
2416