struct rtw89_debugfs_priv phy_info;
struct rtw89_debugfs_priv stations;
struct rtw89_debugfs_priv disable_dm;
+ struct rtw89_debugfs_priv static_pd_th;
struct rtw89_debugfs_priv mlo_mode;
struct rtw89_debugfs_priv beacon_info;
struct rtw89_debugfs_priv diag_mac;
DM_INFO(MLO),
DM_INFO(HW_SCAN),
DM_INFO(INACTIVE_PS),
+ DM_INFO(DIG_PD),
};
static ssize_t
return count;
}
+#define RTW89_DIG_PD_TH_MIN_DBM -102
+#define RTW89_DIG_PD_TH_MAX_DBM -40
+#define RTW89_DIG_PD_TH_STEP 2
+
+static s8 rtw89_dig_pd_th_to_dbm(u8 reg_val)
+{
+ return RTW89_DIG_PD_TH_MIN_DBM + RTW89_DIG_PD_TH_STEP * reg_val;
+}
+
+static u8 rtw89_dig_pd_th_dbm_to_reg(s8 dbm)
+{
+ return (dbm - RTW89_DIG_PD_TH_MIN_DBM) / RTW89_DIG_PD_TH_STEP;
+}
+
+static ssize_t
+rtw89_debug_priv_static_pd_th_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ char *p = buf, *end = buf + bufsz;
+ bool disabled;
+ s8 pd_th_dbm;
+ s8 cck_pd_th;
+
+ disabled = hal->disabled_dm_bitmap & BIT(RTW89_DM_DIG_PD);
+
+ if (disabled) {
+ pd_th_dbm = rtw89_dig_pd_th_to_dbm(hal->fixed_dig_pd_th);
+ cck_pd_th = hal->fixed_dig_cck_pd_th;
+
+ p += scnprintf(p, end - p, "DIG: static\n");
+ p += scnprintf(p, end - p, "OFDM PD threshold: %d dBm\n", pd_th_dbm);
+ p += scnprintf(p, end - p, "CCK PD threshold: %d dBm\n", cck_pd_th);
+ } else {
+ p += scnprintf(p, end - p, "DIG: dynamic\n");
+ }
+
+ p += scnprintf(p, end - p, "\nUsage: echo <mode> [pd_th] > static_pd_th\n");
+ p += scnprintf(p, end - p, " mode: 0 = dynamic, 1 = static\n");
+ p += scnprintf(p, end - p, " pd_th: PD threshold in dBm (-102 ~ -40)\n");
+
+ return p - buf;
+}
+
+static ssize_t
+rtw89_debug_priv_static_pd_th_set(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
+{
+ struct rtw89_hal *hal = &rtwdev->hal;
+ int ret;
+ u32 mode;
+ s32 pd_th_dbm;
+
+ ret = sscanf(buf, "%u %d", &mode, &pd_th_dbm);
+ if (ret < 1)
+ return -EINVAL;
+
+ if (mode > 1)
+ return -EINVAL;
+
+ if (mode == 0) {
+ rtw89_core_dm_disable_clr(rtwdev, RTW89_DM_DIG_PD);
+ hal->fixed_dig_pd_th = 0;
+ hal->fixed_dig_cck_pd_th = 0;
+
+ rtw89_debug(rtwdev, RTW89_DBG_DIG,
+ "DIG static mode disabled\n");
+ } else {
+ if (ret < 2 || pd_th_dbm < RTW89_DIG_PD_TH_MIN_DBM ||
+ pd_th_dbm > RTW89_DIG_PD_TH_MAX_DBM)
+ return -EINVAL;
+
+ rtw89_core_dm_disable_set(rtwdev, RTW89_DM_DIG_PD);
+ hal->fixed_dig_pd_th = clamp(rtw89_dig_pd_th_dbm_to_reg(pd_th_dbm),
+ 0, 0x1f);
+ /* CCK uses dBm directly */
+ hal->fixed_dig_cck_pd_th = pd_th_dbm;
+
+ rtw89_debug(rtwdev, RTW89_DBG_DIG,
+ "DIG static mode: PD=0x%02x (%d dBm), CCK=%d dBm\n",
+ hal->fixed_dig_pd_th,
+ rtw89_dig_pd_th_to_dbm(hal->fixed_dig_pd_th),
+ hal->fixed_dig_cck_pd_th);
+ }
+
+ return count;
+}
+
static void rtw89_debug_mlo_mode_set_mlsr(struct rtw89_dev *rtwdev,
unsigned int link_id)
{
.phy_info = rtw89_debug_priv_get(phy_info),
.stations = rtw89_debug_priv_get(stations, RLOCK),
.disable_dm = rtw89_debug_priv_set_and_get(disable_dm, RWLOCK),
+ .static_pd_th = rtw89_debug_priv_set_and_get(static_pd_th, RWLOCK),
.mlo_mode = rtw89_debug_priv_set_and_get(mlo_mode, RWLOCK),
.beacon_info = rtw89_debug_priv_get(beacon_info),
.diag_mac = rtw89_debug_priv_get(diag_mac, RSIZE_16K, RLOCK),
rtw89_debugfs_add_r(phy_info);
rtw89_debugfs_add_r(stations);
rtw89_debugfs_add_rw(disable_dm);
+ rtw89_debugfs_add_rw(static_pd_th);
rtw89_debugfs_add_rw(mlo_mode);
rtw89_debugfs_add_r(beacon_info);
rtw89_debugfs_add_r(diag_mac);
const struct rtw89_chan *chan = rtw89_mgnt_chan_get(rtwdev, bb->phy_idx);
const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
struct rtw89_dig_info *dig = &bb->dig;
+ struct rtw89_hal *hal = &rtwdev->hal;
u8 final_rssi, under_region = dig->pd_low_th_ofst;
s8 cck_cca_th;
u32 pd_val;
- pd_val = __rtw89_phy_dig_dyn_pd_th(rtwdev, bb, rssi, enable, chan);
+ if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DIG_PD)) {
+ pd_val = hal->fixed_dig_pd_th;
+
+ rtw89_debug(rtwdev, RTW89_DBG_DIG,
+ "Fixed DIG: PD_low=%d\n", pd_val);
+ } else {
+ pd_val = __rtw89_phy_dig_dyn_pd_th(rtwdev, bb, rssi, enable, chan);
+ }
dig->bak_dig = pd_val;
rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
rtw89_phy_write32_idx(rtwdev, dig_regs->seg0_pd_reg,
dig_regs->pd_spatial_reuse_en, enable, bb->phy_idx);
- if (!rtwdev->hal.support_cckpd)
+ if (!hal->support_cckpd)
return;
- final_rssi = min_t(u8, rssi, dig->igi_rssi);
- under_region = rtw89_phy_dig_cal_under_region(rtwdev, bb, chan);
- cck_cca_th = max_t(s8, final_rssi - under_region, CCKPD_TH_MIN_RSSI);
- pd_val = (u32)(cck_cca_th - IGI_RSSI_MAX);
+ if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DIG_PD)) {
+ pd_val = hal->fixed_dig_cck_pd_th;
- rtw89_debug(rtwdev, RTW89_DBG_DIG,
- "igi=%d, cck_ccaTH=%d, backoff=%d, cck_PD_low=((%d))dB\n",
- final_rssi, cck_cca_th, under_region, pd_val);
+ rtw89_debug(rtwdev, RTW89_DBG_DIG,
+ "Fixed DIG: cck_PD_low=((%d))dB\n", pd_val);
+ } else {
+ final_rssi = min_t(u8, rssi, dig->igi_rssi);
+ under_region = rtw89_phy_dig_cal_under_region(rtwdev, bb, chan);
+ cck_cca_th = max_t(s8, final_rssi - under_region, CCKPD_TH_MIN_RSSI);
+ pd_val = (u32)(cck_cca_th - IGI_RSSI_MAX);
+
+ rtw89_debug(rtwdev, RTW89_DBG_DIG,
+ "igi=%d, cck_ccaTH=%d, backoff=%d, cck_PD_low=((%d))dB\n",
+ final_rssi, cck_cca_th, under_region, pd_val);
+ }
rtw89_phy_write32_idx(rtwdev, dig_regs->bmode_pd_reg,
dig_regs->bmode_cca_rssi_limit_en, enable, bb->phy_idx);
{
const struct rtw89_dig_regs *dig_regs = rtwdev->chip->dig_regs;
struct rtw89_dig_info *dig = &bb->dig;
+ struct rtw89_hal *hal = &rtwdev->hal;
bool en_dig;
u32 pd_val;
if (pause_dig) {
en_dig = false;
- pd_val = 0;
+ if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DIG_PD))
+ pd_val = hal->fixed_dig_pd_th;
+ else
+ pd_val = 0;
} else {
en_dig = rtwdev->total_sta_assoc > 0;
- pd_val = restore ? dig->bak_dig : 0;
+ if (hal->disabled_dm_bitmap & BIT(RTW89_DM_DIG_PD))
+ pd_val = hal->fixed_dig_pd_th;
+ else
+ pd_val = restore ? dig->bak_dig : 0;
}
rtw89_debug(rtwdev, RTW89_DBG_DIG, "%s <%s> PD_low=%d", __func__,