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/pci.h>
30#include <linux/dma-mapping.h>
31#include <linux/delay.h>
32#include <linux/sched.h>
33#include <linux/skbuff.h>
34#include <linux/netdevice.h>
35#include <net/mac80211.h>
36#include <linux/etherdevice.h>
37#include <asm/unaligned.h>
38
39#include "common.h"
40#include "4965.h"
41
42
43
44
45
46
47static int
48il4965_verify_inst_sparse(struct il_priv *il, __le32 * image, u32 len)
49{
50 u32 val;
51 int ret = 0;
52 u32 errcnt = 0;
53 u32 i;
54
55 D_INFO("ucode inst image size is %u\n", len);
56
57 for (i = 0; i < len; i += 100, image += 100 / sizeof(u32)) {
58
59
60
61 il_wr(il, HBUS_TARG_MEM_RADDR, i + IL4965_RTC_INST_LOWER_BOUND);
62 val = _il_rd(il, HBUS_TARG_MEM_RDAT);
63 if (val != le32_to_cpu(*image)) {
64 ret = -EIO;
65 errcnt++;
66 if (errcnt >= 3)
67 break;
68 }
69 }
70
71 return ret;
72}
73
74
75
76
77
78static int
79il4965_verify_inst_full(struct il_priv *il, __le32 * image, u32 len)
80{
81 u32 val;
82 u32 save_len = len;
83 int ret = 0;
84 u32 errcnt;
85
86 D_INFO("ucode inst image size is %u\n", len);
87
88 il_wr(il, HBUS_TARG_MEM_RADDR, IL4965_RTC_INST_LOWER_BOUND);
89
90 errcnt = 0;
91 for (; len > 0; len -= sizeof(u32), image++) {
92
93
94
95 val = _il_rd(il, HBUS_TARG_MEM_RDAT);
96 if (val != le32_to_cpu(*image)) {
97 IL_ERR("uCode INST section is invalid at "
98 "offset 0x%x, is 0x%x, s/b 0x%x\n",
99 save_len - len, val, le32_to_cpu(*image));
100 ret = -EIO;
101 errcnt++;
102 if (errcnt >= 20)
103 break;
104 }
105 }
106
107 if (!errcnt)
108 D_INFO("ucode image in INSTRUCTION memory is good\n");
109
110 return ret;
111}
112
113
114
115
116
117int
118il4965_verify_ucode(struct il_priv *il)
119{
120 __le32 *image;
121 u32 len;
122 int ret;
123
124
125 image = (__le32 *) il->ucode_boot.v_addr;
126 len = il->ucode_boot.len;
127 ret = il4965_verify_inst_sparse(il, image, len);
128 if (!ret) {
129 D_INFO("Bootstrap uCode is good in inst SRAM\n");
130 return 0;
131 }
132
133
134 image = (__le32 *) il->ucode_init.v_addr;
135 len = il->ucode_init.len;
136 ret = il4965_verify_inst_sparse(il, image, len);
137 if (!ret) {
138 D_INFO("Initialize uCode is good in inst SRAM\n");
139 return 0;
140 }
141
142
143 image = (__le32 *) il->ucode_code.v_addr;
144 len = il->ucode_code.len;
145 ret = il4965_verify_inst_sparse(il, image, len);
146 if (!ret) {
147 D_INFO("Runtime uCode is good in inst SRAM\n");
148 return 0;
149 }
150
151 IL_ERR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
152
153
154
155
156 image = (__le32 *) il->ucode_boot.v_addr;
157 len = il->ucode_boot.len;
158 ret = il4965_verify_inst_full(il, image, len);
159
160 return ret;
161}
162
163
164
165
166
167
168
169
170
171
172
173
174
175int
176il4965_eeprom_acquire_semaphore(struct il_priv *il)
177{
178 u16 count;
179 int ret;
180
181 for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
182
183 il_set_bit(il, CSR_HW_IF_CONFIG_REG,
184 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
185
186
187 ret =
188 _il_poll_bit(il, CSR_HW_IF_CONFIG_REG,
189 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
190 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
191 EEPROM_SEM_TIMEOUT);
192 if (ret >= 0)
193 return ret;
194 }
195
196 return ret;
197}
198
199void
200il4965_eeprom_release_semaphore(struct il_priv *il)
201{
202 il_clear_bit(il, CSR_HW_IF_CONFIG_REG,
203 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
204
205}
206
207int
208il4965_eeprom_check_version(struct il_priv *il)
209{
210 u16 eeprom_ver;
211 u16 calib_ver;
212
213 eeprom_ver = il_eeprom_query16(il, EEPROM_VERSION);
214 calib_ver = il_eeprom_query16(il, EEPROM_4965_CALIB_VERSION_OFFSET);
215
216 if (eeprom_ver < il->cfg->eeprom_ver ||
217 calib_ver < il->cfg->eeprom_calib_ver)
218 goto err;
219
220 IL_INFO("device EEPROM VER=0x%x, CALIB=0x%x\n", eeprom_ver, calib_ver);
221
222 return 0;
223err:
224 IL_ERR("Unsupported (too old) EEPROM VER=0x%x < 0x%x "
225 "CALIB=0x%x < 0x%x\n", eeprom_ver, il->cfg->eeprom_ver,
226 calib_ver, il->cfg->eeprom_calib_ver);
227 return -EINVAL;
228
229}
230
231void
232il4965_eeprom_get_mac(const struct il_priv *il, u8 * mac)
233{
234 const u8 *addr = il_eeprom_query_addr(il,
235 EEPROM_MAC_ADDRESS);
236 memcpy(mac, addr, ETH_ALEN);
237}
238
239
240static int
241il4965_send_led_cmd(struct il_priv *il, struct il_led_cmd *led_cmd)
242{
243 struct il_host_cmd cmd = {
244 .id = C_LEDS,
245 .len = sizeof(struct il_led_cmd),
246 .data = led_cmd,
247 .flags = CMD_ASYNC,
248 .callback = NULL,
249 };
250 u32 reg;
251
252 reg = _il_rd(il, CSR_LED_REG);
253 if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
254 _il_wr(il, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
255
256 return il_send_cmd(il, &cmd);
257}
258
259
260void
261il4965_led_enable(struct il_priv *il)
262{
263 _il_wr(il, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
264}
265
266static int il4965_send_tx_power(struct il_priv *il);
267static int il4965_hw_get_temperature(struct il_priv *il);
268
269
270#define IL4965_UCODE_API_MAX 2
271
272
273#define IL4965_UCODE_API_MIN 2
274
275#define IL4965_FW_PRE "iwlwifi-4965-"
276#define _IL4965_MODULE_FIRMWARE(api) IL4965_FW_PRE #api ".ucode"
277#define IL4965_MODULE_FIRMWARE(api) _IL4965_MODULE_FIRMWARE(api)
278
279
280static int
281il4965_verify_bsm(struct il_priv *il)
282{
283 __le32 *image = il->ucode_boot.v_addr;
284 u32 len = il->ucode_boot.len;
285 u32 reg;
286 u32 val;
287
288 D_INFO("Begin verify bsm\n");
289
290
291 val = il_rd_prph(il, BSM_WR_DWCOUNT_REG);
292 for (reg = BSM_SRAM_LOWER_BOUND; reg < BSM_SRAM_LOWER_BOUND + len;
293 reg += sizeof(u32), image++) {
294 val = il_rd_prph(il, reg);
295 if (val != le32_to_cpu(*image)) {
296 IL_ERR("BSM uCode verification failed at "
297 "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
298 BSM_SRAM_LOWER_BOUND, reg - BSM_SRAM_LOWER_BOUND,
299 len, val, le32_to_cpu(*image));
300 return -EIO;
301 }
302 }
303
304 D_INFO("BSM bootstrap uCode image OK\n");
305
306 return 0;
307}
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341static int
342il4965_load_bsm(struct il_priv *il)
343{
344 __le32 *image = il->ucode_boot.v_addr;
345 u32 len = il->ucode_boot.len;
346 dma_addr_t pinst;
347 dma_addr_t pdata;
348 u32 inst_len;
349 u32 data_len;
350 int i;
351 u32 done;
352 u32 reg_offset;
353 int ret;
354
355 D_INFO("Begin load bsm\n");
356
357 il->ucode_type = UCODE_RT;
358
359
360 if (len > IL49_MAX_BSM_SIZE)
361 return -EINVAL;
362
363
364
365
366
367
368
369 pinst = il->ucode_init.p_addr >> 4;
370 pdata = il->ucode_init_data.p_addr >> 4;
371 inst_len = il->ucode_init.len;
372 data_len = il->ucode_init_data.len;
373
374 il_wr_prph(il, BSM_DRAM_INST_PTR_REG, pinst);
375 il_wr_prph(il, BSM_DRAM_DATA_PTR_REG, pdata);
376 il_wr_prph(il, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
377 il_wr_prph(il, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
378
379
380 for (reg_offset = BSM_SRAM_LOWER_BOUND;
381 reg_offset < BSM_SRAM_LOWER_BOUND + len;
382 reg_offset += sizeof(u32), image++)
383 _il_wr_prph(il, reg_offset, le32_to_cpu(*image));
384
385 ret = il4965_verify_bsm(il);
386 if (ret)
387 return ret;
388
389
390 il_wr_prph(il, BSM_WR_MEM_SRC_REG, 0x0);
391 il_wr_prph(il, BSM_WR_MEM_DST_REG, IL49_RTC_INST_LOWER_BOUND);
392 il_wr_prph(il, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
393
394
395
396 il_wr_prph(il, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START);
397
398
399 for (i = 0; i < 100; i++) {
400 done = il_rd_prph(il, BSM_WR_CTRL_REG);
401 if (!(done & BSM_WR_CTRL_REG_BIT_START))
402 break;
403 udelay(10);
404 }
405 if (i < 100)
406 D_INFO("BSM write complete, poll %d iterations\n", i);
407 else {
408 IL_ERR("BSM write did not complete!\n");
409 return -EIO;
410 }
411
412
413
414 il_wr_prph(il, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN);
415
416 return 0;
417}
418
419
420
421
422
423
424
425
426
427
428static int
429il4965_set_ucode_ptrs(struct il_priv *il)
430{
431 dma_addr_t pinst;
432 dma_addr_t pdata;
433 int ret = 0;
434
435
436 pinst = il->ucode_code.p_addr >> 4;
437 pdata = il->ucode_data_backup.p_addr >> 4;
438
439
440 il_wr_prph(il, BSM_DRAM_INST_PTR_REG, pinst);
441 il_wr_prph(il, BSM_DRAM_DATA_PTR_REG, pdata);
442 il_wr_prph(il, BSM_DRAM_DATA_BYTECOUNT_REG, il->ucode_data.len);
443
444
445
446 il_wr_prph(il, BSM_DRAM_INST_BYTECOUNT_REG,
447 il->ucode_code.len | BSM_DRAM_INST_LOAD);
448 D_INFO("Runtime uCode pointers are set.\n");
449
450 return ret;
451}
452
453
454
455
456
457
458
459
460
461
462
463
464static void
465il4965_init_alive_start(struct il_priv *il)
466{
467
468
469
470 if (il4965_verify_ucode(il)) {
471
472
473 D_INFO("Bad \"initialize\" uCode load.\n");
474 goto restart;
475 }
476
477
478 il->temperature = il4965_hw_get_temperature(il);
479
480
481
482
483 D_INFO("Initialization Alive received.\n");
484 if (il4965_set_ucode_ptrs(il)) {
485
486
487 D_INFO("Couldn't set up uCode pointers.\n");
488 goto restart;
489 }
490 return;
491
492restart:
493 queue_work(il->workqueue, &il->restart);
494}
495
496static bool
497iw4965_is_ht40_channel(__le32 rxon_flags)
498{
499 int chan_mod =
500 le32_to_cpu(rxon_flags & RXON_FLG_CHANNEL_MODE_MSK) >>
501 RXON_FLG_CHANNEL_MODE_POS;
502 return (chan_mod == CHANNEL_MODE_PURE_40 ||
503 chan_mod == CHANNEL_MODE_MIXED);
504}
505
506void
507il4965_nic_config(struct il_priv *il)
508{
509 unsigned long flags;
510 u16 radio_cfg;
511
512 spin_lock_irqsave(&il->lock, flags);
513
514 radio_cfg = il_eeprom_query16(il, EEPROM_RADIO_CONFIG);
515
516
517 if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) == EEPROM_4965_RF_CFG_TYPE_MAX)
518 il_set_bit(il, CSR_HW_IF_CONFIG_REG,
519 EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
520 EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
521 EEPROM_RF_CFG_DASH_MSK(radio_cfg));
522
523
524 il_set_bit(il, CSR_HW_IF_CONFIG_REG,
525 CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
526 CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
527
528 il->calib_info =
529 (struct il_eeprom_calib_info *)
530 il_eeprom_query_addr(il, EEPROM_4965_CALIB_TXPOWER_OFFSET);
531
532 spin_unlock_irqrestore(&il->lock, flags);
533}
534
535
536
537
538static void
539il4965_chain_noise_reset(struct il_priv *il)
540{
541 struct il_chain_noise_data *data = &(il->chain_noise_data);
542
543 if (data->state == IL_CHAIN_NOISE_ALIVE && il_is_any_associated(il)) {
544 struct il_calib_diff_gain_cmd cmd;
545
546
547 data->chain_noise_a = 0;
548 data->chain_noise_b = 0;
549 data->chain_noise_c = 0;
550 data->chain_signal_a = 0;
551 data->chain_signal_b = 0;
552 data->chain_signal_c = 0;
553 data->beacon_count = 0;
554
555 memset(&cmd, 0, sizeof(cmd));
556 cmd.hdr.op_code = IL_PHY_CALIBRATE_DIFF_GAIN_CMD;
557 cmd.diff_gain_a = 0;
558 cmd.diff_gain_b = 0;
559 cmd.diff_gain_c = 0;
560 if (il_send_cmd_pdu(il, C_PHY_CALIBRATION, sizeof(cmd), &cmd))
561 IL_ERR("Could not send C_PHY_CALIBRATION\n");
562 data->state = IL_CHAIN_NOISE_ACCUMULATE;
563 D_CALIB("Run chain_noise_calibrate\n");
564 }
565}
566
567static s32
568il4965_math_div_round(s32 num, s32 denom, s32 * res)
569{
570 s32 sign = 1;
571
572 if (num < 0) {
573 sign = -sign;
574 num = -num;
575 }
576 if (denom < 0) {
577 sign = -sign;
578 denom = -denom;
579 }
580 *res = 1;
581 *res = ((num * 2 + denom) / (denom * 2)) * sign;
582
583 return 1;
584}
585
586
587
588
589
590
591
592
593
594
595
596
597static s32
598il4965_get_voltage_compensation(s32 eeprom_voltage, s32 current_voltage)
599{
600 s32 comp = 0;
601
602 if (TX_POWER_IL_ILLEGAL_VOLTAGE == eeprom_voltage ||
603 TX_POWER_IL_ILLEGAL_VOLTAGE == current_voltage)
604 return 0;
605
606 il4965_math_div_round(current_voltage - eeprom_voltage,
607 TX_POWER_IL_VOLTAGE_CODES_PER_03V, &comp);
608
609 if (current_voltage > eeprom_voltage)
610 comp *= 2;
611 if ((comp < -2) || (comp > 2))
612 comp = 0;
613
614 return comp;
615}
616
617static s32
618il4965_get_tx_atten_grp(u16 channel)
619{
620 if (channel >= CALIB_IL_TX_ATTEN_GR5_FCH &&
621 channel <= CALIB_IL_TX_ATTEN_GR5_LCH)
622 return CALIB_CH_GROUP_5;
623
624 if (channel >= CALIB_IL_TX_ATTEN_GR1_FCH &&
625 channel <= CALIB_IL_TX_ATTEN_GR1_LCH)
626 return CALIB_CH_GROUP_1;
627
628 if (channel >= CALIB_IL_TX_ATTEN_GR2_FCH &&
629 channel <= CALIB_IL_TX_ATTEN_GR2_LCH)
630 return CALIB_CH_GROUP_2;
631
632 if (channel >= CALIB_IL_TX_ATTEN_GR3_FCH &&
633 channel <= CALIB_IL_TX_ATTEN_GR3_LCH)
634 return CALIB_CH_GROUP_3;
635
636 if (channel >= CALIB_IL_TX_ATTEN_GR4_FCH &&
637 channel <= CALIB_IL_TX_ATTEN_GR4_LCH)
638 return CALIB_CH_GROUP_4;
639
640 return -EINVAL;
641}
642
643static u32
644il4965_get_sub_band(const struct il_priv *il, u32 channel)
645{
646 s32 b = -1;
647
648 for (b = 0; b < EEPROM_TX_POWER_BANDS; b++) {
649 if (il->calib_info->band_info[b].ch_from == 0)
650 continue;
651
652 if (channel >= il->calib_info->band_info[b].ch_from &&
653 channel <= il->calib_info->band_info[b].ch_to)
654 break;
655 }
656
657 return b;
658}
659
660static s32
661il4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
662{
663 s32 val;
664
665 if (x2 == x1)
666 return y1;
667 else {
668 il4965_math_div_round((x2 - x) * (y1 - y2), (x2 - x1), &val);
669 return val + y2;
670 }
671}
672
673
674
675
676
677
678
679
680
681static int
682il4965_interpolate_chan(struct il_priv *il, u32 channel,
683 struct il_eeprom_calib_ch_info *chan_info)
684{
685 s32 s = -1;
686 u32 c;
687 u32 m;
688 const struct il_eeprom_calib_measure *m1;
689 const struct il_eeprom_calib_measure *m2;
690 struct il_eeprom_calib_measure *omeas;
691 u32 ch_i1;
692 u32 ch_i2;
693
694 s = il4965_get_sub_band(il, channel);
695 if (s >= EEPROM_TX_POWER_BANDS) {
696 IL_ERR("Tx Power can not find channel %d\n", channel);
697 return -1;
698 }
699
700 ch_i1 = il->calib_info->band_info[s].ch1.ch_num;
701 ch_i2 = il->calib_info->band_info[s].ch2.ch_num;
702 chan_info->ch_num = (u8) channel;
703
704 D_TXPOWER("channel %d subband %d factory cal ch %d & %d\n", channel, s,
705 ch_i1, ch_i2);
706
707 for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) {
708 for (m = 0; m < EEPROM_TX_POWER_MEASUREMENTS; m++) {
709 m1 = &(il->calib_info->band_info[s].ch1.
710 measurements[c][m]);
711 m2 = &(il->calib_info->band_info[s].ch2.
712 measurements[c][m]);
713 omeas = &(chan_info->measurements[c][m]);
714
715 omeas->actual_pow =
716 (u8) il4965_interpolate_value(channel, ch_i1,
717 m1->actual_pow, ch_i2,
718 m2->actual_pow);
719 omeas->gain_idx =
720 (u8) il4965_interpolate_value(channel, ch_i1,
721 m1->gain_idx, ch_i2,
722 m2->gain_idx);
723 omeas->temperature =
724 (u8) il4965_interpolate_value(channel, ch_i1,
725 m1->temperature,
726 ch_i2,
727 m2->temperature);
728 omeas->pa_det =
729 (s8) il4965_interpolate_value(channel, ch_i1,
730 m1->pa_det, ch_i2,
731 m2->pa_det);
732
733 D_TXPOWER("chain %d meas %d AP1=%d AP2=%d AP=%d\n", c,
734 m, m1->actual_pow, m2->actual_pow,
735 omeas->actual_pow);
736 D_TXPOWER("chain %d meas %d NI1=%d NI2=%d NI=%d\n", c,
737 m, m1->gain_idx, m2->gain_idx,
738 omeas->gain_idx);
739 D_TXPOWER("chain %d meas %d PA1=%d PA2=%d PA=%d\n", c,
740 m, m1->pa_det, m2->pa_det, omeas->pa_det);
741 D_TXPOWER("chain %d meas %d T1=%d T2=%d T=%d\n", c,
742 m, m1->temperature, m2->temperature,
743 omeas->temperature);
744 }
745 }
746
747 return 0;
748}
749
750
751
752static s32 back_off_table[] = {
753 10, 10, 10, 10, 10, 15, 17, 20,
754 10, 10, 10, 10, 10, 15, 17, 20,
755 10, 10, 10, 10, 10, 15, 17, 20,
756 10, 10, 10, 10, 10, 15, 17, 20,
757 10
758};
759
760
761
762static struct il4965_txpower_comp_entry {
763 s32 degrees_per_05db_a;
764 s32 degrees_per_05db_a_denom;
765} tx_power_cmp_tble[CALIB_CH_GROUP_MAX] = {
766 {
767 9, 2},
768 {
769 4, 1},
770 {
771 4, 1},
772 {
773 4, 1},
774 {
775 3, 1}
776};
777
778static s32
779get_min_power_idx(s32 rate_power_idx, u32 band)
780{
781 if (!band) {
782 if ((rate_power_idx & 7) <= 4)
783 return MIN_TX_GAIN_IDX_52GHZ_EXT;
784 }
785 return MIN_TX_GAIN_IDX;
786}
787
788struct gain_entry {
789 u8 dsp;
790 u8 radio;
791};
792
793static const struct gain_entry gain_table[2][108] = {
794
795 {
796 {123, 0x3F},
797 {117, 0x3F},
798 {110, 0x3F},
799 {104, 0x3F},
800 {98, 0x3F},
801 {110, 0x3E},
802 {104, 0x3E},
803 {98, 0x3E},
804 {110, 0x3D},
805 {104, 0x3D},
806 {98, 0x3D},
807 {110, 0x3C},
808 {104, 0x3C},
809 {98, 0x3C},
810 {110, 0x3B},
811 {104, 0x3B},
812 {98, 0x3B},
813 {110, 0x3A},
814 {104, 0x3A},
815 {98, 0x3A},
816 {110, 0x39},
817 {104, 0x39},
818 {98, 0x39},
819 {110, 0x38},
820 {104, 0x38},
821 {98, 0x38},
822 {110, 0x37},
823 {104, 0x37},
824 {98, 0x37},
825 {110, 0x36},
826 {104, 0x36},
827 {98, 0x36},
828 {110, 0x35},
829 {104, 0x35},
830 {98, 0x35},
831 {110, 0x34},
832 {104, 0x34},
833 {98, 0x34},
834 {110, 0x33},
835 {104, 0x33},
836 {98, 0x33},
837 {110, 0x32},
838 {104, 0x32},
839 {98, 0x32},
840 {110, 0x31},
841 {104, 0x31},
842 {98, 0x31},
843 {110, 0x30},
844 {104, 0x30},
845 {98, 0x30},
846 {110, 0x25},
847 {104, 0x25},
848 {98, 0x25},
849 {110, 0x24},
850 {104, 0x24},
851 {98, 0x24},
852 {110, 0x23},
853 {104, 0x23},
854 {98, 0x23},
855 {110, 0x22},
856 {104, 0x18},
857 {98, 0x18},
858 {110, 0x17},
859 {104, 0x17},
860 {98, 0x17},
861 {110, 0x16},
862 {104, 0x16},
863 {98, 0x16},
864 {110, 0x15},
865 {104, 0x15},
866 {98, 0x15},
867 {110, 0x14},
868 {104, 0x14},
869 {98, 0x14},
870 {110, 0x13},
871 {104, 0x13},
872 {98, 0x13},
873 {110, 0x12},
874 {104, 0x08},
875 {98, 0x08},
876 {110, 0x07},
877 {104, 0x07},
878 {98, 0x07},
879 {110, 0x06},
880 {104, 0x06},
881 {98, 0x06},
882 {110, 0x05},
883 {104, 0x05},
884 {98, 0x05},
885 {110, 0x04},
886 {104, 0x04},
887 {98, 0x04},
888 {110, 0x03},
889 {104, 0x03},
890 {98, 0x03},
891 {110, 0x02},
892 {104, 0x02},
893 {98, 0x02},
894 {110, 0x01},
895 {104, 0x01},
896 {98, 0x01},
897 {110, 0x00},
898 {104, 0x00},
899 {98, 0x00},
900 {93, 0x00},
901 {88, 0x00},
902 {83, 0x00},
903 {78, 0x00},
904 },
905
906 {
907 {110, 0x3f},
908 {104, 0x3f},
909 {98, 0x3f},
910 {110, 0x3e},
911 {104, 0x3e},
912 {98, 0x3e},
913 {110, 0x3d},
914 {104, 0x3d},
915 {98, 0x3d},
916 {110, 0x3c},
917 {104, 0x3c},
918 {98, 0x3c},
919 {110, 0x3b},
920 {104, 0x3b},
921 {98, 0x3b},
922 {110, 0x3a},
923 {104, 0x3a},
924 {98, 0x3a},
925 {110, 0x39},
926 {104, 0x39},
927 {98, 0x39},
928 {110, 0x38},
929 {104, 0x38},
930 {98, 0x38},
931 {110, 0x37},
932 {104, 0x37},
933 {98, 0x37},
934 {110, 0x36},
935 {104, 0x36},
936 {98, 0x36},
937 {110, 0x35},
938 {104, 0x35},
939 {98, 0x35},
940 {110, 0x34},
941 {104, 0x34},
942 {98, 0x34},
943 {110, 0x33},
944 {104, 0x33},
945 {98, 0x33},
946 {110, 0x32},
947 {104, 0x32},
948 {98, 0x32},
949 {110, 0x31},
950 {104, 0x31},
951 {98, 0x31},
952 {110, 0x30},
953 {104, 0x30},
954 {98, 0x30},
955 {110, 0x6},
956 {104, 0x6},
957 {98, 0x6},
958 {110, 0x5},
959 {104, 0x5},
960 {98, 0x5},
961 {110, 0x4},
962 {104, 0x4},
963 {98, 0x4},
964 {110, 0x3},
965 {104, 0x3},
966 {98, 0x3},
967 {110, 0x2},
968 {104, 0x2},
969 {98, 0x2},
970 {110, 0x1},
971 {104, 0x1},
972 {98, 0x1},
973 {110, 0x0},
974 {104, 0x0},
975 {98, 0x0},
976 {97, 0},
977 {96, 0},
978 {95, 0},
979 {94, 0},
980 {93, 0},
981 {92, 0},
982 {91, 0},
983 {90, 0},
984 {89, 0},
985 {88, 0},
986 {87, 0},
987 {86, 0},
988 {85, 0},
989 {84, 0},
990 {83, 0},
991 {82, 0},
992 {81, 0},
993 {80, 0},
994 {79, 0},
995 {78, 0},
996 {77, 0},
997 {76, 0},
998 {75, 0},
999 {74, 0},
1000 {73, 0},
1001 {72, 0},
1002 {71, 0},
1003 {70, 0},
1004 {69, 0},
1005 {68, 0},
1006 {67, 0},
1007 {66, 0},
1008 {65, 0},
1009 {64, 0},
1010 {63, 0},
1011 {62, 0},
1012 {61, 0},
1013 {60, 0},
1014 {59, 0},
1015 }
1016};
1017
1018static int
1019il4965_fill_txpower_tbl(struct il_priv *il, u8 band, u16 channel, u8 is_ht40,
1020 u8 ctrl_chan_high,
1021 struct il4965_tx_power_db *tx_power_tbl)
1022{
1023 u8 saturation_power;
1024 s32 target_power;
1025 s32 user_target_power;
1026 s32 power_limit;
1027 s32 current_temp;
1028 s32 reg_limit;
1029 s32 current_regulatory;
1030 s32 txatten_grp = CALIB_CH_GROUP_MAX;
1031 int i;
1032 int c;
1033 const struct il_channel_info *ch_info = NULL;
1034 struct il_eeprom_calib_ch_info ch_eeprom_info;
1035 const struct il_eeprom_calib_measure *measurement;
1036 s16 voltage;
1037 s32 init_voltage;
1038 s32 voltage_compensation;
1039 s32 degrees_per_05db_num;
1040 s32 degrees_per_05db_denom;
1041 s32 factory_temp;
1042 s32 temperature_comp[2];
1043 s32 factory_gain_idx[2];
1044 s32 factory_actual_pwr[2];
1045 s32 power_idx;
1046
1047
1048
1049 user_target_power = 2 * il->tx_power_user_lmt;
1050
1051
1052 D_TXPOWER("chan %d band %d is_ht40 %d\n", channel, band, is_ht40);
1053
1054 ch_info = il_get_channel_info(il, il->band, channel);
1055
1056 if (!il_is_channel_valid(ch_info))
1057 return -EINVAL;
1058
1059
1060
1061 txatten_grp = il4965_get_tx_atten_grp(channel);
1062 if (txatten_grp < 0) {
1063 IL_ERR("Can't find txatten group for channel %d.\n", channel);
1064 return txatten_grp;
1065 }
1066
1067 D_TXPOWER("channel %d belongs to txatten group %d\n", channel,
1068 txatten_grp);
1069
1070 if (is_ht40) {
1071 if (ctrl_chan_high)
1072 channel -= 2;
1073 else
1074 channel += 2;
1075 }
1076
1077
1078
1079 if (band)
1080 saturation_power = il->calib_info->saturation_power24;
1081 else
1082 saturation_power = il->calib_info->saturation_power52;
1083
1084 if (saturation_power < IL_TX_POWER_SATURATION_MIN ||
1085 saturation_power > IL_TX_POWER_SATURATION_MAX) {
1086 if (band)
1087 saturation_power = IL_TX_POWER_DEFAULT_SATURATION_24;
1088 else
1089 saturation_power = IL_TX_POWER_DEFAULT_SATURATION_52;
1090 }
1091
1092
1093
1094 if (is_ht40)
1095 reg_limit = ch_info->ht40_max_power_avg * 2;
1096 else
1097 reg_limit = ch_info->max_power_avg * 2;
1098
1099 if ((reg_limit < IL_TX_POWER_REGULATORY_MIN) ||
1100 (reg_limit > IL_TX_POWER_REGULATORY_MAX)) {
1101 if (band)
1102 reg_limit = IL_TX_POWER_DEFAULT_REGULATORY_24;
1103 else
1104 reg_limit = IL_TX_POWER_DEFAULT_REGULATORY_52;
1105 }
1106
1107
1108
1109 il4965_interpolate_chan(il, channel, &ch_eeprom_info);
1110
1111
1112 voltage = le16_to_cpu(il->calib_info->voltage);
1113 init_voltage = (s32) le32_to_cpu(il->card_alive_init.voltage);
1114 voltage_compensation =
1115 il4965_get_voltage_compensation(voltage, init_voltage);
1116
1117 D_TXPOWER("curr volt %d eeprom volt %d volt comp %d\n", init_voltage,
1118 voltage, voltage_compensation);
1119
1120
1121 current_temp = max(il->temperature, IL_TX_POWER_TEMPERATURE_MIN);
1122 current_temp = min(il->temperature, IL_TX_POWER_TEMPERATURE_MAX);
1123 current_temp = KELVIN_TO_CELSIUS(current_temp);
1124
1125
1126
1127 degrees_per_05db_num =
1128 tx_power_cmp_tble[txatten_grp].degrees_per_05db_a;
1129 degrees_per_05db_denom =
1130 tx_power_cmp_tble[txatten_grp].degrees_per_05db_a_denom;
1131
1132
1133 for (c = 0; c < 2; c++) {
1134 measurement = &ch_eeprom_info.measurements[c][1];
1135
1136
1137
1138 factory_temp = measurement->temperature;
1139 il4965_math_div_round((current_temp -
1140 factory_temp) * degrees_per_05db_denom,
1141 degrees_per_05db_num,
1142 &temperature_comp[c]);
1143
1144 factory_gain_idx[c] = measurement->gain_idx;
1145 factory_actual_pwr[c] = measurement->actual_pow;
1146
1147 D_TXPOWER("chain = %d\n", c);
1148 D_TXPOWER("fctry tmp %d, " "curr tmp %d, comp %d steps\n",
1149 factory_temp, current_temp, temperature_comp[c]);
1150
1151 D_TXPOWER("fctry idx %d, fctry pwr %d\n", factory_gain_idx[c],
1152 factory_actual_pwr[c]);
1153 }
1154
1155
1156 for (i = 0; i < POWER_TBL_NUM_ENTRIES; i++) {
1157 u8 is_mimo_rate;
1158 union il4965_tx_power_dual_stream tx_power;
1159
1160
1161
1162
1163 if (i & 0x8) {
1164 current_regulatory =
1165 reg_limit -
1166 IL_TX_POWER_MIMO_REGULATORY_COMPENSATION;
1167 is_mimo_rate = 1;
1168 } else {
1169 current_regulatory = reg_limit;
1170 is_mimo_rate = 0;
1171 }
1172
1173
1174 power_limit = saturation_power - back_off_table[i];
1175 if (power_limit > current_regulatory)
1176 power_limit = current_regulatory;
1177
1178
1179
1180 target_power = user_target_power;
1181 if (target_power > power_limit)
1182 target_power = power_limit;
1183
1184 D_TXPOWER("rate %d sat %d reg %d usr %d tgt %d\n", i,
1185 saturation_power - back_off_table[i],
1186 current_regulatory, user_target_power, target_power);
1187
1188
1189 for (c = 0; c < 2; c++) {
1190 s32 atten_value;
1191
1192 if (is_mimo_rate)
1193 atten_value =
1194 (s32) le32_to_cpu(il->card_alive_init.
1195 tx_atten[txatten_grp][c]);
1196 else
1197 atten_value = 0;
1198
1199
1200 power_idx =
1201 (u8) (factory_gain_idx[c] -
1202 (target_power - factory_actual_pwr[c]) -
1203 temperature_comp[c] - voltage_compensation +
1204 atten_value);
1205
1206
1207
1208
1209 if (power_idx < get_min_power_idx(i, band))
1210 power_idx = get_min_power_idx(i, band);
1211
1212
1213 if (!band)
1214 power_idx += 9;
1215
1216
1217 if (i == POWER_TBL_CCK_ENTRY)
1218 power_idx +=
1219 IL_TX_POWER_CCK_COMPENSATION_C_STEP;
1220
1221
1222 if (power_idx > 107) {
1223 IL_WARN("txpower idx %d > 107\n", power_idx);
1224 power_idx = 107;
1225 }
1226 if (power_idx < 0) {
1227 IL_WARN("txpower idx %d < 0\n", power_idx);
1228 power_idx = 0;
1229 }
1230
1231
1232 tx_power.s.radio_tx_gain[c] =
1233 gain_table[band][power_idx].radio;
1234 tx_power.s.dsp_predis_atten[c] =
1235 gain_table[band][power_idx].dsp;
1236
1237 D_TXPOWER("chain %d mimo %d idx %d "
1238 "gain 0x%02x dsp %d\n", c, atten_value,
1239 power_idx, tx_power.s.radio_tx_gain[c],
1240 tx_power.s.dsp_predis_atten[c]);
1241 }
1242
1243 tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw);
1244
1245 }
1246
1247 return 0;
1248}
1249
1250
1251
1252
1253
1254
1255
1256static int
1257il4965_send_tx_power(struct il_priv *il)
1258{
1259 struct il4965_txpowertable_cmd cmd = { 0 };
1260 int ret;
1261 u8 band = 0;
1262 bool is_ht40 = false;
1263 u8 ctrl_chan_high = 0;
1264
1265 if (WARN_ONCE
1266 (test_bit(S_SCAN_HW, &il->status),
1267 "TX Power requested while scanning!\n"))
1268 return -EAGAIN;
1269
1270 band = il->band == NL80211_BAND_2GHZ;
1271
1272 is_ht40 = iw4965_is_ht40_channel(il->active.flags);
1273
1274 if (is_ht40 && (il->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
1275 ctrl_chan_high = 1;
1276
1277 cmd.band = band;
1278 cmd.channel = il->active.channel;
1279
1280 ret =
1281 il4965_fill_txpower_tbl(il, band, le16_to_cpu(il->active.channel),
1282 is_ht40, ctrl_chan_high, &cmd.tx_power);
1283 if (ret)
1284 goto out;
1285
1286 ret = il_send_cmd_pdu(il, C_TX_PWR_TBL, sizeof(cmd), &cmd);
1287
1288out:
1289 return ret;
1290}
1291
1292static int
1293il4965_send_rxon_assoc(struct il_priv *il)
1294{
1295 int ret = 0;
1296 struct il4965_rxon_assoc_cmd rxon_assoc;
1297 const struct il_rxon_cmd *rxon1 = &il->staging;
1298 const struct il_rxon_cmd *rxon2 = &il->active;
1299
1300 if (rxon1->flags == rxon2->flags &&
1301 rxon1->filter_flags == rxon2->filter_flags &&
1302 rxon1->cck_basic_rates == rxon2->cck_basic_rates &&
1303 rxon1->ofdm_ht_single_stream_basic_rates ==
1304 rxon2->ofdm_ht_single_stream_basic_rates &&
1305 rxon1->ofdm_ht_dual_stream_basic_rates ==
1306 rxon2->ofdm_ht_dual_stream_basic_rates &&
1307 rxon1->rx_chain == rxon2->rx_chain &&
1308 rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates) {
1309 D_INFO("Using current RXON_ASSOC. Not resending.\n");
1310 return 0;
1311 }
1312
1313 rxon_assoc.flags = il->staging.flags;
1314 rxon_assoc.filter_flags = il->staging.filter_flags;
1315 rxon_assoc.ofdm_basic_rates = il->staging.ofdm_basic_rates;
1316 rxon_assoc.cck_basic_rates = il->staging.cck_basic_rates;
1317 rxon_assoc.reserved = 0;
1318 rxon_assoc.ofdm_ht_single_stream_basic_rates =
1319 il->staging.ofdm_ht_single_stream_basic_rates;
1320 rxon_assoc.ofdm_ht_dual_stream_basic_rates =
1321 il->staging.ofdm_ht_dual_stream_basic_rates;
1322 rxon_assoc.rx_chain_select_flags = il->staging.rx_chain;
1323
1324 ret =
1325 il_send_cmd_pdu_async(il, C_RXON_ASSOC, sizeof(rxon_assoc),
1326 &rxon_assoc, NULL);
1327
1328 return ret;
1329}
1330
1331static int
1332il4965_commit_rxon(struct il_priv *il)
1333{
1334
1335 struct il_rxon_cmd *active_rxon = (void *)&il->active;
1336 int ret;
1337 bool new_assoc = !!(il->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
1338
1339 if (!il_is_alive(il))
1340 return -EBUSY;
1341
1342
1343 il->staging.flags |= RXON_FLG_TSF2HOST_MSK;
1344
1345 ret = il_check_rxon_cmd(il);
1346 if (ret) {
1347 IL_ERR("Invalid RXON configuration. Not committing.\n");
1348 return -EINVAL;
1349 }
1350
1351
1352
1353
1354
1355 if (test_bit(S_CHANNEL_SWITCH_PENDING, &il->status) &&
1356 il->switch_channel != il->staging.channel) {
1357 D_11H("abort channel switch on %d\n",
1358 le16_to_cpu(il->switch_channel));
1359 il_chswitch_done(il, false);
1360 }
1361
1362
1363
1364
1365 if (!il_full_rxon_required(il)) {
1366 ret = il_send_rxon_assoc(il);
1367 if (ret) {
1368 IL_ERR("Error setting RXON_ASSOC (%d)\n", ret);
1369 return ret;
1370 }
1371
1372 memcpy(active_rxon, &il->staging, sizeof(*active_rxon));
1373 il_print_rx_config_cmd(il);
1374
1375
1376
1377
1378 il_set_tx_power(il, il->tx_power_next, false);
1379 return 0;
1380 }
1381
1382
1383
1384
1385
1386 if (il_is_associated(il) && new_assoc) {
1387 D_INFO("Toggling associated bit on current RXON\n");
1388 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1389
1390 ret =
1391 il_send_cmd_pdu(il, C_RXON,
1392 sizeof(struct il_rxon_cmd), active_rxon);
1393
1394
1395
1396 if (ret) {
1397 active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
1398 IL_ERR("Error clearing ASSOC_MSK (%d)\n", ret);
1399 return ret;
1400 }
1401 il_clear_ucode_stations(il);
1402 il_restore_stations(il);
1403 ret = il4965_restore_default_wep_keys(il);
1404 if (ret) {
1405 IL_ERR("Failed to restore WEP keys (%d)\n", ret);
1406 return ret;
1407 }
1408 }
1409
1410 D_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n"
1411 "* channel = %d\n" "* bssid = %pM\n", (new_assoc ? "" : "out"),
1412 le16_to_cpu(il->staging.channel), il->staging.bssid_addr);
1413
1414 il_set_rxon_hwcrypto(il, !il->cfg->mod_params->sw_crypto);
1415
1416
1417
1418
1419
1420 if (!new_assoc) {
1421 ret =
1422 il_send_cmd_pdu(il, C_RXON,
1423 sizeof(struct il_rxon_cmd), &il->staging);
1424 if (ret) {
1425 IL_ERR("Error setting new RXON (%d)\n", ret);
1426 return ret;
1427 }
1428 D_INFO("Return from !new_assoc RXON.\n");
1429 memcpy(active_rxon, &il->staging, sizeof(*active_rxon));
1430 il_clear_ucode_stations(il);
1431 il_restore_stations(il);
1432 ret = il4965_restore_default_wep_keys(il);
1433 if (ret) {
1434 IL_ERR("Failed to restore WEP keys (%d)\n", ret);
1435 return ret;
1436 }
1437 }
1438 if (new_assoc) {
1439 il->start_calib = 0;
1440
1441
1442
1443 ret =
1444 il_send_cmd_pdu(il, C_RXON,
1445 sizeof(struct il_rxon_cmd), &il->staging);
1446 if (ret) {
1447 IL_ERR("Error setting new RXON (%d)\n", ret);
1448 return ret;
1449 }
1450 memcpy(active_rxon, &il->staging, sizeof(*active_rxon));
1451 }
1452 il_print_rx_config_cmd(il);
1453
1454 il4965_init_sensitivity(il);
1455
1456
1457
1458 ret = il_set_tx_power(il, il->tx_power_next, true);
1459 if (ret) {
1460 IL_ERR("Error sending TX power (%d)\n", ret);
1461 return ret;
1462 }
1463
1464 return 0;
1465}
1466
1467static int
1468il4965_hw_channel_switch(struct il_priv *il,
1469 struct ieee80211_channel_switch *ch_switch)
1470{
1471 int rc;
1472 u8 band = 0;
1473 bool is_ht40 = false;
1474 u8 ctrl_chan_high = 0;
1475 struct il4965_channel_switch_cmd cmd;
1476 const struct il_channel_info *ch_info;
1477 u32 switch_time_in_usec, ucode_switch_time;
1478 u16 ch;
1479 u32 tsf_low;
1480 u8 switch_count;
1481 u16 beacon_interval = le16_to_cpu(il->timing.beacon_interval);
1482 struct ieee80211_vif *vif = il->vif;
1483 band = (il->band == NL80211_BAND_2GHZ);
1484
1485 if (WARN_ON_ONCE(vif == NULL))
1486 return -EIO;
1487
1488 is_ht40 = iw4965_is_ht40_channel(il->staging.flags);
1489
1490 if (is_ht40 && (il->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
1491 ctrl_chan_high = 1;
1492
1493 cmd.band = band;
1494 cmd.expect_beacon = 0;
1495 ch = ch_switch->chandef.chan->hw_value;
1496 cmd.channel = cpu_to_le16(ch);
1497 cmd.rxon_flags = il->staging.flags;
1498 cmd.rxon_filter_flags = il->staging.filter_flags;
1499 switch_count = ch_switch->count;
1500 tsf_low = ch_switch->timestamp & 0x0ffffffff;
1501
1502
1503
1504
1505 if (il->ucode_beacon_time > tsf_low && beacon_interval) {
1506 if (switch_count >
1507 ((il->ucode_beacon_time - tsf_low) / beacon_interval)) {
1508 switch_count -=
1509 (il->ucode_beacon_time - tsf_low) / beacon_interval;
1510 } else
1511 switch_count = 0;
1512 }
1513 if (switch_count <= 1)
1514 cmd.switch_time = cpu_to_le32(il->ucode_beacon_time);
1515 else {
1516 switch_time_in_usec =
1517 vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
1518 ucode_switch_time =
1519 il_usecs_to_beacons(il, switch_time_in_usec,
1520 beacon_interval);
1521 cmd.switch_time =
1522 il_add_beacon_time(il, il->ucode_beacon_time,
1523 ucode_switch_time, beacon_interval);
1524 }
1525 D_11H("uCode time for the switch is 0x%x\n", cmd.switch_time);
1526 ch_info = il_get_channel_info(il, il->band, ch);
1527 if (ch_info)
1528 cmd.expect_beacon = il_is_channel_radar(ch_info);
1529 else {
1530 IL_ERR("invalid channel switch from %u to %u\n",
1531 il->active.channel, ch);
1532 return -EFAULT;
1533 }
1534
1535 rc = il4965_fill_txpower_tbl(il, band, ch, is_ht40, ctrl_chan_high,
1536 &cmd.tx_power);
1537 if (rc) {
1538 D_11H("error:%d fill txpower_tbl\n", rc);
1539 return rc;
1540 }
1541
1542 return il_send_cmd_pdu(il, C_CHANNEL_SWITCH, sizeof(cmd), &cmd);
1543}
1544
1545
1546
1547
1548static void
1549il4965_txq_update_byte_cnt_tbl(struct il_priv *il, struct il_tx_queue *txq,
1550 u16 byte_cnt)
1551{
1552 struct il4965_scd_bc_tbl *scd_bc_tbl = il->scd_bc_tbls.addr;
1553 int txq_id = txq->q.id;
1554 int write_ptr = txq->q.write_ptr;
1555 int len = byte_cnt + IL_TX_CRC_SIZE + IL_TX_DELIMITER_SIZE;
1556 __le16 bc_ent;
1557
1558 WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
1559
1560 bc_ent = cpu_to_le16(len & 0xFFF);
1561
1562 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
1563
1564
1565 if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
1566 scd_bc_tbl[txq_id].tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] =
1567 bc_ent;
1568}
1569
1570
1571
1572
1573
1574
1575
1576static int
1577il4965_hw_get_temperature(struct il_priv *il)
1578{
1579 s32 temperature;
1580 s32 vt;
1581 s32 R1, R2, R3;
1582 u32 R4;
1583
1584 if (test_bit(S_TEMPERATURE, &il->status) &&
1585 (il->_4965.stats.flag & STATS_REPLY_FLG_HT40_MODE_MSK)) {
1586 D_TEMP("Running HT40 temperature calibration\n");
1587 R1 = (s32) le32_to_cpu(il->card_alive_init.therm_r1[1]);
1588 R2 = (s32) le32_to_cpu(il->card_alive_init.therm_r2[1]);
1589 R3 = (s32) le32_to_cpu(il->card_alive_init.therm_r3[1]);
1590 R4 = le32_to_cpu(il->card_alive_init.therm_r4[1]);
1591 } else {
1592 D_TEMP("Running temperature calibration\n");
1593 R1 = (s32) le32_to_cpu(il->card_alive_init.therm_r1[0]);
1594 R2 = (s32) le32_to_cpu(il->card_alive_init.therm_r2[0]);
1595 R3 = (s32) le32_to_cpu(il->card_alive_init.therm_r3[0]);
1596 R4 = le32_to_cpu(il->card_alive_init.therm_r4[0]);
1597 }
1598
1599
1600
1601
1602
1603
1604
1605
1606 if (!test_bit(S_TEMPERATURE, &il->status))
1607 vt = sign_extend32(R4, 23);
1608 else
1609 vt = sign_extend32(le32_to_cpu
1610 (il->_4965.stats.general.common.temperature),
1611 23);
1612
1613 D_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
1614
1615 if (R3 == R1) {
1616 IL_ERR("Calibration conflict R1 == R3\n");
1617 return -1;
1618 }
1619
1620
1621
1622 temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2);
1623 temperature /= (R3 - R1);
1624 temperature =
1625 (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET;
1626
1627 D_TEMP("Calibrated temperature: %dK, %dC\n", temperature,
1628 KELVIN_TO_CELSIUS(temperature));
1629
1630 return temperature;
1631}
1632
1633
1634#define IL_TEMPERATURE_THRESHOLD 3
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645static int
1646il4965_is_temp_calib_needed(struct il_priv *il)
1647{
1648 int temp_diff;
1649
1650 if (!test_bit(S_STATS, &il->status)) {
1651 D_TEMP("Temperature not updated -- no stats.\n");
1652 return 0;
1653 }
1654
1655 temp_diff = il->temperature - il->last_temperature;
1656
1657
1658 if (temp_diff < 0) {
1659 D_POWER("Getting cooler, delta %d\n", temp_diff);
1660 temp_diff = -temp_diff;
1661 } else if (temp_diff == 0)
1662 D_POWER("Temperature unchanged\n");
1663 else
1664 D_POWER("Getting warmer, delta %d\n", temp_diff);
1665
1666 if (temp_diff < IL_TEMPERATURE_THRESHOLD) {
1667 D_POWER(" => thermal txpower calib not needed\n");
1668 return 0;
1669 }
1670
1671 D_POWER(" => thermal txpower calib needed\n");
1672
1673 return 1;
1674}
1675
1676void
1677il4965_temperature_calib(struct il_priv *il)
1678{
1679 s32 temp;
1680
1681 temp = il4965_hw_get_temperature(il);
1682 if (IL_TX_POWER_TEMPERATURE_OUT_OF_RANGE(temp))
1683 return;
1684
1685 if (il->temperature != temp) {
1686 if (il->temperature)
1687 D_TEMP("Temperature changed " "from %dC to %dC\n",
1688 KELVIN_TO_CELSIUS(il->temperature),
1689 KELVIN_TO_CELSIUS(temp));
1690 else
1691 D_TEMP("Temperature " "initialized to %dC\n",
1692 KELVIN_TO_CELSIUS(temp));
1693 }
1694
1695 il->temperature = temp;
1696 set_bit(S_TEMPERATURE, &il->status);
1697
1698 if (!il->disable_tx_power_cal &&
1699 unlikely(!test_bit(S_SCANNING, &il->status)) &&
1700 il4965_is_temp_calib_needed(il))
1701 queue_work(il->workqueue, &il->txpower_work);
1702}
1703
1704static u16
1705il4965_get_hcmd_size(u8 cmd_id, u16 len)
1706{
1707 switch (cmd_id) {
1708 case C_RXON:
1709 return (u16) sizeof(struct il4965_rxon_cmd);
1710 default:
1711 return len;
1712 }
1713}
1714
1715static u16
1716il4965_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data)
1717{
1718 struct il4965_addsta_cmd *addsta = (struct il4965_addsta_cmd *)data;
1719 addsta->mode = cmd->mode;
1720 memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify));
1721 memcpy(&addsta->key, &cmd->key, sizeof(struct il4965_keyinfo));
1722 addsta->station_flags = cmd->station_flags;
1723 addsta->station_flags_msk = cmd->station_flags_msk;
1724 addsta->tid_disable_tx = cmd->tid_disable_tx;
1725 addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;
1726 addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;
1727 addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;
1728 addsta->sleep_tx_count = cmd->sleep_tx_count;
1729 addsta->reserved1 = cpu_to_le16(0);
1730 addsta->reserved2 = cpu_to_le16(0);
1731
1732 return (u16) sizeof(struct il4965_addsta_cmd);
1733}
1734
1735static void
1736il4965_post_scan(struct il_priv *il)
1737{
1738
1739
1740
1741
1742 if (memcmp(&il->staging, &il->active, sizeof(il->staging)))
1743 il_commit_rxon(il);
1744}
1745
1746static void
1747il4965_post_associate(struct il_priv *il)
1748{
1749 struct ieee80211_vif *vif = il->vif;
1750 int ret = 0;
1751
1752 if (!vif || !il->is_open)
1753 return;
1754
1755 if (test_bit(S_EXIT_PENDING, &il->status))
1756 return;
1757
1758 il_scan_cancel_timeout(il, 200);
1759
1760 il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1761 il_commit_rxon(il);
1762
1763 ret = il_send_rxon_timing(il);
1764 if (ret)
1765 IL_WARN("RXON timing - " "Attempting to continue.\n");
1766
1767 il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
1768
1769 il_set_rxon_ht(il, &il->current_ht_config);
1770
1771 if (il->ops->set_rxon_chain)
1772 il->ops->set_rxon_chain(il);
1773
1774 il->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
1775
1776 D_ASSOC("assoc id %d beacon interval %d\n", vif->bss_conf.aid,
1777 vif->bss_conf.beacon_int);
1778
1779 if (vif->bss_conf.use_short_preamble)
1780 il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
1781 else
1782 il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
1783
1784 if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
1785 if (vif->bss_conf.use_short_slot)
1786 il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
1787 else
1788 il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
1789 }
1790
1791 il_commit_rxon(il);
1792
1793 D_ASSOC("Associated as %d to: %pM\n", vif->bss_conf.aid,
1794 il->active.bssid_addr);
1795
1796 switch (vif->type) {
1797 case NL80211_IFTYPE_STATION:
1798 break;
1799 case NL80211_IFTYPE_ADHOC:
1800 il4965_send_beacon_cmd(il);
1801 break;
1802 default:
1803 IL_ERR("%s Should not be called in %d mode\n", __func__,
1804 vif->type);
1805 break;
1806 }
1807
1808
1809
1810
1811 if (il->chain_noise_data.state == IL_CHAIN_NOISE_DONE)
1812 il_power_update_mode(il, false);
1813
1814
1815 il4965_chain_noise_reset(il);
1816 il->start_calib = 1;
1817}
1818
1819static void
1820il4965_config_ap(struct il_priv *il)
1821{
1822 struct ieee80211_vif *vif = il->vif;
1823 int ret = 0;
1824
1825 lockdep_assert_held(&il->mutex);
1826
1827 if (test_bit(S_EXIT_PENDING, &il->status))
1828 return;
1829
1830
1831 if (!il_is_associated(il)) {
1832
1833
1834 il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1835 il_commit_rxon(il);
1836
1837
1838 ret = il_send_rxon_timing(il);
1839 if (ret)
1840 IL_WARN("RXON timing failed - "
1841 "Attempting to continue.\n");
1842
1843
1844 il->chain_noise_data.active_chains = il->hw_params.valid_rx_ant;
1845 il_set_rxon_ht(il, &il->current_ht_config);
1846 if (il->ops->set_rxon_chain)
1847 il->ops->set_rxon_chain(il);
1848
1849 il->staging.assoc_id = 0;
1850
1851 if (vif->bss_conf.use_short_preamble)
1852 il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
1853 else
1854 il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
1855
1856 if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
1857 if (vif->bss_conf.use_short_slot)
1858 il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
1859 else
1860 il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
1861 }
1862
1863 il4965_send_beacon_cmd(il);
1864
1865 il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
1866 il_commit_rxon(il);
1867 }
1868 il4965_send_beacon_cmd(il);
1869}
1870
1871const struct il_ops il4965_ops = {
1872 .txq_update_byte_cnt_tbl = il4965_txq_update_byte_cnt_tbl,
1873 .txq_attach_buf_to_tfd = il4965_hw_txq_attach_buf_to_tfd,
1874 .txq_free_tfd = il4965_hw_txq_free_tfd,
1875 .txq_init = il4965_hw_tx_queue_init,
1876 .is_valid_rtc_data_addr = il4965_hw_valid_rtc_data_addr,
1877 .init_alive_start = il4965_init_alive_start,
1878 .load_ucode = il4965_load_bsm,
1879 .dump_nic_error_log = il4965_dump_nic_error_log,
1880 .dump_fh = il4965_dump_fh,
1881 .set_channel_switch = il4965_hw_channel_switch,
1882 .apm_init = il_apm_init,
1883 .send_tx_power = il4965_send_tx_power,
1884 .update_chain_flags = il4965_update_chain_flags,
1885 .eeprom_acquire_semaphore = il4965_eeprom_acquire_semaphore,
1886 .eeprom_release_semaphore = il4965_eeprom_release_semaphore,
1887
1888 .rxon_assoc = il4965_send_rxon_assoc,
1889 .commit_rxon = il4965_commit_rxon,
1890 .set_rxon_chain = il4965_set_rxon_chain,
1891
1892 .get_hcmd_size = il4965_get_hcmd_size,
1893 .build_addsta_hcmd = il4965_build_addsta_hcmd,
1894 .request_scan = il4965_request_scan,
1895 .post_scan = il4965_post_scan,
1896
1897 .post_associate = il4965_post_associate,
1898 .config_ap = il4965_config_ap,
1899 .manage_ibss_station = il4965_manage_ibss_station,
1900 .update_bcast_stations = il4965_update_bcast_stations,
1901
1902 .send_led_cmd = il4965_send_led_cmd,
1903};
1904
1905struct il_cfg il4965_cfg = {
1906 .name = "Intel(R) Wireless WiFi Link 4965AGN",
1907 .fw_name_pre = IL4965_FW_PRE,
1908 .ucode_api_max = IL4965_UCODE_API_MAX,
1909 .ucode_api_min = IL4965_UCODE_API_MIN,
1910 .sku = IL_SKU_A | IL_SKU_G | IL_SKU_N,
1911 .valid_tx_ant = ANT_AB,
1912 .valid_rx_ant = ANT_ABC,
1913 .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
1914 .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
1915 .mod_params = &il4965_mod_params,
1916 .led_mode = IL_LED_BLINK,
1917
1918
1919
1920
1921 .scan_rx_antennas[NL80211_BAND_5GHZ] = ANT_BC,
1922
1923 .eeprom_size = IL4965_EEPROM_IMG_SIZE,
1924 .num_of_queues = IL49_NUM_QUEUES,
1925 .num_of_ampdu_queues = IL49_NUM_AMPDU_QUEUES,
1926 .pll_cfg_val = 0,
1927 .set_l0s = true,
1928 .use_bsm = true,
1929 .led_compensation = 61,
1930 .chain_noise_num_beacons = IL4965_CAL_NUM_BEACONS,
1931 .wd_timeout = IL_DEF_WD_TIMEOUT,
1932 .temperature_kelvin = true,
1933 .ucode_tracing = true,
1934 .sensitivity_calib_by_driver = true,
1935 .chain_noise_calib_by_driver = true,
1936
1937 .regulatory_bands = {
1938 EEPROM_REGULATORY_BAND_1_CHANNELS,
1939 EEPROM_REGULATORY_BAND_2_CHANNELS,
1940 EEPROM_REGULATORY_BAND_3_CHANNELS,
1941 EEPROM_REGULATORY_BAND_4_CHANNELS,
1942 EEPROM_REGULATORY_BAND_5_CHANNELS,
1943 EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
1944 EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS
1945 },
1946
1947};
1948
1949
1950MODULE_FIRMWARE(IL4965_MODULE_FIRMWARE(IL4965_UCODE_API_MAX));
1951