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