1 /******************************************************************************
3 * Copyright(c) 2007 - 2016 Realtek Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
26 /* ************************************************************
28 * *************************************************************/
30 #include "mp_precomp.h"
31 #include "phydm_precomp.h"
33 static const u16 db_invert_table[12][8] = {
34 {1, 1, 1, 2, 2, 2, 2, 3},
35 {3, 3, 4, 4, 4, 5, 6, 6},
36 {7, 8, 9, 10, 11, 13, 14, 16},
37 {18, 20, 22, 25, 28, 32, 35, 40},
38 {45, 50, 56, 63, 71, 79, 89, 100},
39 {112, 126, 141, 158, 178, 200, 224, 251},
40 {282, 316, 355, 398, 447, 501, 562, 631},
41 {708, 794, 891, 1000, 1122, 1259, 1413, 1585},
42 {1778, 1995, 2239, 2512, 2818, 3162, 3548, 3981},
43 {4467, 5012, 5623, 6310, 7079, 7943, 8913, 10000},
44 {11220, 12589, 14125, 15849, 17783, 19953, 22387, 25119},
45 {28184, 31623, 35481, 39811, 44668, 50119, 56234, 65535},
48 /* ************************************************************
49 * Local Function predefine.
50 * *************************************************************/
52 /* START------------COMMON INFO RELATED--------------- */
54 static void odm_update_power_training_state(struct phy_dm_struct *dm);
56 /* ************************************************************
58 * *************************************************************/
61 s32 odm_pwdb_conversion(s32 X, u32 total_bit, u32 decimal_bit)
63 s32 Y, integer = 0, decimal = 0;
67 X = 1; /* log2(x), x can't be 0 */
69 for (i = (total_bit - 1); i > 0; i--) {
73 /* decimal is 0.5dB*3=1.5dB~=2dB */
74 decimal = (X & BIT(i - 1)) ? 2 : 0;
80 Y = 3 * (integer - decimal_bit) + decimal; /* 10*log(x)=3*log2(x), */
85 s32 odm_sign_conversion(s32 value, u32 total_bit)
87 if (value & BIT(total_bit - 1))
88 value -= BIT(total_bit);
92 void phydm_seq_sorting(void *dm_void, u32 *value, u32 *rank_idx, u32 *idx_out,
97 u32 tmp_idx_a, tmp_idx_b;
99 for (i = 0; i < seq_length; i++) {
104 for (i = 0; i < (seq_length - 1); i++) {
105 for (j = 0; j < (seq_length - 1 - i); j++) {
107 tmp_b = value[j + 1];
109 tmp_idx_a = rank_idx[j];
110 tmp_idx_b = rank_idx[j + 1];
114 value[j + 1] = tmp_a;
116 rank_idx[j] = tmp_idx_b;
117 rank_idx[j + 1] = tmp_idx_a;
122 for (i = 0; i < seq_length; i++) {
123 idx_out[rank_idx[i]] = i + 1;
128 void odm_init_mp_driver_status(struct phy_dm_struct *dm)
133 static void odm_update_mp_driver_status(struct phy_dm_struct *dm)
138 static void phydm_init_trx_antenna_setting(struct phy_dm_struct *dm)
140 /*#if (RTL8814A_SUPPORT == 1)*/
142 if (dm->support_ic_type & (ODM_RTL8814A)) {
143 u8 rx_ant = 0, tx_ant = 0;
145 rx_ant = (u8)odm_get_bb_reg(dm, ODM_REG(BB_RX_PATH, dm),
146 ODM_BIT(BB_RX_PATH, dm));
147 tx_ant = (u8)odm_get_bb_reg(dm, ODM_REG(BB_TX_PATH, dm),
148 ODM_BIT(BB_TX_PATH, dm));
149 dm->tx_ant_status = (tx_ant & 0xf);
150 dm->rx_ant_status = (rx_ant & 0xf);
151 } else if (dm->support_ic_type & (ODM_RTL8723D | ODM_RTL8821C |
152 ODM_RTL8710B)) { /* JJ ADD 20161014 */
153 dm->tx_ant_status = 0x1;
154 dm->rx_ant_status = 0x1;
159 static void phydm_traffic_load_decision(void *dm_void)
161 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
163 /*---TP & Trafic-load calculation---*/
165 if (dm->last_tx_ok_cnt > *dm->num_tx_bytes_unicast)
166 dm->last_tx_ok_cnt = *dm->num_tx_bytes_unicast;
168 if (dm->last_rx_ok_cnt > *dm->num_rx_bytes_unicast)
169 dm->last_rx_ok_cnt = *dm->num_rx_bytes_unicast;
171 dm->cur_tx_ok_cnt = *dm->num_tx_bytes_unicast - dm->last_tx_ok_cnt;
172 dm->cur_rx_ok_cnt = *dm->num_rx_bytes_unicast - dm->last_rx_ok_cnt;
173 dm->last_tx_ok_cnt = *dm->num_tx_bytes_unicast;
174 dm->last_rx_ok_cnt = *dm->num_rx_bytes_unicast;
176 dm->tx_tp = ((dm->tx_tp) >> 1) +
177 (u32)(((dm->cur_tx_ok_cnt) >> 18) >>
178 1); /* <<3(8bit), >>20(10^6,M), >>1(2sec)*/
179 dm->rx_tp = ((dm->rx_tp) >> 1) +
180 (u32)(((dm->cur_rx_ok_cnt) >> 18) >>
181 1); /* <<3(8bit), >>20(10^6,M), >>1(2sec)*/
182 dm->total_tp = dm->tx_tp + dm->rx_tp;
184 dm->pre_traffic_load = dm->traffic_load;
186 if (dm->cur_tx_ok_cnt > 1875000 ||
188 1875000) { /* ( 1.875M * 8bit ) / 2sec= 7.5M bits /sec )*/
190 dm->traffic_load = TRAFFIC_HIGH;
193 dm->cur_tx_ok_cnt > 500000 ||
195 500000) { /*( 0.5M * 8bit ) / 2sec = 2M bits /sec )*/
197 dm->traffic_load = TRAFFIC_MID;
200 dm->cur_tx_ok_cnt > 100000 ||
202 100000) { /*( 0.1M * 8bit ) / 2sec = 0.4M bits /sec )*/
204 dm->traffic_load = TRAFFIC_LOW;
207 dm->traffic_load = TRAFFIC_ULTRA_LOW;
212 static void phydm_config_ofdm_tx_path(struct phy_dm_struct *dm, u32 path) {}
214 void phydm_config_ofdm_rx_path(struct phy_dm_struct *dm, u32 path)
218 if (dm->support_ic_type & (ODM_RTL8192E)) {
219 } else if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8822B)) {
220 if (path == PHYDM_A) {
223 } else if (path == PHYDM_B) {
226 } else if (path == PHYDM_AB) {
231 odm_set_bb_reg(dm, 0x808, MASKBYTE0,
232 ((ofdm_rx_path << 4) | ofdm_rx_path));
236 static void phydm_config_cck_rx_antenna_init(struct phy_dm_struct *dm) {}
238 static void phydm_config_cck_rx_path(struct phy_dm_struct *dm, u8 path,
243 void phydm_config_trx_path(void *dm_void, u32 *const dm_value, u32 *_used,
244 char *output, u32 *_out_len)
246 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
248 u32 out_len = *_out_len;
251 if (dm_value[0] == 0) {
252 if (dm_value[1] == 1) { /*TX*/
253 if (dm_value[2] == 1)
254 odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x8);
255 else if (dm_value[2] == 2)
256 odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x4);
257 else if (dm_value[2] == 3)
258 odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0xc);
259 } else if (dm_value[1] == 2) { /*RX*/
261 phydm_config_cck_rx_antenna_init(dm);
263 if (dm_value[2] == 1)
264 phydm_config_cck_rx_path(dm, PHYDM_A,
265 CCA_PATHDIV_DISABLE);
266 else if (dm_value[2] == 2)
267 phydm_config_cck_rx_path(dm, PHYDM_B,
268 CCA_PATHDIV_DISABLE);
269 else if (dm_value[2] == 3 &&
270 dm_value[3] == 1) /*enable path diversity*/
271 phydm_config_cck_rx_path(dm, PHYDM_AB,
273 else if (dm_value[2] == 3 && dm_value[3] != 1)
274 phydm_config_cck_rx_path(dm, PHYDM_B,
275 CCA_PATHDIV_DISABLE);
279 else if (dm_value[0] == 1) {
280 if (dm_value[1] == 1) { /*TX*/
281 phydm_config_ofdm_tx_path(dm, dm_value[2]);
283 } else if (dm_value[1] == 2) { /*RX*/
284 phydm_config_ofdm_rx_path(dm, dm_value[2]);
290 output + used, out_len - used,
291 "PHYDM Set path [%s] [%s] = [%s%s%s%s]\n",
292 (dm_value[0] == 1) ? "OFDM" : "CCK",
293 (dm_value[1] == 1) ? "TX" : "RX",
294 (dm_value[2] & 0x1) ? "A" : "", (dm_value[2] & 0x2) ? "B" : "",
295 (dm_value[2] & 0x4) ? "C" : "", (dm_value[2] & 0x8) ? "D" : "");
298 static void phydm_init_cck_setting(struct phy_dm_struct *dm)
300 dm->is_cck_high_power = (bool)odm_get_bb_reg(
301 dm, ODM_REG(CCK_RPT_FORMAT, dm), ODM_BIT(CCK_RPT_FORMAT, dm));
303 /* JJ ADD 20161014 */
304 /* JJ ADD 20161014 */
305 if (dm->support_ic_type & (ODM_RTL8723D | ODM_RTL8822B | ODM_RTL8197F |
306 ODM_RTL8821C | ODM_RTL8710B))
307 dm->cck_new_agc = odm_get_bb_reg(dm, 0xa9c, BIT(17)) ?
309 false; /*1: new agc 0: old agc*/
311 dm->cck_new_agc = false;
314 static void phydm_init_soft_ml_setting(struct phy_dm_struct *dm)
317 if (dm->support_ic_type & ODM_RTL8822B)
318 odm_set_bb_reg(dm, 0x19a8, MASKDWORD, 0xc10a0000);
322 static void phydm_init_hw_info_by_rfe(struct phy_dm_struct *dm)
324 if (dm->support_ic_type & ODM_RTL8822B)
325 phydm_init_hw_info_by_rfe_type_8822b(dm);
328 static void odm_common_info_self_init(struct phy_dm_struct *dm)
330 phydm_init_cck_setting(dm);
331 dm->rf_path_rx_enable = (u8)odm_get_bb_reg(dm, ODM_REG(BB_RX_PATH, dm),
332 ODM_BIT(BB_RX_PATH, dm));
333 odm_init_mp_driver_status(dm);
334 phydm_init_trx_antenna_setting(dm);
335 phydm_init_soft_ml_setting(dm);
337 dm->phydm_period = PHYDM_WATCH_DOG_PERIOD;
338 dm->phydm_sys_up_time = 0;
340 if (dm->support_ic_type & ODM_IC_1SS)
342 else if (dm->support_ic_type & ODM_IC_2SS)
344 else if (dm->support_ic_type & ODM_IC_3SS)
346 else if (dm->support_ic_type & ODM_IC_4SS)
351 dm->number_linked_client = 0;
352 dm->pre_number_linked_client = 0;
353 dm->number_active_client = 0;
354 dm->pre_number_active_client = 0;
356 dm->last_tx_ok_cnt = 0;
357 dm->last_rx_ok_cnt = 0;
361 dm->traffic_load = TRAFFIC_LOW;
363 dm->nbi_set_result = 0;
364 dm->is_init_hw_info_by_rfe = false;
365 dm->pre_dbg_priority = BB_DBGPORT_RELEASE;
368 static void odm_common_info_self_update(struct phy_dm_struct *dm)
370 u8 entry_cnt = 0, num_active_client = 0;
371 u32 i, one_entry_macid = 0;
372 struct rtl_sta_info *entry;
374 /* THis variable cannot be used because it is wrong*/
375 if (*dm->band_width == ODM_BW40M) {
376 if (*dm->sec_ch_offset == 1)
377 dm->control_channel = *dm->channel - 2;
378 else if (*dm->sec_ch_offset == 2)
379 dm->control_channel = *dm->channel + 2;
381 dm->control_channel = *dm->channel;
384 for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
385 entry = dm->odm_sta_info[i];
386 if (IS_STA_VALID(entry)) {
393 if (entry_cnt == 1) {
394 dm->is_one_entry_only = true;
395 dm->one_entry_macid = one_entry_macid;
397 dm->is_one_entry_only = false;
400 dm->pre_number_linked_client = dm->number_linked_client;
401 dm->pre_number_active_client = dm->number_active_client;
403 dm->number_linked_client = entry_cnt;
404 dm->number_active_client = num_active_client;
406 /* Update MP driver status*/
407 odm_update_mp_driver_status(dm);
409 /*Traffic load information update*/
410 phydm_traffic_load_decision(dm);
412 dm->phydm_sys_up_time += dm->phydm_period;
415 static void odm_common_info_self_reset(struct phy_dm_struct *dm)
417 dm->phy_dbg_info.num_qry_beacon_pkt = 0;
420 void *phydm_get_structure(struct phy_dm_struct *dm, u8 structure_type)
423 void *p_struct = NULL;
425 switch (structure_type) {
426 case PHYDM_FALSEALMCNT:
427 p_struct = &dm->false_alm_cnt;
431 p_struct = &dm->dm_cfo_track;
434 case PHYDM_ADAPTIVITY:
435 p_struct = &dm->adaptivity;
445 static void odm_hw_setting(struct phy_dm_struct *dm)
447 if (dm->support_ic_type & ODM_RTL8822B)
448 phydm_hwsetting_8822b(dm);
451 static void phydm_supportability_init(void *dm_void)
453 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
454 u32 support_ability = 0;
456 if (dm->support_ic_type != ODM_RTL8821C)
459 switch (dm->support_ic_type) {
460 /*---------------AC Series-------------------*/
463 support_ability |= ODM_BB_DIG | ODM_BB_FA_CNT | ODM_BB_CCK_PD |
464 ODM_BB_CFO_TRACKING | ODM_BB_RATE_ADAPTIVE |
465 ODM_BB_RSSI_MONITOR | ODM_BB_RA_MASK |
470 support_ability |= ODM_BB_DIG | ODM_BB_FA_CNT | ODM_BB_CCK_PD |
471 ODM_BB_CFO_TRACKING | ODM_BB_RATE_ADAPTIVE |
472 ODM_BB_RSSI_MONITOR | ODM_BB_RA_MASK |
475 ODM_RT_TRACE(dm, ODM_COMP_UNCOND,
476 "[Warning] Supportability Init Warning !!!\n");
480 if (*dm->enable_antdiv)
481 support_ability |= ODM_BB_ANT_DIV;
483 if (*dm->enable_adaptivity) {
484 ODM_RT_TRACE(dm, ODM_COMP_INIT,
485 "ODM adaptivity is set to Enabled!!!\n");
487 support_ability |= ODM_BB_ADAPTIVITY;
490 ODM_RT_TRACE(dm, ODM_COMP_INIT,
491 "ODM adaptivity is set to disnabled!!!\n");
495 ODM_RT_TRACE(dm, ODM_COMP_INIT, "PHYDM support_ability = ((0x%x))\n",
497 odm_cmn_info_init(dm, ODM_CMNINFO_ABILITY, support_ability);
501 * 2011/09/21 MH Add to describe different team necessary resource allocate??
503 void odm_dm_init(struct phy_dm_struct *dm)
505 phydm_supportability_init(dm);
506 odm_common_info_self_init(dm);
508 phydm_nhm_counter_statistics_init(dm);
509 phydm_adaptivity_init(dm);
510 phydm_ra_info_init(dm);
511 odm_rate_adaptive_mask_init(dm);
512 odm_cfo_tracking_init(dm);
513 odm_edca_turbo_init(dm);
514 odm_rssi_monitor_init(dm);
516 odm_txpowertracking_init(dm);
518 if (dm->support_ic_type & ODM_RTL8822B)
519 phydm_txcurrentcalibration(dm);
521 odm_antenna_diversity_init(dm);
522 odm_auto_channel_select_init(dm);
523 odm_dynamic_tx_power_init(dm);
524 phydm_init_ra_info(dm);
527 phydm_beamforming_init(dm);
529 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
531 odm_dynamic_bb_power_saving_init(dm);
537 void odm_dm_reset(struct phy_dm_struct *dm)
539 struct dig_thres *dig_tab = &dm->dm_dig_table;
541 odm_ant_div_reset(dm);
542 phydm_set_edcca_threshold_api(dm, dig_tab->cur_ig_value);
545 void phydm_support_ability_debug(void *dm_void, u32 *const dm_value, u32 *_used,
546 char *output, u32 *_out_len)
548 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
549 u32 pre_support_ability;
551 u32 out_len = *_out_len;
553 pre_support_ability = dm->support_ability;
554 PHYDM_SNPRINTF(output + used, out_len - used, "\n%s\n",
555 "================================");
556 if (dm_value[0] == 100) {
557 PHYDM_SNPRINTF(output + used, out_len - used,
558 "[Supportability] PhyDM Selection\n");
559 PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
560 "================================");
562 output + used, out_len - used, "00. (( %s ))DIG\n",
563 ((dm->support_ability & ODM_BB_DIG) ? ("V") : (".")));
565 output + used, out_len - used, "01. (( %s ))RA_MASK\n",
566 ((dm->support_ability & ODM_BB_RA_MASK) ? ("V") :
568 PHYDM_SNPRINTF(output + used, out_len - used,
569 "02. (( %s ))DYNAMIC_TXPWR\n",
570 ((dm->support_ability & ODM_BB_DYNAMIC_TXPWR) ?
573 PHYDM_SNPRINTF(output + used, out_len - used,
574 "03. (( %s ))FA_CNT\n",
575 ((dm->support_ability & ODM_BB_FA_CNT) ? ("V") :
577 PHYDM_SNPRINTF(output + used, out_len - used,
578 "04. (( %s ))RSSI_MONITOR\n",
579 ((dm->support_ability & ODM_BB_RSSI_MONITOR) ?
582 PHYDM_SNPRINTF(output + used, out_len - used,
583 "05. (( %s ))CCK_PD\n",
584 ((dm->support_ability & ODM_BB_CCK_PD) ? ("V") :
587 output + used, out_len - used, "06. (( %s ))ANT_DIV\n",
588 ((dm->support_ability & ODM_BB_ANT_DIV) ? ("V") :
590 PHYDM_SNPRINTF(output + used, out_len - used,
591 "08. (( %s ))PWR_TRAIN\n",
592 ((dm->support_ability & ODM_BB_PWR_TRAIN) ?
595 PHYDM_SNPRINTF(output + used, out_len - used,
596 "09. (( %s ))RATE_ADAPTIVE\n",
597 ((dm->support_ability & ODM_BB_RATE_ADAPTIVE) ?
601 output + used, out_len - used, "10. (( %s ))PATH_DIV\n",
602 ((dm->support_ability & ODM_BB_PATH_DIV) ? ("V") :
604 PHYDM_SNPRINTF(output + used, out_len - used,
605 "13. (( %s ))ADAPTIVITY\n",
606 ((dm->support_ability & ODM_BB_ADAPTIVITY) ?
609 PHYDM_SNPRINTF(output + used, out_len - used,
610 "14. (( %s ))struct cfo_tracking\n",
611 ((dm->support_ability & ODM_BB_CFO_TRACKING) ?
615 output + used, out_len - used, "15. (( %s ))NHM_CNT\n",
616 ((dm->support_ability & ODM_BB_NHM_CNT) ? ("V") :
618 PHYDM_SNPRINTF(output + used, out_len - used,
619 "16. (( %s ))PRIMARY_CCA\n",
620 ((dm->support_ability & ODM_BB_PRIMARY_CCA) ?
624 output + used, out_len - used, "17. (( %s ))TXBF\n",
625 ((dm->support_ability & ODM_BB_TXBF) ? ("V") : (".")));
626 PHYDM_SNPRINTF(output + used, out_len - used,
627 "18. (( %s ))DYNAMIC_ARFR\n",
628 ((dm->support_ability & ODM_BB_DYNAMIC_ARFR) ?
631 PHYDM_SNPRINTF(output + used, out_len - used,
632 "20. (( %s ))EDCA_TURBO\n",
633 ((dm->support_ability & ODM_MAC_EDCA_TURBO) ?
636 PHYDM_SNPRINTF(output + used, out_len - used,
637 "21. (( %s ))DYNAMIC_RX_PATH\n",
638 ((dm->support_ability & ODM_BB_DYNAMIC_RX_PATH) ?
641 PHYDM_SNPRINTF(output + used, out_len - used,
642 "24. (( %s ))TX_PWR_TRACK\n",
643 ((dm->support_ability & ODM_RF_TX_PWR_TRACK) ?
646 PHYDM_SNPRINTF(output + used, out_len - used,
647 "25. (( %s ))RX_GAIN_TRACK\n",
648 ((dm->support_ability & ODM_RF_RX_GAIN_TRACK) ?
651 PHYDM_SNPRINTF(output + used, out_len - used,
652 "26. (( %s ))RF_CALIBRATION\n",
653 ((dm->support_ability & ODM_RF_CALIBRATION) ?
656 PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
657 "================================");
659 if (dm_value[1] == 1) { /* enable */
660 dm->support_ability |= BIT(dm_value[0]);
661 } else if (dm_value[1] == 2) /* disable */
662 dm->support_ability &= ~(BIT(dm_value[0]));
664 PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
665 "[Warning!!!] 1:enable, 2:disable");
668 PHYDM_SNPRINTF(output + used, out_len - used,
669 "pre-support_ability = 0x%x\n", pre_support_ability);
670 PHYDM_SNPRINTF(output + used, out_len - used,
671 "Curr-support_ability = 0x%x\n", dm->support_ability);
672 PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
673 "================================");
676 void phydm_watchdog_mp(struct phy_dm_struct *dm) {}
678 * 2011/09/20 MH This is the entry pointer for all team to execute HW outsrc DM.
679 * You can not add any dummy function here, be care, you can only use DM struct
680 * to perform any new ODM_DM.
682 void odm_dm_watchdog(struct phy_dm_struct *dm)
684 odm_common_info_self_update(dm);
685 phydm_basic_dbg_message(dm);
688 odm_false_alarm_counter_statistics(dm);
689 phydm_noisy_detection(dm);
691 odm_rssi_monitor_check(dm);
693 if (*dm->is_power_saving) {
694 odm_dig_by_rssi_lps(dm);
695 phydm_adaptivity(dm);
696 odm_antenna_diversity(
697 dm); /*enable AntDiv in PS mode, request from SD4 Jeff*/
698 ODM_RT_TRACE(dm, ODM_COMP_COMMON,
699 "DMWatchdog in power saving mode\n");
703 phydm_check_adaptivity(dm);
704 odm_update_power_training_state(dm);
706 phydm_adaptivity(dm);
707 odm_cck_packet_detection_thresh(dm);
709 phydm_ra_info_watchdog(dm);
710 odm_edca_turbo_check(dm);
711 odm_cfo_tracking(dm);
712 odm_dynamic_tx_power(dm);
713 odm_antenna_diversity(dm);
715 phydm_beamforming_watchdog(dm);
717 phydm_rf_watchdog(dm);
721 odm_common_info_self_reset(dm);
725 * Init /.. Fixed HW value. Only init time.
727 void odm_cmn_info_init(struct phy_dm_struct *dm, enum odm_cmninfo cmn_info,
730 /* This section is used for init value */
732 /* Fixed ODM value. */
733 case ODM_CMNINFO_ABILITY:
734 dm->support_ability = (u32)value;
737 case ODM_CMNINFO_RF_TYPE:
738 dm->rf_type = (u8)value;
741 case ODM_CMNINFO_PLATFORM:
742 dm->support_platform = (u8)value;
745 case ODM_CMNINFO_INTERFACE:
746 dm->support_interface = (u8)value;
749 case ODM_CMNINFO_MP_TEST_CHIP:
750 dm->is_mp_chip = (u8)value;
753 case ODM_CMNINFO_IC_TYPE:
754 dm->support_ic_type = value;
757 case ODM_CMNINFO_CUT_VER:
758 dm->cut_version = (u8)value;
761 case ODM_CMNINFO_FAB_VER:
762 dm->fab_version = (u8)value;
765 case ODM_CMNINFO_RFE_TYPE:
766 dm->rfe_type = (u8)value;
767 phydm_init_hw_info_by_rfe(dm);
770 case ODM_CMNINFO_RF_ANTENNA_TYPE:
771 dm->ant_div_type = (u8)value;
774 case ODM_CMNINFO_WITH_EXT_ANTENNA_SWITCH:
775 dm->with_extenal_ant_switch = (u8)value;
778 case ODM_CMNINFO_BE_FIX_TX_ANT:
779 dm->dm_fat_table.b_fix_tx_ant = (u8)value;
782 case ODM_CMNINFO_BOARD_TYPE:
783 if (!dm->is_init_hw_info_by_rfe)
784 dm->board_type = (u8)value;
787 case ODM_CMNINFO_PACKAGE_TYPE:
788 if (!dm->is_init_hw_info_by_rfe)
789 dm->package_type = (u8)value;
792 case ODM_CMNINFO_EXT_LNA:
793 if (!dm->is_init_hw_info_by_rfe)
794 dm->ext_lna = (u8)value;
797 case ODM_CMNINFO_5G_EXT_LNA:
798 if (!dm->is_init_hw_info_by_rfe)
799 dm->ext_lna_5g = (u8)value;
802 case ODM_CMNINFO_EXT_PA:
803 if (!dm->is_init_hw_info_by_rfe)
804 dm->ext_pa = (u8)value;
807 case ODM_CMNINFO_5G_EXT_PA:
808 if (!dm->is_init_hw_info_by_rfe)
809 dm->ext_pa_5g = (u8)value;
812 case ODM_CMNINFO_GPA:
813 if (!dm->is_init_hw_info_by_rfe)
814 dm->type_gpa = (u16)value;
817 case ODM_CMNINFO_APA:
818 if (!dm->is_init_hw_info_by_rfe)
819 dm->type_apa = (u16)value;
822 case ODM_CMNINFO_GLNA:
823 if (!dm->is_init_hw_info_by_rfe)
824 dm->type_glna = (u16)value;
827 case ODM_CMNINFO_ALNA:
828 if (!dm->is_init_hw_info_by_rfe)
829 dm->type_alna = (u16)value;
832 case ODM_CMNINFO_EXT_TRSW:
833 if (!dm->is_init_hw_info_by_rfe)
834 dm->ext_trsw = (u8)value;
836 case ODM_CMNINFO_EXT_LNA_GAIN:
837 dm->ext_lna_gain = (u8)value;
839 case ODM_CMNINFO_PATCH_ID:
840 dm->patch_id = (u8)value;
842 case ODM_CMNINFO_BINHCT_TEST:
843 dm->is_in_hct_test = (bool)value;
845 case ODM_CMNINFO_BWIFI_TEST:
846 dm->wifi_test = (u8)value;
848 case ODM_CMNINFO_SMART_CONCURRENT:
849 dm->is_dual_mac_smart_concurrent = (bool)value;
851 case ODM_CMNINFO_DOMAIN_CODE_2G:
852 dm->odm_regulation_2_4g = (u8)value;
854 case ODM_CMNINFO_DOMAIN_CODE_5G:
855 dm->odm_regulation_5g = (u8)value;
857 case ODM_CMNINFO_CONFIG_BB_RF:
858 dm->config_bbrf = (bool)value;
860 case ODM_CMNINFO_IQKFWOFFLOAD:
861 dm->iqk_fw_offload = (u8)value;
863 case ODM_CMNINFO_IQKPAOFF:
864 dm->rf_calibrate_info.is_iqk_pa_off = (bool)value;
866 case ODM_CMNINFO_REGRFKFREEENABLE:
867 dm->rf_calibrate_info.reg_rf_kfree_enable = (u8)value;
869 case ODM_CMNINFO_RFKFREEENABLE:
870 dm->rf_calibrate_info.rf_kfree_enable = (u8)value;
872 case ODM_CMNINFO_NORMAL_RX_PATH_CHANGE:
873 dm->normal_rx_path = (u8)value;
875 case ODM_CMNINFO_EFUSE0X3D8:
876 dm->efuse0x3d8 = (u8)value;
878 case ODM_CMNINFO_EFUSE0X3D7:
879 dm->efuse0x3d7 = (u8)value;
881 /* To remove the compiler warning, must add an empty default statement
882 * to handle the other values.
890 void odm_cmn_info_hook(struct phy_dm_struct *dm, enum odm_cmninfo cmn_info,
894 /* Hook call by reference pointer. */
898 /* Dynamic call by reference pointer. */
900 case ODM_CMNINFO_MAC_PHY_MODE:
901 dm->mac_phy_mode = (u8 *)value;
904 case ODM_CMNINFO_TX_UNI:
905 dm->num_tx_bytes_unicast = (u64 *)value;
908 case ODM_CMNINFO_RX_UNI:
909 dm->num_rx_bytes_unicast = (u64 *)value;
912 case ODM_CMNINFO_WM_MODE:
913 dm->wireless_mode = (u8 *)value;
916 case ODM_CMNINFO_BAND:
917 dm->band_type = (u8 *)value;
920 case ODM_CMNINFO_SEC_CHNL_OFFSET:
921 dm->sec_ch_offset = (u8 *)value;
924 case ODM_CMNINFO_SEC_MODE:
925 dm->security = (u8 *)value;
929 dm->band_width = (u8 *)value;
932 case ODM_CMNINFO_CHNL:
933 dm->channel = (u8 *)value;
936 case ODM_CMNINFO_DMSP_GET_VALUE:
937 dm->is_get_value_from_other_mac = (bool *)value;
940 case ODM_CMNINFO_BUDDY_ADAPTOR:
941 dm->buddy_adapter = (void **)value;
944 case ODM_CMNINFO_DMSP_IS_MASTER:
945 dm->is_master_of_dmsp = (bool *)value;
948 case ODM_CMNINFO_SCAN:
949 dm->is_scan_in_process = (bool *)value;
952 case ODM_CMNINFO_POWER_SAVING:
953 dm->is_power_saving = (bool *)value;
956 case ODM_CMNINFO_ONE_PATH_CCA:
957 dm->one_path_cca = (u8 *)value;
960 case ODM_CMNINFO_DRV_STOP:
961 dm->is_driver_stopped = (bool *)value;
964 case ODM_CMNINFO_PNP_IN:
965 dm->is_driver_is_going_to_pnp_set_power_sleep = (bool *)value;
968 case ODM_CMNINFO_INIT_ON:
969 dm->pinit_adpt_in_progress = (bool *)value;
972 case ODM_CMNINFO_ANT_TEST:
973 dm->antenna_test = (u8 *)value;
976 case ODM_CMNINFO_NET_CLOSED:
977 dm->is_net_closed = (bool *)value;
980 case ODM_CMNINFO_FORCED_RATE:
981 dm->forced_data_rate = (u16 *)value;
983 case ODM_CMNINFO_ANT_DIV:
984 dm->enable_antdiv = (u8 *)value;
986 case ODM_CMNINFO_ADAPTIVITY:
987 dm->enable_adaptivity = (u8 *)value;
989 case ODM_CMNINFO_FORCED_IGI_LB:
990 dm->pu1_forced_igi_lb = (u8 *)value;
993 case ODM_CMNINFO_P2P_LINK:
994 dm->dm_dig_table.is_p2p_in_process = (u8 *)value;
997 case ODM_CMNINFO_IS1ANTENNA:
998 dm->is_1_antenna = (bool *)value;
1001 case ODM_CMNINFO_RFDEFAULTPATH:
1002 dm->rf_default_path = (u8 *)value;
1005 case ODM_CMNINFO_FCS_MODE:
1006 dm->is_fcs_mode_enable = (bool *)value;
1008 /*add by YuChen for beamforming PhyDM*/
1009 case ODM_CMNINFO_HUBUSBMODE:
1010 dm->hub_usb_mode = (u8 *)value;
1012 case ODM_CMNINFO_FWDWRSVDPAGEINPROGRESS:
1013 dm->is_fw_dw_rsvd_page_in_progress = (bool *)value;
1015 case ODM_CMNINFO_TX_TP:
1016 dm->current_tx_tp = (u32 *)value;
1018 case ODM_CMNINFO_RX_TP:
1019 dm->current_rx_tp = (u32 *)value;
1021 case ODM_CMNINFO_SOUNDING_SEQ:
1022 dm->sounding_seq = (u8 *)value;
1024 case ODM_CMNINFO_FORCE_TX_ANT_BY_TXDESC:
1025 dm->dm_fat_table.p_force_tx_ant_by_desc = (u8 *)value;
1027 case ODM_CMNINFO_SET_S0S1_DEFAULT_ANTENNA:
1028 dm->dm_fat_table.p_default_s0_s1 = (u8 *)value;
1037 void odm_cmn_info_ptr_array_hook(struct phy_dm_struct *dm,
1038 enum odm_cmninfo cmn_info, u16 index,
1041 /*Hook call by reference pointer.*/
1043 /*Dynamic call by reference pointer. */
1044 case ODM_CMNINFO_STA_STATUS:
1045 dm->odm_sta_info[index] = (struct rtl_sta_info *)value;
1047 if (IS_STA_VALID(dm->odm_sta_info[index]))
1048 dm->platform2phydm_macid_table[index] = index;
1051 /* To remove the compiler warning, must add an empty default statement
1052 * to handle the other values.
1061 * Update band/CHannel/.. The values are dynamic but non-per-packet.
1063 void odm_cmn_info_update(struct phy_dm_struct *dm, u32 cmn_info, u64 value)
1065 /* This init variable may be changed in run time. */
1067 case ODM_CMNINFO_LINK_IN_PROGRESS:
1068 dm->is_link_in_process = (bool)value;
1071 case ODM_CMNINFO_ABILITY:
1072 dm->support_ability = (u32)value;
1075 case ODM_CMNINFO_RF_TYPE:
1076 dm->rf_type = (u8)value;
1079 case ODM_CMNINFO_WIFI_DIRECT:
1080 dm->is_wifi_direct = (bool)value;
1083 case ODM_CMNINFO_WIFI_DISPLAY:
1084 dm->is_wifi_display = (bool)value;
1087 case ODM_CMNINFO_LINK:
1088 dm->is_linked = (bool)value;
1091 case ODM_CMNINFO_CMW500LINK:
1092 dm->is_linkedcmw500 = (bool)value;
1095 case ODM_CMNINFO_LPSPG:
1096 dm->is_in_lps_pg = (bool)value;
1099 case ODM_CMNINFO_STATION_STATE:
1100 dm->bsta_state = (bool)value;
1103 case ODM_CMNINFO_RSSI_MIN:
1104 dm->rssi_min = (u8)value;
1107 case ODM_CMNINFO_DBG_COMP:
1108 dm->debug_components = (u32)value;
1111 case ODM_CMNINFO_DBG_LEVEL:
1112 dm->debug_level = (u32)value;
1114 case ODM_CMNINFO_RA_THRESHOLD_HIGH:
1115 dm->rate_adaptive.high_rssi_thresh = (u8)value;
1118 case ODM_CMNINFO_RA_THRESHOLD_LOW:
1119 dm->rate_adaptive.low_rssi_thresh = (u8)value;
1121 /* The following is for BT HS mode and BT coexist mechanism. */
1122 case ODM_CMNINFO_BT_ENABLED:
1123 dm->is_bt_enabled = (bool)value;
1126 case ODM_CMNINFO_BT_HS_CONNECT_PROCESS:
1127 dm->is_bt_connect_process = (bool)value;
1130 case ODM_CMNINFO_BT_HS_RSSI:
1131 dm->bt_hs_rssi = (u8)value;
1134 case ODM_CMNINFO_BT_OPERATION:
1135 dm->is_bt_hs_operation = (bool)value;
1138 case ODM_CMNINFO_BT_LIMITED_DIG:
1139 dm->is_bt_limited_dig = (bool)value;
1142 case ODM_CMNINFO_BT_DIG:
1143 dm->bt_hs_dig_val = (u8)value;
1146 case ODM_CMNINFO_BT_BUSY:
1147 dm->is_bt_busy = (bool)value;
1150 case ODM_CMNINFO_BT_DISABLE_EDCA:
1151 dm->is_bt_disable_edca_turbo = (bool)value;
1154 case ODM_CMNINFO_AP_TOTAL_NUM:
1155 dm->ap_total_num = (u8)value;
1158 case ODM_CMNINFO_POWER_TRAINING:
1159 dm->is_disable_power_training = (bool)value;
1168 u32 phydm_cmn_info_query(struct phy_dm_struct *dm,
1169 enum phydm_info_query info_type)
1171 struct false_alarm_stat *false_alm_cnt =
1172 (struct false_alarm_stat *)phydm_get_structure(
1173 dm, PHYDM_FALSEALMCNT);
1175 switch (info_type) {
1176 case PHYDM_INFO_FA_OFDM:
1177 return false_alm_cnt->cnt_ofdm_fail;
1179 case PHYDM_INFO_FA_CCK:
1180 return false_alm_cnt->cnt_cck_fail;
1182 case PHYDM_INFO_FA_TOTAL:
1183 return false_alm_cnt->cnt_all;
1185 case PHYDM_INFO_CCA_OFDM:
1186 return false_alm_cnt->cnt_ofdm_cca;
1188 case PHYDM_INFO_CCA_CCK:
1189 return false_alm_cnt->cnt_cck_cca;
1191 case PHYDM_INFO_CCA_ALL:
1192 return false_alm_cnt->cnt_cca_all;
1194 case PHYDM_INFO_CRC32_OK_VHT:
1195 return false_alm_cnt->cnt_vht_crc32_ok;
1197 case PHYDM_INFO_CRC32_OK_HT:
1198 return false_alm_cnt->cnt_ht_crc32_ok;
1200 case PHYDM_INFO_CRC32_OK_LEGACY:
1201 return false_alm_cnt->cnt_ofdm_crc32_ok;
1203 case PHYDM_INFO_CRC32_OK_CCK:
1204 return false_alm_cnt->cnt_cck_crc32_ok;
1206 case PHYDM_INFO_CRC32_ERROR_VHT:
1207 return false_alm_cnt->cnt_vht_crc32_error;
1209 case PHYDM_INFO_CRC32_ERROR_HT:
1210 return false_alm_cnt->cnt_ht_crc32_error;
1212 case PHYDM_INFO_CRC32_ERROR_LEGACY:
1213 return false_alm_cnt->cnt_ofdm_crc32_error;
1215 case PHYDM_INFO_CRC32_ERROR_CCK:
1216 return false_alm_cnt->cnt_cck_crc32_error;
1218 case PHYDM_INFO_EDCCA_FLAG:
1219 return false_alm_cnt->edcca_flag;
1221 case PHYDM_INFO_OFDM_ENABLE:
1222 return false_alm_cnt->ofdm_block_enable;
1224 case PHYDM_INFO_CCK_ENABLE:
1225 return false_alm_cnt->cck_block_enable;
1227 case PHYDM_INFO_DBG_PORT_0:
1228 return false_alm_cnt->dbg_port0;
1235 void odm_init_all_timers(struct phy_dm_struct *dm) {}
1237 void odm_cancel_all_timers(struct phy_dm_struct *dm) {}
1239 void odm_release_all_timers(struct phy_dm_struct *dm) {}
1241 /* 3============================================================
1242 * 3 Tx Power Tracking
1243 * 3============================================================
1246 /* need to ODM CE Platform
1247 * move to here for ANT detection mechanism using
1250 u32 odm_convert_to_db(u32 value)
1256 value = value & 0xFFFF;
1258 for (i = 0; i < 12; i++) {
1259 if (value <= db_invert_table[i][7])
1264 return 96; /* maximum 96 dB */
1266 for (j = 0; j < 8; j++) {
1267 if (value <= db_invert_table[i][j])
1271 dB = (i << 3) + j + 1;
1276 u32 odm_convert_to_linear(u32 value)
1284 value = value & 0xFF;
1286 i = (u8)((value - 1) >> 3);
1287 j = (u8)(value - 1) - (i << 3);
1289 linear = db_invert_table[i][j];
1295 * ODM multi-port consideration, added by Roger, 2013.10.01.
1297 void odm_asoc_entry_init(struct phy_dm_struct *dm) {}
1299 /* Justin: According to the current RRSI to adjust Response Frame TX power */
1300 void odm_dtc(struct phy_dm_struct *dm) {}
1302 static void odm_update_power_training_state(struct phy_dm_struct *dm)
1304 struct false_alarm_stat *false_alm_cnt =
1305 (struct false_alarm_stat *)phydm_get_structure(
1306 dm, PHYDM_FALSEALMCNT);
1307 struct dig_thres *dig_tab = &dm->dm_dig_table;
1310 if (!(dm->support_ability & ODM_BB_PWR_TRAIN))
1313 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "%s()============>\n", __func__);
1314 dm->is_change_state = false;
1317 if (dm->force_power_training_state) {
1318 if (dm->force_power_training_state == 1 &&
1319 !dm->is_disable_power_training) {
1320 dm->is_change_state = true;
1321 dm->is_disable_power_training = true;
1322 } else if (dm->force_power_training_state == 2 &&
1323 dm->is_disable_power_training) {
1324 dm->is_change_state = true;
1325 dm->is_disable_power_training = false;
1329 dm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
1330 dm->phy_dbg_info.num_qry_phy_status_cck = 0;
1331 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1332 "%s(): force_power_training_state = %d\n",
1333 __func__, dm->force_power_training_state);
1341 if ((dm->is_linked) && !dig_tab->is_media_connect_0) {
1343 dm->is_change_state = true;
1344 dm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
1345 dm->phy_dbg_info.num_qry_phy_status_cck = 0;
1346 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "%s(): First Connect\n",
1352 if (dm->nhm_cnt_0 >= 215) {
1354 } else if (dm->nhm_cnt_0 >= 190) {
1355 score = 1; /* unknown state */
1359 rx_pkt_cnt = (u32)(dm->phy_dbg_info.num_qry_phy_status_ofdm) +
1360 (u32)(dm->phy_dbg_info.num_qry_phy_status_cck);
1362 if ((false_alm_cnt->cnt_cca_all > 31 && rx_pkt_cnt > 31) &&
1363 (false_alm_cnt->cnt_cca_all >= rx_pkt_cnt)) {
1364 if ((rx_pkt_cnt + (rx_pkt_cnt >> 1)) <=
1365 false_alm_cnt->cnt_cca_all)
1367 else if ((rx_pkt_cnt + (rx_pkt_cnt >> 2)) <=
1368 false_alm_cnt->cnt_cca_all)
1373 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1374 "%s(): rx_pkt_cnt = %d, cnt_cca_all = %d\n",
1375 __func__, rx_pkt_cnt, false_alm_cnt->cnt_cca_all);
1378 dm, ODM_COMP_RA_MASK,
1379 "%s(): num_qry_phy_status_ofdm = %d, num_qry_phy_status_cck = %d\n",
1380 __func__, (u32)(dm->phy_dbg_info.num_qry_phy_status_ofdm),
1381 (u32)(dm->phy_dbg_info.num_qry_phy_status_cck));
1382 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "%s(): nhm_cnt_0 = %d, score = %d\n",
1383 __func__, dm->nhm_cnt_0, score);
1386 dm->PT_score = (score << 4) + (dm->PT_score >> 1) + (dm->PT_score >> 2);
1387 score = (dm->PT_score + 32) >> 6;
1388 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1389 "%s(): PT_score = %d, score after smoothing = %d\n",
1390 __func__, dm->PT_score, score);
1394 if (dm->is_disable_power_training) {
1395 dm->is_change_state = true;
1396 dm->is_disable_power_training = false;
1397 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1398 "%s(): Change state\n", __func__);
1400 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1401 "%s(): Enable Power Training\n", __func__);
1402 } else if (score == 0) {
1403 if (!dm->is_disable_power_training) {
1404 dm->is_change_state = true;
1405 dm->is_disable_power_training = true;
1406 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1407 "%s(): Change state\n", __func__);
1409 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1410 "%s(): Disable Power Training\n", __func__);
1413 dm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
1414 dm->phy_dbg_info.num_qry_phy_status_cck = 0;
1417 /*===========================================================*/
1418 /* The following is for compile only*/
1419 /*===========================================================*/
1420 /*#define TARGET_CHNL_NUM_2G_5G 59*/
1421 /*===========================================================*/
1423 void phydm_noisy_detection(struct phy_dm_struct *dm)
1425 u32 total_fa_cnt, total_cca_cnt;
1426 u32 score = 0, i, score_smooth;
1428 total_cca_cnt = dm->false_alm_cnt.cnt_cca_all;
1429 total_fa_cnt = dm->false_alm_cnt.cnt_all;
1431 for (i = 0; i <= 16; i++) {
1432 if (total_fa_cnt * 16 >= total_cca_cnt * (16 - i)) {
1438 /* noisy_decision_smooth = noisy_decision_smooth>>1 + (score<<3)>>1; */
1439 dm->noisy_decision_smooth =
1440 (dm->noisy_decision_smooth >> 1) + (score << 2);
1442 /* Round the noisy_decision_smooth: +"3" comes from (2^3)/2-1 */
1443 score_smooth = (total_cca_cnt >= 300) ?
1444 ((dm->noisy_decision_smooth + 3) >> 3) :
1447 dm->noisy_decision = (score_smooth >= 3) ? 1 : 0;
1449 dm, ODM_COMP_NOISY_DETECT,
1450 "[NoisyDetection] total_cca_cnt=%d, total_fa_cnt=%d, noisy_decision_smooth=%d, score=%d, score_smooth=%d, dm->noisy_decision=%d\n",
1451 total_cca_cnt, total_fa_cnt, dm->noisy_decision_smooth, score,
1452 score_smooth, dm->noisy_decision);
1455 void phydm_set_ext_switch(void *dm_void, u32 *const dm_value, u32 *_used,
1456 char *output, u32 *_out_len)
1458 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1459 u32 ext_ant_switch = dm_value[0];
1461 if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
1462 /*Output Pin Settings*/
1463 odm_set_mac_reg(dm, 0x4C, BIT(23),
1464 0); /*select DPDT_P and DPDT_N as output pin*/
1465 odm_set_mac_reg(dm, 0x4C, BIT(24), 1); /*by WLAN control*/
1467 odm_set_bb_reg(dm, 0xCB4, 0xF, 7); /*DPDT_P = 1b'0*/
1468 odm_set_bb_reg(dm, 0xCB4, 0xF0, 7); /*DPDT_N = 1b'0*/
1470 if (ext_ant_switch == MAIN_ANT) {
1471 odm_set_bb_reg(dm, 0xCB4, (BIT(29) | BIT(28)), 1);
1474 "***8821A set ant switch = 2b'01 (Main)\n");
1475 } else if (ext_ant_switch == AUX_ANT) {
1476 odm_set_bb_reg(dm, 0xCB4, BIT(29) | BIT(28), 2);
1477 ODM_RT_TRACE(dm, ODM_COMP_API,
1478 "***8821A set ant switch = 2b'10 (Aux)\n");
1483 static void phydm_csi_mask_enable(void *dm_void, u32 enable)
1485 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1488 reg_value = (enable == CSI_MASK_ENABLE) ? 1 : 0;
1490 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1491 odm_set_bb_reg(dm, 0xD2C, BIT(28), reg_value);
1492 ODM_RT_TRACE(dm, ODM_COMP_API,
1493 "Enable CSI Mask: Reg 0xD2C[28] = ((0x%x))\n",
1496 } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1497 odm_set_bb_reg(dm, 0x874, BIT(0), reg_value);
1498 ODM_RT_TRACE(dm, ODM_COMP_API,
1499 "Enable CSI Mask: Reg 0x874[0] = ((0x%x))\n",
1504 static void phydm_clean_all_csi_mask(void *dm_void)
1506 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1508 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1509 odm_set_bb_reg(dm, 0xD40, MASKDWORD, 0);
1510 odm_set_bb_reg(dm, 0xD44, MASKDWORD, 0);
1511 odm_set_bb_reg(dm, 0xD48, MASKDWORD, 0);
1512 odm_set_bb_reg(dm, 0xD4c, MASKDWORD, 0);
1514 } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1515 odm_set_bb_reg(dm, 0x880, MASKDWORD, 0);
1516 odm_set_bb_reg(dm, 0x884, MASKDWORD, 0);
1517 odm_set_bb_reg(dm, 0x888, MASKDWORD, 0);
1518 odm_set_bb_reg(dm, 0x88c, MASKDWORD, 0);
1519 odm_set_bb_reg(dm, 0x890, MASKDWORD, 0);
1520 odm_set_bb_reg(dm, 0x894, MASKDWORD, 0);
1521 odm_set_bb_reg(dm, 0x898, MASKDWORD, 0);
1522 odm_set_bb_reg(dm, 0x89c, MASKDWORD, 0);
1526 static void phydm_set_csi_mask_reg(void *dm_void, u32 tone_idx_tmp,
1529 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1530 u8 byte_offset, bit_offset;
1534 u32 tone_num_shift = 0;
1535 u32 csi_mask_reg_p = 0, csi_mask_reg_n = 0;
1537 /* calculate real tone idx*/
1538 if ((tone_idx_tmp % 10) >= 5)
1541 tone_idx_tmp = (tone_idx_tmp / 10);
1543 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1545 csi_mask_reg_p = 0xD40;
1546 csi_mask_reg_n = 0xD48;
1548 } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1550 csi_mask_reg_p = 0x880;
1551 csi_mask_reg_n = 0x890;
1554 if (tone_direction == FREQ_POSITIVE) {
1555 if (tone_idx_tmp >= (tone_num - 1))
1556 tone_idx_tmp = (tone_num - 1);
1558 byte_offset = (u8)(tone_idx_tmp >> 3);
1559 bit_offset = (u8)(tone_idx_tmp & 0x7);
1560 target_reg = csi_mask_reg_p + byte_offset;
1563 tone_num_shift = tone_num;
1565 if (tone_idx_tmp >= tone_num)
1566 tone_idx_tmp = tone_num;
1568 tone_idx_tmp = tone_num - tone_idx_tmp;
1570 byte_offset = (u8)(tone_idx_tmp >> 3);
1571 bit_offset = (u8)(tone_idx_tmp & 0x7);
1572 target_reg = csi_mask_reg_n + byte_offset;
1575 reg_tmp_value = odm_read_1byte(dm, target_reg);
1576 ODM_RT_TRACE(dm, ODM_COMP_API,
1577 "Pre Mask tone idx[%d]: Reg0x%x = ((0x%x))\n",
1578 (tone_idx_tmp + tone_num_shift), target_reg,
1580 reg_tmp_value |= BIT(bit_offset);
1581 odm_write_1byte(dm, target_reg, reg_tmp_value);
1582 ODM_RT_TRACE(dm, ODM_COMP_API,
1583 "New Mask tone idx[%d]: Reg0x%x = ((0x%x))\n",
1584 (tone_idx_tmp + tone_num_shift), target_reg,
1588 static void phydm_set_nbi_reg(void *dm_void, u32 tone_idx_tmp, u32 bw)
1590 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1591 u32 nbi_table_128[NBI_TABLE_SIZE_128] = {
1592 25, 55, 85, 115, 135, 155, 185, 205, 225, 245,
1593 /*1~10*/ /*tone_idx X 10*/
1594 265, 285, 305, 335, 355, 375, 395, 415, 435, 455, /*11~20*/
1595 485, 505, 525, 555, 585, 615, 635}; /*21~27*/
1597 u32 nbi_table_256[NBI_TABLE_SIZE_256] = {
1598 25, 55, 85, 115, 135, 155, 175, 195, 225,
1600 265, 285, 305, 325, 345, 365, 385, 405, 425,
1602 465, 485, 505, 525, 545, 565, 585, 605, 625,
1604 665, 695, 715, 735, 755, 775, 795, 815, 835,
1606 875, 895, 915, 935, 955, 975, 995, 1015, 1035,
1608 1085, 1105, 1125, 1145, 1175, 1195, 1225, 1255, 1275}; /*51~59*/
1612 u8 nbi_table_idx = FFT_128_TYPE;
1614 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1615 nbi_table_idx = FFT_128_TYPE;
1616 } else if (dm->support_ic_type & ODM_IC_11AC_1_SERIES) {
1617 nbi_table_idx = FFT_256_TYPE;
1618 } else if (dm->support_ic_type & ODM_IC_11AC_2_SERIES) {
1620 nbi_table_idx = FFT_256_TYPE;
1622 nbi_table_idx = FFT_128_TYPE;
1625 if (nbi_table_idx == FFT_128_TYPE) {
1626 for (i = 0; i < NBI_TABLE_SIZE_128; i++) {
1627 if (tone_idx_tmp < nbi_table_128[i]) {
1633 } else if (nbi_table_idx == FFT_256_TYPE) {
1634 for (i = 0; i < NBI_TABLE_SIZE_256; i++) {
1635 if (tone_idx_tmp < nbi_table_256[i]) {
1642 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1643 odm_set_bb_reg(dm, 0xc40, 0x1f000000, reg_idx);
1644 ODM_RT_TRACE(dm, ODM_COMP_API,
1645 "Set tone idx: Reg0xC40[28:24] = ((0x%x))\n",
1649 odm_set_bb_reg(dm, 0x87c, 0xfc000, reg_idx);
1650 ODM_RT_TRACE(dm, ODM_COMP_API,
1651 "Set tone idx: Reg0x87C[19:14] = ((0x%x))\n",
1657 static void phydm_nbi_enable(void *dm_void, u32 enable)
1659 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1662 reg_value = (enable == NBI_ENABLE) ? 1 : 0;
1664 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1665 odm_set_bb_reg(dm, 0xc40, BIT(9), reg_value);
1666 ODM_RT_TRACE(dm, ODM_COMP_API,
1667 "Enable NBI Reg0xC40[9] = ((0x%x))\n", reg_value);
1669 } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1670 odm_set_bb_reg(dm, 0x87c, BIT(13), reg_value);
1671 ODM_RT_TRACE(dm, ODM_COMP_API,
1672 "Enable NBI Reg0x87C[13] = ((0x%x))\n", reg_value);
1676 static u8 phydm_calculate_fc(void *dm_void, u32 channel, u32 bw, u32 second_ch,
1679 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1681 u32 start_ch_per_40m[NUM_START_CH_40M + 1] = {
1682 36, 44, 52, 60, 100, 108, 116, 124,
1683 132, 140, 149, 157, 165, 173, 173 + 8,
1685 u32 start_ch_per_80m[NUM_START_CH_80M + 1] = {
1686 36, 52, 100, 116, 132, 149, 165, 165 + 16,
1688 u32 *start_ch = &start_ch_per_40m[0];
1689 u32 num_start_channel = NUM_START_CH_40M;
1690 u32 channel_offset = 0;
1694 if (channel <= 14 && channel > 0) {
1698 fc = 2412 + (channel - 1) * 5;
1700 if (bw == 40 && (second_ch == PHYDM_ABOVE)) {
1701 if (channel >= 10) {
1704 "CH = ((%d)), Scnd_CH = ((%d)) Error setting\n",
1705 channel, second_ch);
1709 } else if (bw == 40 && (second_ch == PHYDM_BELOW)) {
1713 "CH = ((%d)), Scnd_CH = ((%d)) Error setting\n",
1714 channel, second_ch);
1721 else if (channel >= 36 && channel <= 177) {
1723 fc = 5180 + (channel - 36) * 5;
1729 num_start_channel = NUM_START_CH_40M;
1730 start_ch = &start_ch_per_40m[0];
1731 channel_offset = CH_OFFSET_40M;
1732 } else if (bw == 80) {
1733 num_start_channel = NUM_START_CH_80M;
1734 start_ch = &start_ch_per_80m[0];
1735 channel_offset = CH_OFFSET_80M;
1738 for (i = 0; i < num_start_channel; i++) {
1739 if (channel < start_ch[i + 1]) {
1740 channel = start_ch[i] + channel_offset;
1745 ODM_RT_TRACE(dm, ODM_COMP_API, "Mod_CH = ((%d))\n", channel);
1747 fc = 5180 + (channel - 36) * 5;
1750 ODM_RT_TRACE(dm, ODM_COMP_API, "CH = ((%d)) Error setting\n",
1760 static u8 phydm_calculate_intf_distance(void *dm_void, u32 bw, u32 fc,
1762 u32 *tone_idx_tmp_in)
1764 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1768 u8 set_result = SET_NO_NEED;
1770 bw_up = fc + bw / 2;
1771 bw_low = fc - bw / 2;
1773 ODM_RT_TRACE(dm, ODM_COMP_API,
1774 "[f_l, fc, fh] = [ %d, %d, %d ], f_int = ((%d))\n", bw_low,
1775 fc, bw_up, f_interference);
1777 if ((f_interference >= bw_low) && (f_interference <= bw_up)) {
1778 int_distance = (fc >= f_interference) ? (fc - f_interference) :
1779 (f_interference - fc);
1781 (int_distance << 5); /* =10*(int_distance /0.3125) */
1784 "int_distance = ((%d MHz)) Mhz, tone_idx_tmp = ((%d.%d))\n",
1785 int_distance, (tone_idx_tmp / 10), (tone_idx_tmp % 10));
1786 *tone_idx_tmp_in = tone_idx_tmp;
1787 set_result = SET_SUCCESS;
1793 static u8 phydm_csi_mask_setting(void *dm_void, u32 enable, u32 channel, u32 bw,
1794 u32 f_interference, u32 second_ch)
1796 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1800 u8 set_result = SET_SUCCESS;
1802 if (enable == CSI_MASK_DISABLE) {
1803 set_result = SET_SUCCESS;
1804 phydm_clean_all_csi_mask(dm);
1809 "[Set CSI MASK_] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
1810 channel, bw, f_interference,
1811 (((bw == 20) || (channel > 14)) ?
1813 (second_ch == PHYDM_ABOVE) ? "H" : "L"));
1816 if (phydm_calculate_fc(dm, channel, bw, second_ch, &fc) ==
1818 set_result = SET_ERROR;
1820 /*calculate interference distance*/
1821 if (phydm_calculate_intf_distance(
1822 dm, bw, fc, f_interference,
1823 &tone_idx_tmp) == SET_SUCCESS) {
1824 tone_direction = (f_interference >= fc) ?
1827 phydm_set_csi_mask_reg(dm, tone_idx_tmp,
1829 set_result = SET_SUCCESS;
1831 set_result = SET_NO_NEED;
1836 if (set_result == SET_SUCCESS)
1837 phydm_csi_mask_enable(dm, enable);
1839 phydm_csi_mask_enable(dm, CSI_MASK_DISABLE);
1844 u8 phydm_nbi_setting(void *dm_void, u32 enable, u32 channel, u32 bw,
1845 u32 f_interference, u32 second_ch)
1847 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1850 u8 set_result = SET_SUCCESS;
1852 if (enable == NBI_DISABLE) {
1853 set_result = SET_SUCCESS;
1857 "[Set NBI] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
1858 channel, bw, f_interference,
1859 (((second_ch == PHYDM_DONT_CARE) || (bw == 20) ||
1862 (second_ch == PHYDM_ABOVE) ? "H" : "L"));
1865 if (phydm_calculate_fc(dm, channel, bw, second_ch, &fc) ==
1867 set_result = SET_ERROR;
1869 /*calculate interference distance*/
1870 if (phydm_calculate_intf_distance(
1871 dm, bw, fc, f_interference,
1872 &tone_idx_tmp) == SET_SUCCESS) {
1873 phydm_set_nbi_reg(dm, tone_idx_tmp, bw);
1874 set_result = SET_SUCCESS;
1876 set_result = SET_NO_NEED;
1881 if (set_result == SET_SUCCESS)
1882 phydm_nbi_enable(dm, enable);
1884 phydm_nbi_enable(dm, NBI_DISABLE);
1889 void phydm_api_debug(void *dm_void, u32 function_map, u32 *const dm_value,
1890 u32 *_used, char *output, u32 *_out_len)
1892 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1894 u32 out_len = *_out_len;
1895 u32 channel = dm_value[1];
1896 u32 bw = dm_value[2];
1897 u32 f_interference = dm_value[3];
1898 u32 second_ch = dm_value[4];
1902 /*--------------------------------------------------------------------*/
1903 if (function_map == PHYDM_API_NBI) {
1904 if (dm_value[0] == 100) {
1906 output + used, out_len - used,
1907 "[HELP-NBI] EN(on=1, off=2) CH BW(20/40/80) f_intf(Mhz) Scnd_CH(L=1, H=2)\n");
1910 } else if (dm_value[0] == NBI_ENABLE) {
1912 output + used, out_len - used,
1913 "[Enable NBI] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
1914 channel, bw, f_interference,
1915 ((second_ch == PHYDM_DONT_CARE) || (bw == 20) ||
1918 ((second_ch == PHYDM_ABOVE) ? "H" :
1921 phydm_nbi_setting(dm, NBI_ENABLE, channel, bw,
1922 f_interference, second_ch);
1924 } else if (dm_value[0] == NBI_DISABLE) {
1925 PHYDM_SNPRINTF(output + used, out_len - used,
1928 phydm_nbi_setting(dm, NBI_DISABLE, channel, bw,
1929 f_interference, second_ch);
1932 set_result = SET_ERROR;
1936 output + used, out_len - used, "[NBI set result: %s]\n",
1937 (set_result == SET_SUCCESS) ?
1939 ((set_result == SET_NO_NEED) ? "No need" :
1944 /*--------------------------------------------------------------------*/
1945 else if (function_map == PHYDM_API_CSI_MASK) {
1946 if (dm_value[0] == 100) {
1948 output + used, out_len - used,
1949 "[HELP-CSI MASK] EN(on=1, off=2) CH BW(20/40/80) f_intf(Mhz) Scnd_CH(L=1, H=2)\n");
1952 } else if (dm_value[0] == CSI_MASK_ENABLE) {
1954 output + used, out_len - used,
1955 "[Enable CSI MASK] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
1956 channel, bw, f_interference,
1959 (((second_ch == PHYDM_DONT_CARE) ||
1960 (bw == 20) || (channel > 14)) ?
1963 set_result = phydm_csi_mask_setting(
1964 dm, CSI_MASK_ENABLE, channel, bw,
1965 f_interference, second_ch);
1967 } else if (dm_value[0] == CSI_MASK_DISABLE) {
1968 PHYDM_SNPRINTF(output + used, out_len - used,
1969 "[Disable CSI MASK]\n");
1970 set_result = phydm_csi_mask_setting(
1971 dm, CSI_MASK_DISABLE, channel, bw,
1972 f_interference, second_ch);
1975 set_result = SET_ERROR;
1978 PHYDM_SNPRINTF(output + used, out_len - used,
1979 "[CSI MASK set result: %s]\n",
1980 (set_result == SET_SUCCESS) ?
1982 ((set_result == SET_NO_NEED) ?