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