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 <net/mac80211.h>
21#include <linux/etherdevice.h>
22#include <asm/unaligned.h>
23
24#include "common.h"
25#include "4965.h"
26
27
28
29
30
31
32static int
33il4965_verify_inst_sparse(struct il_priv *il, __le32 * image, u32 len)
34{
35 u32 val;
36 int ret = 0;
37 u32 errcnt = 0;
38 u32 i;
39
40 D_INFO("ucode inst image size is %u\n", len);
41
42 for (i = 0; i < len; i += 100, image += 100 / sizeof(u32)) {
43
44
45
46 il_wr(il, HBUS_TARG_MEM_RADDR, i + IL4965_RTC_INST_LOWER_BOUND);
47 val = _il_rd(il, HBUS_TARG_MEM_RDAT);
48 if (val != le32_to_cpu(*image)) {
49 ret = -EIO;
50 errcnt++;
51 if (errcnt >= 3)
52 break;
53 }
54 }
55
56 return ret;
57}
58
59
60
61
62
63static int
64il4965_verify_inst_full(struct il_priv *il, __le32 * image, u32 len)
65{
66 u32 val;
67 u32 save_len = len;
68 int ret = 0;
69 u32 errcnt;
70
71 D_INFO("ucode inst image size is %u\n", len);
72
73 il_wr(il, HBUS_TARG_MEM_RADDR, IL4965_RTC_INST_LOWER_BOUND);
74
75 errcnt = 0;
76 for (; len > 0; len -= sizeof(u32), image++) {
77
78
79
80 val = _il_rd(il, HBUS_TARG_MEM_RDAT);
81 if (val != le32_to_cpu(*image)) {
82 IL_ERR("uCode INST section is invalid at "
83 "offset 0x%x, is 0x%x, s/b 0x%x\n",
84 save_len - len, val, le32_to_cpu(*image));
85 ret = -EIO;
86 errcnt++;
87 if (errcnt >= 20)
88 break;
89 }
90 }
91
92 if (!errcnt)
93 D_INFO("ucode image in INSTRUCTION memory is good\n");
94
95 return ret;
96}
97
98
99
100
101
102int
103il4965_verify_ucode(struct il_priv *il)
104{
105 __le32 *image;
106 u32 len;
107 int ret;
108
109
110 image = (__le32 *) il->ucode_boot.v_addr;
111 len = il->ucode_boot.len;
112 ret = il4965_verify_inst_sparse(il, image, len);
113 if (!ret) {
114 D_INFO("Bootstrap uCode is good in inst SRAM\n");
115 return 0;
116 }
117
118
119 image = (__le32 *) il->ucode_init.v_addr;
120 len = il->ucode_init.len;
121 ret = il4965_verify_inst_sparse(il, image, len);
122 if (!ret) {
123 D_INFO("Initialize uCode is good in inst SRAM\n");
124 return 0;
125 }
126
127
128 image = (__le32 *) il->ucode_code.v_addr;
129 len = il->ucode_code.len;
130 ret = il4965_verify_inst_sparse(il, image, len);
131 if (!ret) {
132 D_INFO("Runtime uCode is good in inst SRAM\n");
133 return 0;
134 }
135
136 IL_ERR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
137
138
139
140
141 image = (__le32 *) il->ucode_boot.v_addr;
142 len = il->ucode_boot.len;
143 ret = il4965_verify_inst_full(il, image, len);
144
145 return ret;
146}
147
148
149
150
151
152
153
154
155
156
157
158
159
160int
161il4965_eeprom_acquire_semaphore(struct il_priv *il)
162{
163 u16 count;
164 int ret;
165
166 for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
167
168 il_set_bit(il, CSR_HW_IF_CONFIG_REG,
169 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
170
171
172 ret =
173 _il_poll_bit(il, CSR_HW_IF_CONFIG_REG,
174 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
175 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
176 EEPROM_SEM_TIMEOUT);
177 if (ret >= 0)
178 return ret;
179 }
180
181 return ret;
182}
183
184void
185il4965_eeprom_release_semaphore(struct il_priv *il)
186{
187 il_clear_bit(il, CSR_HW_IF_CONFIG_REG,
188 CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
189
190}
191
192int
193il4965_eeprom_check_version(struct il_priv *il)
194{
195 u16 eeprom_ver;
196 u16 calib_ver;
197
198 eeprom_ver = il_eeprom_query16(il, EEPROM_VERSION);
199 calib_ver = il_eeprom_query16(il, EEPROM_4965_CALIB_VERSION_OFFSET);
200
201 if (eeprom_ver < il->cfg->eeprom_ver ||
202 calib_ver < il->cfg->eeprom_calib_ver)
203 goto err;
204
205 IL_INFO("device EEPROM VER=0x%x, CALIB=0x%x\n", eeprom_ver, calib_ver);
206
207 return 0;
208err:
209 IL_ERR("Unsupported (too old) EEPROM VER=0x%x < 0x%x "
210 "CALIB=0x%x < 0x%x\n", eeprom_ver, il->cfg->eeprom_ver,
211 calib_ver, il->cfg->eeprom_calib_ver);
212 return -EINVAL;
213
214}
215
216void
217il4965_eeprom_get_mac(const struct il_priv *il, u8 * mac)
218{
219 const u8 *addr = il_eeprom_query_addr(il,
220 EEPROM_MAC_ADDRESS);
221 memcpy(mac, addr, ETH_ALEN);
222}
223
224
225static int
226il4965_send_led_cmd(struct il_priv *il, struct il_led_cmd *led_cmd)
227{
228 struct il_host_cmd cmd = {
229 .id = C_LEDS,
230 .len = sizeof(struct il_led_cmd),
231 .data = led_cmd,
232 .flags = CMD_ASYNC,
233 .callback = NULL,
234 };
235 u32 reg;
236
237 reg = _il_rd(il, CSR_LED_REG);
238 if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
239 _il_wr(il, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
240
241 return il_send_cmd(il, &cmd);
242}
243
244
245void
246il4965_led_enable(struct il_priv *il)
247{
248 _il_wr(il, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
249}
250
251static int il4965_send_tx_power(struct il_priv *il);
252static int il4965_hw_get_temperature(struct il_priv *il);
253
254
255#define IL4965_UCODE_API_MAX 2
256
257
258#define IL4965_UCODE_API_MIN 2
259
260#define IL4965_FW_PRE "iwlwifi-4965-"
261#define _IL4965_MODULE_FIRMWARE(api) IL4965_FW_PRE #api ".ucode"
262#define IL4965_MODULE_FIRMWARE(api) _IL4965_MODULE_FIRMWARE(api)
263
264
265static int
266il4965_verify_bsm(struct il_priv *il)
267{
268 __le32 *image = il->ucode_boot.v_addr;
269 u32 len = il->ucode_boot.len;
270 u32 reg;
271 u32 val;
272
273 D_INFO("Begin verify bsm\n");
274
275
276 val = il_rd_prph(il, BSM_WR_DWCOUNT_REG);
277 for (reg = BSM_SRAM_LOWER_BOUND; reg < BSM_SRAM_LOWER_BOUND + len;
278 reg += sizeof(u32), image++) {
279 val = il_rd_prph(il, reg);
280 if (val != le32_to_cpu(*image)) {
281 IL_ERR("BSM uCode verification failed at "
282 "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
283 BSM_SRAM_LOWER_BOUND, reg - BSM_SRAM_LOWER_BOUND,
284 len, val, le32_to_cpu(*image));
285 return -EIO;
286 }
287 }
288
289 D_INFO("BSM bootstrap uCode image OK\n");
290
291 return 0;
292}
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
326static int
327il4965_load_bsm(struct il_priv *il)
328{
329 __le32 *image = il->ucode_boot.v_addr;
330 u32 len = il->ucode_boot.len;
331 dma_addr_t pinst;
332 dma_addr_t pdata;
333 u32 inst_len;
334 u32 data_len;
335 int i;
336 u32 done;
337 u32 reg_offset;
338 int ret;
339
340 D_INFO("Begin load bsm\n");
341
342 il->ucode_type = UCODE_RT;
343
344
345 if (len > IL49_MAX_BSM_SIZE)
346 return -EINVAL;
347
348
349
350
351
352
353
354 pinst = il->ucode_init.p_addr >> 4;
355 pdata = il->ucode_init_data.p_addr >> 4;
356 inst_len = il->ucode_init.len;
357 data_len = il->ucode_init_data.len;
358
359 il_wr_prph(il, BSM_DRAM_INST_PTR_REG, pinst);
360 il_wr_prph(il, BSM_DRAM_DATA_PTR_REG, pdata);
361 il_wr_prph(il, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
362 il_wr_prph(il, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
363
364
365 for (reg_offset = BSM_SRAM_LOWER_BOUND;
366 reg_offset < BSM_SRAM_LOWER_BOUND + len;
367 reg_offset += sizeof(u32), image++)
368 _il_wr_prph(il, reg_offset, le32_to_cpu(*image));
369
370 ret = il4965_verify_bsm(il);
371 if (ret)
372 return ret;
373
374
375 il_wr_prph(il, BSM_WR_MEM_SRC_REG, 0x0);
376 il_wr_prph(il, BSM_WR_MEM_DST_REG, IL49_RTC_INST_LOWER_BOUND);
377 il_wr_prph(il, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
378
379
380
381 il_wr_prph(il, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START);
382
383
384 for (i = 0; i < 100; i++) {
385 done = il_rd_prph(il, BSM_WR_CTRL_REG);
386 if (!(done & BSM_WR_CTRL_REG_BIT_START))
387 break;
388 udelay(10);
389 }
390 if (i < 100)
391 D_INFO("BSM write complete, poll %d iterations\n", i);
392 else {
393 IL_ERR("BSM write did not complete!\n");
394 return -EIO;
395 }
396
397
398
399 il_wr_prph(il, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN);
400
401 return 0;
402}
403
404
405
406
407
408
409
410
411
412
413static int
414il4965_set_ucode_ptrs(struct il_priv *il)
415{
416 dma_addr_t pinst;
417 dma_addr_t pdata;
418 int ret = 0;
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 ret;
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
1561
1562static int
1563il4965_hw_get_temperature(struct il_priv *il)
1564{
1565 s32 temperature;
1566 s32 vt;
1567 s32 R1, R2, R3;
1568 u32 R4;
1569
1570 if (test_bit(S_TEMPERATURE, &il->status) &&
1571 (il->_4965.stats.flag & STATS_REPLY_FLG_HT40_MODE_MSK)) {
1572 D_TEMP("Running HT40 temperature calibration\n");
1573 R1 = (s32) le32_to_cpu(il->card_alive_init.therm_r1[1]);
1574 R2 = (s32) le32_to_cpu(il->card_alive_init.therm_r2[1]);
1575 R3 = (s32) le32_to_cpu(il->card_alive_init.therm_r3[1]);
1576 R4 = le32_to_cpu(il->card_alive_init.therm_r4[1]);
1577 } else {
1578 D_TEMP("Running temperature calibration\n");
1579 R1 = (s32) le32_to_cpu(il->card_alive_init.therm_r1[0]);
1580 R2 = (s32) le32_to_cpu(il->card_alive_init.therm_r2[0]);
1581 R3 = (s32) le32_to_cpu(il->card_alive_init.therm_r3[0]);
1582 R4 = le32_to_cpu(il->card_alive_init.therm_r4[0]);
1583 }
1584
1585
1586
1587
1588
1589
1590
1591
1592 if (!test_bit(S_TEMPERATURE, &il->status))
1593 vt = sign_extend32(R4, 23);
1594 else
1595 vt = sign_extend32(le32_to_cpu
1596 (il->_4965.stats.general.common.temperature),
1597 23);
1598
1599 D_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
1600
1601 if (R3 == R1) {
1602 IL_ERR("Calibration conflict R1 == R3\n");
1603 return -1;
1604 }
1605
1606
1607
1608 temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2);
1609 temperature /= (R3 - R1);
1610 temperature =
1611 (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET;
1612
1613 D_TEMP("Calibrated temperature: %dK, %dC\n", temperature,
1614 KELVIN_TO_CELSIUS(temperature));
1615
1616 return temperature;
1617}
1618
1619
1620#define IL_TEMPERATURE_THRESHOLD 3
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631static int
1632il4965_is_temp_calib_needed(struct il_priv *il)
1633{
1634 int temp_diff;
1635
1636 if (!test_bit(S_STATS, &il->status)) {
1637 D_TEMP("Temperature not updated -- no stats.\n");
1638 return 0;
1639 }
1640
1641 temp_diff = il->temperature - il->last_temperature;
1642
1643
1644 if (temp_diff < 0) {
1645 D_POWER("Getting cooler, delta %d\n", temp_diff);
1646 temp_diff = -temp_diff;
1647 } else if (temp_diff == 0)
1648 D_POWER("Temperature unchanged\n");
1649 else
1650 D_POWER("Getting warmer, delta %d\n", temp_diff);
1651
1652 if (temp_diff < IL_TEMPERATURE_THRESHOLD) {
1653 D_POWER(" => thermal txpower calib not needed\n");
1654 return 0;
1655 }
1656
1657 D_POWER(" => thermal txpower calib needed\n");
1658
1659 return 1;
1660}
1661
1662void
1663il4965_temperature_calib(struct il_priv *il)
1664{
1665 s32 temp;
1666
1667 temp = il4965_hw_get_temperature(il);
1668 if (IL_TX_POWER_TEMPERATURE_OUT_OF_RANGE(temp))
1669 return;
1670
1671 if (il->temperature != temp) {
1672 if (il->temperature)
1673 D_TEMP("Temperature changed " "from %dC to %dC\n",
1674 KELVIN_TO_CELSIUS(il->temperature),
1675 KELVIN_TO_CELSIUS(temp));
1676 else
1677 D_TEMP("Temperature " "initialized to %dC\n",
1678 KELVIN_TO_CELSIUS(temp));
1679 }
1680
1681 il->temperature = temp;
1682 set_bit(S_TEMPERATURE, &il->status);
1683
1684 if (!il->disable_tx_power_cal &&
1685 unlikely(!test_bit(S_SCANNING, &il->status)) &&
1686 il4965_is_temp_calib_needed(il))
1687 queue_work(il->workqueue, &il->txpower_work);
1688}
1689
1690static u16
1691il4965_get_hcmd_size(u8 cmd_id, u16 len)
1692{
1693 switch (cmd_id) {
1694 case C_RXON:
1695 return (u16) sizeof(struct il4965_rxon_cmd);
1696 default:
1697 return len;
1698 }
1699}
1700
1701static u16
1702il4965_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data)
1703{
1704 struct il4965_addsta_cmd *addsta = (struct il4965_addsta_cmd *)data;
1705 addsta->mode = cmd->mode;
1706 memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify));
1707 memcpy(&addsta->key, &cmd->key, sizeof(struct il4965_keyinfo));
1708 addsta->station_flags = cmd->station_flags;
1709 addsta->station_flags_msk = cmd->station_flags_msk;
1710 addsta->tid_disable_tx = cmd->tid_disable_tx;
1711 addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;
1712 addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;
1713 addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;
1714 addsta->sleep_tx_count = cmd->sleep_tx_count;
1715 addsta->reserved1 = cpu_to_le16(0);
1716 addsta->reserved2 = cpu_to_le16(0);
1717
1718 return (u16) sizeof(struct il4965_addsta_cmd);
1719}
1720
1721static void
1722il4965_post_scan(struct il_priv *il)
1723{
1724
1725
1726
1727
1728 if (memcmp(&il->staging, &il->active, sizeof(il->staging)))
1729 il_commit_rxon(il);
1730}
1731
1732static void
1733il4965_post_associate(struct il_priv *il)
1734{
1735 struct ieee80211_vif *vif = il->vif;
1736 int ret = 0;
1737
1738 if (!vif || !il->is_open)
1739 return;
1740
1741 if (test_bit(S_EXIT_PENDING, &il->status))
1742 return;
1743
1744 il_scan_cancel_timeout(il, 200);
1745
1746 il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1747 il_commit_rxon(il);
1748
1749 ret = il_send_rxon_timing(il);
1750 if (ret)
1751 IL_WARN("RXON timing - " "Attempting to continue.\n");
1752
1753 il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
1754
1755 il_set_rxon_ht(il, &il->current_ht_config);
1756
1757 if (il->ops->set_rxon_chain)
1758 il->ops->set_rxon_chain(il);
1759
1760 il->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
1761
1762 D_ASSOC("assoc id %d beacon interval %d\n", vif->bss_conf.aid,
1763 vif->bss_conf.beacon_int);
1764
1765 if (vif->bss_conf.use_short_preamble)
1766 il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
1767 else
1768 il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
1769
1770 if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
1771 if (vif->bss_conf.use_short_slot)
1772 il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
1773 else
1774 il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
1775 }
1776
1777 il_commit_rxon(il);
1778
1779 D_ASSOC("Associated as %d to: %pM\n", vif->bss_conf.aid,
1780 il->active.bssid_addr);
1781
1782 switch (vif->type) {
1783 case NL80211_IFTYPE_STATION:
1784 break;
1785 case NL80211_IFTYPE_ADHOC:
1786 il4965_send_beacon_cmd(il);
1787 break;
1788 default:
1789 IL_ERR("%s Should not be called in %d mode\n", __func__,
1790 vif->type);
1791 break;
1792 }
1793
1794
1795
1796
1797 if (il->chain_noise_data.state == IL_CHAIN_NOISE_DONE)
1798 il_power_update_mode(il, false);
1799
1800
1801 il4965_chain_noise_reset(il);
1802 il->start_calib = 1;
1803}
1804
1805static void
1806il4965_config_ap(struct il_priv *il)
1807{
1808 struct ieee80211_vif *vif = il->vif;
1809 int ret = 0;
1810
1811 lockdep_assert_held(&il->mutex);
1812
1813 if (test_bit(S_EXIT_PENDING, &il->status))
1814 return;
1815
1816
1817 if (!il_is_associated(il)) {
1818
1819
1820 il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1821 il_commit_rxon(il);
1822
1823
1824 ret = il_send_rxon_timing(il);
1825 if (ret)
1826 IL_WARN("RXON timing failed - "
1827 "Attempting to continue.\n");
1828
1829
1830 il->chain_noise_data.active_chains = il->hw_params.valid_rx_ant;
1831 il_set_rxon_ht(il, &il->current_ht_config);
1832 if (il->ops->set_rxon_chain)
1833 il->ops->set_rxon_chain(il);
1834
1835 il->staging.assoc_id = 0;
1836
1837 if (vif->bss_conf.use_short_preamble)
1838 il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
1839 else
1840 il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
1841
1842 if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
1843 if (vif->bss_conf.use_short_slot)
1844 il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
1845 else
1846 il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
1847 }
1848
1849 il4965_send_beacon_cmd(il);
1850
1851 il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
1852 il_commit_rxon(il);
1853 }
1854 il4965_send_beacon_cmd(il);
1855}
1856
1857const struct il_ops il4965_ops = {
1858 .txq_update_byte_cnt_tbl = il4965_txq_update_byte_cnt_tbl,
1859 .txq_attach_buf_to_tfd = il4965_hw_txq_attach_buf_to_tfd,
1860 .txq_free_tfd = il4965_hw_txq_free_tfd,
1861 .txq_init = il4965_hw_tx_queue_init,
1862 .is_valid_rtc_data_addr = il4965_hw_valid_rtc_data_addr,
1863 .init_alive_start = il4965_init_alive_start,
1864 .load_ucode = il4965_load_bsm,
1865 .dump_nic_error_log = il4965_dump_nic_error_log,
1866 .dump_fh = il4965_dump_fh,
1867 .set_channel_switch = il4965_hw_channel_switch,
1868 .apm_init = il_apm_init,
1869 .send_tx_power = il4965_send_tx_power,
1870 .update_chain_flags = il4965_update_chain_flags,
1871 .eeprom_acquire_semaphore = il4965_eeprom_acquire_semaphore,
1872 .eeprom_release_semaphore = il4965_eeprom_release_semaphore,
1873
1874 .rxon_assoc = il4965_send_rxon_assoc,
1875 .commit_rxon = il4965_commit_rxon,
1876 .set_rxon_chain = il4965_set_rxon_chain,
1877
1878 .get_hcmd_size = il4965_get_hcmd_size,
1879 .build_addsta_hcmd = il4965_build_addsta_hcmd,
1880 .request_scan = il4965_request_scan,
1881 .post_scan = il4965_post_scan,
1882
1883 .post_associate = il4965_post_associate,
1884 .config_ap = il4965_config_ap,
1885 .manage_ibss_station = il4965_manage_ibss_station,
1886 .update_bcast_stations = il4965_update_bcast_stations,
1887
1888 .send_led_cmd = il4965_send_led_cmd,
1889};
1890
1891struct il_cfg il4965_cfg = {
1892 .name = "Intel(R) Wireless WiFi Link 4965AGN",
1893 .fw_name_pre = IL4965_FW_PRE,
1894 .ucode_api_max = IL4965_UCODE_API_MAX,
1895 .ucode_api_min = IL4965_UCODE_API_MIN,
1896 .sku = IL_SKU_A | IL_SKU_G | IL_SKU_N,
1897 .valid_tx_ant = ANT_AB,
1898 .valid_rx_ant = ANT_ABC,
1899 .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
1900 .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
1901 .mod_params = &il4965_mod_params,
1902 .led_mode = IL_LED_BLINK,
1903
1904
1905
1906
1907 .scan_rx_antennas[NL80211_BAND_5GHZ] = ANT_BC,
1908
1909 .eeprom_size = IL4965_EEPROM_IMG_SIZE,
1910 .num_of_queues = IL49_NUM_QUEUES,
1911 .num_of_ampdu_queues = IL49_NUM_AMPDU_QUEUES,
1912 .pll_cfg_val = 0,
1913 .set_l0s = true,
1914 .use_bsm = true,
1915 .led_compensation = 61,
1916 .chain_noise_num_beacons = IL4965_CAL_NUM_BEACONS,
1917 .wd_timeout = IL_DEF_WD_TIMEOUT,
1918 .temperature_kelvin = true,
1919 .ucode_tracing = true,
1920 .sensitivity_calib_by_driver = true,
1921 .chain_noise_calib_by_driver = true,
1922
1923 .regulatory_bands = {
1924 EEPROM_REGULATORY_BAND_1_CHANNELS,
1925 EEPROM_REGULATORY_BAND_2_CHANNELS,
1926 EEPROM_REGULATORY_BAND_3_CHANNELS,
1927 EEPROM_REGULATORY_BAND_4_CHANNELS,
1928 EEPROM_REGULATORY_BAND_5_CHANNELS,
1929 EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
1930 EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS
1931 },
1932
1933};
1934
1935
1936MODULE_FIRMWARE(IL4965_MODULE_FIRMWARE(IL4965_UCODE_API_MAX));
1937