121 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright(c) 2024 Realtek Corporation.*/3 4#include "../wifi.h"5#include "../core.h"6#include "../rtl8192d/reg.h"7#include "../rtl8192d/def.h"8#include "../rtl8192d/dm_common.h"9#include "../rtl8192d/fw_common.h"10#include "dm.h"11 12static void rtl92du_dm_init_1r_cca(struct ieee80211_hw *hw)13{14 struct rtl_priv *rtlpriv = rtl_priv(hw);15 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;16 17 dm_pstable->pre_ccastate = CCA_MAX;18 dm_pstable->cur_ccasate = CCA_MAX;19}20 21static void rtl92du_dm_1r_cca(struct ieee80211_hw *hw)22{23 struct rtl_priv *rtlpriv = rtl_priv(hw);24 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;25 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);26 int pwdb = rtlpriv->dm_digtable.min_undec_pwdb_for_dm;27 28 if (rtlhal->macphymode != SINGLEMAC_SINGLEPHY ||29 rtlhal->current_bandtype != BAND_ON_5G)30 return;31 32 if (pwdb != 0) {33 if (dm_pstable->pre_ccastate == CCA_2R ||34 dm_pstable->pre_ccastate == CCA_MAX)35 dm_pstable->cur_ccasate = (pwdb >= 35) ? CCA_1R : CCA_2R;36 else37 dm_pstable->cur_ccasate = (pwdb <= 30) ? CCA_2R : CCA_1R;38 } else {39 dm_pstable->cur_ccasate = CCA_MAX;40 }41 42 if (dm_pstable->pre_ccastate == dm_pstable->cur_ccasate)43 return;44 45 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_TRACE,46 "Old CCA state: %d new CCA state: %d\n",47 dm_pstable->pre_ccastate, dm_pstable->cur_ccasate);48 49 if (dm_pstable->cur_ccasate == CCA_1R) {50 if (rtlpriv->phy.rf_type == RF_2T2R)51 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x13);52 else /* Is this branch reachable? */53 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);54 } else { /* CCA_2R or CCA_MAX */55 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x33);56 }57}58 59static void rtl92du_dm_pwdb_monitor(struct ieee80211_hw *hw)60{61 struct rtl_priv *rtlpriv = rtl_priv(hw);62 const u32 max_macid = 32;63 u32 temp;64 65 /* AP & ADHOC & MESH will return tmp */66 if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)67 return;68 69 /* Indicate Rx signal strength to FW. */70 if (rtlpriv->dm.useramask) {71 temp = rtlpriv->dm.undec_sm_pwdb << 16;72 temp |= max_macid << 8;73 74 rtl92d_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, (u8 *)(&temp));75 } else {76 rtl_write_byte(rtlpriv, 0x4fe, (u8)rtlpriv->dm.undec_sm_pwdb);77 }78}79 80void rtl92du_dm_init(struct ieee80211_hw *hw)81{82 struct rtl_priv *rtlpriv = rtl_priv(hw);83 84 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;85 rtl_dm_diginit(hw, 0x20);86 rtlpriv->dm_digtable.rx_gain_max = DM_DIG_FA_UPPER;87 rtlpriv->dm_digtable.rx_gain_min = DM_DIG_FA_LOWER;88 rtl92d_dm_init_edca_turbo(hw);89 rtl92du_dm_init_1r_cca(hw);90 rtl92d_dm_init_rate_adaptive_mask(hw);91 rtl92d_dm_initialize_txpower_tracking(hw);92}93 94void rtl92du_dm_watchdog(struct ieee80211_hw *hw)95{96 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));97 bool fw_current_inpsmode = false;98 bool fwps_awake = true;99 100 /* 1. RF is OFF. (No need to do DM.)101 * 2. Fw is under power saving mode for FwLPS.102 * (Prevent from SW/FW I/O racing.)103 * 3. IPS workitem is scheduled. (Prevent from IPS sequence104 * to be swapped with DM.105 * 4. RFChangeInProgress is TRUE.106 * (Prevent from broken by IPS/HW/SW Rf off.)107 */108 109 if (ppsc->rfpwr_state != ERFON || fw_current_inpsmode ||110 !fwps_awake || ppsc->rfchange_inprogress)111 return;112 113 rtl92du_dm_pwdb_monitor(hw);114 rtl92d_dm_false_alarm_counter_statistics(hw);115 rtl92d_dm_find_minimum_rssi(hw);116 rtl92d_dm_dig(hw);117 rtl92d_dm_check_txpower_tracking_thermal_meter(hw);118 rtl92d_dm_check_edca_turbo(hw);119 rtl92du_dm_1r_cca(hw);120}121