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