Commit 6b069898 authored by Ping-Ke Shih's avatar Ping-Ke Shih Committed by Kalle Valo

wifi: rtw89: 8852b: add chip_ops::set_channel

set_channel is main function to configure channel and bandwidth for all
layers, namely MAC, BB and RF. Additionally, MAC layer enables CCK rate
checking to avoid wrong rate from driver. BB layer configures SCO
(Sample Clock Offset) for CCK, TX gain error/offset, and reset baseband
hardware circuit after all configurations done.
Signed-off-by: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20221005083212.45683-7-pkshih@realtek.com
parent 6e5125bc
......@@ -3429,6 +3429,7 @@ struct rtw89_phy_efuse_gain {
bool comp_valid;
s8 offset[RF_PATH_MAX][RTW89_GAIN_OFFSET_NR]; /* S(8, 0) */
s8 offset_base[RTW89_PHY_MAX]; /* S(8, 4) */
s8 rssi_base[RTW89_PHY_MAX]; /* S(8, 4) */
s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */
};
......
......@@ -1427,6 +1427,15 @@ void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
}
EXPORT_SYMBOL(rtw89_phy_write32_idx);
u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
enum rtw89_phy_idx phy_idx)
{
if (rtwdev->dbcc_en && phy_idx == RTW89_PHY_1)
addr += rtw89_phy0_phy1_offset(rtwdev, addr);
return rtw89_phy_read32_mask(rtwdev, addr, mask);
}
EXPORT_SYMBOL(rtw89_phy_read32_idx);
void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
u32 val)
{
......
......@@ -499,6 +499,8 @@ void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev,
void rtw89_phy_dm_init(struct rtw89_dev *rtwdev);
void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
u32 data, enum rtw89_phy_idx phy_idx);
u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
enum rtw89_phy_idx phy_idx);
void rtw89_phy_load_txpwr_byrate(struct rtw89_dev *rtwdev,
const struct rtw89_txpwr_table *tbl);
s8 rtw89_phy_read_txpwr_limit(struct rtw89_dev *rtwdev, u8 band,
......
......@@ -3313,6 +3313,10 @@
#define CFGCH_BAND1_2G 0
#define CFGCH_BAND1_5G 1
#define CFGCH_BAND1_6G 3
#define RR_CFGCH_POW_LCK BIT(15)
#define RR_CFGCH_TRX_AH BIT(14)
#define RR_CFGCH_BCN BIT(13)
#define RR_CFGCH_BW2 BIT(12)
#define RR_CFGCH_BAND0 GENMASK(9, 8)
#define CFGCH_BAND0_2G 0
#define CFGCH_BAND0_5G 1
......@@ -3448,14 +3452,31 @@
#define RR_TIA_N6 BIT(8)
#define RR_MIXER 0x9f
#define RR_MIXER_GN GENMASK(4, 3)
#define RR_POW 0xa0
#define RR_POW_SYN GENMASK(3, 2)
#define RR_LOGEN 0xa3
#define RR_LOGEN_RPT GENMASK(19, 16)
#define RR_SX 0xaf
#define RR_LDO 0xb1
#define RR_LDO_SEL GENMASK(8, 6)
#define RR_VCO 0xb2
#define RR_LPF 0xb7
#define RR_LPF_BUSY BIT(8)
#define RR_XTALX2 0xb8
#define RR_MALSEL 0xbe
#define RR_SYNFB 0xc5
#define RR_SYNFB_LK BIT(15)
#define RR_LCKST 0xcf
#define RR_LCKST_BIN BIT(0)
#define RR_LCK_TRG 0xd3
#define RR_LCK_TRGSEL BIT(8)
#define RR_MMD 0xd5
#define RR_MMD_RST_EN BIT(8)
#define RR_MMD_RST_SYN BIT(6)
#define RR_IQKPLL 0xdc
#define RR_IQKPLL_MOD GENMASK(9, 8)
#define RR_SYNLUT 0xdd
#define RR_SYNLUT_MOD BIT(4)
#define RR_RCKD 0xde
#define RR_RCKD_POW GENMASK(19, 13)
#define RR_RCKD_BW BIT(2)
......@@ -3624,6 +3645,8 @@
#define R_P0_RFMODE 0x12AC
#define B_P0_RFMODE_ORI_TXRX_FTM_TX GENMASK(31, 4)
#define B_P0_RFMODE_MUX GENMASK(11, 4)
#define R_P0_RFMODE_ORI_RX 0x12AC
#define B_P0_RFMODE_ORI_RX_ALL GENMASK(23, 12)
#define R_P0_NRBW 0x12B8
#define B_P0_NRBW_DBG BIT(30)
#define R_S0_RXDC 0x12D4
......@@ -3717,6 +3740,8 @@
#define B_RXCCA_DIS_V1 BIT(0)
#define R_RXSC 0x237C
#define B_RXSC_EN BIT(0)
#define R_RX_RPL_OFST 0x23AC
#define B_RX_RPL_OFST_CCK_MASK GENMASK(6, 0)
#define R_RXSCOBC 0x23B0
#define B_RXSCOBC_TH GENMASK(18, 0)
#define R_RXSCOCCK 0x23B4
......@@ -3733,6 +3758,8 @@
#define R_P1_RFMODE 0x32AC
#define B_P1_RFMODE_ORI_TXRX_FTM_TX GENMASK(31, 4)
#define B_P1_RFMODE_MUX GENMASK(11, 4)
#define R_P1_RFMODE_ORI_RX 0x32AC
#define B_P1_RFMODE_ORI_RX_ALL GENMASK(23, 12)
#define R_P1_DBGMOD 0x32B8
#define B_P1_DBGMOD_ON BIT(30)
#define R_S1_RXDC 0x32D4
......@@ -3766,7 +3793,10 @@
#define R_T2F_GI_COMB 0x4424
#define B_T2F_GI_COMB_EN BIT(2)
#define R_BT_DYN_DC_EST_EN 0x441C
#define R_BT_DYN_DC_EST_EN_V1 0x4420
#define B_BT_DYN_DC_EST_EN_MSK BIT(31)
#define R_ASSIGN_SBD_OPT_V1 0x4440
#define B_ASSIGN_SBD_OPT_EN_V1 BIT(31)
#define R_ASSIGN_SBD_OPT 0x4450
#define B_ASSIGN_SBD_OPT_EN BIT(24)
#define R_DCFO_COMP_S0 0x448C
......@@ -3916,20 +3946,42 @@
#define R_2P4G_BAND 0x4970
#define B_2P4G_BAND_SEL BIT(1)
#define R_FC0_BW 0x4974
#define B_FC0_BW_INV GENMASK(6, 0)
#define R_FC0_BW_V1 0x49C0
#define B_FC0_BW_SET GENMASK(31, 30)
#define B_ANT_RX_BT_SEG0 GENMASK(25, 22)
#define B_ANT_RX_1RCCA_SEG1 GENMASK(21, 18)
#define B_ANT_RX_1RCCA_SEG0 GENMASK(17, 14)
#define B_FC0_BW_INV GENMASK(6, 0)
#define R_CHBW_MOD 0x4978
#define R_CHBW_MOD_V1 0x49C4
#define B_BT_SHARE BIT(14)
#define B_CHBW_MOD_SBW GENMASK(13, 12)
#define B_CHBW_MOD_PRICH GENMASK(11, 8)
#define B_ANT_RX_SEG0 GENMASK(3, 0)
#define R_P0_RPL1 0x49B0
#define B_P0_RPL1_41_MASK GENMASK(31, 24)
#define B_P0_RPL1_40_MASK GENMASK(23, 16)
#define B_P0_RPL1_20_MASK GENMASK(15, 8)
#define B_P0_RPL1_MASK (B_P0_RPL1_41_MASK | B_P0_RPL1_40_MASK | B_P0_RPL1_20_MASK)
#define B_P0_RPL1_SHIFT 8
#define B_P0_RPL1_BIAS_MASK GENMASK(7, 0)
#define R_P0_RPL2 0x49B4
#define B_P0_RTL2_8A_MASK GENMASK(31, 24)
#define B_P0_RTL2_81_MASK GENMASK(23, 16)
#define B_P0_RTL2_80_MASK GENMASK(15, 8)
#define B_P0_RTL2_42_MASK GENMASK(7, 0)
#define R_P0_RPL3 0x49B8
#define B_P0_RTL3_89_MASK GENMASK(31, 24)
#define B_P0_RTL3_84_MASK GENMASK(23, 16)
#define B_P0_RTL3_83_MASK GENMASK(15, 8)
#define B_P0_RTL3_82_MASK GENMASK(7, 0)
#define R_PD_BOOST_EN 0x49E8
#define B_PD_BOOST_EN BIT(7)
#define R_P1_BACKOFF_IBADC_V1 0x49F0
#define B_P1_BACKOFF_IBADC_V1 GENMASK(31, 26)
#define R_P1_RPL1 0x4A00
#define R_P1_RPL2 0x4A04
#define R_P1_RPL3 0x4A08
#define R_BK_FC0_INV_V1 0x4A1C
#define B_BK_FC0_INV_MSK_V1 GENMASK(18, 0)
#define R_CCK_FC0_INV_V1 0x4A20
......@@ -3940,8 +3992,10 @@
#define B_P1_AGC_EN BIT(31)
#define R_PATH1_TIA_INIT_V1 0x4AA8
#define B_PATH1_TIA_INIT_IDX_MSK_V1 BIT(9)
#define R_P0_AGC_RSVD 0x4ACC
#define R_PATH0_RXBB_V1 0x4AD4
#define B_PATH0_RXBB_MSK_V1 GENMASK(31, 0)
#define R_P1_AGC_RSVD 0x4AD8
#define R_PATH1_RXBB_V1 0x4AE0
#define B_PATH1_RXBB_MSK_V1 GENMASK(31, 0)
#define R_PATH0_BT_BACKOFF_V1 0x4AE4
......@@ -3957,6 +4011,7 @@
#define B_PATH0_NOTCH2_EN BIT(12)
#define B_PATH0_NOTCH2_VAL GENMASK(11, 0)
#define R_PATH0_5MDET 0x4C4C
#define R_PATH0_5MDET_V1 0x46F8
#define B_PATH0_5MDET_EN BIT(12)
#define B_PATH0_5MDET_SB2 BIT(8)
#define B_PATH0_5MDET_SB0 BIT(6)
......@@ -3970,6 +4025,7 @@
#define B_PATH1_NOTCH2_EN BIT(12)
#define B_PATH1_NOTCH2_VAL GENMASK(11, 0)
#define R_PATH1_5MDET 0x4D10
#define R_PATH1_5MDET_V1 0x47B8
#define B_PATH1_5MDET_EN BIT(12)
#define B_PATH1_5MDET_SB2 BIT(8)
#define B_PATH1_5MDET_SB0 BIT(6)
......
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/* Copyright(c) 2019-2022 Realtek Corporation
*/
#include "coex.h"
#include "debug.h"
#include "mac.h"
#include "phy.h"
#include "reg.h"
#include "rtw8852b.h"
#include "rtw8852b_rfk.h"
#include "rtw8852b_rfk_table.h"
#include "rtw8852b_table.h"
static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
{
u8 val;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x,PHY%d\n",
rtwdev->dbcc_en, phy_idx);
if (!rtwdev->dbcc_en) {
val = RF_AB;
} else {
if (phy_idx == RTW89_PHY_0)
val = RF_A;
else
val = RF_B;
}
return val;
}
static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
enum rtw89_bandwidth bw, bool dav)
{
u32 rf_reg18;
u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__);
rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK);
if (rf_reg18 == INV_RF_DATA) {
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RFK]Invalid RF_0x18 for Path-%d\n", path);
return;
}
rf_reg18 &= ~RR_CFGCH_BW;
switch (bw) {
case RTW89_CHANNEL_WIDTH_5:
case RTW89_CHANNEL_WIDTH_10:
case RTW89_CHANNEL_WIDTH_20:
rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_20M);
break;
case RTW89_CHANNEL_WIDTH_40:
rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_40M);
break;
case RTW89_CHANNEL_WIDTH_80:
rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_80M);
break;
default:
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]Fail to set CH\n");
}
rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN |
RR_CFGCH_BW2) & RFREG_MASK;
rf_reg18 |= RR_CFGCH_BW2;
rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set %x at path%d, %x =0x%x\n",
bw, path, reg18_addr,
rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK));
}
static void _ctrl_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_bandwidth bw)
{
_bw_setting(rtwdev, RF_PATH_A, bw, true);
_bw_setting(rtwdev, RF_PATH_B, bw, true);
_bw_setting(rtwdev, RF_PATH_A, bw, false);
_bw_setting(rtwdev, RF_PATH_B, bw, false);
}
static bool _set_s0_arfc18(struct rtw89_dev *rtwdev, u32 val)
{
u32 bak;
u32 tmp;
int ret;
bak = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RR_LDO_SEL, 0x1);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK, val);
ret = read_poll_timeout_atomic(rtw89_read_rf, tmp, tmp == 0, 1, 1000,
false, rtwdev, RF_PATH_A, RR_LPF, RR_LPF_BUSY);
if (ret)
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]LCK timeout\n");
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK, bak);
return !!ret;
}
static void _lck_check(struct rtw89_dev *rtwdev)
{
u32 tmp;
if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) {
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN MMD reset\n");
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x1);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x1);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x0);
}
udelay(10);
if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) {
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]re-set RF 0x18\n");
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1);
tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK);
_set_s0_arfc18(rtwdev, tmp);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0);
}
if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) {
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN off/on\n");
tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK, tmp);
tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK, tmp);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x1);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x0);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1);
tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK);
_set_s0_arfc18(rtwdev, tmp);
rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]0xb2=%x, 0xc5=%x\n",
rtw89_read_rf(rtwdev, RF_PATH_A, RR_VCO, RFREG_MASK),
rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RFREG_MASK));
}
}
static void _set_ch(struct rtw89_dev *rtwdev, u32 val)
{
bool timeout;
timeout = _set_s0_arfc18(rtwdev, val);
if (!timeout)
_lck_check(rtwdev);
}
static void _ch_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
u8 central_ch, bool dav)
{
u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1;
bool is_2g_ch = central_ch <= 14;
u32 rf_reg18;
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__);
rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK);
rf_reg18 &= ~(RR_CFGCH_BAND1 | RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH |
RR_CFGCH_BCN | RR_CFGCH_BAND0 | RR_CFGCH_CH);
rf_reg18 |= FIELD_PREP(RR_CFGCH_CH, central_ch);
if (!is_2g_ch)
rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_5G) |
FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_5G);
rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN |
RR_CFGCH_BW2) & RFREG_MASK;
rf_reg18 |= RR_CFGCH_BW2;
if (path == RF_PATH_A && dav)
_set_ch(rtwdev, rf_reg18);
else
rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18);
rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 0);
rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 1);
rtw89_debug(rtwdev, RTW89_DBG_RFK,
"[RFK]CH: %d for Path-%d, reg0x%x = 0x%x\n",
central_ch, path, reg18_addr,
rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK));
}
static void _ctrl_ch(struct rtw89_dev *rtwdev, u8 central_ch)
{
_ch_setting(rtwdev, RF_PATH_A, central_ch, true);
_ch_setting(rtwdev, RF_PATH_B, central_ch, true);
_ch_setting(rtwdev, RF_PATH_A, central_ch, false);
_ch_setting(rtwdev, RF_PATH_B, central_ch, false);
}
static void _set_rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_bandwidth bw,
enum rtw89_rf_path path)
{
rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1);
rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0x12);
if (bw == RTW89_CHANNEL_WIDTH_20)
rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x1b);
else if (bw == RTW89_CHANNEL_WIDTH_40)
rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x13);
else if (bw == RTW89_CHANNEL_WIDTH_80)
rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0xb);
else
rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x3);
rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set S%d RXBB BW 0x3F = 0x%x\n", path,
rtw89_read_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB));
rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0);
}
static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
enum rtw89_bandwidth bw)
{
u8 kpath, path;
kpath = _kpath(rtwdev, phy);
for (path = 0; path < RF_PATH_NUM_8852B; path++) {
if (!(kpath & BIT(path)))
continue;
_set_rxbb_bw(rtwdev, bw, path);
}
}
static void rtw8852b_ctrl_bw_ch(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy, u8 central_ch,
enum rtw89_band band, enum rtw89_bandwidth bw)
{
_ctrl_ch(rtwdev, central_ch);
_ctrl_bw(rtwdev, phy, bw);
_rxbb_bw(rtwdev, phy, bw);
}
void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
rtw8852b_ctrl_bw_ch(rtwdev, phy_idx, chan->channel, chan->band_type,
chan->band_width);
}
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* Copyright(c) 2019-2022 Realtek Corporation
*/
#ifndef __RTW89_8852B_RFK_H__
#define __RTW89_8852B_RFK_H__
#include "core.h"
void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment