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