1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
4 * Copyright(c) 2007 - 2016 Realtek Corporation.
7 * wlanfae <wlanfae@realtek.com>
8 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
11 * Larry Finger <Larry.Finger@lwfinger.net>
13 *****************************************************************************/
15 /* ************************************************************
17 * *************************************************************/
19 #include "mp_precomp.h"
20 #include "phydm_precomp.h"
22 static const u16 db_invert_table[12][8] = {
23 {1, 1, 1, 2, 2, 2, 2, 3},
24 {3, 3, 4, 4, 4, 5, 6, 6},
25 {7, 8, 9, 10, 11, 13, 14, 16},
26 {18, 20, 22, 25, 28, 32, 35, 40},
27 {45, 50, 56, 63, 71, 79, 89, 100},
28 {112, 126, 141, 158, 178, 200, 224, 251},
29 {282, 316, 355, 398, 447, 501, 562, 631},
30 {708, 794, 891, 1000, 1122, 1259, 1413, 1585},
31 {1778, 1995, 2239, 2512, 2818, 3162, 3548, 3981},
32 {4467, 5012, 5623, 6310, 7079, 7943, 8913, 10000},
33 {11220, 12589, 14125, 15849, 17783, 19953, 22387, 25119},
34 {28184, 31623, 35481, 39811, 44668, 50119, 56234, 65535},
37 /* ************************************************************
38 * Local Function predefine.
39 * *************************************************************/
41 /* START------------COMMON INFO RELATED--------------- */
43 static void odm_update_power_training_state(struct phy_dm_struct *dm);
45 /* ************************************************************
47 * *************************************************************/
50 s32 odm_pwdb_conversion(s32 X, u32 total_bit, u32 decimal_bit)
52 s32 Y, integer = 0, decimal = 0;
56 X = 1; /* log2(x), x can't be 0 */
58 for (i = (total_bit - 1); i > 0; i--) {
62 /* decimal is 0.5dB*3=1.5dB~=2dB */
63 decimal = (X & BIT(i - 1)) ? 2 : 0;
69 Y = 3 * (integer - decimal_bit) + decimal; /* 10*log(x)=3*log2(x), */
74 s32 odm_sign_conversion(s32 value, u32 total_bit)
76 if (value & BIT(total_bit - 1))
77 value -= BIT(total_bit);
81 void phydm_seq_sorting(void *dm_void, u32 *value, u32 *rank_idx, u32 *idx_out,
86 u32 tmp_idx_a, tmp_idx_b;
88 for (i = 0; i < seq_length; i++) {
93 for (i = 0; i < (seq_length - 1); i++) {
94 for (j = 0; j < (seq_length - 1 - i); j++) {
98 tmp_idx_a = rank_idx[j];
99 tmp_idx_b = rank_idx[j + 1];
103 value[j + 1] = tmp_a;
105 rank_idx[j] = tmp_idx_b;
106 rank_idx[j + 1] = tmp_idx_a;
111 for (i = 0; i < seq_length; i++) {
112 idx_out[rank_idx[i]] = i + 1;
117 void odm_init_mp_driver_status(struct phy_dm_struct *dm)
122 static void odm_update_mp_driver_status(struct phy_dm_struct *dm)
127 static void phydm_init_trx_antenna_setting(struct phy_dm_struct *dm)
129 /*#if (RTL8814A_SUPPORT == 1)*/
131 if (dm->support_ic_type & (ODM_RTL8814A)) {
132 u8 rx_ant = 0, tx_ant = 0;
134 rx_ant = (u8)odm_get_bb_reg(dm, ODM_REG(BB_RX_PATH, dm),
135 ODM_BIT(BB_RX_PATH, dm));
136 tx_ant = (u8)odm_get_bb_reg(dm, ODM_REG(BB_TX_PATH, dm),
137 ODM_BIT(BB_TX_PATH, dm));
138 dm->tx_ant_status = (tx_ant & 0xf);
139 dm->rx_ant_status = (rx_ant & 0xf);
140 } else if (dm->support_ic_type & (ODM_RTL8723D | ODM_RTL8821C |
141 ODM_RTL8710B)) { /* JJ ADD 20161014 */
142 dm->tx_ant_status = 0x1;
143 dm->rx_ant_status = 0x1;
148 static void phydm_traffic_load_decision(void *dm_void)
150 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
152 /*---TP & Traffic-load calculation---*/
154 if (dm->last_tx_ok_cnt > *dm->num_tx_bytes_unicast)
155 dm->last_tx_ok_cnt = *dm->num_tx_bytes_unicast;
157 if (dm->last_rx_ok_cnt > *dm->num_rx_bytes_unicast)
158 dm->last_rx_ok_cnt = *dm->num_rx_bytes_unicast;
160 dm->cur_tx_ok_cnt = *dm->num_tx_bytes_unicast - dm->last_tx_ok_cnt;
161 dm->cur_rx_ok_cnt = *dm->num_rx_bytes_unicast - dm->last_rx_ok_cnt;
162 dm->last_tx_ok_cnt = *dm->num_tx_bytes_unicast;
163 dm->last_rx_ok_cnt = *dm->num_rx_bytes_unicast;
165 dm->tx_tp = ((dm->tx_tp) >> 1) +
166 (u32)(((dm->cur_tx_ok_cnt) >> 18) >>
167 1); /* <<3(8bit), >>20(10^6,M), >>1(2sec)*/
168 dm->rx_tp = ((dm->rx_tp) >> 1) +
169 (u32)(((dm->cur_rx_ok_cnt) >> 18) >>
170 1); /* <<3(8bit), >>20(10^6,M), >>1(2sec)*/
171 dm->total_tp = dm->tx_tp + dm->rx_tp;
173 dm->pre_traffic_load = dm->traffic_load;
175 if (dm->cur_tx_ok_cnt > 1875000 ||
177 1875000) { /* ( 1.875M * 8bit ) / 2sec= 7.5M bits /sec )*/
179 dm->traffic_load = TRAFFIC_HIGH;
182 dm->cur_tx_ok_cnt > 500000 ||
184 500000) { /*( 0.5M * 8bit ) / 2sec = 2M bits /sec )*/
186 dm->traffic_load = TRAFFIC_MID;
189 dm->cur_tx_ok_cnt > 100000 ||
191 100000) { /*( 0.1M * 8bit ) / 2sec = 0.4M bits /sec )*/
193 dm->traffic_load = TRAFFIC_LOW;
196 dm->traffic_load = TRAFFIC_ULTRA_LOW;
201 static void phydm_config_ofdm_tx_path(struct phy_dm_struct *dm, u32 path) {}
203 void phydm_config_ofdm_rx_path(struct phy_dm_struct *dm, u32 path)
207 if (dm->support_ic_type & (ODM_RTL8192E)) {
208 } else if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8822B)) {
209 if (path == PHYDM_A) {
212 } else if (path == PHYDM_B) {
215 } else if (path == PHYDM_AB) {
220 odm_set_bb_reg(dm, 0x808, MASKBYTE0,
221 ((ofdm_rx_path << 4) | ofdm_rx_path));
225 static void phydm_config_cck_rx_antenna_init(struct phy_dm_struct *dm) {}
227 static void phydm_config_cck_rx_path(struct phy_dm_struct *dm, u8 path,
232 void phydm_config_trx_path(void *dm_void, u32 *const dm_value, u32 *_used,
233 char *output, u32 *_out_len)
235 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
237 u32 out_len = *_out_len;
240 if (dm_value[0] == 0) {
241 if (dm_value[1] == 1) { /*TX*/
242 if (dm_value[2] == 1)
243 odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x8);
244 else if (dm_value[2] == 2)
245 odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0x4);
246 else if (dm_value[2] == 3)
247 odm_set_bb_reg(dm, 0xa04, 0xf0000000, 0xc);
248 } else if (dm_value[1] == 2) { /*RX*/
250 phydm_config_cck_rx_antenna_init(dm);
252 if (dm_value[2] == 1)
253 phydm_config_cck_rx_path(dm, PHYDM_A,
254 CCA_PATHDIV_DISABLE);
255 else if (dm_value[2] == 2)
256 phydm_config_cck_rx_path(dm, PHYDM_B,
257 CCA_PATHDIV_DISABLE);
258 else if (dm_value[2] == 3 &&
259 dm_value[3] == 1) /*enable path diversity*/
260 phydm_config_cck_rx_path(dm, PHYDM_AB,
262 else if (dm_value[2] == 3 && dm_value[3] != 1)
263 phydm_config_cck_rx_path(dm, PHYDM_B,
264 CCA_PATHDIV_DISABLE);
268 else if (dm_value[0] == 1) {
269 if (dm_value[1] == 1) { /*TX*/
270 phydm_config_ofdm_tx_path(dm, dm_value[2]);
272 } else if (dm_value[1] == 2) { /*RX*/
273 phydm_config_ofdm_rx_path(dm, dm_value[2]);
279 output + used, out_len - used,
280 "PHYDM Set path [%s] [%s] = [%s%s%s%s]\n",
281 (dm_value[0] == 1) ? "OFDM" : "CCK",
282 (dm_value[1] == 1) ? "TX" : "RX",
283 (dm_value[2] & 0x1) ? "A" : "", (dm_value[2] & 0x2) ? "B" : "",
284 (dm_value[2] & 0x4) ? "C" : "", (dm_value[2] & 0x8) ? "D" : "");
287 static void phydm_init_cck_setting(struct phy_dm_struct *dm)
289 dm->is_cck_high_power = (bool)odm_get_bb_reg(
290 dm, ODM_REG(CCK_RPT_FORMAT, dm), ODM_BIT(CCK_RPT_FORMAT, dm));
292 /* JJ ADD 20161014 */
293 /* JJ ADD 20161014 */
294 if (dm->support_ic_type & (ODM_RTL8723D | ODM_RTL8822B | ODM_RTL8197F |
295 ODM_RTL8821C | ODM_RTL8710B))
296 dm->cck_new_agc = odm_get_bb_reg(dm, 0xa9c, BIT(17)) ?
298 false; /*1: new agc 0: old agc*/
300 dm->cck_new_agc = false;
303 static void phydm_init_soft_ml_setting(struct phy_dm_struct *dm)
306 if (dm->support_ic_type & ODM_RTL8822B)
307 odm_set_bb_reg(dm, 0x19a8, MASKDWORD, 0xc10a0000);
311 static void phydm_init_hw_info_by_rfe(struct phy_dm_struct *dm)
313 if (dm->support_ic_type & ODM_RTL8822B)
314 phydm_init_hw_info_by_rfe_type_8822b(dm);
317 static void odm_common_info_self_init(struct phy_dm_struct *dm)
319 phydm_init_cck_setting(dm);
320 dm->rf_path_rx_enable = (u8)odm_get_bb_reg(dm, ODM_REG(BB_RX_PATH, dm),
321 ODM_BIT(BB_RX_PATH, dm));
322 odm_init_mp_driver_status(dm);
323 phydm_init_trx_antenna_setting(dm);
324 phydm_init_soft_ml_setting(dm);
326 dm->phydm_period = PHYDM_WATCH_DOG_PERIOD;
327 dm->phydm_sys_up_time = 0;
329 if (dm->support_ic_type & ODM_IC_1SS)
331 else if (dm->support_ic_type & ODM_IC_2SS)
333 else if (dm->support_ic_type & ODM_IC_3SS)
335 else if (dm->support_ic_type & ODM_IC_4SS)
340 dm->number_linked_client = 0;
341 dm->pre_number_linked_client = 0;
342 dm->number_active_client = 0;
343 dm->pre_number_active_client = 0;
345 dm->last_tx_ok_cnt = 0;
346 dm->last_rx_ok_cnt = 0;
350 dm->traffic_load = TRAFFIC_LOW;
352 dm->nbi_set_result = 0;
353 dm->is_init_hw_info_by_rfe = false;
354 dm->pre_dbg_priority = BB_DBGPORT_RELEASE;
357 static void odm_common_info_self_update(struct phy_dm_struct *dm)
359 u8 entry_cnt = 0, num_active_client = 0;
360 u32 i, one_entry_macid = 0;
361 struct rtl_sta_info *entry;
363 /* THis variable cannot be used because it is wrong*/
364 if (*dm->band_width == ODM_BW40M) {
365 if (*dm->sec_ch_offset == 1)
366 dm->control_channel = *dm->channel - 2;
367 else if (*dm->sec_ch_offset == 2)
368 dm->control_channel = *dm->channel + 2;
370 dm->control_channel = *dm->channel;
373 for (i = 0; i < ODM_ASSOCIATE_ENTRY_NUM; i++) {
374 entry = dm->odm_sta_info[i];
375 if (IS_STA_VALID(entry)) {
382 if (entry_cnt == 1) {
383 dm->is_one_entry_only = true;
384 dm->one_entry_macid = one_entry_macid;
386 dm->is_one_entry_only = false;
389 dm->pre_number_linked_client = dm->number_linked_client;
390 dm->pre_number_active_client = dm->number_active_client;
392 dm->number_linked_client = entry_cnt;
393 dm->number_active_client = num_active_client;
395 /* Update MP driver status*/
396 odm_update_mp_driver_status(dm);
398 /*Traffic load information update*/
399 phydm_traffic_load_decision(dm);
401 dm->phydm_sys_up_time += dm->phydm_period;
404 static void odm_common_info_self_reset(struct phy_dm_struct *dm)
406 dm->phy_dbg_info.num_qry_beacon_pkt = 0;
409 void *phydm_get_structure(struct phy_dm_struct *dm, u8 structure_type)
412 void *p_struct = NULL;
414 switch (structure_type) {
415 case PHYDM_FALSEALMCNT:
416 p_struct = &dm->false_alm_cnt;
420 p_struct = &dm->dm_cfo_track;
423 case PHYDM_ADAPTIVITY:
424 p_struct = &dm->adaptivity;
434 static void odm_hw_setting(struct phy_dm_struct *dm)
436 if (dm->support_ic_type & ODM_RTL8822B)
437 phydm_hwsetting_8822b(dm);
440 static void phydm_supportability_init(void *dm_void)
442 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
443 u32 support_ability = 0;
445 if (dm->support_ic_type != ODM_RTL8821C)
448 switch (dm->support_ic_type) {
449 /*---------------AC Series-------------------*/
452 support_ability |= ODM_BB_DIG | ODM_BB_FA_CNT | ODM_BB_CCK_PD |
453 ODM_BB_CFO_TRACKING | ODM_BB_RATE_ADAPTIVE |
454 ODM_BB_RSSI_MONITOR | ODM_BB_RA_MASK |
459 support_ability |= ODM_BB_DIG | ODM_BB_FA_CNT | ODM_BB_CCK_PD |
460 ODM_BB_CFO_TRACKING | ODM_BB_RATE_ADAPTIVE |
461 ODM_BB_RSSI_MONITOR | ODM_BB_RA_MASK |
464 ODM_RT_TRACE(dm, ODM_COMP_UNCOND,
465 "[Warning] Supportability Init Warning !!!\n");
469 if (*dm->enable_antdiv)
470 support_ability |= ODM_BB_ANT_DIV;
472 if (*dm->enable_adaptivity) {
473 ODM_RT_TRACE(dm, ODM_COMP_INIT,
474 "ODM adaptivity is set to Enabled!!!\n");
476 support_ability |= ODM_BB_ADAPTIVITY;
479 ODM_RT_TRACE(dm, ODM_COMP_INIT,
480 "ODM adaptivity is set to disnabled!!!\n");
484 ODM_RT_TRACE(dm, ODM_COMP_INIT, "PHYDM support_ability = ((0x%x))\n",
486 odm_cmn_info_init(dm, ODM_CMNINFO_ABILITY, support_ability);
490 * 2011/09/21 MH Add to describe different team necessary resource allocate??
492 void odm_dm_init(struct phy_dm_struct *dm)
494 phydm_supportability_init(dm);
495 odm_common_info_self_init(dm);
497 phydm_nhm_counter_statistics_init(dm);
498 phydm_adaptivity_init(dm);
499 phydm_ra_info_init(dm);
500 odm_rate_adaptive_mask_init(dm);
501 odm_cfo_tracking_init(dm);
502 odm_edca_turbo_init(dm);
503 odm_rssi_monitor_init(dm);
505 odm_txpowertracking_init(dm);
507 if (dm->support_ic_type & ODM_RTL8822B)
508 phydm_txcurrentcalibration(dm);
510 odm_antenna_diversity_init(dm);
511 odm_auto_channel_select_init(dm);
512 odm_dynamic_tx_power_init(dm);
513 phydm_init_ra_info(dm);
516 phydm_beamforming_init(dm);
518 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
520 odm_dynamic_bb_power_saving_init(dm);
526 void odm_dm_reset(struct phy_dm_struct *dm)
528 struct dig_thres *dig_tab = &dm->dm_dig_table;
530 odm_ant_div_reset(dm);
531 phydm_set_edcca_threshold_api(dm, dig_tab->cur_ig_value);
534 void phydm_support_ability_debug(void *dm_void, u32 *const dm_value, u32 *_used,
535 char *output, u32 *_out_len)
537 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
538 u32 pre_support_ability;
540 u32 out_len = *_out_len;
542 pre_support_ability = dm->support_ability;
543 PHYDM_SNPRINTF(output + used, out_len - used, "\n%s\n",
544 "================================");
545 if (dm_value[0] == 100) {
546 PHYDM_SNPRINTF(output + used, out_len - used,
547 "[Supportability] PhyDM Selection\n");
548 PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
549 "================================");
551 output + used, out_len - used, "00. (( %s ))DIG\n",
552 ((dm->support_ability & ODM_BB_DIG) ? ("V") : (".")));
554 output + used, out_len - used, "01. (( %s ))RA_MASK\n",
555 ((dm->support_ability & ODM_BB_RA_MASK) ? ("V") :
557 PHYDM_SNPRINTF(output + used, out_len - used,
558 "02. (( %s ))DYNAMIC_TXPWR\n",
559 ((dm->support_ability & ODM_BB_DYNAMIC_TXPWR) ?
562 PHYDM_SNPRINTF(output + used, out_len - used,
563 "03. (( %s ))FA_CNT\n",
564 ((dm->support_ability & ODM_BB_FA_CNT) ? ("V") :
566 PHYDM_SNPRINTF(output + used, out_len - used,
567 "04. (( %s ))RSSI_MONITOR\n",
568 ((dm->support_ability & ODM_BB_RSSI_MONITOR) ?
571 PHYDM_SNPRINTF(output + used, out_len - used,
572 "05. (( %s ))CCK_PD\n",
573 ((dm->support_ability & ODM_BB_CCK_PD) ? ("V") :
576 output + used, out_len - used, "06. (( %s ))ANT_DIV\n",
577 ((dm->support_ability & ODM_BB_ANT_DIV) ? ("V") :
579 PHYDM_SNPRINTF(output + used, out_len - used,
580 "08. (( %s ))PWR_TRAIN\n",
581 ((dm->support_ability & ODM_BB_PWR_TRAIN) ?
584 PHYDM_SNPRINTF(output + used, out_len - used,
585 "09. (( %s ))RATE_ADAPTIVE\n",
586 ((dm->support_ability & ODM_BB_RATE_ADAPTIVE) ?
590 output + used, out_len - used, "10. (( %s ))PATH_DIV\n",
591 ((dm->support_ability & ODM_BB_PATH_DIV) ? ("V") :
593 PHYDM_SNPRINTF(output + used, out_len - used,
594 "13. (( %s ))ADAPTIVITY\n",
595 ((dm->support_ability & ODM_BB_ADAPTIVITY) ?
598 PHYDM_SNPRINTF(output + used, out_len - used,
599 "14. (( %s ))struct cfo_tracking\n",
600 ((dm->support_ability & ODM_BB_CFO_TRACKING) ?
604 output + used, out_len - used, "15. (( %s ))NHM_CNT\n",
605 ((dm->support_ability & ODM_BB_NHM_CNT) ? ("V") :
607 PHYDM_SNPRINTF(output + used, out_len - used,
608 "16. (( %s ))PRIMARY_CCA\n",
609 ((dm->support_ability & ODM_BB_PRIMARY_CCA) ?
613 output + used, out_len - used, "17. (( %s ))TXBF\n",
614 ((dm->support_ability & ODM_BB_TXBF) ? ("V") : (".")));
615 PHYDM_SNPRINTF(output + used, out_len - used,
616 "18. (( %s ))DYNAMIC_ARFR\n",
617 ((dm->support_ability & ODM_BB_DYNAMIC_ARFR) ?
620 PHYDM_SNPRINTF(output + used, out_len - used,
621 "20. (( %s ))EDCA_TURBO\n",
622 ((dm->support_ability & ODM_MAC_EDCA_TURBO) ?
625 PHYDM_SNPRINTF(output + used, out_len - used,
626 "21. (( %s ))DYNAMIC_RX_PATH\n",
627 ((dm->support_ability & ODM_BB_DYNAMIC_RX_PATH) ?
630 PHYDM_SNPRINTF(output + used, out_len - used,
631 "24. (( %s ))TX_PWR_TRACK\n",
632 ((dm->support_ability & ODM_RF_TX_PWR_TRACK) ?
635 PHYDM_SNPRINTF(output + used, out_len - used,
636 "25. (( %s ))RX_GAIN_TRACK\n",
637 ((dm->support_ability & ODM_RF_RX_GAIN_TRACK) ?
640 PHYDM_SNPRINTF(output + used, out_len - used,
641 "26. (( %s ))RF_CALIBRATION\n",
642 ((dm->support_ability & ODM_RF_CALIBRATION) ?
645 PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
646 "================================");
648 if (dm_value[1] == 1) { /* enable */
649 dm->support_ability |= BIT(dm_value[0]);
650 } else if (dm_value[1] == 2) /* disable */
651 dm->support_ability &= ~(BIT(dm_value[0]));
653 PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
654 "[Warning!!!] 1:enable, 2:disable");
657 PHYDM_SNPRINTF(output + used, out_len - used,
658 "pre-support_ability = 0x%x\n", pre_support_ability);
659 PHYDM_SNPRINTF(output + used, out_len - used,
660 "Curr-support_ability = 0x%x\n", dm->support_ability);
661 PHYDM_SNPRINTF(output + used, out_len - used, "%s\n",
662 "================================");
665 void phydm_watchdog_mp(struct phy_dm_struct *dm) {}
667 * 2011/09/20 MH This is the entry pointer for all team to execute HW outsrc DM.
668 * You can not add any dummy function here, be care, you can only use DM struct
669 * to perform any new ODM_DM.
671 void odm_dm_watchdog(struct phy_dm_struct *dm)
673 odm_common_info_self_update(dm);
674 phydm_basic_dbg_message(dm);
677 odm_false_alarm_counter_statistics(dm);
678 phydm_noisy_detection(dm);
680 odm_rssi_monitor_check(dm);
682 if (*dm->is_power_saving) {
683 odm_dig_by_rssi_lps(dm);
684 phydm_adaptivity(dm);
685 odm_antenna_diversity(
686 dm); /*enable AntDiv in PS mode, request from SD4 Jeff*/
687 ODM_RT_TRACE(dm, ODM_COMP_COMMON,
688 "DMWatchdog in power saving mode\n");
692 phydm_check_adaptivity(dm);
693 odm_update_power_training_state(dm);
695 phydm_adaptivity(dm);
696 odm_cck_packet_detection_thresh(dm);
698 phydm_ra_info_watchdog(dm);
699 odm_edca_turbo_check(dm);
700 odm_cfo_tracking(dm);
701 odm_dynamic_tx_power(dm);
702 odm_antenna_diversity(dm);
704 phydm_beamforming_watchdog(dm);
706 phydm_rf_watchdog(dm);
710 odm_common_info_self_reset(dm);
714 * Init /.. Fixed HW value. Only init time.
716 void odm_cmn_info_init(struct phy_dm_struct *dm, enum odm_cmninfo cmn_info,
719 /* This section is used for init value */
721 /* Fixed ODM value. */
722 case ODM_CMNINFO_ABILITY:
723 dm->support_ability = (u32)value;
726 case ODM_CMNINFO_RF_TYPE:
727 dm->rf_type = (u8)value;
730 case ODM_CMNINFO_PLATFORM:
731 dm->support_platform = (u8)value;
734 case ODM_CMNINFO_INTERFACE:
735 dm->support_interface = (u8)value;
738 case ODM_CMNINFO_MP_TEST_CHIP:
739 dm->is_mp_chip = (u8)value;
742 case ODM_CMNINFO_IC_TYPE:
743 dm->support_ic_type = value;
746 case ODM_CMNINFO_CUT_VER:
747 dm->cut_version = (u8)value;
750 case ODM_CMNINFO_FAB_VER:
751 dm->fab_version = (u8)value;
754 case ODM_CMNINFO_RFE_TYPE:
755 dm->rfe_type = (u8)value;
756 phydm_init_hw_info_by_rfe(dm);
759 case ODM_CMNINFO_RF_ANTENNA_TYPE:
760 dm->ant_div_type = (u8)value;
763 case ODM_CMNINFO_WITH_EXT_ANTENNA_SWITCH:
764 dm->with_extenal_ant_switch = (u8)value;
767 case ODM_CMNINFO_BE_FIX_TX_ANT:
768 dm->dm_fat_table.b_fix_tx_ant = (u8)value;
771 case ODM_CMNINFO_BOARD_TYPE:
772 if (!dm->is_init_hw_info_by_rfe)
773 dm->board_type = (u8)value;
776 case ODM_CMNINFO_PACKAGE_TYPE:
777 if (!dm->is_init_hw_info_by_rfe)
778 dm->package_type = (u8)value;
781 case ODM_CMNINFO_EXT_LNA:
782 if (!dm->is_init_hw_info_by_rfe)
783 dm->ext_lna = (u8)value;
786 case ODM_CMNINFO_5G_EXT_LNA:
787 if (!dm->is_init_hw_info_by_rfe)
788 dm->ext_lna_5g = (u8)value;
791 case ODM_CMNINFO_EXT_PA:
792 if (!dm->is_init_hw_info_by_rfe)
793 dm->ext_pa = (u8)value;
796 case ODM_CMNINFO_5G_EXT_PA:
797 if (!dm->is_init_hw_info_by_rfe)
798 dm->ext_pa_5g = (u8)value;
801 case ODM_CMNINFO_GPA:
802 if (!dm->is_init_hw_info_by_rfe)
803 dm->type_gpa = (u16)value;
806 case ODM_CMNINFO_APA:
807 if (!dm->is_init_hw_info_by_rfe)
808 dm->type_apa = (u16)value;
811 case ODM_CMNINFO_GLNA:
812 if (!dm->is_init_hw_info_by_rfe)
813 dm->type_glna = (u16)value;
816 case ODM_CMNINFO_ALNA:
817 if (!dm->is_init_hw_info_by_rfe)
818 dm->type_alna = (u16)value;
821 case ODM_CMNINFO_EXT_TRSW:
822 if (!dm->is_init_hw_info_by_rfe)
823 dm->ext_trsw = (u8)value;
825 case ODM_CMNINFO_EXT_LNA_GAIN:
826 dm->ext_lna_gain = (u8)value;
828 case ODM_CMNINFO_PATCH_ID:
829 dm->patch_id = (u8)value;
831 case ODM_CMNINFO_BINHCT_TEST:
832 dm->is_in_hct_test = (bool)value;
834 case ODM_CMNINFO_BWIFI_TEST:
835 dm->wifi_test = (u8)value;
837 case ODM_CMNINFO_SMART_CONCURRENT:
838 dm->is_dual_mac_smart_concurrent = (bool)value;
840 case ODM_CMNINFO_DOMAIN_CODE_2G:
841 dm->odm_regulation_2_4g = (u8)value;
843 case ODM_CMNINFO_DOMAIN_CODE_5G:
844 dm->odm_regulation_5g = (u8)value;
846 case ODM_CMNINFO_CONFIG_BB_RF:
847 dm->config_bbrf = (bool)value;
849 case ODM_CMNINFO_IQKFWOFFLOAD:
850 dm->iqk_fw_offload = (u8)value;
852 case ODM_CMNINFO_IQKPAOFF:
853 dm->rf_calibrate_info.is_iqk_pa_off = (bool)value;
855 case ODM_CMNINFO_REGRFKFREEENABLE:
856 dm->rf_calibrate_info.reg_rf_kfree_enable = (u8)value;
858 case ODM_CMNINFO_RFKFREEENABLE:
859 dm->rf_calibrate_info.rf_kfree_enable = (u8)value;
861 case ODM_CMNINFO_NORMAL_RX_PATH_CHANGE:
862 dm->normal_rx_path = (u8)value;
864 case ODM_CMNINFO_EFUSE0X3D8:
865 dm->efuse0x3d8 = (u8)value;
867 case ODM_CMNINFO_EFUSE0X3D7:
868 dm->efuse0x3d7 = (u8)value;
870 /* To remove the compiler warning, must add an empty default statement
871 * to handle the other values.
879 void odm_cmn_info_hook(struct phy_dm_struct *dm, enum odm_cmninfo cmn_info,
883 /* Hook call by reference pointer. */
887 /* Dynamic call by reference pointer. */
889 case ODM_CMNINFO_MAC_PHY_MODE:
890 dm->mac_phy_mode = (u8 *)value;
893 case ODM_CMNINFO_TX_UNI:
894 dm->num_tx_bytes_unicast = (u64 *)value;
897 case ODM_CMNINFO_RX_UNI:
898 dm->num_rx_bytes_unicast = (u64 *)value;
901 case ODM_CMNINFO_WM_MODE:
902 dm->wireless_mode = (u8 *)value;
905 case ODM_CMNINFO_BAND:
906 dm->band_type = (u8 *)value;
909 case ODM_CMNINFO_SEC_CHNL_OFFSET:
910 dm->sec_ch_offset = (u8 *)value;
913 case ODM_CMNINFO_SEC_MODE:
914 dm->security = (u8 *)value;
918 dm->band_width = (u8 *)value;
921 case ODM_CMNINFO_CHNL:
922 dm->channel = (u8 *)value;
925 case ODM_CMNINFO_DMSP_GET_VALUE:
926 dm->is_get_value_from_other_mac = (bool *)value;
929 case ODM_CMNINFO_BUDDY_ADAPTOR:
930 dm->buddy_adapter = (void **)value;
933 case ODM_CMNINFO_DMSP_IS_MASTER:
934 dm->is_master_of_dmsp = (bool *)value;
937 case ODM_CMNINFO_SCAN:
938 dm->is_scan_in_process = (bool *)value;
941 case ODM_CMNINFO_POWER_SAVING:
942 dm->is_power_saving = (bool *)value;
945 case ODM_CMNINFO_ONE_PATH_CCA:
946 dm->one_path_cca = (u8 *)value;
949 case ODM_CMNINFO_DRV_STOP:
950 dm->is_driver_stopped = (bool *)value;
953 case ODM_CMNINFO_PNP_IN:
954 dm->is_driver_is_going_to_pnp_set_power_sleep = (bool *)value;
957 case ODM_CMNINFO_INIT_ON:
958 dm->pinit_adpt_in_progress = (bool *)value;
961 case ODM_CMNINFO_ANT_TEST:
962 dm->antenna_test = (u8 *)value;
965 case ODM_CMNINFO_NET_CLOSED:
966 dm->is_net_closed = (bool *)value;
969 case ODM_CMNINFO_FORCED_RATE:
970 dm->forced_data_rate = (u16 *)value;
972 case ODM_CMNINFO_ANT_DIV:
973 dm->enable_antdiv = (u8 *)value;
975 case ODM_CMNINFO_ADAPTIVITY:
976 dm->enable_adaptivity = (u8 *)value;
978 case ODM_CMNINFO_FORCED_IGI_LB:
979 dm->pu1_forced_igi_lb = (u8 *)value;
982 case ODM_CMNINFO_P2P_LINK:
983 dm->dm_dig_table.is_p2p_in_process = (u8 *)value;
986 case ODM_CMNINFO_IS1ANTENNA:
987 dm->is_1_antenna = (bool *)value;
990 case ODM_CMNINFO_RFDEFAULTPATH:
991 dm->rf_default_path = (u8 *)value;
994 case ODM_CMNINFO_FCS_MODE:
995 dm->is_fcs_mode_enable = (bool *)value;
997 /*add by YuChen for beamforming PhyDM*/
998 case ODM_CMNINFO_HUBUSBMODE:
999 dm->hub_usb_mode = (u8 *)value;
1001 case ODM_CMNINFO_FWDWRSVDPAGEINPROGRESS:
1002 dm->is_fw_dw_rsvd_page_in_progress = (bool *)value;
1004 case ODM_CMNINFO_TX_TP:
1005 dm->current_tx_tp = (u32 *)value;
1007 case ODM_CMNINFO_RX_TP:
1008 dm->current_rx_tp = (u32 *)value;
1010 case ODM_CMNINFO_SOUNDING_SEQ:
1011 dm->sounding_seq = (u8 *)value;
1013 case ODM_CMNINFO_FORCE_TX_ANT_BY_TXDESC:
1014 dm->dm_fat_table.p_force_tx_ant_by_desc = (u8 *)value;
1016 case ODM_CMNINFO_SET_S0S1_DEFAULT_ANTENNA:
1017 dm->dm_fat_table.p_default_s0_s1 = (u8 *)value;
1026 void odm_cmn_info_ptr_array_hook(struct phy_dm_struct *dm,
1027 enum odm_cmninfo cmn_info, u16 index,
1030 /*Hook call by reference pointer.*/
1032 /*Dynamic call by reference pointer. */
1033 case ODM_CMNINFO_STA_STATUS:
1034 dm->odm_sta_info[index] = (struct rtl_sta_info *)value;
1036 if (IS_STA_VALID(dm->odm_sta_info[index]))
1037 dm->platform2phydm_macid_table[index] = index;
1040 /* To remove the compiler warning, must add an empty default statement
1041 * to handle the other values.
1050 * Update band/CHannel/.. The values are dynamic but non-per-packet.
1052 void odm_cmn_info_update(struct phy_dm_struct *dm, u32 cmn_info, u64 value)
1054 /* This init variable may be changed in run time. */
1056 case ODM_CMNINFO_LINK_IN_PROGRESS:
1057 dm->is_link_in_process = (bool)value;
1060 case ODM_CMNINFO_ABILITY:
1061 dm->support_ability = (u32)value;
1064 case ODM_CMNINFO_RF_TYPE:
1065 dm->rf_type = (u8)value;
1068 case ODM_CMNINFO_WIFI_DIRECT:
1069 dm->is_wifi_direct = (bool)value;
1072 case ODM_CMNINFO_WIFI_DISPLAY:
1073 dm->is_wifi_display = (bool)value;
1076 case ODM_CMNINFO_LINK:
1077 dm->is_linked = (bool)value;
1080 case ODM_CMNINFO_CMW500LINK:
1081 dm->is_linkedcmw500 = (bool)value;
1084 case ODM_CMNINFO_LPSPG:
1085 dm->is_in_lps_pg = (bool)value;
1088 case ODM_CMNINFO_STATION_STATE:
1089 dm->bsta_state = (bool)value;
1092 case ODM_CMNINFO_RSSI_MIN:
1093 dm->rssi_min = (u8)value;
1096 case ODM_CMNINFO_DBG_COMP:
1097 dm->debug_components = (u32)value;
1100 case ODM_CMNINFO_DBG_LEVEL:
1101 dm->debug_level = (u32)value;
1103 case ODM_CMNINFO_RA_THRESHOLD_HIGH:
1104 dm->rate_adaptive.high_rssi_thresh = (u8)value;
1107 case ODM_CMNINFO_RA_THRESHOLD_LOW:
1108 dm->rate_adaptive.low_rssi_thresh = (u8)value;
1110 /* The following is for BT HS mode and BT coexist mechanism. */
1111 case ODM_CMNINFO_BT_ENABLED:
1112 dm->is_bt_enabled = (bool)value;
1115 case ODM_CMNINFO_BT_HS_CONNECT_PROCESS:
1116 dm->is_bt_connect_process = (bool)value;
1119 case ODM_CMNINFO_BT_HS_RSSI:
1120 dm->bt_hs_rssi = (u8)value;
1123 case ODM_CMNINFO_BT_OPERATION:
1124 dm->is_bt_hs_operation = (bool)value;
1127 case ODM_CMNINFO_BT_LIMITED_DIG:
1128 dm->is_bt_limited_dig = (bool)value;
1131 case ODM_CMNINFO_BT_DIG:
1132 dm->bt_hs_dig_val = (u8)value;
1135 case ODM_CMNINFO_BT_BUSY:
1136 dm->is_bt_busy = (bool)value;
1139 case ODM_CMNINFO_BT_DISABLE_EDCA:
1140 dm->is_bt_disable_edca_turbo = (bool)value;
1143 case ODM_CMNINFO_AP_TOTAL_NUM:
1144 dm->ap_total_num = (u8)value;
1147 case ODM_CMNINFO_POWER_TRAINING:
1148 dm->is_disable_power_training = (bool)value;
1157 u32 phydm_cmn_info_query(struct phy_dm_struct *dm,
1158 enum phydm_info_query info_type)
1160 struct false_alarm_stat *false_alm_cnt =
1161 (struct false_alarm_stat *)phydm_get_structure(
1162 dm, PHYDM_FALSEALMCNT);
1164 switch (info_type) {
1165 case PHYDM_INFO_FA_OFDM:
1166 return false_alm_cnt->cnt_ofdm_fail;
1168 case PHYDM_INFO_FA_CCK:
1169 return false_alm_cnt->cnt_cck_fail;
1171 case PHYDM_INFO_FA_TOTAL:
1172 return false_alm_cnt->cnt_all;
1174 case PHYDM_INFO_CCA_OFDM:
1175 return false_alm_cnt->cnt_ofdm_cca;
1177 case PHYDM_INFO_CCA_CCK:
1178 return false_alm_cnt->cnt_cck_cca;
1180 case PHYDM_INFO_CCA_ALL:
1181 return false_alm_cnt->cnt_cca_all;
1183 case PHYDM_INFO_CRC32_OK_VHT:
1184 return false_alm_cnt->cnt_vht_crc32_ok;
1186 case PHYDM_INFO_CRC32_OK_HT:
1187 return false_alm_cnt->cnt_ht_crc32_ok;
1189 case PHYDM_INFO_CRC32_OK_LEGACY:
1190 return false_alm_cnt->cnt_ofdm_crc32_ok;
1192 case PHYDM_INFO_CRC32_OK_CCK:
1193 return false_alm_cnt->cnt_cck_crc32_ok;
1195 case PHYDM_INFO_CRC32_ERROR_VHT:
1196 return false_alm_cnt->cnt_vht_crc32_error;
1198 case PHYDM_INFO_CRC32_ERROR_HT:
1199 return false_alm_cnt->cnt_ht_crc32_error;
1201 case PHYDM_INFO_CRC32_ERROR_LEGACY:
1202 return false_alm_cnt->cnt_ofdm_crc32_error;
1204 case PHYDM_INFO_CRC32_ERROR_CCK:
1205 return false_alm_cnt->cnt_cck_crc32_error;
1207 case PHYDM_INFO_EDCCA_FLAG:
1208 return false_alm_cnt->edcca_flag;
1210 case PHYDM_INFO_OFDM_ENABLE:
1211 return false_alm_cnt->ofdm_block_enable;
1213 case PHYDM_INFO_CCK_ENABLE:
1214 return false_alm_cnt->cck_block_enable;
1216 case PHYDM_INFO_DBG_PORT_0:
1217 return false_alm_cnt->dbg_port0;
1224 void odm_init_all_timers(struct phy_dm_struct *dm) {}
1226 void odm_cancel_all_timers(struct phy_dm_struct *dm) {}
1228 void odm_release_all_timers(struct phy_dm_struct *dm) {}
1230 /* 3============================================================
1231 * 3 Tx Power Tracking
1232 * 3============================================================
1235 /* need to ODM CE Platform
1236 * move to here for ANT detection mechanism using
1239 u32 odm_convert_to_db(u32 value)
1245 value = value & 0xFFFF;
1247 for (i = 0; i < 12; i++) {
1248 if (value <= db_invert_table[i][7])
1253 return 96; /* maximum 96 dB */
1255 for (j = 0; j < 8; j++) {
1256 if (value <= db_invert_table[i][j])
1260 dB = (i << 3) + j + 1;
1265 u32 odm_convert_to_linear(u32 value)
1273 value = value & 0xFF;
1275 i = (u8)((value - 1) >> 3);
1276 j = (u8)(value - 1) - (i << 3);
1278 linear = db_invert_table[i][j];
1284 * ODM multi-port consideration, added by Roger, 2013.10.01.
1286 void odm_asoc_entry_init(struct phy_dm_struct *dm) {}
1288 /* Justin: According to the current RRSI to adjust Response Frame TX power */
1289 void odm_dtc(struct phy_dm_struct *dm) {}
1291 static void odm_update_power_training_state(struct phy_dm_struct *dm)
1293 struct false_alarm_stat *false_alm_cnt =
1294 (struct false_alarm_stat *)phydm_get_structure(
1295 dm, PHYDM_FALSEALMCNT);
1296 struct dig_thres *dig_tab = &dm->dm_dig_table;
1299 if (!(dm->support_ability & ODM_BB_PWR_TRAIN))
1302 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "%s()============>\n", __func__);
1303 dm->is_change_state = false;
1306 if (dm->force_power_training_state) {
1307 if (dm->force_power_training_state == 1 &&
1308 !dm->is_disable_power_training) {
1309 dm->is_change_state = true;
1310 dm->is_disable_power_training = true;
1311 } else if (dm->force_power_training_state == 2 &&
1312 dm->is_disable_power_training) {
1313 dm->is_change_state = true;
1314 dm->is_disable_power_training = false;
1318 dm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
1319 dm->phy_dbg_info.num_qry_phy_status_cck = 0;
1320 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1321 "%s(): force_power_training_state = %d\n",
1322 __func__, dm->force_power_training_state);
1330 if (dm->is_linked && !dig_tab->is_media_connect_0) {
1332 dm->is_change_state = true;
1333 dm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
1334 dm->phy_dbg_info.num_qry_phy_status_cck = 0;
1335 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "%s(): First Connect\n",
1341 if (dm->nhm_cnt_0 >= 215) {
1343 } else if (dm->nhm_cnt_0 >= 190) {
1344 score = 1; /* unknown state */
1348 rx_pkt_cnt = (u32)(dm->phy_dbg_info.num_qry_phy_status_ofdm) +
1349 (u32)(dm->phy_dbg_info.num_qry_phy_status_cck);
1351 if ((false_alm_cnt->cnt_cca_all > 31 && rx_pkt_cnt > 31) &&
1352 false_alm_cnt->cnt_cca_all >= rx_pkt_cnt) {
1353 if ((rx_pkt_cnt + (rx_pkt_cnt >> 1)) <=
1354 false_alm_cnt->cnt_cca_all)
1356 else if ((rx_pkt_cnt + (rx_pkt_cnt >> 2)) <=
1357 false_alm_cnt->cnt_cca_all)
1362 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1363 "%s(): rx_pkt_cnt = %d, cnt_cca_all = %d\n",
1364 __func__, rx_pkt_cnt, false_alm_cnt->cnt_cca_all);
1367 dm, ODM_COMP_RA_MASK,
1368 "%s(): num_qry_phy_status_ofdm = %d, num_qry_phy_status_cck = %d\n",
1369 __func__, (u32)(dm->phy_dbg_info.num_qry_phy_status_ofdm),
1370 (u32)(dm->phy_dbg_info.num_qry_phy_status_cck));
1371 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK, "%s(): nhm_cnt_0 = %d, score = %d\n",
1372 __func__, dm->nhm_cnt_0, score);
1375 dm->PT_score = (score << 4) + (dm->PT_score >> 1) + (dm->PT_score >> 2);
1376 score = (dm->PT_score + 32) >> 6;
1377 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1378 "%s(): PT_score = %d, score after smoothing = %d\n",
1379 __func__, dm->PT_score, score);
1383 if (dm->is_disable_power_training) {
1384 dm->is_change_state = true;
1385 dm->is_disable_power_training = false;
1386 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1387 "%s(): Change state\n", __func__);
1389 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1390 "%s(): Enable Power Training\n", __func__);
1391 } else if (score == 0) {
1392 if (!dm->is_disable_power_training) {
1393 dm->is_change_state = true;
1394 dm->is_disable_power_training = true;
1395 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1396 "%s(): Change state\n", __func__);
1398 ODM_RT_TRACE(dm, ODM_COMP_RA_MASK,
1399 "%s(): Disable Power Training\n", __func__);
1402 dm->phy_dbg_info.num_qry_phy_status_ofdm = 0;
1403 dm->phy_dbg_info.num_qry_phy_status_cck = 0;
1406 /*===========================================================*/
1407 /* The following is for compile only*/
1408 /*===========================================================*/
1409 /*#define TARGET_CHNL_NUM_2G_5G 59*/
1410 /*===========================================================*/
1412 void phydm_noisy_detection(struct phy_dm_struct *dm)
1414 u32 total_fa_cnt, total_cca_cnt;
1415 u32 score = 0, i, score_smooth;
1417 total_cca_cnt = dm->false_alm_cnt.cnt_cca_all;
1418 total_fa_cnt = dm->false_alm_cnt.cnt_all;
1420 for (i = 0; i <= 16; i++) {
1421 if (total_fa_cnt * 16 >= total_cca_cnt * (16 - i)) {
1427 /* noisy_decision_smooth = noisy_decision_smooth>>1 + (score<<3)>>1; */
1428 dm->noisy_decision_smooth =
1429 (dm->noisy_decision_smooth >> 1) + (score << 2);
1431 /* Round the noisy_decision_smooth: +"3" comes from (2^3)/2-1 */
1432 score_smooth = (total_cca_cnt >= 300) ?
1433 ((dm->noisy_decision_smooth + 3) >> 3) :
1436 dm->noisy_decision = (score_smooth >= 3) ? 1 : 0;
1438 dm, ODM_COMP_NOISY_DETECT,
1439 "[NoisyDetection] total_cca_cnt=%d, total_fa_cnt=%d, noisy_decision_smooth=%d, score=%d, score_smooth=%d, dm->noisy_decision=%d\n",
1440 total_cca_cnt, total_fa_cnt, dm->noisy_decision_smooth, score,
1441 score_smooth, dm->noisy_decision);
1444 void phydm_set_ext_switch(void *dm_void, u32 *const dm_value, u32 *_used,
1445 char *output, u32 *_out_len)
1447 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1448 u32 ext_ant_switch = dm_value[0];
1450 if (dm->support_ic_type & (ODM_RTL8821 | ODM_RTL8881A)) {
1451 /*Output Pin Settings*/
1452 odm_set_mac_reg(dm, 0x4C, BIT(23),
1453 0); /*select DPDT_P and DPDT_N as output pin*/
1454 odm_set_mac_reg(dm, 0x4C, BIT(24), 1); /*by WLAN control*/
1456 odm_set_bb_reg(dm, 0xCB4, 0xF, 7); /*DPDT_P = 1b'0*/
1457 odm_set_bb_reg(dm, 0xCB4, 0xF0, 7); /*DPDT_N = 1b'0*/
1459 if (ext_ant_switch == MAIN_ANT) {
1460 odm_set_bb_reg(dm, 0xCB4, (BIT(29) | BIT(28)), 1);
1463 "***8821A set ant switch = 2b'01 (Main)\n");
1464 } else if (ext_ant_switch == AUX_ANT) {
1465 odm_set_bb_reg(dm, 0xCB4, BIT(29) | BIT(28), 2);
1466 ODM_RT_TRACE(dm, ODM_COMP_API,
1467 "***8821A set ant switch = 2b'10 (Aux)\n");
1472 static void phydm_csi_mask_enable(void *dm_void, u32 enable)
1474 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1477 reg_value = (enable == CSI_MASK_ENABLE) ? 1 : 0;
1479 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1480 odm_set_bb_reg(dm, 0xD2C, BIT(28), reg_value);
1481 ODM_RT_TRACE(dm, ODM_COMP_API,
1482 "Enable CSI Mask: Reg 0xD2C[28] = ((0x%x))\n",
1485 } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1486 odm_set_bb_reg(dm, 0x874, BIT(0), reg_value);
1487 ODM_RT_TRACE(dm, ODM_COMP_API,
1488 "Enable CSI Mask: Reg 0x874[0] = ((0x%x))\n",
1493 static void phydm_clean_all_csi_mask(void *dm_void)
1495 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1497 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1498 odm_set_bb_reg(dm, 0xD40, MASKDWORD, 0);
1499 odm_set_bb_reg(dm, 0xD44, MASKDWORD, 0);
1500 odm_set_bb_reg(dm, 0xD48, MASKDWORD, 0);
1501 odm_set_bb_reg(dm, 0xD4c, MASKDWORD, 0);
1503 } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1504 odm_set_bb_reg(dm, 0x880, MASKDWORD, 0);
1505 odm_set_bb_reg(dm, 0x884, MASKDWORD, 0);
1506 odm_set_bb_reg(dm, 0x888, MASKDWORD, 0);
1507 odm_set_bb_reg(dm, 0x88c, MASKDWORD, 0);
1508 odm_set_bb_reg(dm, 0x890, MASKDWORD, 0);
1509 odm_set_bb_reg(dm, 0x894, MASKDWORD, 0);
1510 odm_set_bb_reg(dm, 0x898, MASKDWORD, 0);
1511 odm_set_bb_reg(dm, 0x89c, MASKDWORD, 0);
1515 static void phydm_set_csi_mask_reg(void *dm_void, u32 tone_idx_tmp,
1518 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1519 u8 byte_offset, bit_offset;
1523 u32 tone_num_shift = 0;
1524 u32 csi_mask_reg_p = 0, csi_mask_reg_n = 0;
1526 /* calculate real tone idx*/
1527 if ((tone_idx_tmp % 10) >= 5)
1530 tone_idx_tmp = (tone_idx_tmp / 10);
1532 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1534 csi_mask_reg_p = 0xD40;
1535 csi_mask_reg_n = 0xD48;
1537 } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1539 csi_mask_reg_p = 0x880;
1540 csi_mask_reg_n = 0x890;
1543 if (tone_direction == FREQ_POSITIVE) {
1544 if (tone_idx_tmp >= (tone_num - 1))
1545 tone_idx_tmp = (tone_num - 1);
1547 byte_offset = (u8)(tone_idx_tmp >> 3);
1548 bit_offset = (u8)(tone_idx_tmp & 0x7);
1549 target_reg = csi_mask_reg_p + byte_offset;
1552 tone_num_shift = tone_num;
1554 if (tone_idx_tmp >= tone_num)
1555 tone_idx_tmp = tone_num;
1557 tone_idx_tmp = tone_num - tone_idx_tmp;
1559 byte_offset = (u8)(tone_idx_tmp >> 3);
1560 bit_offset = (u8)(tone_idx_tmp & 0x7);
1561 target_reg = csi_mask_reg_n + byte_offset;
1564 reg_tmp_value = odm_read_1byte(dm, target_reg);
1565 ODM_RT_TRACE(dm, ODM_COMP_API,
1566 "Pre Mask tone idx[%d]: Reg0x%x = ((0x%x))\n",
1567 (tone_idx_tmp + tone_num_shift), target_reg,
1569 reg_tmp_value |= BIT(bit_offset);
1570 odm_write_1byte(dm, target_reg, reg_tmp_value);
1571 ODM_RT_TRACE(dm, ODM_COMP_API,
1572 "New Mask tone idx[%d]: Reg0x%x = ((0x%x))\n",
1573 (tone_idx_tmp + tone_num_shift), target_reg,
1577 static void phydm_set_nbi_reg(void *dm_void, u32 tone_idx_tmp, u32 bw)
1579 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1580 u32 nbi_table_128[NBI_TABLE_SIZE_128] = {
1581 25, 55, 85, 115, 135, 155, 185, 205, 225, 245,
1582 /*1~10*/ /*tone_idx X 10*/
1583 265, 285, 305, 335, 355, 375, 395, 415, 435, 455, /*11~20*/
1584 485, 505, 525, 555, 585, 615, 635}; /*21~27*/
1586 u32 nbi_table_256[NBI_TABLE_SIZE_256] = {
1587 25, 55, 85, 115, 135, 155, 175, 195, 225,
1589 265, 285, 305, 325, 345, 365, 385, 405, 425,
1591 465, 485, 505, 525, 545, 565, 585, 605, 625,
1593 665, 695, 715, 735, 755, 775, 795, 815, 835,
1595 875, 895, 915, 935, 955, 975, 995, 1015, 1035,
1597 1085, 1105, 1125, 1145, 1175, 1195, 1225, 1255, 1275}; /*51~59*/
1601 u8 nbi_table_idx = FFT_128_TYPE;
1603 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1604 nbi_table_idx = FFT_128_TYPE;
1605 } else if (dm->support_ic_type & ODM_IC_11AC_1_SERIES) {
1606 nbi_table_idx = FFT_256_TYPE;
1607 } else if (dm->support_ic_type & ODM_IC_11AC_2_SERIES) {
1609 nbi_table_idx = FFT_256_TYPE;
1611 nbi_table_idx = FFT_128_TYPE;
1614 if (nbi_table_idx == FFT_128_TYPE) {
1615 for (i = 0; i < NBI_TABLE_SIZE_128; i++) {
1616 if (tone_idx_tmp < nbi_table_128[i]) {
1622 } else if (nbi_table_idx == FFT_256_TYPE) {
1623 for (i = 0; i < NBI_TABLE_SIZE_256; i++) {
1624 if (tone_idx_tmp < nbi_table_256[i]) {
1631 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1632 odm_set_bb_reg(dm, 0xc40, 0x1f000000, reg_idx);
1633 ODM_RT_TRACE(dm, ODM_COMP_API,
1634 "Set tone idx: Reg0xC40[28:24] = ((0x%x))\n",
1638 odm_set_bb_reg(dm, 0x87c, 0xfc000, reg_idx);
1639 ODM_RT_TRACE(dm, ODM_COMP_API,
1640 "Set tone idx: Reg0x87C[19:14] = ((0x%x))\n",
1646 static void phydm_nbi_enable(void *dm_void, u32 enable)
1648 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1651 reg_value = (enable == NBI_ENABLE) ? 1 : 0;
1653 if (dm->support_ic_type & ODM_IC_11N_SERIES) {
1654 odm_set_bb_reg(dm, 0xc40, BIT(9), reg_value);
1655 ODM_RT_TRACE(dm, ODM_COMP_API,
1656 "Enable NBI Reg0xC40[9] = ((0x%x))\n", reg_value);
1658 } else if (dm->support_ic_type & ODM_IC_11AC_SERIES) {
1659 odm_set_bb_reg(dm, 0x87c, BIT(13), reg_value);
1660 ODM_RT_TRACE(dm, ODM_COMP_API,
1661 "Enable NBI Reg0x87C[13] = ((0x%x))\n", reg_value);
1665 static u8 phydm_calculate_fc(void *dm_void, u32 channel, u32 bw, u32 second_ch,
1668 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1670 u32 start_ch_per_40m[NUM_START_CH_40M + 1] = {
1671 36, 44, 52, 60, 100, 108, 116, 124,
1672 132, 140, 149, 157, 165, 173, 173 + 8,
1674 u32 start_ch_per_80m[NUM_START_CH_80M + 1] = {
1675 36, 52, 100, 116, 132, 149, 165, 165 + 16,
1677 u32 *start_ch = &start_ch_per_40m[0];
1678 u32 num_start_channel = NUM_START_CH_40M;
1679 u32 channel_offset = 0;
1683 if (channel <= 14 && channel > 0) {
1687 fc = 2412 + (channel - 1) * 5;
1689 if (bw == 40 && second_ch == PHYDM_ABOVE) {
1690 if (channel >= 10) {
1693 "CH = ((%d)), Scnd_CH = ((%d)) Error setting\n",
1694 channel, second_ch);
1698 } else if (bw == 40 && (second_ch == PHYDM_BELOW)) {
1702 "CH = ((%d)), Scnd_CH = ((%d)) Error setting\n",
1703 channel, second_ch);
1710 else if (channel >= 36 && channel <= 177) {
1712 fc = 5180 + (channel - 36) * 5;
1718 num_start_channel = NUM_START_CH_40M;
1719 start_ch = &start_ch_per_40m[0];
1720 channel_offset = CH_OFFSET_40M;
1721 } else if (bw == 80) {
1722 num_start_channel = NUM_START_CH_80M;
1723 start_ch = &start_ch_per_80m[0];
1724 channel_offset = CH_OFFSET_80M;
1727 for (i = 0; i < num_start_channel; i++) {
1728 if (channel < start_ch[i + 1]) {
1729 channel = start_ch[i] + channel_offset;
1734 ODM_RT_TRACE(dm, ODM_COMP_API, "Mod_CH = ((%d))\n", channel);
1736 fc = 5180 + (channel - 36) * 5;
1739 ODM_RT_TRACE(dm, ODM_COMP_API, "CH = ((%d)) Error setting\n",
1749 static u8 phydm_calculate_intf_distance(void *dm_void, u32 bw, u32 fc,
1751 u32 *tone_idx_tmp_in)
1753 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1757 u8 set_result = SET_NO_NEED;
1759 bw_up = fc + bw / 2;
1760 bw_low = fc - bw / 2;
1762 ODM_RT_TRACE(dm, ODM_COMP_API,
1763 "[f_l, fc, fh] = [ %d, %d, %d ], f_int = ((%d))\n", bw_low,
1764 fc, bw_up, f_interference);
1766 if (f_interference >= bw_low && f_interference <= bw_up) {
1767 int_distance = (fc >= f_interference) ? (fc - f_interference) :
1768 (f_interference - fc);
1770 (int_distance << 5); /* =10*(int_distance /0.3125) */
1773 "int_distance = ((%d MHz)) Mhz, tone_idx_tmp = ((%d.%d))\n",
1774 int_distance, (tone_idx_tmp / 10), (tone_idx_tmp % 10));
1775 *tone_idx_tmp_in = tone_idx_tmp;
1776 set_result = SET_SUCCESS;
1782 static u8 phydm_csi_mask_setting(void *dm_void, u32 enable, u32 channel, u32 bw,
1783 u32 f_interference, u32 second_ch)
1785 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1789 u8 set_result = SET_SUCCESS;
1791 if (enable == CSI_MASK_DISABLE) {
1792 set_result = SET_SUCCESS;
1793 phydm_clean_all_csi_mask(dm);
1798 "[Set CSI MASK_] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
1799 channel, bw, f_interference,
1800 (((bw == 20) || (channel > 14)) ?
1802 (second_ch == PHYDM_ABOVE) ? "H" : "L"));
1805 if (phydm_calculate_fc(dm, channel, bw, second_ch, &fc) ==
1807 set_result = SET_ERROR;
1809 /*calculate interference distance*/
1810 if (phydm_calculate_intf_distance(
1811 dm, bw, fc, f_interference,
1812 &tone_idx_tmp) == SET_SUCCESS) {
1813 tone_direction = (f_interference >= fc) ?
1816 phydm_set_csi_mask_reg(dm, tone_idx_tmp,
1818 set_result = SET_SUCCESS;
1820 set_result = SET_NO_NEED;
1825 if (set_result == SET_SUCCESS)
1826 phydm_csi_mask_enable(dm, enable);
1828 phydm_csi_mask_enable(dm, CSI_MASK_DISABLE);
1833 u8 phydm_nbi_setting(void *dm_void, u32 enable, u32 channel, u32 bw,
1834 u32 f_interference, u32 second_ch)
1836 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1839 u8 set_result = SET_SUCCESS;
1841 if (enable == NBI_DISABLE) {
1842 set_result = SET_SUCCESS;
1846 "[Set NBI] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
1847 channel, bw, f_interference,
1848 (((second_ch == PHYDM_DONT_CARE) || (bw == 20) ||
1851 (second_ch == PHYDM_ABOVE) ? "H" : "L"));
1854 if (phydm_calculate_fc(dm, channel, bw, second_ch, &fc) ==
1856 set_result = SET_ERROR;
1858 /*calculate interference distance*/
1859 if (phydm_calculate_intf_distance(
1860 dm, bw, fc, f_interference,
1861 &tone_idx_tmp) == SET_SUCCESS) {
1862 phydm_set_nbi_reg(dm, tone_idx_tmp, bw);
1863 set_result = SET_SUCCESS;
1865 set_result = SET_NO_NEED;
1870 if (set_result == SET_SUCCESS)
1871 phydm_nbi_enable(dm, enable);
1873 phydm_nbi_enable(dm, NBI_DISABLE);
1878 void phydm_api_debug(void *dm_void, u32 function_map, u32 *const dm_value,
1879 u32 *_used, char *output, u32 *_out_len)
1881 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
1883 u32 out_len = *_out_len;
1884 u32 channel = dm_value[1];
1885 u32 bw = dm_value[2];
1886 u32 f_interference = dm_value[3];
1887 u32 second_ch = dm_value[4];
1891 /*--------------------------------------------------------------------*/
1892 if (function_map == PHYDM_API_NBI) {
1893 if (dm_value[0] == 100) {
1895 output + used, out_len - used,
1896 "[HELP-NBI] EN(on=1, off=2) CH BW(20/40/80) f_intf(Mhz) Scnd_CH(L=1, H=2)\n");
1899 } else if (dm_value[0] == NBI_ENABLE) {
1901 output + used, out_len - used,
1902 "[Enable NBI] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
1903 channel, bw, f_interference,
1904 ((second_ch == PHYDM_DONT_CARE) || (bw == 20) ||
1907 ((second_ch == PHYDM_ABOVE) ? "H" :
1910 phydm_nbi_setting(dm, NBI_ENABLE, channel, bw,
1911 f_interference, second_ch);
1913 } else if (dm_value[0] == NBI_DISABLE) {
1914 PHYDM_SNPRINTF(output + used, out_len - used,
1917 phydm_nbi_setting(dm, NBI_DISABLE, channel, bw,
1918 f_interference, second_ch);
1921 set_result = SET_ERROR;
1925 output + used, out_len - used, "[NBI set result: %s]\n",
1926 (set_result == SET_SUCCESS) ?
1928 ((set_result == SET_NO_NEED) ? "No need" :
1933 /*--------------------------------------------------------------------*/
1934 else if (function_map == PHYDM_API_CSI_MASK) {
1935 if (dm_value[0] == 100) {
1937 output + used, out_len - used,
1938 "[HELP-CSI MASK] EN(on=1, off=2) CH BW(20/40/80) f_intf(Mhz) Scnd_CH(L=1, H=2)\n");
1941 } else if (dm_value[0] == CSI_MASK_ENABLE) {
1943 output + used, out_len - used,
1944 "[Enable CSI MASK] CH = ((%d)), BW = ((%d)), f_intf = ((%d)), Scnd_CH = ((%s))\n",
1945 channel, bw, f_interference,
1948 (((second_ch == PHYDM_DONT_CARE) ||
1949 (bw == 20) || (channel > 14)) ?
1952 set_result = phydm_csi_mask_setting(
1953 dm, CSI_MASK_ENABLE, channel, bw,
1954 f_interference, second_ch);
1956 } else if (dm_value[0] == CSI_MASK_DISABLE) {
1957 PHYDM_SNPRINTF(output + used, out_len - used,
1958 "[Disable CSI MASK]\n");
1959 set_result = phydm_csi_mask_setting(
1960 dm, CSI_MASK_DISABLE, channel, bw,
1961 f_interference, second_ch);
1964 set_result = SET_ERROR;
1967 PHYDM_SNPRINTF(output + used, out_len - used,
1968 "[CSI MASK set result: %s]\n",
1969 (set_result == SET_SUCCESS) ?
1971 ((set_result == SET_NO_NEED) ?