Merge tag 'rtw-next-2025-02-10-v2' of https://github.com/pkshih/rtw

Ping-Ke says:

====================
rtw-next patches for v6.15

Major changes are listed below:

rtw88:

 * preparation to support RTL8814AU

rtw89:

 * switch using wiphy_lock and wiphy_work

 * add BB context to manipulate two PHY as preparation of MLO

 * improve BT-coexistence mechanism to play A2DP smoothly

 * firmware file can contain regd table
====================

Link: https://lore.kernel.org/linux-wireless/b65fae15-79bf-40fa-8acc-63d87ae35e19@RTEXMBS04.realtek.com.tw/
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg
2025-02-11 15:55:48 +01:00
51 changed files with 4409 additions and 3376 deletions

View File

@@ -644,6 +644,8 @@ struct rtl8xxxu_fileops rtl8192cu_fops = {
.rx_agg_buf_size = 16000,
.tx_desc_size = sizeof(struct rtl8xxxu_txdesc32),
.rx_desc_size = sizeof(struct rtl8xxxu_rxdesc16),
.supports_ap = 1,
.max_macid_num = 32,
.max_sec_cam_num = 32,
.adda_1t_init = 0x0b1b25a0,
.adda_1t_path_on = 0x0bdb25a0,

View File

@@ -860,9 +860,10 @@ rtl8xxxu_writeN(struct rtl8xxxu_priv *priv, u16 addr, u8 *buf, u16 len)
return len;
write_error:
dev_info(&udev->dev,
"%s: Failed to write block at addr: %04x size: %04x\n",
__func__, addr, blocksize);
if (rtl8xxxu_debug & RTL8XXXU_DEBUG_REG_WRITE)
dev_info(&udev->dev,
"%s: Failed to write block at addr: %04x size: %04x\n",
__func__, addr, blocksize);
return -EAGAIN;
}
@@ -4064,8 +4065,14 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
*/
rtl8xxxu_write16(priv, REG_TRXFF_BNDY + 2, fops->trxff_boundary);
ret = rtl8xxxu_download_firmware(priv);
dev_dbg(dev, "%s: download_firmware %i\n", __func__, ret);
for (int retry = 5; retry >= 0 ; retry--) {
ret = rtl8xxxu_download_firmware(priv);
dev_dbg(dev, "%s: download_firmware %i\n", __func__, ret);
if (ret != -EAGAIN)
break;
if (retry)
dev_dbg(dev, "%s: retry firmware download\n", __func__);
}
if (ret)
goto exit;
ret = rtl8xxxu_start_firmware(priv);

View File

@@ -484,7 +484,7 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
* pathA or mac1 has to set phy0&phy1 pathA */
if ((content == radiob_txt) && (rfpath == RF90_PATH_A)) {
rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
" ===> althougth Path A, we load radiob.txt\n");
" ===> although Path A, we load radiob.txt\n");
radioa_arraylen = radiob_arraylen;
radioa_array_table = radiob_array_table;
}
@@ -750,7 +750,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
&& rtlhal->interfaceindex == 1) {
need_pwr_down = rtl92d_phy_enable_anotherphy(hw, false);
rtlhal->during_mac1init_radioa = true;
/* asume no this case */
/* assume no this case */
if (need_pwr_down)
rtl92d_phy_enable_rf_env(hw, path,
&u4regvalue);
@@ -1885,7 +1885,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw,
bneed_powerdown_radio =
rtl92d_phy_enable_anotherphy(hw, false);
rtlpriv->rtlhal.during_mac1init_radioa = true;
/* asume no this case */
/* assume no this case */
if (bneed_powerdown_radio)
rtl92d_phy_enable_rf_env(hw, erfpath,
&u4regvalue);

View File

@@ -735,6 +735,7 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
{
u8 h2c_pkt[H2C_PKT_SIZE] = {0};
bool disable_pt = true;
u32 mask_hi;
SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO);
@@ -755,6 +756,20 @@ void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
si->init_ra_lv = 0;
rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
if (rtwdev->chip->id != RTW_CHIP_TYPE_8814A)
return;
SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_RA_INFO_HI);
mask_hi = si->ra_mask >> 32;
SET_RA_INFO_RA_MASK0(h2c_pkt, (mask_hi & 0xff));
SET_RA_INFO_RA_MASK1(h2c_pkt, (mask_hi & 0xff00) >> 8);
SET_RA_INFO_RA_MASK2(h2c_pkt, (mask_hi & 0xff0000) >> 16);
SET_RA_INFO_RA_MASK3(h2c_pkt, (mask_hi & 0xff000000) >> 24);
rtw_fw_send_h2c_command(rtwdev, h2c_pkt);
}
void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool connect)

View File

@@ -557,6 +557,7 @@ static inline void rtw_h2c_pkt_set_header(u8 *h2c_pkt, u8 sub_id)
#define H2C_CMD_DEFAULT_PORT 0x2c
#define H2C_CMD_RA_INFO 0x40
#define H2C_CMD_RSSI_MONITOR 0x42
#define H2C_CMD_RA_INFO_HI 0x46
#define H2C_CMD_BCN_FILTER_OFFLOAD_P0 0x56
#define H2C_CMD_BCN_FILTER_OFFLOAD_P1 0x57
#define H2C_CMD_WL_PHY_INFO 0x58

View File

@@ -784,7 +784,8 @@ static int __rtw_download_firmware(struct rtw_dev *rtwdev,
if (!check_firmware_size(data, size))
return -EINVAL;
if (!ltecoex_read_reg(rtwdev, 0x38, &ltecoex_bckp))
if (rtwdev->chip->ltecoex_addr &&
!ltecoex_read_reg(rtwdev, 0x38, &ltecoex_bckp))
return -EBUSY;
wlan_cpu_enable(rtwdev, false);
@@ -802,7 +803,8 @@ static int __rtw_download_firmware(struct rtw_dev *rtwdev,
wlan_cpu_enable(rtwdev, true);
if (!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) {
if (rtwdev->chip->ltecoex_addr &&
!ltecoex_reg_write(rtwdev, 0x38, ltecoex_bckp)) {
ret = -EBUSY;
goto dlfw_fail;
}

View File

@@ -136,7 +136,7 @@ u16 rtw_desc_to_bitrate(u8 desc_rate)
return rate.bitrate;
}
static struct ieee80211_supported_band rtw_band_2ghz = {
static const struct ieee80211_supported_band rtw_band_2ghz = {
.band = NL80211_BAND_2GHZ,
.channels = rtw_channeltable_2g,
@@ -149,7 +149,7 @@ static struct ieee80211_supported_band rtw_band_2ghz = {
.vht_cap = {0},
};
static struct ieee80211_supported_band rtw_band_5ghz = {
static const struct ieee80211_supported_band rtw_band_5ghz = {
.band = NL80211_BAND_5GHZ,
.channels = rtw_channeltable_5g,
@@ -1234,7 +1234,9 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC)
ldpc_en = VHT_LDPC_EN;
} else if (sta->deflink.ht_cap.ht_supported) {
ra_mask |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20) |
ra_mask |= ((u64)sta->deflink.ht_cap.mcs.rx_mask[3] << 36) |
((u64)sta->deflink.ht_cap.mcs.rx_mask[2] << 28) |
(sta->deflink.ht_cap.mcs.rx_mask[1] << 20) |
(sta->deflink.ht_cap.mcs.rx_mask[0] << 12);
if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_RX_STBC)
stbc_en = HT_STBC_EN;
@@ -1244,6 +1246,9 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
if (efuse->hw_cap.nss == 1 || rtwdev->hal.txrx_1ss)
ra_mask &= RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS;
else if (efuse->hw_cap.nss == 2)
ra_mask &= RA_MASK_VHT_RATES_2SS | RA_MASK_HT_RATES_2SS |
RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS;
if (hal->current_band_type == RTW_BAND_5G) {
ra_mask |= (u64)sta->deflink.supp_rates[NL80211_BAND_5GHZ] << 4;
@@ -1302,10 +1307,9 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si,
break;
}
if (sta->deflink.vht_cap.vht_supported && ra_mask & 0xffc00000)
tx_num = 2;
else if (sta->deflink.ht_cap.ht_supported && ra_mask & 0xfff00000)
tx_num = 2;
if (sta->deflink.vht_cap.vht_supported ||
sta->deflink.ht_cap.ht_supported)
tx_num = efuse->hw_cap.nss;
rate_id = get_rate_id(wireless_set, bw_mode, tx_num);

View File

@@ -61,7 +61,7 @@ enum rtw_hci_type {
};
struct rtw_hci {
struct rtw_hci_ops *ops;
const struct rtw_hci_ops *ops;
enum rtw_hci_type type;
u32 rpwm_addr;
@@ -166,9 +166,14 @@ enum rtw_rate_section {
RTW_RATE_SECTION_HT_2S,
RTW_RATE_SECTION_VHT_1S,
RTW_RATE_SECTION_VHT_2S,
__RTW_RATE_SECTION_2SS_MAX = RTW_RATE_SECTION_VHT_2S,
RTW_RATE_SECTION_HT_3S,
RTW_RATE_SECTION_HT_4S,
RTW_RATE_SECTION_VHT_3S,
RTW_RATE_SECTION_VHT_4S,
/* keep last */
RTW_RATE_SECTION_MAX,
RTW_RATE_SECTION_NUM,
};
enum rtw_wireless_set {
@@ -191,6 +196,7 @@ enum rtw_chip_type {
RTW_CHIP_TYPE_8703B,
RTW_CHIP_TYPE_8821A,
RTW_CHIP_TYPE_8812A,
RTW_CHIP_TYPE_8814A,
};
enum rtw_tx_queue_type {
@@ -1130,14 +1136,26 @@ struct rtw_rfe_def {
* For 2G there are cck rate and ofdm rate with different settings.
*/
struct rtw_pwr_track_tbl {
const u8 *pwrtrk_5gd_n[RTW_PWR_TRK_5G_NUM];
const u8 *pwrtrk_5gd_p[RTW_PWR_TRK_5G_NUM];
const u8 *pwrtrk_5gc_n[RTW_PWR_TRK_5G_NUM];
const u8 *pwrtrk_5gc_p[RTW_PWR_TRK_5G_NUM];
const u8 *pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM];
const u8 *pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM];
const u8 *pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM];
const u8 *pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM];
const u8 *pwrtrk_2gd_n;
const u8 *pwrtrk_2gd_p;
const u8 *pwrtrk_2gc_n;
const u8 *pwrtrk_2gc_p;
const u8 *pwrtrk_2gb_n;
const u8 *pwrtrk_2gb_p;
const u8 *pwrtrk_2ga_n;
const u8 *pwrtrk_2ga_p;
const u8 *pwrtrk_2g_cckd_n;
const u8 *pwrtrk_2g_cckd_p;
const u8 *pwrtrk_2g_cckc_n;
const u8 *pwrtrk_2g_cckc_p;
const u8 *pwrtrk_2g_cckb_n;
const u8 *pwrtrk_2g_cckb_p;
const u8 *pwrtrk_2g_ccka_n;
@@ -1227,8 +1245,8 @@ struct rtw_chip_info {
const struct rtw_hw_reg *dig;
const struct rtw_hw_reg *dig_cck;
u32 rf_base_addr[2];
u32 rf_sipi_addr[2];
u32 rf_base_addr[RTW_RF_PATH_MAX];
u32 rf_sipi_addr[RTW_RF_PATH_MAX];
const struct rtw_rf_sipi_addr *rf_sipi_read_addr;
u8 fix_rf_phy_num;
const struct rtw_ltecoex_addr *ltecoex_addr;
@@ -1924,7 +1942,7 @@ union rtw_sar_cfg {
struct rtw_sar {
enum rtw_sar_sources src;
union rtw_sar_cfg cfg[RTW_RF_PATH_MAX][RTW_RATE_SECTION_MAX];
union rtw_sar_cfg cfg[RTW_RF_PATH_MAX][RTW_RATE_SECTION_NUM];
};
struct rtw_hal {
@@ -1968,16 +1986,16 @@ struct rtw_hal {
s8 tx_pwr_by_rate_offset_5g[RTW_RF_PATH_MAX]
[DESC_RATE_MAX];
s8 tx_pwr_by_rate_base_2g[RTW_RF_PATH_MAX]
[RTW_RATE_SECTION_MAX];
[RTW_RATE_SECTION_NUM];
s8 tx_pwr_by_rate_base_5g[RTW_RF_PATH_MAX]
[RTW_RATE_SECTION_MAX];
[RTW_RATE_SECTION_NUM];
s8 tx_pwr_limit_2g[RTW_REGD_MAX]
[RTW_CHANNEL_WIDTH_MAX]
[RTW_RATE_SECTION_MAX]
[RTW_RATE_SECTION_NUM]
[RTW_MAX_CHANNEL_NUM_2G];
s8 tx_pwr_limit_5g[RTW_REGD_MAX]
[RTW_CHANNEL_WIDTH_MAX]
[RTW_RATE_SECTION_MAX]
[RTW_RATE_SECTION_NUM]
[RTW_MAX_CHANNEL_NUM_5G];
s8 tx_pwr_tbl[RTW_RF_PATH_MAX]
[DESC_RATE_MAX];

View File

@@ -20,7 +20,7 @@ module_param_named(disable_aspm, rtw_pci_disable_aspm, bool, 0644);
MODULE_PARM_DESC(disable_msi, "Set Y to disable MSI interrupt support");
MODULE_PARM_DESC(disable_aspm, "Set Y to disable PCI ASPM support");
static u32 rtw_pci_tx_queue_idx_addr[] = {
static const u32 rtw_pci_tx_queue_idx_addr[] = {
[RTW_TX_QUEUE_BK] = RTK_PCI_TXBD_IDX_BKQ,
[RTW_TX_QUEUE_BE] = RTK_PCI_TXBD_IDX_BEQ,
[RTW_TX_QUEUE_VI] = RTK_PCI_TXBD_IDX_VIQ,
@@ -1591,7 +1591,7 @@ static void rtw_pci_destroy(struct rtw_dev *rtwdev, struct pci_dev *pdev)
rtw_pci_io_unmapping(rtwdev, pdev);
}
static struct rtw_hci_ops rtw_pci_ops = {
static const struct rtw_hci_ops rtw_pci_ops = {
.tx_write = rtw_pci_tx_write,
.tx_kick_off = rtw_pci_tx_kick_off,
.flush_queues = rtw_pci_flush_queues,

View File

@@ -52,60 +52,93 @@ static const u32 db_invert_table[12][8] = {
1995262315, 2511886432U, 3162277660U, 3981071706U}
};
u8 rtw_cck_rates[] = { DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M };
u8 rtw_ofdm_rates[] = {
const u8 rtw_cck_rates[] = { DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M };
const u8 rtw_ofdm_rates[] = {
DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
DESC_RATE48M, DESC_RATE54M
};
u8 rtw_ht_1s_rates[] = {
const u8 rtw_ht_1s_rates[] = {
DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
DESC_RATEMCS6, DESC_RATEMCS7
};
u8 rtw_ht_2s_rates[] = {
const u8 rtw_ht_2s_rates[] = {
DESC_RATEMCS8, DESC_RATEMCS9, DESC_RATEMCS10,
DESC_RATEMCS11, DESC_RATEMCS12, DESC_RATEMCS13,
DESC_RATEMCS14, DESC_RATEMCS15
};
u8 rtw_vht_1s_rates[] = {
const u8 rtw_vht_1s_rates[] = {
DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9
};
u8 rtw_vht_2s_rates[] = {
const u8 rtw_vht_2s_rates[] = {
DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9
};
u8 *rtw_rate_section[RTW_RATE_SECTION_MAX] = {
const u8 rtw_ht_3s_rates[] = {
DESC_RATEMCS16, DESC_RATEMCS17, DESC_RATEMCS18,
DESC_RATEMCS19, DESC_RATEMCS20, DESC_RATEMCS21,
DESC_RATEMCS22, DESC_RATEMCS23
};
const u8 rtw_ht_4s_rates[] = {
DESC_RATEMCS24, DESC_RATEMCS25, DESC_RATEMCS26,
DESC_RATEMCS27, DESC_RATEMCS28, DESC_RATEMCS29,
DESC_RATEMCS30, DESC_RATEMCS31
};
const u8 rtw_vht_3s_rates[] = {
DESC_RATEVHT3SS_MCS0, DESC_RATEVHT3SS_MCS1,
DESC_RATEVHT3SS_MCS2, DESC_RATEVHT3SS_MCS3,
DESC_RATEVHT3SS_MCS4, DESC_RATEVHT3SS_MCS5,
DESC_RATEVHT3SS_MCS6, DESC_RATEVHT3SS_MCS7,
DESC_RATEVHT3SS_MCS8, DESC_RATEVHT3SS_MCS9
};
const u8 rtw_vht_4s_rates[] = {
DESC_RATEVHT4SS_MCS0, DESC_RATEVHT4SS_MCS1,
DESC_RATEVHT4SS_MCS2, DESC_RATEVHT4SS_MCS3,
DESC_RATEVHT4SS_MCS4, DESC_RATEVHT4SS_MCS5,
DESC_RATEVHT4SS_MCS6, DESC_RATEVHT4SS_MCS7,
DESC_RATEVHT4SS_MCS8, DESC_RATEVHT4SS_MCS9
};
const u8 * const rtw_rate_section[RTW_RATE_SECTION_NUM] = {
rtw_cck_rates, rtw_ofdm_rates,
rtw_ht_1s_rates, rtw_ht_2s_rates,
rtw_vht_1s_rates, rtw_vht_2s_rates
rtw_vht_1s_rates, rtw_vht_2s_rates,
rtw_ht_3s_rates, rtw_ht_4s_rates,
rtw_vht_3s_rates, rtw_vht_4s_rates
};
EXPORT_SYMBOL(rtw_rate_section);
u8 rtw_rate_size[RTW_RATE_SECTION_MAX] = {
const u8 rtw_rate_size[RTW_RATE_SECTION_NUM] = {
ARRAY_SIZE(rtw_cck_rates),
ARRAY_SIZE(rtw_ofdm_rates),
ARRAY_SIZE(rtw_ht_1s_rates),
ARRAY_SIZE(rtw_ht_2s_rates),
ARRAY_SIZE(rtw_vht_1s_rates),
ARRAY_SIZE(rtw_vht_2s_rates)
ARRAY_SIZE(rtw_vht_2s_rates),
ARRAY_SIZE(rtw_ht_3s_rates),
ARRAY_SIZE(rtw_ht_4s_rates),
ARRAY_SIZE(rtw_vht_3s_rates),
ARRAY_SIZE(rtw_vht_4s_rates)
};
EXPORT_SYMBOL(rtw_rate_size);
static const u8 rtw_cck_size = ARRAY_SIZE(rtw_cck_rates);
static const u8 rtw_ofdm_size = ARRAY_SIZE(rtw_ofdm_rates);
static const u8 rtw_ht_1s_size = ARRAY_SIZE(rtw_ht_1s_rates);
static const u8 rtw_ht_2s_size = ARRAY_SIZE(rtw_ht_2s_rates);
static const u8 rtw_vht_1s_size = ARRAY_SIZE(rtw_vht_1s_rates);
static const u8 rtw_vht_2s_size = ARRAY_SIZE(rtw_vht_2s_rates);
enum rtw_phy_band_type {
PHY_BAND_2G = 0,
PHY_BAND_5G = 1,
@@ -1590,7 +1623,7 @@ static void rtw_phy_set_tx_power_limit(struct rtw_dev *rtwdev, u8 regd, u8 band,
ch_idx = rtw_channel_to_idx(band, ch);
if (regd >= RTW_REGD_MAX || bw >= RTW_CHANNEL_WIDTH_MAX ||
rs >= RTW_RATE_SECTION_MAX || ch_idx < 0) {
rs >= RTW_RATE_SECTION_NUM || ch_idx < 0) {
WARN(1,
"wrong txpwr_lmt regd=%u, band=%u bw=%u, rs=%u, ch_idx=%u, pwr_limit=%d\n",
regd, band, bw, rs, ch_idx, pwr_limit);
@@ -1634,11 +1667,15 @@ rtw_xref_5g_txpwr_lmt(struct rtw_dev *rtwdev, u8 regd,
static void
rtw_xref_txpwr_lmt_by_rs(struct rtw_dev *rtwdev, u8 regd, u8 bw, u8 ch_idx)
{
static const u8 rs_cmp[4][2] = {
{RTW_RATE_SECTION_HT_1S, RTW_RATE_SECTION_VHT_1S},
{RTW_RATE_SECTION_HT_2S, RTW_RATE_SECTION_VHT_2S},
{RTW_RATE_SECTION_HT_3S, RTW_RATE_SECTION_VHT_3S},
{RTW_RATE_SECTION_HT_4S, RTW_RATE_SECTION_VHT_4S}
};
u8 rs_idx, rs_ht, rs_vht;
u8 rs_cmp[2][2] = {{RTW_RATE_SECTION_HT_1S, RTW_RATE_SECTION_VHT_1S},
{RTW_RATE_SECTION_HT_2S, RTW_RATE_SECTION_VHT_2S} };
for (rs_idx = 0; rs_idx < 2; rs_idx++) {
for (rs_idx = 0; rs_idx < 4; rs_idx++) {
rs_ht = rs_cmp[rs_idx][0];
rs_vht = rs_cmp[rs_idx][1];
@@ -1695,7 +1732,7 @@ rtw_cfg_txpwr_lmt_by_alt(struct rtw_dev *rtwdev, u8 regd, u8 regd_alt)
u8 bw, rs;
for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++)
for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++)
for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++)
__cfg_txpwr_lmt_by_alt(&rtwdev->hal, regd, regd_alt,
bw, rs);
}
@@ -1959,10 +1996,10 @@ static u8 rtw_phy_get_2g_tx_power_index(struct rtw_dev *rtwdev,
u8 rate, u8 group)
{
const struct rtw_chip_info *chip = rtwdev->chip;
u8 tx_power;
bool mcs_rate;
bool above_2ss;
bool above_2ss, above_3ss, above_4ss;
u8 factor = chip->txgi_factor;
bool mcs_rate;
u8 tx_power;
if (rate <= DESC_RATE11M)
tx_power = pwr_idx_2g->cck_base[group];
@@ -1972,11 +2009,15 @@ static u8 rtw_phy_get_2g_tx_power_index(struct rtw_dev *rtwdev,
if (rate >= DESC_RATE6M && rate <= DESC_RATE54M)
tx_power += pwr_idx_2g->ht_1s_diff.ofdm * factor;
mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS31) ||
(rate >= DESC_RATEVHT1SS_MCS0 &&
rate <= DESC_RATEVHT2SS_MCS9);
above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
rate <= DESC_RATEVHT4SS_MCS9);
above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS31) ||
(rate >= DESC_RATEVHT2SS_MCS0);
above_3ss = (rate >= DESC_RATEMCS16 && rate <= DESC_RATEMCS31) ||
(rate >= DESC_RATEVHT3SS_MCS0);
above_4ss = (rate >= DESC_RATEMCS24 && rate <= DESC_RATEMCS31) ||
(rate >= DESC_RATEVHT4SS_MCS0);
if (!mcs_rate)
return tx_power;
@@ -1989,11 +2030,19 @@ static u8 rtw_phy_get_2g_tx_power_index(struct rtw_dev *rtwdev,
tx_power += pwr_idx_2g->ht_1s_diff.bw20 * factor;
if (above_2ss)
tx_power += pwr_idx_2g->ht_2s_diff.bw20 * factor;
if (above_3ss)
tx_power += pwr_idx_2g->ht_3s_diff.bw20 * factor;
if (above_4ss)
tx_power += pwr_idx_2g->ht_4s_diff.bw20 * factor;
break;
case RTW_CHANNEL_WIDTH_40:
/* bw40 is the base power */
if (above_2ss)
tx_power += pwr_idx_2g->ht_2s_diff.bw40 * factor;
if (above_3ss)
tx_power += pwr_idx_2g->ht_3s_diff.bw40 * factor;
if (above_4ss)
tx_power += pwr_idx_2g->ht_4s_diff.bw40 * factor;
break;
}
@@ -2006,19 +2055,23 @@ static u8 rtw_phy_get_5g_tx_power_index(struct rtw_dev *rtwdev,
u8 rate, u8 group)
{
const struct rtw_chip_info *chip = rtwdev->chip;
u8 tx_power;
bool above_2ss, above_3ss, above_4ss;
u8 factor = chip->txgi_factor;
u8 upper, lower;
bool mcs_rate;
bool above_2ss;
u8 factor = chip->txgi_factor;
u8 tx_power;
tx_power = pwr_idx_5g->bw40_base[group];
mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
mcs_rate = (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS31) ||
(rate >= DESC_RATEVHT1SS_MCS0 &&
rate <= DESC_RATEVHT2SS_MCS9);
above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
rate <= DESC_RATEVHT4SS_MCS9);
above_2ss = (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS31) ||
(rate >= DESC_RATEVHT2SS_MCS0);
above_3ss = (rate >= DESC_RATEMCS16 && rate <= DESC_RATEMCS31) ||
(rate >= DESC_RATEVHT3SS_MCS0);
above_4ss = (rate >= DESC_RATEMCS24 && rate <= DESC_RATEMCS31) ||
(rate >= DESC_RATEVHT4SS_MCS0);
if (!mcs_rate) {
tx_power += pwr_idx_5g->ht_1s_diff.ofdm * factor;
@@ -2033,11 +2086,19 @@ static u8 rtw_phy_get_5g_tx_power_index(struct rtw_dev *rtwdev,
tx_power += pwr_idx_5g->ht_1s_diff.bw20 * factor;
if (above_2ss)
tx_power += pwr_idx_5g->ht_2s_diff.bw20 * factor;
if (above_3ss)
tx_power += pwr_idx_5g->ht_3s_diff.bw20 * factor;
if (above_4ss)
tx_power += pwr_idx_5g->ht_4s_diff.bw20 * factor;
break;
case RTW_CHANNEL_WIDTH_40:
/* bw40 is the base power */
if (above_2ss)
tx_power += pwr_idx_5g->ht_2s_diff.bw40 * factor;
if (above_3ss)
tx_power += pwr_idx_5g->ht_3s_diff.bw40 * factor;
if (above_4ss)
tx_power += pwr_idx_5g->ht_4s_diff.bw40 * factor;
break;
case RTW_CHANNEL_WIDTH_80:
/* the base idx of bw80 is the average of bw40+/bw40- */
@@ -2048,13 +2109,17 @@ static u8 rtw_phy_get_5g_tx_power_index(struct rtw_dev *rtwdev,
tx_power += pwr_idx_5g->vht_1s_diff.bw80 * factor;
if (above_2ss)
tx_power += pwr_idx_5g->vht_2s_diff.bw80 * factor;
if (above_3ss)
tx_power += pwr_idx_5g->vht_3s_diff.bw80 * factor;
if (above_4ss)
tx_power += pwr_idx_5g->vht_4s_diff.bw80 * factor;
break;
}
return tx_power;
}
/* return RTW_RATE_SECTION_MAX to indicate rate is invalid */
/* return RTW_RATE_SECTION_NUM to indicate rate is invalid */
static u8 rtw_phy_rate_to_rate_section(u8 rate)
{
if (rate >= DESC_RATE1M && rate <= DESC_RATE11M)
@@ -2065,12 +2130,20 @@ static u8 rtw_phy_rate_to_rate_section(u8 rate)
return RTW_RATE_SECTION_HT_1S;
else if (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15)
return RTW_RATE_SECTION_HT_2S;
else if (rate >= DESC_RATEMCS16 && rate <= DESC_RATEMCS23)
return RTW_RATE_SECTION_HT_3S;
else if (rate >= DESC_RATEMCS24 && rate <= DESC_RATEMCS31)
return RTW_RATE_SECTION_HT_4S;
else if (rate >= DESC_RATEVHT1SS_MCS0 && rate <= DESC_RATEVHT1SS_MCS9)
return RTW_RATE_SECTION_VHT_1S;
else if (rate >= DESC_RATEVHT2SS_MCS0 && rate <= DESC_RATEVHT2SS_MCS9)
return RTW_RATE_SECTION_VHT_2S;
else if (rate >= DESC_RATEVHT3SS_MCS0 && rate <= DESC_RATEVHT3SS_MCS9)
return RTW_RATE_SECTION_VHT_3S;
else if (rate >= DESC_RATEVHT4SS_MCS0 && rate <= DESC_RATEVHT4SS_MCS9)
return RTW_RATE_SECTION_VHT_4S;
else
return RTW_RATE_SECTION_MAX;
return RTW_RATE_SECTION_NUM;
}
static s8 rtw_phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band,
@@ -2088,7 +2161,7 @@ static s8 rtw_phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band,
if (regd > RTW_REGD_WW)
return power_limit;
if (rs == RTW_RATE_SECTION_MAX)
if (rs == RTW_RATE_SECTION_NUM)
goto err;
/* only 20M BW with cck and ofdm */
@@ -2096,7 +2169,7 @@ static s8 rtw_phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band,
bw = RTW_CHANNEL_WIDTH_20;
/* only 20/40M BW with ht */
if (rs == RTW_RATE_SECTION_HT_1S || rs == RTW_RATE_SECTION_HT_2S)
if (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS31)
bw = min_t(u8, bw, RTW_CHANNEL_WIDTH_40);
/* select min power limit among [20M BW ~ current BW] */
@@ -2132,7 +2205,7 @@ static s8 rtw_phy_get_tx_power_sar(struct rtw_dev *rtwdev, u8 sar_band,
.rs = rs,
};
if (rs == RTW_RATE_SECTION_MAX)
if (rs == RTW_RATE_SECTION_NUM)
goto err;
return rtw_query_sar(rtwdev, &arg);
@@ -2214,14 +2287,14 @@ static void rtw_phy_set_tx_power_index_by_rs(struct rtw_dev *rtwdev,
{
struct rtw_hal *hal = &rtwdev->hal;
u8 regd = rtw_regd_get(rtwdev);
u8 *rates;
const u8 *rates;
u8 size;
u8 rate;
u8 pwr_idx;
u8 bw;
int i;
if (rs >= RTW_RATE_SECTION_MAX)
if (rs >= RTW_RATE_SECTION_NUM)
return;
rates = rtw_rate_section[rs];
@@ -2252,7 +2325,7 @@ static void rtw_phy_set_tx_power_level_by_path(struct rtw_dev *rtwdev,
else
rs = RTW_RATE_SECTION_OFDM;
for (; rs < RTW_RATE_SECTION_MAX; rs++)
for (; rs < RTW_RATE_SECTION_NUM; rs++)
rtw_phy_set_tx_power_index_by_rs(rtwdev, ch, path, rs);
}
@@ -2274,13 +2347,13 @@ EXPORT_SYMBOL(rtw_phy_set_tx_power_level);
static void
rtw_phy_tx_power_by_rate_config_by_path(struct rtw_hal *hal, u8 path,
u8 rs, u8 size, u8 *rates)
u8 rs, u8 size, const u8 *rates)
{
u8 rate;
u8 base_idx, rate_idx;
s8 base_2g, base_5g;
if (rs >= RTW_RATE_SECTION_VHT_1S)
if (size == 10) /* VHT rates */
base_idx = rates[size - 3];
else
base_idx = rates[size - 1];
@@ -2297,28 +2370,12 @@ rtw_phy_tx_power_by_rate_config_by_path(struct rtw_hal *hal, u8 path,
void rtw_phy_tx_power_by_rate_config(struct rtw_hal *hal)
{
u8 path;
u8 path, rs;
for (path = 0; path < RTW_RF_PATH_MAX; path++) {
rtw_phy_tx_power_by_rate_config_by_path(hal, path,
RTW_RATE_SECTION_CCK,
rtw_cck_size, rtw_cck_rates);
rtw_phy_tx_power_by_rate_config_by_path(hal, path,
RTW_RATE_SECTION_OFDM,
rtw_ofdm_size, rtw_ofdm_rates);
rtw_phy_tx_power_by_rate_config_by_path(hal, path,
RTW_RATE_SECTION_HT_1S,
rtw_ht_1s_size, rtw_ht_1s_rates);
rtw_phy_tx_power_by_rate_config_by_path(hal, path,
RTW_RATE_SECTION_HT_2S,
rtw_ht_2s_size, rtw_ht_2s_rates);
rtw_phy_tx_power_by_rate_config_by_path(hal, path,
RTW_RATE_SECTION_VHT_1S,
rtw_vht_1s_size, rtw_vht_1s_rates);
rtw_phy_tx_power_by_rate_config_by_path(hal, path,
RTW_RATE_SECTION_VHT_2S,
rtw_vht_2s_size, rtw_vht_2s_rates);
}
for (path = 0; path < RTW_RF_PATH_MAX; path++)
for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++)
rtw_phy_tx_power_by_rate_config_by_path(hal, path, rs,
rtw_rate_size[rs], rtw_rate_section[rs]);
}
static void
@@ -2347,7 +2404,7 @@ void rtw_phy_tx_power_limit_config(struct rtw_hal *hal)
for (regd = 0; regd < RTW_REGD_MAX; regd++)
for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++)
for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++)
for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++)
__rtw_phy_tx_power_limit_config(hal, regd, bw, rs);
}
@@ -2383,7 +2440,7 @@ void rtw_phy_init_tx_power(struct rtw_dev *rtwdev)
/* init tx power limit */
for (regd = 0; regd < RTW_REGD_MAX; regd++)
for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++)
for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++)
for (rs = 0; rs < RTW_RATE_SECTION_NUM; rs++)
rtw_phy_init_tx_power_limit(rtwdev, regd, bw,
rs);
}

View File

@@ -7,14 +7,18 @@
#include "debug.h"
extern u8 rtw_cck_rates[];
extern u8 rtw_ofdm_rates[];
extern u8 rtw_ht_1s_rates[];
extern u8 rtw_ht_2s_rates[];
extern u8 rtw_vht_1s_rates[];
extern u8 rtw_vht_2s_rates[];
extern u8 *rtw_rate_section[];
extern u8 rtw_rate_size[];
extern const u8 rtw_cck_rates[];
extern const u8 rtw_ofdm_rates[];
extern const u8 rtw_ht_1s_rates[];
extern const u8 rtw_ht_2s_rates[];
extern const u8 rtw_vht_1s_rates[];
extern const u8 rtw_vht_2s_rates[];
extern const u8 rtw_ht_3s_rates[];
extern const u8 rtw_ht_4s_rates[];
extern const u8 rtw_vht_3s_rates[];
extern const u8 rtw_vht_4s_rates[];
extern const u8 * const rtw_rate_section[];
extern const u8 rtw_rate_size[];
void rtw_phy_init(struct rtw_dev *rtwdev);
void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev);

View File

@@ -130,6 +130,7 @@
#define BIT_SHIFT_ROM_PGE 16
#define BIT_FW_INIT_RDY BIT(15)
#define BIT_FW_DW_RDY BIT(14)
#define BIT_CPU_CLK_SEL (BIT(12) | BIT(13))
#define BIT_RPWM_TOGGLE BIT(7)
#define BIT_RAM_DL_SEL BIT(7) /* legacy only */
#define BIT_DMEM_CHKSUM_OK BIT(6)
@@ -147,7 +148,7 @@
BIT_CHECK_SUM_OK)
#define FW_READY_LEGACY (BIT_MCUFWDL_RDY | BIT_FWDL_CHK_RPT | \
BIT_WINTINI_RDY | BIT_RAM_DL_SEL)
#define FW_READY_MASK 0xffff
#define FW_READY_MASK (0xffff & ~BIT_CPU_CLK_SEL)
#define REG_MCU_TST_CFG 0x84
#define VAL_FW_TRIGGER 0x1

View File

@@ -444,7 +444,7 @@ static u8 rtw8723d_iqk_check_tx_failed(struct rtw_dev *rtwdev,
rtw_read32(rtwdev, REG_IQK_RES_TX),
rtw_read32(rtwdev, REG_IQK_RES_TY));
rtw_dbg(rtwdev, RTW_DBG_RFK,
"[IQK] 0xe90(before IQK)= 0x%x, 0xe98(afer IQK) = 0x%x\n",
"[IQK] 0xe90(before IQK)= 0x%x, 0xe98(after IQK) = 0x%x\n",
rtw_read32(rtwdev, 0xe90),
rtw_read32(rtwdev, 0xe98));
@@ -472,7 +472,7 @@ static u8 rtw8723d_iqk_check_rx_failed(struct rtw_dev *rtwdev,
rtw_read32(rtwdev, REG_IQK_RES_RY));
rtw_dbg(rtwdev, RTW_DBG_RFK,
"[IQK] 0xea0(before IQK)= 0x%x, 0xea8(afer IQK) = 0x%x\n",
"[IQK] 0xea0(before IQK)= 0x%x, 0xea8(after IQK) = 0x%x\n",
rtw_read32(rtwdev, 0xea0),
rtw_read32(rtwdev, 0xea8));

View File

@@ -680,11 +680,11 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
}
static void
rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path,
u8 rs, u32 *phy_pwr_idx)
{
struct rtw_hal *hal = &rtwdev->hal;
static const u32 offset_txagc[2] = {0x1d00, 0x1d80};
static u32 phy_pwr_idx;
u8 rate, rate_idx, pwr_index, shift;
int j;
@@ -692,12 +692,12 @@ rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
rate = rtw_rate_section[rs][j];
pwr_index = hal->tx_pwr_tbl[path][rate];
shift = rate & 0x3;
phy_pwr_idx |= ((u32)pwr_index << (shift * 8));
*phy_pwr_idx |= ((u32)pwr_index << (shift * 8));
if (shift == 0x3 || rate == DESC_RATEVHT1SS_MCS9) {
rate_idx = rate & 0xfc;
rtw_write32(rtwdev, offset_txagc[path] + rate_idx,
phy_pwr_idx);
phy_pwr_idx = 0;
*phy_pwr_idx);
*phy_pwr_idx = 0;
}
}
}
@@ -705,14 +705,16 @@ rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
static void rtw8821c_set_tx_power_index(struct rtw_dev *rtwdev)
{
struct rtw_hal *hal = &rtwdev->hal;
u32 phy_pwr_idx = 0;
int rs, path;
for (path = 0; path < hal->rf_path_num; path++) {
for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) {
for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) {
if (rs == RTW_RATE_SECTION_HT_2S ||
rs == RTW_RATE_SECTION_VHT_2S)
continue;
rtw8821c_set_tx_power_index_by_rate(rtwdev, path, rs);
rtw8821c_set_tx_power_index_by_rate(rtwdev, path, rs,
&phy_pwr_idx);
}
}
}

View File

@@ -935,11 +935,11 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
}
static void
rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path,
u8 rs, u32 *phy_pwr_idx)
{
struct rtw_hal *hal = &rtwdev->hal;
static const u32 offset_txagc[2] = {0x1d00, 0x1d80};
static u32 phy_pwr_idx;
u8 rate, rate_idx, pwr_index, shift;
int j;
@@ -947,12 +947,12 @@ rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
rate = rtw_rate_section[rs][j];
pwr_index = hal->tx_pwr_tbl[path][rate];
shift = rate & 0x3;
phy_pwr_idx |= ((u32)pwr_index << (shift * 8));
*phy_pwr_idx |= ((u32)pwr_index << (shift * 8));
if (shift == 0x3) {
rate_idx = rate & 0xfc;
rtw_write32(rtwdev, offset_txagc[path] + rate_idx,
phy_pwr_idx);
phy_pwr_idx = 0;
*phy_pwr_idx);
*phy_pwr_idx = 0;
}
}
}
@@ -960,11 +960,13 @@ rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
static void rtw8822b_set_tx_power_index(struct rtw_dev *rtwdev)
{
struct rtw_hal *hal = &rtwdev->hal;
u32 phy_pwr_idx = 0;
int rs, path;
for (path = 0; path < hal->rf_path_num; path++) {
for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++)
rtw8822b_set_tx_power_index_by_rate(rtwdev, path, rs);
for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++)
rtw8822b_set_tx_power_index_by_rate(rtwdev, path, rs,
&phy_pwr_idx);
}
}

View File

@@ -2746,7 +2746,7 @@ static void rtw8822c_set_tx_power_index(struct rtw_dev *rtwdev)
s8 diff_idx[4];
rtw8822c_set_write_tx_power_ref(rtwdev, pwr_ref_cck, pwr_ref_ofdm);
for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) {
for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) {
for (j = 0; j < rtw_rate_size[rs]; j++) {
rate = rtw_rate_section[rs][j];
pwr_a = hal->tx_pwr_tbl[RF_PATH_A][rate];

View File

@@ -1637,7 +1637,7 @@ void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev)
int rs, path;
for (path = 0; path < hal->rf_path_num; path++) {
for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) {
for (rs = 0; rs <= __RTW_RATE_SECTION_2SS_MAX; rs++) {
if (hal->rf_path_num == 1 &&
(rs == RTW_RATE_SECTION_HT_2S ||
rs == RTW_RATE_SECTION_VHT_2S))

View File

@@ -97,7 +97,7 @@ int rtw_set_sar_specs(struct rtw_dev *rtwdev,
power, BIT(RTW_COMMON_SAR_FCT));
for (j = 0; j < RTW_RF_PATH_MAX; j++) {
for (k = 0; k < RTW_RATE_SECTION_MAX; k++) {
for (k = 0; k < RTW_RATE_SECTION_NUM; k++) {
arg = (struct rtw_sar_arg){
.sar_band = idx,
.path = j,

View File

@@ -1147,7 +1147,7 @@ static void rtw_sdio_declaim(struct rtw_dev *rtwdev,
sdio_release_host(sdio_func);
}
static struct rtw_hci_ops rtw_sdio_ops = {
static const struct rtw_hci_ops rtw_sdio_ops = {
.tx_write = rtw_sdio_tx_write,
.tx_kick_off = rtw_sdio_tx_kick_off,
.setup = rtw_sdio_setup,

View File

@@ -881,7 +881,7 @@ static void rtw_usb_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable)
}
}
static struct rtw_hci_ops rtw_usb_ops = {
static const struct rtw_hci_ops rtw_usb_ops = {
.tx_write = rtw_usb_tx_write,
.tx_kick_off = rtw_usb_tx_kick_off,
.setup = rtw_usb_setup,

View File

@@ -123,7 +123,7 @@ config RTW89_DEBUGMSG
config RTW89_DEBUGFS
bool "Realtek rtw89 debugfs support"
depends on RTW89_CORE
depends on RTW89_CORE && CFG80211_DEBUGFS
select RTW89_DEBUG
help
Enable debugfs support

View File

@@ -155,7 +155,7 @@ int rtw89_iterate_entity_chan(struct rtw89_dev *rtwdev,
int ret;
u8 idx;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
for_each_set_bit(idx, hal->entity_map, NUM_OF_RTW89_CHANCTX) {
chan = rtw89_chan_get(rtwdev, idx);
@@ -310,7 +310,7 @@ const struct rtw89_chan *__rtw89_mgnt_chan_get(struct rtw89_dev *rtwdev,
enum rtw89_entity_mode mode;
u8 role_index;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (unlikely(link_index >= __RTW89_MLD_MAX_LINK_NUM)) {
WARN(1, "link index %u is invalid (max link inst num: %d)\n",
@@ -366,7 +366,7 @@ static void rtw89_entity_recalc_mgnt_roles(struct rtw89_dev *rtwdev)
u8 pos = 0;
int i, j;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
for (i = 0; i < RTW89_MAX_INTERFACE_NUM; i++)
mgnt->active_roles[i] = NULL;
@@ -427,7 +427,7 @@ enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
struct rtw89_chan chan;
u8 idx;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
bitmap_copy(recalc_map, hal->entity_map, NUM_OF_RTW89_CHANCTX);
@@ -2390,7 +2390,7 @@ static void rtw89_mcc_update_limit(struct rtw89_dev *rtwdev)
rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_upd_lmt_iterator, NULL);
}
void rtw89_chanctx_work(struct work_struct *work)
void rtw89_chanctx_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
chanctx_work.work);
@@ -2401,12 +2401,10 @@ void rtw89_chanctx_work(struct work_struct *work)
int ret;
int i;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(wiphy);
if (hal->entity_pause) {
mutex_unlock(&rtwdev->mutex);
if (hal->entity_pause)
return;
}
for (i = 0; i < NUM_OF_RTW89_CHANCTX_CHANGES; i++) {
if (test_and_clear_bit(i, hal->changes))
@@ -2445,8 +2443,6 @@ void rtw89_chanctx_work(struct work_struct *work)
default:
break;
}
mutex_unlock(&rtwdev->mutex);
}
void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
@@ -2477,8 +2473,8 @@ void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"queue chanctx work for mode %d with delay %d us\n",
mode, delay);
ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->chanctx_work,
usecs_to_jiffies(delay));
wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->chanctx_work,
usecs_to_jiffies(delay));
}
void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev)
@@ -2491,7 +2487,7 @@ void rtw89_chanctx_track(struct rtw89_dev *rtwdev)
struct rtw89_hal *hal = &rtwdev->hal;
enum rtw89_entity_mode mode;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (hal->entity_pause)
return;
@@ -2512,7 +2508,7 @@ void rtw89_chanctx_pause(struct rtw89_dev *rtwdev,
struct rtw89_hal *hal = &rtwdev->hal;
enum rtw89_entity_mode mode;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (hal->entity_pause)
return;
@@ -2555,7 +2551,7 @@ void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev,
enum rtw89_entity_mode mode;
int ret;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (unlikely(!hal->entity_pause)) {
rtw89_chanctx_proceed_cb(rtwdev, cb_parm);

View File

@@ -99,7 +99,7 @@ void rtw89_config_roc_chandef(struct rtw89_dev *rtwdev,
const struct cfg80211_chan_def *chandef);
void rtw89_entity_init(struct rtw89_dev *rtwdev);
enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev);
void rtw89_chanctx_work(struct work_struct *work);
void rtw89_chanctx_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_queue_chanctx_work(struct rtw89_dev *rtwdev);
void rtw89_queue_chanctx_change(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_changes change);

File diff suppressed because it is too large Load Diff

View File

@@ -267,10 +267,10 @@ void rtw89_btc_ntfy_scan_finish(struct rtw89_dev *rtwdev, u8 phy_idx);
void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band);
void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev,
enum btc_pkt_type pkt_type);
void rtw89_btc_ntfy_eapol_packet_work(struct work_struct *work);
void rtw89_btc_ntfy_arp_packet_work(struct work_struct *work);
void rtw89_btc_ntfy_dhcp_packet_work(struct work_struct *work);
void rtw89_btc_ntfy_icmp_packet_work(struct work_struct *work);
void rtw89_btc_ntfy_eapol_packet_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_btc_ntfy_arp_packet_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_btc_ntfy_dhcp_packet_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_btc_ntfy_icmp_packet_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
@@ -282,14 +282,16 @@ void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map,
void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev);
void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u32 len, u8 class, u8 func);
void rtw89_btc_dump_info(struct rtw89_dev *rtwdev, struct seq_file *m);
void rtw89_coex_act1_work(struct work_struct *work);
void rtw89_coex_bt_devinfo_work(struct work_struct *work);
void rtw89_coex_rfk_chk_work(struct work_struct *work);
ssize_t rtw89_btc_dump_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz);
void rtw89_coex_act1_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_coex_bt_devinfo_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_coex_rfk_chk_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_coex_power_on(struct rtw89_dev *rtwdev);
void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type);
void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type);
void rtw89_coex_recognize_ver(struct rtw89_dev *rtwdev);
void rtw89_btc_ntfy_preserve_bt_time(struct rtw89_dev *rtwdev, u32 ms);
void rtw89_btc_ntfy_conn_rfk(struct rtw89_dev *rtwdev, bool state);
static inline u8 rtw89_btc_phymap(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,

View File

@@ -913,16 +913,17 @@ static enum btc_pkt_type
rtw89_core_tx_btc_spec_pkt_notify(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
struct wiphy *wiphy = rtwdev->hw->wiphy;
struct sk_buff *skb = tx_req->skb;
struct udphdr *udphdr;
if (IEEE80211_SKB_CB(skb)->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO) {
ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.eapol_notify_work);
wiphy_work_queue(wiphy, &rtwdev->btc.eapol_notify_work);
return PACKET_EAPOL;
}
if (skb->protocol == htons(ETH_P_ARP)) {
ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.arp_notify_work);
wiphy_work_queue(wiphy, &rtwdev->btc.arp_notify_work);
return PACKET_ARP;
}
@@ -932,14 +933,14 @@ rtw89_core_tx_btc_spec_pkt_notify(struct rtw89_dev *rtwdev,
if (((udphdr->source == htons(67) && udphdr->dest == htons(68)) ||
(udphdr->source == htons(68) && udphdr->dest == htons(67))) &&
skb->len > 282) {
ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.dhcp_notify_work);
wiphy_work_queue(wiphy, &rtwdev->btc.dhcp_notify_work);
return PACKET_DHCP;
}
}
if (skb->protocol == htons(ETH_P_IP) &&
ip_hdr(skb)->protocol == IPPROTO_ICMP) {
ieee80211_queue_work(rtwdev->hw, &rtwdev->btc.icmp_notify_work);
wiphy_work_queue(wiphy, &rtwdev->btc.icmp_notify_work);
return PACKET_ICMP;
}
@@ -2071,17 +2072,17 @@ static void rtw89_stats_trigger_frame(struct rtw89_dev *rtwdev,
}
}
static void rtw89_cancel_6ghz_probe_work(struct work_struct *work)
static void rtw89_cancel_6ghz_probe_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
cancel_6ghz_probe_work);
struct list_head *pkt_list = rtwdev->scan_info.pkt_list;
struct rtw89_pktofld_info *info;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(wiphy);
if (!rtwdev->scanning)
goto out;
return;
list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) {
if (!info->cancel || !test_bit(info->id, rtwdev->pkt_offload))
@@ -2094,9 +2095,6 @@ static void rtw89_cancel_6ghz_probe_work(struct work_struct *work)
* since if during scanning, pkt_list is accessed in bottom half.
*/
}
out:
mutex_unlock(&rtwdev->mutex);
}
static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev,
@@ -2131,7 +2129,7 @@ static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev,
}
if (queue_work)
ieee80211_queue_work(rtwdev->hw, &rtwdev->cancel_6ghz_probe_work);
wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->cancel_6ghz_probe_work);
}
static void rtw89_vif_sync_bcn_tsf(struct rtw89_vif_link *rtwvif_link,
@@ -2194,8 +2192,11 @@ static void rtw89_vif_rx_stats_iter(void *data, u8 *mac,
}
pkt_stat->beacon_nr++;
if (phy_ppdu)
if (phy_ppdu) {
ewma_rssi_add(&rtwdev->phystat.bcn_rssi, phy_ppdu->rssi_avg);
if (!test_bit(RTW89_FLAG_LOW_POWER_MODE, rtwdev->flags))
rtwvif_link->bcn_bw_idx = phy_ppdu->bw_idx;
}
pkt_stat->beacon_rate = desc_info->data_rate;
}
@@ -3143,13 +3144,14 @@ static void rtw89_core_txq_schedule(struct rtw89_dev *rtwdev, u8 ac, bool *reinv
ieee80211_txq_schedule_end(hw, ac);
}
static void rtw89_ips_work(struct work_struct *work)
static void rtw89_ips_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
ips_work);
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(wiphy);
rtw89_enter_ips_by_hwflags(rtwdev);
mutex_unlock(&rtwdev->mutex);
}
static void rtw89_core_txq_work(struct work_struct *w)
@@ -3291,7 +3293,7 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
u32 reg;
int ret;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtw89_leave_ips_by_hwflags(rtwdev);
rtw89_leave_lps(rtwdev);
@@ -3330,9 +3332,9 @@ void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
rtw89_write32_clr(rtwdev, reg, B_AX_A_UC_CAM_MATCH | B_AX_A_BC_CAM_MATCH);
ieee80211_ready_on_channel(hw);
cancel_delayed_work(&rtwvif->roc.roc_work);
ieee80211_queue_delayed_work(hw, &rtwvif->roc.roc_work,
msecs_to_jiffies(rtwvif->roc.duration));
wiphy_delayed_work_cancel(hw->wiphy, &rtwvif->roc.roc_work);
wiphy_delayed_work_queue(hw->wiphy, &rtwvif->roc.roc_work,
msecs_to_jiffies(rtwvif->roc.duration));
}
void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
@@ -3345,7 +3347,7 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
u32 reg;
int ret;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
ieee80211_remain_on_channel_expired(hw);
@@ -3377,18 +3379,18 @@ void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
queue_work(rtwdev->txq_wq, &rtwdev->txq_work);
if (hw->conf.flags & IEEE80211_CONF_IDLE)
ieee80211_queue_delayed_work(hw, &roc->roc_work,
msecs_to_jiffies(RTW89_ROC_IDLE_TIMEOUT));
wiphy_delayed_work_queue(hw->wiphy, &roc->roc_work,
msecs_to_jiffies(RTW89_ROC_IDLE_TIMEOUT));
}
void rtw89_roc_work(struct work_struct *work)
void rtw89_roc_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif,
roc.roc_work.work);
struct rtw89_dev *rtwdev = rtwvif->rtwdev;
struct rtw89_roc *roc = &rtwvif->roc;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(wiphy);
switch (roc->state) {
case RTW89_ROC_IDLE:
@@ -3401,8 +3403,6 @@ void rtw89_roc_work(struct work_struct *work)
default:
break;
}
mutex_unlock(&rtwdev->mutex);
}
static enum rtw89_tfc_lv rtw89_get_traffic_level(struct rtw89_dev *rtwdev,
@@ -3533,26 +3533,26 @@ void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev,
ewma_tp_init(&stats->rx_ewma_tp);
}
static void rtw89_track_work(struct work_struct *work)
static void rtw89_track_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
track_work.work);
bool tfc_changed;
lockdep_assert_wiphy(wiphy);
if (test_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags))
return;
mutex_lock(&rtwdev->mutex);
if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
goto out;
return;
ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work,
RTW89_TRACK_WORK_PERIOD);
wiphy_delayed_work_queue(wiphy, &rtwdev->track_work,
RTW89_TRACK_WORK_PERIOD);
tfc_changed = rtw89_traffic_stats_track(rtwdev);
if (rtwdev->scanning)
goto out;
return;
rtw89_leave_lps(rtwdev);
@@ -3577,9 +3577,6 @@ static void rtw89_track_work(struct work_struct *work)
if (rtwdev->lps_enabled && !rtwdev->btc.lps)
rtw89_enter_lps_track(rtwdev);
out:
mutex_unlock(&rtwdev->mutex);
}
u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size)
@@ -3613,7 +3610,7 @@ int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
u8 idx;
int i;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
idx = rtw89_core_acquire_bit_map(cam_info->ba_cam_map, chip->bacam_num);
if (idx == chip->bacam_num) {
@@ -3657,7 +3654,7 @@ int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
struct rtw89_ba_cam_entry *entry = NULL, *tmp;
u8 idx;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
list_for_each_entry_safe(entry, tmp, &rtwsta_link->ba_cam_list, list) {
if (entry->tid != tid)
@@ -4432,26 +4429,26 @@ static void rtw89_core_ppdu_sts_init(struct rtw89_dev *rtwdev)
{
int i;
for (i = 0; i < RTW89_PHY_MAX; i++)
for (i = 0; i < RTW89_PHY_NUM; i++)
skb_queue_head_init(&rtwdev->ppdu_sts.rx_queue[i]);
for (i = 0; i < RTW89_PHY_MAX; i++)
for (i = 0; i < RTW89_PHY_NUM; i++)
rtwdev->ppdu_sts.curr_rx_ppdu_cnt[i] = U8_MAX;
}
void rtw89_core_update_beacon_work(struct work_struct *work)
void rtw89_core_update_beacon_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev;
struct rtw89_vif_link *rtwvif_link = container_of(work, struct rtw89_vif_link,
update_beacon_work);
lockdep_assert_wiphy(wiphy);
if (rtwvif_link->net_type != RTW89_NET_TYPE_AP_MODE)
return;
rtwdev = rtwvif_link->rtwvif->rtwdev;
mutex_lock(&rtwdev->mutex);
rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link);
mutex_unlock(&rtwdev->mutex);
}
int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond)
@@ -4568,8 +4565,8 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
return ret;
}
ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work,
RTW89_TRACK_WORK_PERIOD);
wiphy_delayed_work_queue(rtwdev->hw->wiphy, &rtwdev->track_work,
RTW89_TRACK_WORK_PERIOD);
set_bit(RTW89_FLAG_RUNNING, rtwdev->flags);
@@ -4583,8 +4580,11 @@ int rtw89_core_start(struct rtw89_dev *rtwdev)
void rtw89_core_stop(struct rtw89_dev *rtwdev)
{
struct wiphy *wiphy = rtwdev->hw->wiphy;
struct rtw89_btc *btc = &rtwdev->btc;
lockdep_assert_wiphy(wiphy);
/* Prvent to stop twice; enter_ips and ops_stop */
if (!test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
return;
@@ -4593,25 +4593,21 @@ void rtw89_core_stop(struct rtw89_dev *rtwdev)
clear_bit(RTW89_FLAG_RUNNING, rtwdev->flags);
mutex_unlock(&rtwdev->mutex);
cancel_work_sync(&rtwdev->c2h_work);
cancel_work_sync(&rtwdev->cancel_6ghz_probe_work);
cancel_work_sync(&btc->eapol_notify_work);
cancel_work_sync(&btc->arp_notify_work);
cancel_work_sync(&btc->dhcp_notify_work);
cancel_work_sync(&btc->icmp_notify_work);
wiphy_work_cancel(wiphy, &rtwdev->c2h_work);
wiphy_work_cancel(wiphy, &rtwdev->cancel_6ghz_probe_work);
wiphy_work_cancel(wiphy, &btc->eapol_notify_work);
wiphy_work_cancel(wiphy, &btc->arp_notify_work);
wiphy_work_cancel(wiphy, &btc->dhcp_notify_work);
wiphy_work_cancel(wiphy, &btc->icmp_notify_work);
cancel_delayed_work_sync(&rtwdev->txq_reinvoke_work);
cancel_delayed_work_sync(&rtwdev->track_work);
cancel_delayed_work_sync(&rtwdev->chanctx_work);
cancel_delayed_work_sync(&rtwdev->coex_act1_work);
cancel_delayed_work_sync(&rtwdev->coex_bt_devinfo_work);
cancel_delayed_work_sync(&rtwdev->coex_rfk_chk_work);
cancel_delayed_work_sync(&rtwdev->cfo_track_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->track_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->chanctx_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_act1_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_bt_devinfo_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->coex_rfk_chk_work);
wiphy_delayed_work_cancel(wiphy, &rtwdev->cfo_track_work);
cancel_delayed_work_sync(&rtwdev->forbid_ba_work);
cancel_delayed_work_sync(&rtwdev->antdiv_work);
mutex_lock(&rtwdev->mutex);
wiphy_delayed_work_cancel(wiphy, &rtwdev->antdiv_work);
rtw89_btc_ntfy_poweroff(rtwdev);
rtw89_hci_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1, true);
@@ -4825,20 +4821,19 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
INIT_WORK(&rtwdev->ba_work, rtw89_core_ba_work);
INIT_WORK(&rtwdev->txq_work, rtw89_core_txq_work);
INIT_DELAYED_WORK(&rtwdev->txq_reinvoke_work, rtw89_core_txq_reinvoke_work);
INIT_DELAYED_WORK(&rtwdev->track_work, rtw89_track_work);
INIT_DELAYED_WORK(&rtwdev->chanctx_work, rtw89_chanctx_work);
INIT_DELAYED_WORK(&rtwdev->coex_act1_work, rtw89_coex_act1_work);
INIT_DELAYED_WORK(&rtwdev->coex_bt_devinfo_work, rtw89_coex_bt_devinfo_work);
INIT_DELAYED_WORK(&rtwdev->coex_rfk_chk_work, rtw89_coex_rfk_chk_work);
INIT_DELAYED_WORK(&rtwdev->cfo_track_work, rtw89_phy_cfo_track_work);
wiphy_delayed_work_init(&rtwdev->track_work, rtw89_track_work);
wiphy_delayed_work_init(&rtwdev->chanctx_work, rtw89_chanctx_work);
wiphy_delayed_work_init(&rtwdev->coex_act1_work, rtw89_coex_act1_work);
wiphy_delayed_work_init(&rtwdev->coex_bt_devinfo_work, rtw89_coex_bt_devinfo_work);
wiphy_delayed_work_init(&rtwdev->coex_rfk_chk_work, rtw89_coex_rfk_chk_work);
wiphy_delayed_work_init(&rtwdev->cfo_track_work, rtw89_phy_cfo_track_work);
INIT_DELAYED_WORK(&rtwdev->forbid_ba_work, rtw89_forbid_ba_work);
INIT_DELAYED_WORK(&rtwdev->antdiv_work, rtw89_phy_antdiv_work);
wiphy_delayed_work_init(&rtwdev->antdiv_work, rtw89_phy_antdiv_work);
rtwdev->txq_wq = alloc_workqueue("rtw89_tx_wq", WQ_UNBOUND | WQ_HIGHPRI, 0);
if (!rtwdev->txq_wq)
return -ENOMEM;
spin_lock_init(&rtwdev->ba_lock);
spin_lock_init(&rtwdev->rpwm_lock);
mutex_init(&rtwdev->mutex);
mutex_init(&rtwdev->rf_mutex);
rtwdev->total_sta_assoc = 0;
@@ -4847,10 +4842,10 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
rtw89_init_wait(&rtwdev->wow.wait);
rtw89_init_wait(&rtwdev->mac.ps_wait);
INIT_WORK(&rtwdev->c2h_work, rtw89_fw_c2h_work);
INIT_WORK(&rtwdev->ips_work, rtw89_ips_work);
wiphy_work_init(&rtwdev->c2h_work, rtw89_fw_c2h_work);
wiphy_work_init(&rtwdev->ips_work, rtw89_ips_work);
wiphy_work_init(&rtwdev->cancel_6ghz_probe_work, rtw89_cancel_6ghz_probe_work);
INIT_WORK(&rtwdev->load_firmware_work, rtw89_load_firmware_work);
INIT_WORK(&rtwdev->cancel_6ghz_probe_work, rtw89_cancel_6ghz_probe_work);
skb_queue_head_init(&rtwdev->c2h_queue);
rtw89_core_ppdu_sts_init(rtwdev);
@@ -4867,10 +4862,13 @@ int rtw89_core_init(struct rtw89_dev *rtwdev)
rtwdev->mlo_dbcc_mode = MLO_2_PLUS_0_1RF;
}
INIT_WORK(&btc->eapol_notify_work, rtw89_btc_ntfy_eapol_packet_work);
INIT_WORK(&btc->arp_notify_work, rtw89_btc_ntfy_arp_packet_work);
INIT_WORK(&btc->dhcp_notify_work, rtw89_btc_ntfy_dhcp_packet_work);
INIT_WORK(&btc->icmp_notify_work, rtw89_btc_ntfy_icmp_packet_work);
rtwdev->bbs[RTW89_PHY_0].phy_idx = RTW89_PHY_0;
rtwdev->bbs[RTW89_PHY_1].phy_idx = RTW89_PHY_1;
wiphy_work_init(&btc->eapol_notify_work, rtw89_btc_ntfy_eapol_packet_work);
wiphy_work_init(&btc->arp_notify_work, rtw89_btc_ntfy_arp_packet_work);
wiphy_work_init(&btc->dhcp_notify_work, rtw89_btc_ntfy_dhcp_packet_work);
wiphy_work_init(&btc->icmp_notify_work, rtw89_btc_ntfy_icmp_packet_work);
init_completion(&rtwdev->fw.req.completion);
init_completion(&rtwdev->rfk_wait.completion);
@@ -4890,11 +4888,10 @@ void rtw89_core_deinit(struct rtw89_dev *rtwdev)
{
rtw89_ser_deinit(rtwdev);
rtw89_unload_firmware(rtwdev);
rtw89_fw_free_all_early_h2c(rtwdev);
__rtw89_fw_free_all_early_h2c(rtwdev);
destroy_workqueue(rtwdev->txq_wq);
mutex_destroy(&rtwdev->rf_mutex);
mutex_destroy(&rtwdev->mutex);
}
EXPORT_SYMBOL(rtw89_core_deinit);
@@ -4903,6 +4900,7 @@ void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwv
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
rtwvif_link->chanctx_idx);
struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx);
rtwdev->scanning = true;
rtw89_leave_lps(rtwdev);
@@ -4913,7 +4911,7 @@ void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwv
rtw89_btc_ntfy_scan_start(rtwdev, rtwvif_link->phy_idx, chan->band_type);
rtw89_chip_rfk_scan(rtwdev, rtwvif_link, true);
rtw89_hci_recalc_int_mit(rtwdev);
rtw89_phy_config_edcca(rtwdev, true);
rtw89_phy_config_edcca(rtwdev, bb, true);
rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, mac_addr);
}
@@ -4922,6 +4920,7 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link, bool hw_scan)
{
struct ieee80211_bss_conf *bss_conf;
struct rtw89_bb_ctx *bb;
if (!rtwvif_link)
return;
@@ -4937,12 +4936,14 @@ void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
rtw89_chip_rfk_scan(rtwdev, rtwvif_link, false);
rtw89_btc_ntfy_scan_finish(rtwdev, rtwvif_link->phy_idx);
rtw89_phy_config_edcca(rtwdev, false);
bb = rtw89_get_bb_ctx(rtwdev, rtwvif_link->phy_idx);
rtw89_phy_config_edcca(rtwdev, bb, false);
rtwdev->scanning = false;
rtwdev->dig.bypass_dig = true;
rtw89_for_each_active_bb(rtwdev, bb)
bb->dig.bypass_dig = true;
if (hw_scan && (rtwdev->hw->conf.flags & IEEE80211_CONF_IDLE))
ieee80211_queue_work(rtwdev->hw, &rtwdev->ips_work);
wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->ips_work);
}
static void rtw89_read_chip_ver(struct rtw89_dev *rtwdev)
@@ -5042,8 +5043,6 @@ static int rtw89_chip_efuse_info_setup(struct rtw89_dev *rtwdev)
rtw89_hci_mac_pre_deinit(rtwdev);
rtw89_mac_pwr_off(rtwdev);
return 0;
}
@@ -5124,36 +5123,45 @@ int rtw89_chip_info_setup(struct rtw89_dev *rtwdev)
rtw89_read_chip_ver(rtwdev);
ret = rtw89_mac_pwr_on(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to power on\n");
return ret;
}
ret = rtw89_wait_firmware_completion(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to wait firmware completion\n");
return ret;
goto out;
}
ret = rtw89_fw_recognize(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to recognize firmware\n");
return ret;
goto out;
}
ret = rtw89_chip_efuse_info_setup(rtwdev);
if (ret)
return ret;
goto out;
ret = rtw89_fw_recognize_elements(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to recognize firmware elements\n");
return ret;
goto out;
}
ret = rtw89_chip_board_info_setup(rtwdev);
if (ret)
return ret;
goto out;
rtw89_core_setup_rfe_parms(rtwdev);
rtwdev->ps_mode = rtw89_update_ps_mode(rtwdev);
return 0;
out:
rtw89_mac_pwr_off(rtwdev);
return ret;
}
EXPORT_SYMBOL(rtw89_chip_info_setup);
@@ -5296,7 +5304,7 @@ static int rtw89_core_register_hw(struct rtw89_dev *rtwdev)
goto err_free_supported_band;
}
ret = rtw89_regd_init(rtwdev, rtw89_regd_notifier);
ret = rtw89_regd_init_hint(rtwdev);
if (ret) {
rtw89_err(rtwdev, "failed to init regd\n");
goto err_unregister_hw;

View File

@@ -22,6 +22,7 @@ struct rtw89_h2c_rf_tssi;
struct rtw89_fw_txpwr_track_cfg;
struct rtw89_phy_rfk_log_fmt;
struct rtw89_debugfs;
struct rtw89_regd_data;
extern const struct ieee80211_ops rtw89_ops;
@@ -718,6 +719,7 @@ enum rtw89_ofdma_type {
RTW89_OFDMA_NUM,
};
/* neither insert new in the middle, nor change any given definition */
enum rtw89_regulation_type {
RTW89_WW = 0,
RTW89_ETSI = 1,
@@ -826,7 +828,7 @@ enum rtw89_mac_idx {
enum rtw89_phy_idx {
RTW89_PHY_0 = 0,
RTW89_PHY_1 = 1,
RTW89_PHY_MAX
RTW89_PHY_NUM,
};
#define __RTW89_MLD_MAX_LINK_NUM 2
@@ -1540,16 +1542,16 @@ struct rtw89_btc_u8_sta_chg {
};
struct rtw89_btc_wl_scan_info {
u8 band[RTW89_PHY_MAX];
u8 band[RTW89_PHY_NUM];
u8 phy_map;
u8 rsvd;
};
struct rtw89_btc_wl_dbcc_info {
u8 op_band[RTW89_PHY_MAX]; /* op band in each phy */
u8 scan_band[RTW89_PHY_MAX]; /* scan band in each phy */
u8 real_band[RTW89_PHY_MAX];
u8 role[RTW89_PHY_MAX]; /* role in each phy */
u8 op_band[RTW89_PHY_NUM]; /* op band in each phy */
u8 scan_band[RTW89_PHY_NUM]; /* scan band in each phy */
u8 real_band[RTW89_PHY_NUM];
u8 role[RTW89_PHY_NUM]; /* role in each phy */
};
struct rtw89_btc_wl_active_role {
@@ -1761,7 +1763,8 @@ struct rtw89_btc_wl_rfk_info {
u32 phy_map: 2;
u32 band: 2;
u32 type: 8;
u32 rsvd: 14;
u32 con_rfk: 1;
u32 rsvd: 13;
u32 start_time;
u32 proc_time;
@@ -1898,7 +1901,7 @@ struct rtw89_btc_wl_info {
u8 cn_report;
u8 coex_mode;
u8 pta_req_mac;
u8 bt_polut_type[RTW89_PHY_MAX]; /* BT polluted WL-Tx type for phy0/1 */
u8 bt_polut_type[RTW89_PHY_NUM]; /* BT polluted WL-Tx type for phy0/1 */
bool is_5g_hi_channel;
bool pta_reg_mac_chg;
@@ -2230,7 +2233,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_v4 {
struct rtw89_btc_fbtc_rpt_ctrl_wl_fw_info wl_fw_info;
struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info;
__le32 bt_cnt[BTC_BCNT_STA_MAX];
struct rtw89_mac_ax_gnt gnt_val[RTW89_PHY_MAX];
struct rtw89_mac_ax_gnt gnt_val[RTW89_PHY_NUM];
} __packed;
struct rtw89_btc_fbtc_rpt_ctrl_v5 {
@@ -2238,7 +2241,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_v5 {
u8 rsvd;
__le16 rsvd1;
u8 gnt_val[RTW89_PHY_MAX][4];
u8 gnt_val[RTW89_PHY_NUM][4];
__le16 bt_cnt[BTC_BCNT_STA_MAX];
struct rtw89_btc_fbtc_rpt_ctrl_info_v5 rpt_info;
@@ -2250,7 +2253,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_v105 {
u8 rsvd;
__le16 rsvd1;
u8 gnt_val[RTW89_PHY_MAX][4];
u8 gnt_val[RTW89_PHY_NUM][4];
__le16 bt_cnt[BTC_BCNT_STA_MAX_V105];
struct rtw89_btc_fbtc_rpt_ctrl_info_v5 rpt_info;
@@ -2263,7 +2266,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_v7 {
u8 rsvd1;
u8 rsvd2;
u8 gnt_val[RTW89_PHY_MAX][4];
u8 gnt_val[RTW89_PHY_NUM][4];
__le16 bt_cnt[BTC_BCNT_STA_MAX_V105];
struct rtw89_btc_fbtc_rpt_ctrl_info_v8 rpt_info;
@@ -2276,7 +2279,7 @@ struct rtw89_btc_fbtc_rpt_ctrl_v8 {
u8 rpt_len_max_l; /* BTC_RPT_MAX bit0~7 */
u8 rpt_len_max_h; /* BTC_RPT_MAX bit8~15 */
u8 gnt_val[RTW89_PHY_MAX][4];
u8 gnt_val[RTW89_PHY_NUM][4];
__le16 bt_cnt[BTC_BCNT_STA_MAX_V105];
struct rtw89_btc_fbtc_rpt_ctrl_info_v8 rpt_info;
@@ -3174,10 +3177,10 @@ struct rtw89_btc {
struct rtw89_btc_btf_fwinfo fwinfo;
struct rtw89_btc_dbg dbg;
struct work_struct eapol_notify_work;
struct work_struct arp_notify_work;
struct work_struct dhcp_notify_work;
struct work_struct icmp_notify_work;
struct wiphy_work eapol_notify_work;
struct wiphy_work arp_notify_work;
struct wiphy_work dhcp_notify_work;
struct wiphy_work icmp_notify_work;
u32 bt_req_len;
@@ -3444,7 +3447,7 @@ enum rtw89_roc_state {
struct rtw89_roc {
struct ieee80211_channel chan;
struct delayed_work roc_work;
struct wiphy_delayed_work roc_work;
enum ieee80211_roc_type type;
enum rtw89_roc_state state;
int duration;
@@ -3498,6 +3501,7 @@ struct rtw89_vif_link {
u8 self_role;
u8 wmm;
u8 bcn_hit_cond;
u8 bcn_bw_idx;
u8 hit_rule;
u8 last_noa_nr;
u64 sync_bcn_tsf;
@@ -3514,7 +3518,7 @@ struct rtw89_vif_link {
bool pre_pwr_diff_en;
bool pwr_diff_en;
u8 def_tri_idx;
struct work_struct update_beacon_work;
struct wiphy_work update_beacon_work;
struct rtw89_addr_cam_entry addr_cam;
struct rtw89_bssid_cam_entry bssid_cam;
struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS];
@@ -4189,10 +4193,12 @@ struct rtw89_edcca_regs {
u32 edcca_p_mask;
u32 ppdu_level;
u32 ppdu_mask;
u32 rpt_a;
u32 rpt_b;
u32 rpt_sel;
u32 rpt_sel_mask;
struct rtw89_edcca_p_regs {
u32 rpt_a;
u32 rpt_b;
u32 rpt_sel;
u32 rpt_sel_mask;
} p[RTW89_PHY_NUM];
u32 rpt_sel_be;
u32 rpt_sel_be_mask;
u32 tx_collision_t2r_st;
@@ -4536,6 +4542,7 @@ struct rtw89_fw_elm_info {
struct rtw89_phy_table *rf_nctl;
struct rtw89_fw_txpwr_track_cfg *txpwr_trk;
struct rtw89_phy_rfk_log_fmt *rfk_log_fmt;
const struct rtw89_regd_data *regd;
};
enum rtw89_fw_mss_dev_type {
@@ -4762,12 +4769,11 @@ struct rtw89_hal {
struct rtw89_chanctx chanctx[NUM_OF_RTW89_CHANCTX];
struct cfg80211_chan_def roc_chandef;
bool entity_active[RTW89_PHY_MAX];
bool entity_active[RTW89_PHY_NUM];
bool entity_pause;
enum rtw89_entity_mode entity_mode;
struct rtw89_entity_mgnt entity_mgnt;
struct rtw89_edcca_bak edcca_bak;
u32 disabled_dm_bitmap; /* bitmap of enum rtw89_dm_type */
u8 thermal_prot_th;
@@ -4973,7 +4979,7 @@ struct rtw89_dpk_bkup_para {
struct rtw89_dpk_info {
bool is_dpk_enable;
bool is_dpk_reload_en;
u8 dpk_gs[RTW89_PHY_MAX];
u8 dpk_gs[RTW89_PHY_NUM];
u16 dc_i[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM];
u16 dc_q[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM];
u8 corr_val[RTW89_DPK_RF_PATH][RTW89_DPK_BKUP_NUM];
@@ -5146,9 +5152,27 @@ struct rtw89_power_trim_info {
u8 pad_bias_trim[RF_PATH_MAX];
};
enum rtw89_regd_func {
RTW89_REGD_FUNC_TAS = 0, /* TAS (Time Average SAR) */
RTW89_REGD_FUNC_DAG = 1, /* DAG (Dynamic Antenna Gain) */
NUM_OF_RTW89_REGD_FUNC,
};
struct rtw89_regd {
char alpha2[3];
u8 txpwr_regd[RTW89_BAND_NUM];
DECLARE_BITMAP(func_bitmap, NUM_OF_RTW89_REGD_FUNC);
};
struct rtw89_regd_data {
unsigned int nr;
struct rtw89_regd map[] __counted_by(nr);
};
struct rtw89_regd_ctrl {
unsigned int nr;
const struct rtw89_regd *map;
};
#define RTW89_REGD_MAX_COUNTRY_NUM U8_MAX
@@ -5156,6 +5180,7 @@ struct rtw89_regd {
#define RTW89_5GHZ_UNII4_START_INDEX 25
struct rtw89_regulatory_info {
struct rtw89_regd_ctrl ctrl;
const struct rtw89_regd *regd;
enum rtw89_reg_6ghz_power reg_6ghz_power;
struct rtw89_reg_6ghz_tpe reg_6ghz_tpe;
@@ -5299,8 +5324,8 @@ struct rtw89_lps_parm {
};
struct rtw89_ppdu_sts_info {
struct sk_buff_head rx_queue[RTW89_PHY_MAX];
u8 curr_rx_ppdu_cnt[RTW89_PHY_MAX];
struct sk_buff_head rx_queue[RTW89_PHY_NUM];
u8 curr_rx_ppdu_cnt[RTW89_PHY_NUM];
};
struct rtw89_early_h2c {
@@ -5419,8 +5444,8 @@ struct rtw89_phy_efuse_gain {
bool offset_valid;
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 offset_base[RTW89_PHY_NUM]; /* S(8, 4) */
s8 rssi_base[RTW89_PHY_NUM]; /* S(8, 4) */
s8 comp[RF_PATH_MAX][RTW89_SUBBAND_NR]; /* S(8, 0) */
};
@@ -5629,8 +5654,6 @@ struct rtw89_dev {
struct rtw89_sta_link __rcu *assoc_link_on_macid[RTW89_MAX_MAC_ID_NUM];
refcount_t refcount_ap_info;
/* ensures exclusive access from mac80211 callbacks */
struct mutex mutex;
struct list_head rtwvifs_list;
/* used to protect rf read write */
struct mutex rf_mutex;
@@ -5650,10 +5673,10 @@ struct rtw89_dev {
struct rtw89_cam_info cam_info;
struct sk_buff_head c2h_queue;
struct work_struct c2h_work;
struct work_struct ips_work;
struct wiphy_work c2h_work;
struct wiphy_work ips_work;
struct wiphy_work cancel_6ghz_probe_work;
struct work_struct load_firmware_work;
struct work_struct cancel_6ghz_probe_work;
struct list_head early_h2c_list;
@@ -5682,9 +5705,6 @@ struct rtw89_dev {
struct rtw89_power_trim_info pwr_trim;
struct rtw89_cfo_tracking_info cfo_tracking;
struct rtw89_env_monitor_info env_monitor;
struct rtw89_dig_info dig;
struct rtw89_phy_ch_info ch_info;
union {
struct rtw89_phy_bb_gain_info ax;
struct rtw89_phy_bb_gain_info_be be;
@@ -5693,15 +5713,22 @@ struct rtw89_dev {
struct rtw89_phy_ul_tb_info ul_tb_info;
struct rtw89_antdiv_info antdiv;
struct delayed_work track_work;
struct delayed_work chanctx_work;
struct delayed_work coex_act1_work;
struct delayed_work coex_bt_devinfo_work;
struct delayed_work coex_rfk_chk_work;
struct delayed_work cfo_track_work;
struct rtw89_bb_ctx {
enum rtw89_phy_idx phy_idx;
struct rtw89_env_monitor_info env_monitor;
struct rtw89_dig_info dig;
struct rtw89_phy_ch_info ch_info;
struct rtw89_edcca_bak edcca_bak;
} bbs[RTW89_PHY_NUM];
struct wiphy_delayed_work track_work;
struct wiphy_delayed_work chanctx_work;
struct wiphy_delayed_work coex_act1_work;
struct wiphy_delayed_work coex_bt_devinfo_work;
struct wiphy_delayed_work coex_rfk_chk_work;
struct wiphy_delayed_work cfo_track_work;
struct delayed_work forbid_ba_work;
struct delayed_work roc_work;
struct delayed_work antdiv_work;
struct wiphy_delayed_work antdiv_work;
struct rtw89_ppdu_sts_info ppdu_sts;
u8 total_sta_assoc;
bool scanning;
@@ -6978,6 +7005,48 @@ static inline bool rtw89_is_mlo_1_1(struct rtw89_dev *rtwdev)
}
}
static inline u8 rtw89_get_active_phy_bitmap(struct rtw89_dev *rtwdev)
{
if (!rtwdev->dbcc_en)
return BIT(RTW89_PHY_0);
switch (rtwdev->mlo_dbcc_mode) {
case MLO_0_PLUS_2_1RF:
case MLO_0_PLUS_2_2RF:
return BIT(RTW89_PHY_1);
case MLO_1_PLUS_1_1RF:
case MLO_1_PLUS_1_2RF:
case MLO_2_PLUS_2_2RF:
case DBCC_LEGACY:
return BIT(RTW89_PHY_0) | BIT(RTW89_PHY_1);
case MLO_2_PLUS_0_1RF:
case MLO_2_PLUS_0_2RF:
default:
return BIT(RTW89_PHY_0);
}
}
#define rtw89_for_each_active_bb(rtwdev, bb) \
for (u8 __active_bb_bitmap = rtw89_get_active_phy_bitmap(rtwdev), \
__phy_idx = 0; __phy_idx < RTW89_PHY_NUM; __phy_idx++) \
if (__active_bb_bitmap & BIT(__phy_idx) && \
(bb = &rtwdev->bbs[__phy_idx]))
#define rtw89_for_each_capab_bb(rtwdev, bb) \
for (u8 __phy_idx_max = rtwdev->dbcc_en ? RTW89_PHY_1 : RTW89_PHY_0, \
__phy_idx = 0; __phy_idx <= __phy_idx_max; __phy_idx++) \
if ((bb = &rtwdev->bbs[__phy_idx]))
static inline
struct rtw89_bb_ctx *rtw89_get_bb_ctx(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
if (phy_idx >= RTW89_PHY_NUM)
return &rtwdev->bbs[RTW89_PHY_0];
return &rtwdev->bbs[phy_idx];
}
static inline bool rtw89_is_rtl885xb(struct rtw89_dev *rtwdev)
{
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
@@ -7092,9 +7161,7 @@ void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link);
bool rtw89_ra_report_to_bitrate(struct rtw89_dev *rtwdev, u8 rpt_rate, u16 *bitrate);
int rtw89_regd_setup(struct rtw89_dev *rtwdev);
int rtw89_regd_init(struct rtw89_dev *rtwdev,
void (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request *request));
void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request);
int rtw89_regd_init_hint(struct rtw89_dev *rtwdev);
void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev,
struct rtw89_traffic_stats *stats);
int rtw89_wait_for_cond(struct rtw89_wait_info *wait, unsigned int cond);
@@ -7102,8 +7169,8 @@ void rtw89_complete_cond(struct rtw89_wait_info *wait, unsigned int cond,
const struct rtw89_completion_data *data);
int rtw89_core_start(struct rtw89_dev *rtwdev);
void rtw89_core_stop(struct rtw89_dev *rtwdev);
void rtw89_core_update_beacon_work(struct work_struct *work);
void rtw89_roc_work(struct work_struct *work);
void rtw89_core_update_beacon_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_roc_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_roc_start(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
void rtw89_roc_end(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,

File diff suppressed because it is too large Load Diff

View File

@@ -489,6 +489,30 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev,
}
}
static int rtw89_mfw_validate_hdr(struct rtw89_dev *rtwdev,
const struct firmware *firmware,
const struct rtw89_mfw_hdr *mfw_hdr)
{
const void *mfw = firmware->data;
u32 mfw_len = firmware->size;
u8 fw_nr = mfw_hdr->fw_nr;
const void *ptr;
if (fw_nr == 0) {
rtw89_err(rtwdev, "mfw header has no fw entry\n");
return -ENOENT;
}
ptr = &mfw_hdr->info[fw_nr];
if (ptr > mfw + mfw_len) {
rtw89_err(rtwdev, "mfw header out of address\n");
return -EFAULT;
}
return 0;
}
static
int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
struct rtw89_fw_suit *fw_suit, bool nowarn)
@@ -499,6 +523,7 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
u32 mfw_len = firmware->size;
const struct rtw89_mfw_hdr *mfw_hdr = (const struct rtw89_mfw_hdr *)mfw;
const struct rtw89_mfw_info *mfw_info = NULL, *tmp;
int ret;
int i;
if (mfw_hdr->sig != RTW89_MFW_SIG) {
@@ -511,6 +536,10 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
return 0;
}
ret = rtw89_mfw_validate_hdr(rtwdev, firmware, mfw_hdr);
if (ret)
return ret;
for (i = 0; i < mfw_hdr->fw_nr; i++) {
tmp = &mfw_hdr->info[i];
if (tmp->type != type)
@@ -540,6 +569,12 @@ int rtw89_mfw_recognize(struct rtw89_dev *rtwdev, enum rtw89_fw_type type,
found:
fw_suit->data = mfw + le32_to_cpu(mfw_info->shift);
fw_suit->size = le32_to_cpu(mfw_info->size);
if (fw_suit->data + fw_suit->size > mfw + mfw_len) {
rtw89_err(rtwdev, "fw_suit %d out of address\n", type);
return -EFAULT;
}
return 0;
}
@@ -551,12 +586,17 @@ static u32 rtw89_mfw_get_size(struct rtw89_dev *rtwdev)
(const struct rtw89_mfw_hdr *)firmware->data;
const struct rtw89_mfw_info *mfw_info;
u32 size;
int ret;
if (mfw_hdr->sig != RTW89_MFW_SIG) {
rtw89_warn(rtwdev, "not mfw format\n");
return 0;
}
ret = rtw89_mfw_validate_hdr(rtwdev, firmware, mfw_hdr);
if (ret)
return ret;
mfw_info = &mfw_hdr->info[mfw_hdr->fw_nr - 1];
size = le32_to_cpu(mfw_info->shift) + le32_to_cpu(mfw_info->size);
@@ -1056,6 +1096,101 @@ int rtw89_build_rfk_log_fmt_from_elm(struct rtw89_dev *rtwdev,
return 0;
}
static bool rtw89_regd_entcpy(struct rtw89_regd *regd, const void *cursor,
u8 cursor_size)
{
/* fill default values if needed for backward compatibility */
struct rtw89_fw_regd_entry entry = {
.rule_2ghz = RTW89_NA,
.rule_5ghz = RTW89_NA,
.rule_6ghz = RTW89_NA,
.fmap = cpu_to_le32(0x0),
};
u8 valid_size = min_t(u8, sizeof(entry), cursor_size);
unsigned int i;
u32 fmap;
memcpy(&entry, cursor, valid_size);
memset(regd, 0, sizeof(*regd));
regd->alpha2[0] = entry.alpha2_0;
regd->alpha2[1] = entry.alpha2_1;
regd->alpha2[2] = '\0';
/* also need to consider forward compatibility */
regd->txpwr_regd[RTW89_BAND_2G] = entry.rule_2ghz < RTW89_REGD_NUM ?
entry.rule_2ghz : RTW89_NA;
regd->txpwr_regd[RTW89_BAND_5G] = entry.rule_5ghz < RTW89_REGD_NUM ?
entry.rule_5ghz : RTW89_NA;
regd->txpwr_regd[RTW89_BAND_6G] = entry.rule_6ghz < RTW89_REGD_NUM ?
entry.rule_6ghz : RTW89_NA;
BUILD_BUG_ON(sizeof(fmap) != sizeof(entry.fmap));
BUILD_BUG_ON(sizeof(fmap) * 8 < NUM_OF_RTW89_REGD_FUNC);
fmap = le32_to_cpu(entry.fmap);
for (i = 0; i < NUM_OF_RTW89_REGD_FUNC; i++) {
if (fmap & BIT(i))
set_bit(i, regd->func_bitmap);
}
return true;
}
#define rtw89_for_each_in_regd_element(regd, element) \
for (const void *cursor = (element)->content, \
*end = (element)->content + \
le32_to_cpu((element)->num_ents) * (element)->ent_sz; \
cursor < end; cursor += (element)->ent_sz) \
if (rtw89_regd_entcpy(regd, cursor, (element)->ent_sz))
static
int rtw89_recognize_regd_from_elm(struct rtw89_dev *rtwdev,
const struct rtw89_fw_element_hdr *elm,
const union rtw89_fw_element_arg arg)
{
const struct __rtw89_fw_regd_element *regd_elm = &elm->u.regd;
struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
u32 num_ents = le32_to_cpu(regd_elm->num_ents);
struct rtw89_regd_data *p;
struct rtw89_regd regd;
u32 i = 0;
if (num_ents > RTW89_REGD_MAX_COUNTRY_NUM) {
rtw89_warn(rtwdev,
"regd element ents (%d) are over max num (%d)\n",
num_ents, RTW89_REGD_MAX_COUNTRY_NUM);
rtw89_warn(rtwdev,
"regd element ignore and take another/common\n");
return 1;
}
if (elm_info->regd) {
rtw89_debug(rtwdev, RTW89_DBG_REGD,
"regd element take the latter\n");
devm_kfree(rtwdev->dev, elm_info->regd);
elm_info->regd = NULL;
}
p = devm_kzalloc(rtwdev->dev, struct_size(p, map, num_ents), GFP_KERNEL);
if (!p)
return -ENOMEM;
p->nr = num_ents;
rtw89_for_each_in_regd_element(&regd, regd_elm)
p->map[i++] = regd;
if (i != num_ents) {
rtw89_err(rtwdev, "regd element has %d invalid ents\n",
num_ents - i);
devm_kfree(rtwdev->dev, p);
return -EINVAL;
}
elm_info->regd = p;
return 0;
}
static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
[RTW89_FW_ELEMENT_ID_BBMCU0] = {__rtw89_fw_recognize_from_elm,
{ .fw_type = RTW89_FW_BBMCU0 }, NULL},
@@ -1114,6 +1249,9 @@ static const struct rtw89_fw_element_handler __fw_element_handlers[] = {
[RTW89_FW_ELEMENT_ID_RFKLOG_FMT] = {
rtw89_build_rfk_log_fmt_from_elm, {}, NULL,
},
[RTW89_FW_ELEMENT_ID_REGD] = {
rtw89_recognize_regd_from_elm, {}, "REGD",
},
};
int rtw89_fw_recognize_elements(struct rtw89_dev *rtwdev)
@@ -2697,7 +2835,9 @@ int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev,
{
const struct rtw89_phy_bb_gain_info_be *gain = &rtwdev->bb_gain.be;
struct rtw89_pkt_stat *pkt_stat = &rtwdev->phystat.cur_pkt_stat;
static const u8 bcn_bw_ofst[] = {0, 0, 0, 3, 6, 9, 0, 12};
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_efuse *efuse = &rtwdev->efuse;
struct rtw89_h2c_lps_ml_cmn_info *h2c;
struct rtw89_vif_link *rtwvif_link;
const struct rtw89_chan *chan;
@@ -2705,6 +2845,7 @@ int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev,
u32 len = sizeof(*h2c);
unsigned int link_id;
struct sk_buff *skb;
u8 beacon_bw_ofst;
u8 gain_band;
u32 done;
u8 path;
@@ -2722,9 +2863,10 @@ int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev,
skb_put(skb, len);
h2c = (struct rtw89_h2c_lps_ml_cmn_info *)skb->data;
h2c->fmt_id = 0x1;
h2c->fmt_id = 0x3;
h2c->mlo_dbcc_mode = cpu_to_le32(rtwdev->mlo_dbcc_mode);
h2c->rfe_type = efuse->rfe_type;
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
path = rtwvif_link->phy_idx == RTW89_PHY_1 ? RF_PATH_B : RF_PATH_A;
@@ -2745,9 +2887,21 @@ int rtw89_fw_h2c_lps_ml_cmn_info(struct rtw89_dev *rtwdev,
h2c->tia_gain[rtwvif_link->phy_idx][i] =
cpu_to_le16(gain->tia_gain[gain_band][bw_idx][path][i]);
}
if (rtwvif_link->bcn_bw_idx < ARRAY_SIZE(bcn_bw_ofst)) {
beacon_bw_ofst = bcn_bw_ofst[rtwvif_link->bcn_bw_idx];
h2c->dup_bcn_ofst[rtwvif_link->phy_idx] = beacon_bw_ofst;
}
memcpy(h2c->lna_gain[rtwvif_link->phy_idx],
gain->lna_gain[gain_band][bw_idx][path],
LNA_GAIN_NUM);
memcpy(h2c->tia_lna_op1db[rtwvif_link->phy_idx],
gain->tia_lna_op1db[gain_band][bw_idx][path],
LNA_GAIN_NUM + 1);
memcpy(h2c->lna_op1db[rtwvif_link->phy_idx],
gain->lna_op1db[gain_band][bw_idx][path],
LNA_GAIN_NUM);
}
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
@@ -5311,6 +5465,7 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
u8 macc_role_size = sizeof(*macc_role) * option->num_macc_role;
u8 opch_size = sizeof(*opch) * option->num_opch;
u8 probe_id[NUM_NL80211_BANDS];
u8 scan_offload_ver = U8_MAX;
u8 cfg_len = sizeof(*h2c);
unsigned int cond;
u8 ver = U8_MAX;
@@ -5321,6 +5476,11 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
rtw89_scan_get_6g_disabled_chan(rtwdev, option);
if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw)) {
cfg_len = offsetofend(typeof(*h2c), w8);
scan_offload_ver = 0;
}
len = cfg_len + macc_role_size + opch_size;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
@@ -5392,10 +5552,8 @@ int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
RTW89_H2C_SCANOFLD_BE_W8_PROBE_RATE_6GHZ);
}
if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD_BE_V0, &rtwdev->fw)) {
cfg_len = offsetofend(typeof(*h2c), w8);
if (scan_offload_ver == 0)
goto flex_member;
}
h2c->w9 = le32_encode_bits(sizeof(*h2c) / sizeof(h2c->w0),
RTW89_H2C_SCANOFLD_BE_W9_SIZE_CFG) |
@@ -5994,24 +6152,29 @@ void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev)
{
struct rtw89_early_h2c *early_h2c;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
list_for_each_entry(early_h2c, &rtwdev->early_h2c_list, list) {
rtw89_fw_h2c_raw(rtwdev, early_h2c->h2c, early_h2c->h2c_len);
}
}
void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev)
void __rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev)
{
struct rtw89_early_h2c *early_h2c, *tmp;
mutex_lock(&rtwdev->mutex);
list_for_each_entry_safe(early_h2c, tmp, &rtwdev->early_h2c_list, list) {
list_del(&early_h2c->list);
kfree(early_h2c->h2c);
kfree(early_h2c);
}
mutex_unlock(&rtwdev->mutex);
}
void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev)
{
lockdep_assert_wiphy(rtwdev->hw->wiphy);
__rtw89_fw_free_all_early_h2c(rtwdev);
}
static void rtw89_fw_c2h_parse_attr(struct sk_buff *c2h)
@@ -6055,7 +6218,7 @@ void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h)
enqueue:
skb_queue_tail(&rtwdev->c2h_queue, c2h);
ieee80211_queue_work(rtwdev->hw, &rtwdev->c2h_work);
wiphy_work_queue(rtwdev->hw->wiphy, &rtwdev->c2h_work);
}
static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
@@ -6093,17 +6256,17 @@ static void rtw89_fw_c2h_cmd_handle(struct rtw89_dev *rtwdev,
rtw89_hex_dump(rtwdev, RTW89_DBG_FW, "C2H: ", skb->data, skb->len);
}
void rtw89_fw_c2h_work(struct work_struct *work)
void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work)
{
struct rtw89_dev *rtwdev = container_of(work, struct rtw89_dev,
c2h_work);
struct sk_buff *skb, *tmp;
lockdep_assert_wiphy(rtwdev->hw->wiphy);
skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) {
skb_unlink(skb, &rtwdev->c2h_queue);
mutex_lock(&rtwdev->mutex);
rtw89_fw_c2h_cmd_handle(rtwdev, skb);
mutex_unlock(&rtwdev->mutex);
dev_kfree_skb_any(skb);
}
}
@@ -6184,7 +6347,7 @@ int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev,
u32 ret;
if (h2c_info && h2c_info->id != RTW89_FWCMD_H2CREG_FUNC_GET_FEATURE)
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (!h2c_info && !c2h_info)
return -EINVAL;

View File

@@ -1801,17 +1801,21 @@ struct rtw89_h2c_lps_ch_info {
struct rtw89_h2c_lps_ml_cmn_info {
u8 fmt_id;
u8 rsvd0[3];
u8 rfe_type;
u8 rsvd0[2];
__le32 mlo_dbcc_mode;
u8 central_ch[RTW89_PHY_MAX];
u8 pri_ch[RTW89_PHY_MAX];
u8 bw[RTW89_PHY_MAX];
u8 band[RTW89_PHY_MAX];
u8 bcn_rate_type[RTW89_PHY_MAX];
u8 central_ch[RTW89_PHY_NUM];
u8 pri_ch[RTW89_PHY_NUM];
u8 bw[RTW89_PHY_NUM];
u8 band[RTW89_PHY_NUM];
u8 bcn_rate_type[RTW89_PHY_NUM];
u8 rsvd1[2];
__le16 tia_gain[RTW89_PHY_MAX][TIA_GAIN_NUM];
u8 lna_gain[RTW89_PHY_MAX][LNA_GAIN_NUM];
__le16 tia_gain[RTW89_PHY_NUM][TIA_GAIN_NUM];
u8 lna_gain[RTW89_PHY_NUM][LNA_GAIN_NUM];
u8 rsvd2[2];
u8 tia_lna_op1db[RTW89_PHY_NUM][LNA_GAIN_NUM + 1];
u8 lna_op1db[RTW89_PHY_NUM][LNA_GAIN_NUM];
u8 dup_bcn_ofst[RTW89_PHY_NUM];
} __packed;
static inline void RTW89_SET_FWCMD_CPU_EXCEPTION_TYPE(void *cmd, u32 val)
@@ -3882,6 +3886,7 @@ enum rtw89_fw_element_id {
RTW89_FW_ELEMENT_ID_TX_SHAPE_LMT_RU = 17,
RTW89_FW_ELEMENT_ID_TXPWR_TRK = 18,
RTW89_FW_ELEMENT_ID_RFKLOG_FMT = 19,
RTW89_FW_ELEMENT_ID_REGD = 20,
RTW89_FW_ELEMENT_ID_NUM,
};
@@ -3925,6 +3930,15 @@ struct __rtw89_fw_txpwr_element {
u8 content[];
} __packed;
struct __rtw89_fw_regd_element {
u8 rsvd0;
u8 rsvd1;
u8 rsvd2;
u8 ent_sz;
__le32 num_ents;
u8 content[];
} __packed;
enum rtw89_fw_txpwr_trk_type {
__RTW89_FW_TXPWR_TRK_TYPE_6GHZ_START = 0,
RTW89_FW_TXPWR_TRK_TYPE_6GB_N = 0,
@@ -4016,6 +4030,7 @@ struct rtw89_fw_element_hdr {
__le16 offset[];
} __packed rfk_log_fmt;
struct __rtw89_fw_txpwr_element txpwr;
struct __rtw89_fw_regd_element regd;
} __packed u;
} __packed;
@@ -4588,7 +4603,7 @@ int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
void rtw89_fw_c2h_irqsafe(struct rtw89_dev *rtwdev, struct sk_buff *c2h);
void rtw89_fw_c2h_work(struct work_struct *work);
void rtw89_fw_c2h_work(struct wiphy *wiphy, struct wiphy_work *work);
int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
@@ -4654,6 +4669,7 @@ int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
bool rack, bool dack);
int rtw89_fw_h2c_raw(struct rtw89_dev *rtwdev, const u8 *buf, u16 len);
void rtw89_fw_send_all_early_h2c(struct rtw89_dev *rtwdev);
void __rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev);
void rtw89_fw_free_all_early_h2c(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u8 macid);
@@ -4874,6 +4890,18 @@ int rtw89_chip_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
return 0;
}
/* Must consider compatibility; don't insert new in the mid.
* Fill each field's default value in rtw89_regd_entcpy().
*/
struct rtw89_fw_regd_entry {
u8 alpha2_0;
u8 alpha2_1;
u8 rule_2ghz;
u8 rule_5ghz;
u8 rule_6ghz;
__le32 fmap;
} __packed;
/* must consider compatibility; don't insert new in the mid */
struct rtw89_fw_txpwr_byrate_entry {
u8 band;

View File

@@ -1495,6 +1495,21 @@ static int rtw89_mac_power_switch(struct rtw89_dev *rtwdev, bool on)
#undef PWR_ACT
}
int rtw89_mac_pwr_on(struct rtw89_dev *rtwdev)
{
int ret;
ret = rtw89_mac_power_switch(rtwdev, true);
if (ret) {
rtw89_mac_power_switch(rtwdev, false);
ret = rtw89_mac_power_switch(rtwdev, true);
if (ret)
return ret;
}
return 0;
}
void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev)
{
rtw89_mac_power_switch(rtwdev, false);
@@ -3996,14 +4011,6 @@ int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb)
{
int ret;
ret = rtw89_mac_power_switch(rtwdev, true);
if (ret) {
rtw89_mac_power_switch(rtwdev, false);
ret = rtw89_mac_power_switch(rtwdev, true);
if (ret)
return ret;
}
rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
if (include_bb) {
@@ -4036,6 +4043,10 @@ int rtw89_mac_init(struct rtw89_dev *rtwdev)
bool include_bb = !!chip->bbmcu_nr;
int ret;
ret = rtw89_mac_pwr_on(rtwdev);
if (ret)
return ret;
ret = rtw89_mac_partial_init(rtwdev, include_bb);
if (ret)
goto fail;
@@ -4067,7 +4078,7 @@ int rtw89_mac_init(struct rtw89_dev *rtwdev)
return ret;
fail:
rtw89_mac_power_switch(rtwdev, false);
rtw89_mac_pwr_off(rtwdev);
return ret;
}
@@ -6031,7 +6042,7 @@ int rtw89_mac_cfg_ctrl_path_v1(struct rtw89_dev *rtwdev, bool wl)
if (wl)
return 0;
for (i = 0; i < RTW89_PHY_MAX; i++) {
for (i = 0; i < RTW89_PHY_NUM; i++) {
g[i].gnt_bt_sw_en = 1;
g[i].gnt_bt = 1;
g[i].gnt_wl_sw_en = 1;

View File

@@ -1145,6 +1145,7 @@ rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_l
rtw89_write32_set(rtwdev, reg, bit);
}
int rtw89_mac_pwr_on(struct rtw89_dev *rtwdev);
void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev);
int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb);
int rtw89_mac_init(struct rtw89_dev *rtwdev);

View File

@@ -57,32 +57,30 @@ static void rtw89_ops_wake_tx_queue(struct ieee80211_hw *hw,
static int rtw89_ops_start(struct ieee80211_hw *hw)
{
struct rtw89_dev *rtwdev = hw->priv;
int ret;
mutex_lock(&rtwdev->mutex);
ret = rtw89_core_start(rtwdev);
mutex_unlock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
return ret;
return rtw89_core_start(rtwdev);
}
static void rtw89_ops_stop(struct ieee80211_hw *hw, bool suspend)
{
struct rtw89_dev *rtwdev = hw->priv;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtw89_core_stop(rtwdev);
mutex_unlock(&rtwdev->mutex);
}
static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
{
struct rtw89_dev *rtwdev = hw->priv;
/* let previous ips work finish to ensure we don't leave ips twice */
cancel_work_sync(&rtwdev->ips_work);
lockdep_assert_wiphy(hw->wiphy);
/* let previous ips work finish to ensure we don't leave ips twice */
wiphy_work_cancel(hw->wiphy, &rtwdev->ips_work);
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
@@ -100,8 +98,6 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
!rtwdev->scanning)
rtw89_enter_ips(rtwdev);
mutex_unlock(&rtwdev->mutex);
return 0;
}
@@ -115,7 +111,7 @@ static int __rtw89_ops_add_iface_link(struct rtw89_dev *rtwdev,
rtw89_vif_type_mapping(rtwvif_link, false);
INIT_WORK(&rtwvif_link->update_beacon_work, rtw89_core_update_beacon_work);
wiphy_work_init(&rtwvif_link->update_beacon_work, rtw89_core_update_beacon_work);
INIT_LIST_HEAD(&rtwvif_link->general_pkt_list);
rtwvif_link->hit_rule = 0;
@@ -142,9 +138,9 @@ static int __rtw89_ops_add_iface_link(struct rtw89_dev *rtwdev,
static void __rtw89_ops_remove_iface_link(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
mutex_unlock(&rtwdev->mutex);
cancel_work_sync(&rtwvif_link->update_beacon_work);
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
wiphy_work_cancel(rtwdev->hw->wiphy, &rtwvif_link->update_beacon_work);
rtw89_leave_ps_mode(rtwdev);
@@ -162,11 +158,11 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
u8 mac_id, port;
int ret = 0;
lockdep_assert_wiphy(hw->wiphy);
rtw89_debug(rtwdev, RTW89_DBG_STATE, "add vif %pM type %d, p2p %d\n",
vif->addr, vif->type, vif->p2p);
mutex_lock(&rtwdev->mutex);
rtw89_leave_ips_by_hwflags(rtwdev);
if (RTW89_CHK_FW_FEATURE(BEACON_FILTER, &rtwdev->fw))
@@ -174,10 +170,8 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
IEEE80211_VIF_SUPPORTS_CQM_RSSI;
mac_id = rtw89_acquire_mac_id(rtwdev);
if (mac_id == RTW89_MAX_MAC_ID_NUM) {
ret = -ENOSPC;
goto err;
}
if (mac_id == RTW89_MAX_MAC_ID_NUM)
return -ENOSPC;
port = rtw89_core_acquire_bit_map(rtwdev->hw_port, RTW89_PORT_NUM);
if (port == RTW89_PORT_NUM) {
@@ -198,7 +192,7 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
rtwvif->offchan = false;
rtwvif->roc.state = RTW89_ROC_IDLE;
INIT_DELAYED_WORK(&rtwvif->roc.roc_work, rtw89_roc_work);
wiphy_delayed_work_init(&rtwvif->roc.roc_work, rtw89_roc_work);
rtw89_traffic_stats_init(rtwdev, &rtwvif->stats);
@@ -213,8 +207,6 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
goto unset_link;
rtw89_recalc_lps(rtwdev);
mutex_unlock(&rtwdev->mutex);
return 0;
unset_link:
@@ -224,8 +216,6 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
rtw89_core_release_bit_map(rtwdev->hw_port, port);
release_macid:
rtw89_release_mac_id(rtwdev, mac_id);
err:
mutex_unlock(&rtwdev->mutex);
return ret;
}
@@ -239,12 +229,12 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,
u8 port = rtw89_vif_get_main_port(rtwvif);
struct rtw89_vif_link *rtwvif_link;
lockdep_assert_wiphy(hw->wiphy);
rtw89_debug(rtwdev, RTW89_DBG_STATE, "remove vif %pM type %d p2p %d\n",
vif->addr, vif->type, vif->p2p);
cancel_delayed_work_sync(&rtwvif->roc.roc_work);
mutex_lock(&rtwdev->mutex);
wiphy_delayed_work_cancel(hw->wiphy, &rtwvif->roc.roc_work);
rtwvif_link = rtwvif->links[RTW89_VIF_IDLE_LINK_ID];
if (unlikely(!rtwvif_link)) {
@@ -265,8 +255,6 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,
rtw89_recalc_lps(rtwdev);
rtw89_enter_ips_by_hwflags(rtwdev);
mutex_unlock(&rtwdev->mutex);
}
static int rtw89_ops_change_interface(struct ieee80211_hw *hw,
@@ -304,7 +292,8 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u32 rx_fltr;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtw89_leave_ps_mode(rtwdev);
*new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL |
@@ -367,14 +356,11 @@ static void rtw89_ops_configure_filter(struct ieee80211_hw *hw,
B_AX_RX_FLTR_CFG_MASK,
rx_fltr);
if (!rtwdev->dbcc_en)
goto out;
return;
rtw89_write32_mask(rtwdev,
rtw89_mac_reg_by_idx(rtwdev, mac->rx_fltr, RTW89_MAC_1),
B_AX_RX_FLTR_CFG_MASK,
rx_fltr);
out:
mutex_unlock(&rtwdev->mutex);
}
static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = {
@@ -689,7 +675,8 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw,
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtw89_leave_ps_mode(rtwdev);
if (changed & BSS_CHANGED_ASSOC) {
@@ -712,8 +699,6 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_ARP_FILTER)
rtwvif->ip_addr = vif->cfg.arp_addr_list[0];
mutex_unlock(&rtwdev->mutex);
}
static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw,
@@ -725,7 +710,8 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw,
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtw89_leave_ps_mode(rtwdev);
rtwvif_link = rtwvif->links[conf->link_id];
@@ -733,7 +719,7 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw,
rtw89_err(rtwdev,
"%s: rtwvif link (link_id %u) is not active\n",
__func__, conf->link_id);
goto out;
return;
}
if (changed & BSS_CHANGED_BSSID) {
@@ -763,9 +749,6 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_TPE)
rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true);
out:
mutex_unlock(&rtwdev->mutex);
}
static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
@@ -778,22 +761,19 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
const struct rtw89_chan *chan;
int ret = 0;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtwvif_link = rtwvif->links[link_conf->link_id];
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev,
"%s: rtwvif link (link_id %u) is not active\n",
__func__, link_conf->link_id);
ret = -ENOLINK;
goto out;
return -ENOLINK;
}
chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
if (chan->band_type == RTW89_BAND_6G) {
mutex_unlock(&rtwdev->mutex);
if (chan->band_type == RTW89_BAND_6G)
return -EOPNOTSUPP;
}
if (rtwdev->scanning)
rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
@@ -810,15 +790,12 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
if (RTW89_CHK_FW_FEATURE(NOTIFY_AP_INFO, &rtwdev->fw)) {
ret = rtw89_fw_h2c_ap_info_refcount(rtwdev, true);
if (ret)
goto out;
return ret;
}
rtw89_queue_chanctx_work(rtwdev);
out:
mutex_unlock(&rtwdev->mutex);
return ret;
return 0;
}
static
@@ -829,14 +806,14 @@ void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtwvif_link = rtwvif->links[link_conf->link_id];
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev,
"%s: rtwvif link (link_id %u) is not active\n",
__func__, link_conf->link_id);
goto out;
return;
}
if (RTW89_CHK_FW_FEATURE(NOTIFY_AP_INFO, &rtwdev->fw))
@@ -845,22 +822,18 @@ void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
rtw89_mac_stop_ap(rtwdev, rtwvif_link);
rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, NULL);
rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true);
out:
mutex_unlock(&rtwdev->mutex);
}
static int rtw89_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
bool set)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_vif_link *rtwvif_link;
unsigned int link_id;
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
ieee80211_queue_work(rtwdev->hw, &rtwvif_link->update_beacon_work);
wiphy_work_queue(hw->wiphy, &rtwvif_link->update_beacon_work);
return 0;
}
@@ -873,9 +846,9 @@ static int rtw89_ops_conf_tx(struct ieee80211_hw *hw,
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
int ret = 0;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtw89_leave_ps_mode(rtwdev);
rtwvif_link = rtwvif->links[link_id];
@@ -883,17 +856,13 @@ static int rtw89_ops_conf_tx(struct ieee80211_hw *hw,
rtw89_err(rtwdev,
"%s: rtwvif link (link_id %u) is not active\n",
__func__, link_id);
ret = -ENOLINK;
goto out;
return -ENOLINK;
}
rtwvif_link->tx_params[ac] = *params;
__rtw89_conf_tx(rtwdev, rtwvif_link, ac);
out:
mutex_unlock(&rtwdev->mutex);
return ret;
return 0;
}
static int __rtw89_ops_sta_state(struct ieee80211_hw *hw,
@@ -937,14 +906,11 @@ static int rtw89_ops_sta_state(struct ieee80211_hw *hw,
enum ieee80211_sta_state new_state)
{
struct rtw89_dev *rtwdev = hw->priv;
int ret;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtw89_leave_ps_mode(rtwdev);
ret = __rtw89_ops_sta_state(hw, vif, sta, old_state, new_state);
mutex_unlock(&rtwdev->mutex);
return ret;
return __rtw89_ops_sta_state(hw, vif, sta, old_state, new_state);
}
static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -953,9 +919,10 @@ static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_key_conf *key)
{
struct rtw89_dev *rtwdev = hw->priv;
int ret = 0;
int ret;
lockdep_assert_wiphy(hw->wiphy);
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
switch (cmd) {
@@ -964,7 +931,7 @@ static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
ret = rtw89_cam_sec_key_add(rtwdev, vif, sta, key);
if (ret && ret != -EOPNOTSUPP) {
rtw89_err(rtwdev, "failed to add key to sec cam\n");
goto out;
return ret;
}
break;
case DISABLE_KEY:
@@ -974,14 +941,11 @@ static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
ret = rtw89_cam_sec_key_del(rtwdev, vif, sta, key, true);
if (ret) {
rtw89_err(rtwdev, "failed to remove key from sec cam\n");
goto out;
return ret;
}
break;
}
out:
mutex_unlock(&rtwdev->mutex);
return ret;
}
@@ -997,38 +961,32 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
struct ieee80211_txq *txq = sta->txq[tid];
struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv;
lockdep_assert_wiphy(rtwdev->hw->wiphy);
switch (params->action) {
case IEEE80211_AMPDU_TX_START:
return IEEE80211_AMPDU_TX_START_IMMEDIATE;
case IEEE80211_AMPDU_TX_STOP_CONT:
case IEEE80211_AMPDU_TX_STOP_FLUSH:
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
mutex_lock(&rtwdev->mutex);
clear_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
clear_bit(tid, rtwsta->ampdu_map);
rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta);
mutex_unlock(&rtwdev->mutex);
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
break;
case IEEE80211_AMPDU_TX_OPERATIONAL:
mutex_lock(&rtwdev->mutex);
set_bit(RTW89_TXQ_F_AMPDU, &rtwtxq->flags);
rtwsta->ampdu_params[tid].agg_num = params->buf_size;
rtwsta->ampdu_params[tid].amsdu = params->amsdu;
set_bit(tid, rtwsta->ampdu_map);
rtw89_leave_ps_mode(rtwdev);
rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta);
mutex_unlock(&rtwdev->mutex);
break;
case IEEE80211_AMPDU_RX_START:
mutex_lock(&rtwdev->mutex);
rtw89_chip_h2c_ba_cam(rtwdev, rtwsta, true, params);
mutex_unlock(&rtwdev->mutex);
break;
case IEEE80211_AMPDU_RX_STOP:
mutex_lock(&rtwdev->mutex);
rtw89_chip_h2c_ba_cam(rtwdev, rtwsta, false, params);
mutex_unlock(&rtwdev->mutex);
break;
default:
WARN_ON(1);
@@ -1042,11 +1000,11 @@ static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
{
struct rtw89_dev *rtwdev = hw->priv;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtw89_leave_ps_mode(rtwdev);
if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
rtw89_mac_update_rts_threshold(rtwdev);
mutex_unlock(&rtwdev->mutex);
return 0;
}
@@ -1086,7 +1044,8 @@ static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
{
struct rtw89_dev *rtwdev = hw->priv;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtw89_leave_lps(rtwdev);
rtw89_hci_flush_queues(rtwdev, queues, drop);
@@ -1094,8 +1053,6 @@ static void rtw89_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
__rtw89_drop_packets(rtwdev, vif);
else
rtw89_mac_flush_txq(rtwdev, queues, drop);
mutex_unlock(&rtwdev->mutex);
}
struct rtw89_iter_bitrate_mask_data {
@@ -1142,10 +1099,10 @@ static int rtw89_ops_set_bitrate_mask(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtw89_phy_rate_pattern_vif(rtwdev, vif, mask);
rtw89_ra_mask_info_update(rtwdev, vif, mask);
mutex_unlock(&rtwdev->mutex);
return 0;
}
@@ -1156,6 +1113,8 @@ int rtw89_ops_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_hal *hal = &rtwdev->hal;
lockdep_assert_wiphy(hw->wiphy);
if (hal->ant_diversity) {
if (tx_ant != rx_ant || hweight32(tx_ant) != 1)
return -EINVAL;
@@ -1163,12 +1122,10 @@ int rtw89_ops_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
return -EINVAL;
}
mutex_lock(&rtwdev->mutex);
hal->antenna_tx = tx_ant;
hal->antenna_rx = rx_ant;
hal->tx_path_diversity = false;
hal->ant_diversity_fixed = true;
mutex_unlock(&rtwdev->mutex);
return 0;
}
@@ -1193,18 +1150,15 @@ static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw,
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev, "sw scan start: find no link on HW-0\n");
goto out;
return;
}
rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, false);
out:
mutex_unlock(&rtwdev->mutex);
}
static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw,
@@ -1214,18 +1168,15 @@ static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw,
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev, "sw scan complete: find no link on HW-0\n");
goto out;
return;
}
rtw89_core_scan_complete(rtwdev, rtwvif_link, false);
out:
mutex_unlock(&rtwdev->mutex);
}
static void rtw89_ops_reconfig_complete(struct ieee80211_hw *hw,
@@ -1245,21 +1196,18 @@ static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct rtw89_vif_link *rtwvif_link;
int ret;
lockdep_assert_wiphy(hw->wiphy);
if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
return 1;
mutex_lock(&rtwdev->mutex);
if (rtwdev->scanning || rtwvif->offchan) {
ret = -EBUSY;
goto out;
}
if (rtwdev->scanning || rtwvif->offchan)
return -EBUSY;
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev, "hw scan: find no link on HW-0\n");
ret = -ENOLINK;
goto out;
return -ENOLINK;
}
rtw89_hw_scan_start(rtwdev, rtwvif_link, req);
@@ -1269,9 +1217,6 @@ static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
rtw89_err(rtwdev, "HW scan failed with status: %d\n", ret);
}
out:
mutex_unlock(&rtwdev->mutex);
return ret;
}
@@ -1282,24 +1227,21 @@ static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw,
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
lockdep_assert_wiphy(hw->wiphy);
if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
return;
mutex_lock(&rtwdev->mutex);
if (!rtwdev->scanning)
goto out;
return;
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev, "cancel hw scan: find no link on HW-0\n");
goto out;
return;
}
rtw89_hw_scan_abort(rtwdev, rtwvif_link);
out:
mutex_unlock(&rtwdev->mutex);
}
static void rtw89_ops_sta_rc_update(struct ieee80211_hw *hw,
@@ -1322,13 +1264,10 @@ static int rtw89_ops_add_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_dev *rtwdev = hw->priv;
int ret;
mutex_lock(&rtwdev->mutex);
ret = rtw89_chanctx_ops_add(rtwdev, ctx);
mutex_unlock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
return ret;
return rtw89_chanctx_ops_add(rtwdev, ctx);
}
static void rtw89_ops_remove_chanctx(struct ieee80211_hw *hw,
@@ -1336,9 +1275,9 @@ static void rtw89_ops_remove_chanctx(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtw89_chanctx_ops_remove(rtwdev, ctx);
mutex_unlock(&rtwdev->mutex);
}
static void rtw89_ops_change_chanctx(struct ieee80211_hw *hw,
@@ -1347,9 +1286,9 @@ static void rtw89_ops_change_chanctx(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtw89_chanctx_ops_change(rtwdev, ctx, changed);
mutex_unlock(&rtwdev->mutex);
}
static int rtw89_ops_assign_vif_chanctx(struct ieee80211_hw *hw,
@@ -1360,25 +1299,18 @@ static int rtw89_ops_assign_vif_chanctx(struct ieee80211_hw *hw,
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
int ret;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtwvif_link = rtwvif->links[link_conf->link_id];
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev,
"%s: rtwvif link (link_id %u) is not active\n",
__func__, link_conf->link_id);
ret = -ENOLINK;
goto out;
return -ENOLINK;
}
ret = rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif_link, ctx);
out:
mutex_unlock(&rtwdev->mutex);
return ret;
return rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif_link, ctx);
}
static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw,
@@ -1390,11 +1322,10 @@ static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw,
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtwvif_link = rtwvif->links[link_conf->link_id];
if (unlikely(!rtwvif_link)) {
mutex_unlock(&rtwdev->mutex);
rtw89_err(rtwdev,
"%s: rtwvif link (link_id %u) is not active\n",
__func__, link_conf->link_id);
@@ -1402,7 +1333,6 @@ static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw,
}
rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif_link, ctx);
mutex_unlock(&rtwdev->mutex);
}
static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw,
@@ -1415,13 +1345,12 @@ static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw,
struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
struct rtw89_roc *roc = &rtwvif->roc;
lockdep_assert_wiphy(hw->wiphy);
if (!rtwvif)
return -EINVAL;
mutex_lock(&rtwdev->mutex);
if (roc->state != RTW89_ROC_IDLE) {
mutex_unlock(&rtwdev->mutex);
return -EBUSY;
}
@@ -1439,8 +1368,6 @@ static int rtw89_ops_remain_on_channel(struct ieee80211_hw *hw,
rtw89_roc_start(rtwdev, rtwvif);
mutex_unlock(&rtwdev->mutex);
return 0;
}
@@ -1450,14 +1377,14 @@ static int rtw89_ops_cancel_remain_on_channel(struct ieee80211_hw *hw,
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
lockdep_assert_wiphy(hw->wiphy);
if (!rtwvif)
return -EINVAL;
cancel_delayed_work_sync(&rtwvif->roc.roc_work);
wiphy_delayed_work_cancel(hw->wiphy, &rtwvif->roc.roc_work);
mutex_lock(&rtwdev->mutex);
rtw89_roc_end(rtwdev, rtwvif);
mutex_unlock(&rtwdev->mutex);
return 0;
}
@@ -1478,14 +1405,14 @@ static int rtw89_ops_set_tid_config(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
if (sta)
rtw89_core_set_tid_config(rtwdev, sta, tid_config);
else
ieee80211_iterate_stations_atomic(rtwdev->hw,
rtw89_set_tid_config_iter,
tid_config);
mutex_unlock(&rtwdev->mutex);
return 0;
}
@@ -1509,7 +1436,7 @@ static bool rtw89_ops_can_activate_links(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
guard(mutex)(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
return rtw89_can_work_on_links(rtwdev, vif, active_links);
}
@@ -1571,7 +1498,7 @@ int rtw89_ops_change_vif_links(struct ieee80211_hw *hw,
int ret = 0;
int i;
guard(mutex)(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtw89_debug(rtwdev, RTW89_DBG_STATE,
"%s: old_links (0x%08x) -> new_links (0x%08x)\n",
@@ -1720,7 +1647,7 @@ int rtw89_ops_change_sta_links(struct ieee80211_hw *hw,
unsigned long set_links = new_links & ~old_links;
int ret = 0;
guard(mutex)(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
rtw89_debug(rtwdev, RTW89_DBG_STATE,
"%s: old_links (0x%08x) -> new_links (0x%08x)\n",
@@ -1750,13 +1677,12 @@ static int rtw89_ops_suspend(struct ieee80211_hw *hw,
struct rtw89_dev *rtwdev = hw->priv;
int ret;
lockdep_assert_wiphy(hw->wiphy);
set_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags);
cancel_delayed_work_sync(&rtwdev->track_work);
wiphy_delayed_work_cancel(hw->wiphy, &rtwdev->track_work);
mutex_lock(&rtwdev->mutex);
ret = rtw89_wow_suspend(rtwdev, wowlan);
mutex_unlock(&rtwdev->mutex);
if (ret) {
rtw89_warn(rtwdev, "failed to suspend for wow %d\n", ret);
clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags);
@@ -1771,15 +1697,15 @@ static int rtw89_ops_resume(struct ieee80211_hw *hw)
struct rtw89_dev *rtwdev = hw->priv;
int ret;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
ret = rtw89_wow_resume(rtwdev);
if (ret)
rtw89_warn(rtwdev, "failed to resume for wow %d\n", ret);
mutex_unlock(&rtwdev->mutex);
clear_bit(RTW89_FLAG_FORBIDDEN_TRACK_WROK, rtwdev->flags);
ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work,
RTW89_TRACK_WORK_PERIOD);
wiphy_delayed_work_queue(hw->wiphy, &rtwdev->track_work,
RTW89_TRACK_WORK_PERIOD);
return ret ? 1 : 0;
}
@@ -1799,18 +1725,16 @@ static void rtw89_set_rekey_data(struct ieee80211_hw *hw,
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_wow_gtk_info *gtk_info = &rtw_wow->gtk_info;
lockdep_assert_wiphy(hw->wiphy);
if (data->kek_len > sizeof(gtk_info->kek) ||
data->kck_len > sizeof(gtk_info->kck)) {
rtw89_warn(rtwdev, "kek or kck length over fw limit\n");
return;
}
mutex_lock(&rtwdev->mutex);
memcpy(gtk_info->kek, data->kek, data->kek_len);
memcpy(gtk_info->kck, data->kck, data->kck_len);
mutex_unlock(&rtwdev->mutex);
}
#endif
@@ -1818,16 +1742,13 @@ static void rtw89_ops_rfkill_poll(struct ieee80211_hw *hw)
{
struct rtw89_dev *rtwdev = hw->priv;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(hw->wiphy);
/* wl_disable GPIO get floating when entering LPS */
if (test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
goto out;
return;
rtw89_core_rfkill_poll(rtwdev, false);
out:
mutex_unlock(&rtwdev->mutex);
}
const struct ieee80211_ops rtw89_ops = {

View File

@@ -1865,7 +1865,7 @@ int rtw89_mac_cfg_ctrl_path_v2(struct rtw89_dev *rtwdev, bool wl)
if (wl)
return 0;
for (i = 0; i < RTW89_PHY_MAX; i++) {
for (i = 0; i < RTW89_PHY_NUM; i++) {
g[i].gnt_bt_sw_en = 1;
g[i].gnt_bt = 1;
g[i].gnt_wl_sw_en = 1;

File diff suppressed because it is too large Load Diff

View File

@@ -835,8 +835,8 @@ s8 rtw89_phy_read_txpwr_byrate(struct rtw89_dev *rtwdev, u8 band, u8 bw,
void rtw89_phy_ant_gain_init(struct rtw89_dev *rtwdev);
s16 rtw89_phy_ant_gain_pwr_offset(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan);
void rtw89_print_ant_gain(struct seq_file *m, struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan);
int rtw89_print_ant_gain(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
const struct rtw89_chan *chan);
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,
@@ -978,20 +978,20 @@ void rtw89_phy_rfk_tssi_fill_fwcmd_tmeter_tbl(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
struct rtw89_h2c_rf_tssi *h2c);
void rtw89_phy_cfo_track(struct rtw89_dev *rtwdev);
void rtw89_phy_cfo_track_work(struct work_struct *work);
void rtw89_phy_cfo_track_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_phy_cfo_parse(struct rtw89_dev *rtwdev, s16 cfo_val,
struct rtw89_rx_phy_ppdu *phy_ppdu);
void rtw89_phy_stat_track(struct rtw89_dev *rtwdev);
void rtw89_phy_env_monitor_track(struct rtw89_dev *rtwdev);
void rtw89_phy_set_phy_regs(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
u32 val);
void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev);
void rtw89_phy_dig_reset(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb);
void rtw89_phy_dig(struct rtw89_dev *rtwdev);
void rtw89_phy_tx_path_div_track(struct rtw89_dev *rtwdev);
void rtw89_phy_antdiv_parse(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu);
void rtw89_phy_antdiv_track(struct rtw89_dev *rtwdev);
void rtw89_phy_antdiv_work(struct work_struct *work);
void rtw89_phy_antdiv_work(struct wiphy *wiphy, struct wiphy_work *work);
void rtw89_phy_set_bss_color(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link);
void rtw89_phy_tssi_ctrl_set_bandedge_cfg(struct rtw89_dev *rtwdev,
@@ -1002,9 +1002,10 @@ void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev);
u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band);
void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx,
u8 *ch, enum nl80211_band *band);
void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev, bool scan);
void rtw89_phy_config_edcca(struct rtw89_dev *rtwdev,
struct rtw89_bb_ctx *bb, bool scan);
void rtw89_phy_edcca_track(struct rtw89_dev *rtwdev);
void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev);
void rtw89_phy_edcca_thre_calc(struct rtw89_dev *rtwdev, struct rtw89_bb_ctx *bb);
enum rtw89_rf_path_bit rtw89_phy_get_kpath(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx);
enum rtw89_rf_path rtw89_phy_get_syn_sel(struct rtw89_dev *rtwdev,

View File

@@ -113,7 +113,7 @@ static void __rtw89_leave_lps(struct rtw89_dev *rtwdev,
void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
{
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
__rtw89_leave_ps_mode(rtwdev);
}
@@ -125,7 +125,7 @@ void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
bool can_ps_mode = true;
unsigned int link_id;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (test_and_set_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags))
return;
@@ -162,7 +162,7 @@ void rtw89_leave_lps(struct rtw89_dev *rtwdev)
struct rtw89_vif *rtwvif;
unsigned int link_id;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (!test_and_clear_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags))
return;

View File

@@ -8157,6 +8157,8 @@
#define B_EDCCA_RPT_B_S40 BIT(4)
#define B_EDCCA_RPT_B_S80 BIT(3)
#define B_EDCCA_RPT_B_PATH_MASK GENMASK(2, 1)
#define R_EDCCA_RPT_P1_A 0x1740
#define R_EDCCA_RPT_P1_B 0x1744
#define R_SWSI_V1 0x174C
#define B_SWSI_W_BUSY_V1 BIT(24)
#define B_SWSI_R_BUSY_V1 BIT(25)
@@ -8222,6 +8224,7 @@
#define B_TXCKEN_FORCE_ALL GENMASK(24, 0)
#define R_EDCCA_RPT_SEL 0x20CC
#define B_EDCCA_RPT_SEL_MSK GENMASK(2, 0)
#define B_EDCCA_RPT_SEL_P1_MSK GENMASK(5, 3)
#define R_ADC_FIFO 0x20fc
#define B_ADC_FIFO_RST GENMASK(31, 24)
#define B_ADC_FIFO_RXK GENMASK(31, 16)
@@ -8291,6 +8294,8 @@
#define B_P1_EN_SOUND_WO_NDP BIT(1)
#define R_EDCCA_RPT_A_BE 0x2E38
#define R_EDCCA_RPT_B_BE 0x2E3C
#define R_EDCCA_RPT_P1_A_BE 0x2E40
#define R_EDCCA_RPT_P1_B_BE 0x2E44
#define R_S1_HW_SI_DIS 0x3200
#define B_S1_HW_SI_DIS_W_R_TRIG GENMASK(30, 28)
#define R_P1_RXCK 0x32A0

View File

@@ -7,257 +7,266 @@
#include "ps.h"
#include "util.h"
#define COUNTRY_REGD(_alpha2, _txpwr_regd...) \
{.alpha2 = (_alpha2), \
.txpwr_regd = {_txpwr_regd}, \
static
void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request);
#define COUNTRY_REGD(_alpha2, _rule_2ghz, _rule_5ghz, _rule_6ghz, _fmap) \
{ \
.alpha2 = _alpha2, \
.txpwr_regd[RTW89_BAND_2G] = _rule_2ghz, \
.txpwr_regd[RTW89_BAND_5G] = _rule_5ghz, \
.txpwr_regd[RTW89_BAND_6G] = _rule_6ghz, \
.func_bitmap = { _fmap, }, \
}
static_assert(BITS_PER_TYPE(unsigned long) >= NUM_OF_RTW89_REGD_FUNC);
static const struct rtw89_regd rtw89_ww_regd =
COUNTRY_REGD("00", RTW89_WW, RTW89_WW, RTW89_WW);
COUNTRY_REGD("00", RTW89_WW, RTW89_WW, RTW89_WW, 0x0);
static const struct rtw89_regd rtw89_regd_map[] = {
COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC),
COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("CL", RTW89_CHILE, RTW89_CHILE, RTW89_CHILE),
COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("CR", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("EC", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("SV", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("HN", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC),
COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("UY", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("VE", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("PR", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("DO", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("AT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("BE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("CY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("CZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("DK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("EE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("FI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("FR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("DE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("GR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("HU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("IS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("IE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("IT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("LV", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("LI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("LT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("LU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("MT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("MC", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("NL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("NO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("PL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("PT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("SK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("SI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("ES", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("SE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("CH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("GB", RTW89_UK, RTW89_UK, RTW89_UK),
COUNTRY_REGD("AL", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("BH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("BA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("HR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("EG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("GH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("IQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("IL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("JO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("KZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("LB", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("LS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("MK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("MZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("NA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("NG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("OM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("QA", RTW89_QATAR, RTW89_QATAR, RTW89_QATAR),
COUNTRY_REGD("RO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("RU", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("SN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("ME", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("ZA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("UA", RTW89_UKRAINE, RTW89_UKRAINE, RTW89_UKRAINE),
COUNTRY_REGD("AE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("YE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("ZW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("BD", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("CN", RTW89_CN, RTW89_CN, RTW89_CN),
COUNTRY_REGD("HK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("IN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC, RTW89_KCC),
COUNTRY_REGD("MY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("PK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("PH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("SG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("LK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC, RTW89_ETSI),
COUNTRY_REGD("TH", RTW89_THAILAND, RTW89_THAILAND, RTW89_THAILAND),
COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA),
COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA),
COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("CA", RTW89_IC, RTW89_IC, RTW89_IC),
COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK, RTW89_MKK),
COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("TN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("DZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("AD", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("AQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("AM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("BY", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BZ", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("BJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("BT", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("BV", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("IO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("BN", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BF", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("MM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("CM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("CV", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("CF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("CX", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
COUNTRY_REGD("CC", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
COUNTRY_REGD("KM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("CG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("CD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("CK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("DJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("ER", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("ET", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("FK", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("FO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("FJ", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("GF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("PF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("GE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("GI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("GG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("GW", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GY", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("HM", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
COUNTRY_REGD("VA", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("IM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("JE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KI", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("XK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("LA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("LR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("LY", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("MW", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MV", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("ML", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MH", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("MQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MR", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("MU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("MS", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("NR", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("NP", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("NC", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("NE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("NU", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
COUNTRY_REGD("NF", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
COUNTRY_REGD("MP", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("PW", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("RE", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("RW", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("PM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("VC", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("WS", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("SM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("ST", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC, RTW89_NA),
COUNTRY_REGD("SL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("SB", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("GS", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("SJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("TJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("TZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("TG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("TK", RTW89_ACMA, RTW89_ACMA, RTW89_NA),
COUNTRY_REGD("TO", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TC", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("TV", RTW89_ETSI, RTW89_NA, RTW89_NA),
COUNTRY_REGD("UG", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("VI", RTW89_FCC, RTW89_FCC, RTW89_FCC),
COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI),
COUNTRY_REGD("VU", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("WF", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("EH", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("ZM", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("CU", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("IR", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("SY", RTW89_ETSI, RTW89_NA, RTW89_NA),
COUNTRY_REGD("SD", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("PS", RTW89_ETSI, RTW89_ETSI, RTW89_NA),
COUNTRY_REGD("AR", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC, 0x0),
COUNTRY_REGD("BO", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("BR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("CL", RTW89_CHILE, RTW89_CHILE, RTW89_CHILE, 0x0),
COUNTRY_REGD("CO", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("CR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("EC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("SV", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("GT", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("HN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("MX", RTW89_MEXICO, RTW89_MEXICO, RTW89_FCC, 0x0),
COUNTRY_REGD("NI", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("PA", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("PY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("PE", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("US", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x1),
COUNTRY_REGD("UY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("VE", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("PR", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("DO", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("AT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("BE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("CY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("CZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("DK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("EE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("FI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("FR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("DE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("GR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("HU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("IS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("IE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("IT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("LV", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("LI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("LT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("LU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("MT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("MC", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("NL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("NO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("PL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("PT", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("SK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("SI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("ES", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("SE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("CH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("GB", RTW89_UK, RTW89_UK, RTW89_UK, 0x0),
COUNTRY_REGD("AL", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("AZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("BH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("BA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("BG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("HR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("EG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("GH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("IQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("IL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("JO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("KZ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("KE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("KW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("KG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("LB", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("LS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("MK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("MA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("MZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("NA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("NG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("OM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("QA", RTW89_QATAR, RTW89_QATAR, RTW89_QATAR, 0x0),
COUNTRY_REGD("RO", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x2),
COUNTRY_REGD("RU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("SA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("SN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("RS", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("ME", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("ZA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("TR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("UA", RTW89_UKRAINE, RTW89_UKRAINE, RTW89_UKRAINE, 0x0),
COUNTRY_REGD("AE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("YE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("ZW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("BD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("KH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("CN", RTW89_CN, RTW89_CN, RTW89_CN, 0x0),
COUNTRY_REGD("HK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("IN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("ID", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("KR", RTW89_KCC, RTW89_KCC, RTW89_KCC, 0x1),
COUNTRY_REGD("MY", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("PK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("PH", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("SG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("LK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("TW", RTW89_FCC, RTW89_FCC, RTW89_ETSI, 0x0),
COUNTRY_REGD("TH", RTW89_THAILAND, RTW89_THAILAND, RTW89_THAILAND, 0x0),
COUNTRY_REGD("VN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("AU", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA, 0x0),
COUNTRY_REGD("NZ", RTW89_ACMA, RTW89_ACMA, RTW89_ACMA, 0x0),
COUNTRY_REGD("PG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("CA", RTW89_IC, RTW89_IC, RTW89_IC, 0x1),
COUNTRY_REGD("JP", RTW89_MKK, RTW89_MKK, RTW89_MKK, 0x0),
COUNTRY_REGD("JM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("AN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("TT", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("TN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("AF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("DZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("AS", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("AD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("AO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("AI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("AQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("AG", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("AM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("AW", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("BS", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("BB", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("BY", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("BZ", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("BJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("BM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("BT", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("BW", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("BV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("IO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("VG", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("BN", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("BF", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("MM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("BI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("CM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("CV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("KY", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("CF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("TD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("CX", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
COUNTRY_REGD("CC", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
COUNTRY_REGD("KM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("CG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("CD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("CK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("CI", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("DJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("DM", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("GQ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("ER", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("ET", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("FK", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("FO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("FJ", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("GF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("PF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("TF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("GA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("GM", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("GE", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("GI", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("GL", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("GD", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("GP", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("GU", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("GG", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("GN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("GW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("GY", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("HT", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("HM", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
COUNTRY_REGD("VA", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("IM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("JE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("KI", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("XK", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("LA", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("LR", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("LY", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("MO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("MG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("MW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("MV", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("ML", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("MH", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("MQ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("MR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("MU", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("YT", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("FM", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("MD", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("MN", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("MS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("NR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("NP", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("NC", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("NE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("NU", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
COUNTRY_REGD("NF", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
COUNTRY_REGD("MP", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("PW", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("RE", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("RW", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("SH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("KN", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("LC", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("MF", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("SX", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("PM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("VC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("WS", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("SM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("ST", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("SC", RTW89_FCC, RTW89_FCC, RTW89_NA, 0x0),
COUNTRY_REGD("SL", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("SB", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("SO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("GS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("SR", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("SJ", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("SZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("TJ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("TZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("TG", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("TK", RTW89_ACMA, RTW89_ACMA, RTW89_NA, 0x0),
COUNTRY_REGD("TO", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("TM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("TC", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("TV", RTW89_ETSI, RTW89_NA, RTW89_NA, 0x0),
COUNTRY_REGD("UG", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("VI", RTW89_FCC, RTW89_FCC, RTW89_FCC, 0x0),
COUNTRY_REGD("UZ", RTW89_ETSI, RTW89_ETSI, RTW89_ETSI, 0x0),
COUNTRY_REGD("VU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("WF", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("EH", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("ZM", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("CU", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("IR", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("SY", RTW89_ETSI, RTW89_NA, RTW89_NA, 0x0),
COUNTRY_REGD("SD", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
COUNTRY_REGD("PS", RTW89_ETSI, RTW89_ETSI, RTW89_NA, 0x0),
};
static const char rtw89_alpha2_list_eu[][3] = {
@@ -295,13 +304,16 @@ static const char rtw89_alpha2_list_eu[][3] = {
"RO",
};
static const struct rtw89_regd *rtw89_regd_find_reg_by_name(const char *alpha2)
static const struct rtw89_regd *rtw89_regd_find_reg_by_name(struct rtw89_dev *rtwdev,
const char *alpha2)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_regd_ctrl *regd_ctrl = &regulatory->ctrl;
u32 i;
for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) {
if (!memcmp(rtw89_regd_map[i].alpha2, alpha2, 2))
return &rtw89_regd_map[i];
for (i = 0; i < regd_ctrl->nr; i++) {
if (!memcmp(regd_ctrl->map[i].alpha2, alpha2, 2))
return &regd_ctrl->map[i];
}
return &rtw89_ww_regd;
@@ -312,22 +324,25 @@ static bool rtw89_regd_is_ww(const struct rtw89_regd *regd)
return regd == &rtw89_ww_regd;
}
static u8 rtw89_regd_get_index(const struct rtw89_regd *regd)
static u8 rtw89_regd_get_index(struct rtw89_dev *rtwdev, const struct rtw89_regd *regd)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_regd_ctrl *regd_ctrl = &regulatory->ctrl;
BUILD_BUG_ON(ARRAY_SIZE(rtw89_regd_map) > RTW89_REGD_MAX_COUNTRY_NUM);
if (rtw89_regd_is_ww(regd))
return RTW89_REGD_MAX_COUNTRY_NUM;
return regd - rtw89_regd_map;
return regd - regd_ctrl->map;
}
static u8 rtw89_regd_get_index_by_name(const char *alpha2)
static u8 rtw89_regd_get_index_by_name(struct rtw89_dev *rtwdev, const char *alpha2)
{
const struct rtw89_regd *regd;
regd = rtw89_regd_find_reg_by_name(alpha2);
return rtw89_regd_get_index(regd);
regd = rtw89_regd_find_reg_by_name(rtwdev, alpha2);
return rtw89_regd_get_index(rtwdev, regd);
}
#define rtw89_debug_regd(_dev, _regd, _desc, _argv...) \
@@ -345,6 +360,7 @@ static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev,
struct wiphy *wiphy)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_regd_ctrl *regd_ctrl = &regulatory->ctrl;
const struct rtw89_chip_info *chip = rtwdev->chip;
struct ieee80211_supported_band *sband;
struct rtw89_acpi_dsm_result res = {};
@@ -382,8 +398,8 @@ static void rtw89_regd_setup_unii4(struct rtw89_dev *rtwdev,
"acpi: eval if allow unii-4: 0x%x\n", val);
bottom:
for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) {
const struct rtw89_regd *regd = &rtw89_regd_map[i];
for (i = 0; i < regd_ctrl->nr; i++) {
const struct rtw89_regd *regd = &regd_ctrl->map[i];
switch (regd->txpwr_regd[RTW89_BAND_5G]) {
case RTW89_FCC:
@@ -406,7 +422,7 @@ static void __rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev, bool block,
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
u8 index;
index = rtw89_regd_get_index_by_name(alpha2);
index = rtw89_regd_get_index_by_name(rtwdev, alpha2);
if (index == RTW89_REGD_MAX_COUNTRY_NUM) {
rtw89_debug(rtwdev, RTW89_DBG_REGD, "%s: unknown alpha2 %c%c\n",
__func__, alpha2[0], alpha2[1]);
@@ -474,6 +490,7 @@ static void rtw89_regd_setup_policy_6ghz(struct rtw89_dev *rtwdev)
static void rtw89_regd_setup_policy_6ghz_sp(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_regd_ctrl *regd_ctrl = &regulatory->ctrl;
const struct rtw89_acpi_policy_6ghz_sp *ptr;
struct rtw89_acpi_dsm_result res = {};
bool enable_by_us;
@@ -505,8 +522,8 @@ static void rtw89_regd_setup_policy_6ghz_sp(struct rtw89_dev *rtwdev)
enable_by_us = u8_get_bits(ptr->conf, RTW89_ACPI_CONF_6GHZ_SP_US);
for (i = 0; i < ARRAY_SIZE(rtw89_regd_map); i++) {
const struct rtw89_regd *tmp = &rtw89_regd_map[i];
for (i = 0; i < regd_ctrl->nr; i++) {
const struct rtw89_regd *tmp = &regd_ctrl->map[i];
if (enable_by_us && memcmp(tmp->alpha2, "US", 2) == 0)
clear_bit(i, regulatory->block_6ghz_sp);
@@ -573,8 +590,21 @@ static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy)
int rtw89_regd_setup(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info;
const struct rtw89_regd_data *regd_data = elm_info->regd;
struct wiphy *wiphy = rtwdev->hw->wiphy;
if (regd_data) {
regulatory->ctrl.nr = regd_data->nr;
regulatory->ctrl.map = regd_data->map;
} else {
regulatory->ctrl.nr = ARRAY_SIZE(rtw89_regd_map);
regulatory->ctrl.map = rtw89_regd_map;
}
regulatory->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
if (!wiphy)
return -EINVAL;
@@ -585,21 +615,16 @@ int rtw89_regd_setup(struct rtw89_dev *rtwdev)
return 0;
}
int rtw89_regd_init(struct rtw89_dev *rtwdev,
void (*reg_notifier)(struct wiphy *wiphy,
struct regulatory_request *request))
int rtw89_regd_init_hint(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_regd *chip_regd;
struct wiphy *wiphy = rtwdev->hw->wiphy;
int ret;
regulatory->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
if (!wiphy)
return -EINVAL;
chip_regd = rtw89_regd_find_reg_by_name(rtwdev->efuse.country_code);
chip_regd = rtw89_regd_find_reg_by_name(rtwdev, rtwdev->efuse.country_code);
if (!rtw89_regd_is_ww(chip_regd)) {
rtwdev->regulatory.regd = chip_regd;
/* Ignore country ie if there is a country domain programmed in chip */
@@ -637,7 +662,7 @@ static void rtw89_regd_apply_policy_unii4(struct rtw89_dev *rtwdev,
if (!chip->support_unii4)
return;
index = rtw89_regd_get_index(regd);
index = rtw89_regd_get_index(rtwdev, regd);
if (index != RTW89_REGD_MAX_COUNTRY_NUM &&
!test_bit(index, regulatory->block_unii4))
return;
@@ -655,7 +680,7 @@ static bool regd_is_6ghz_blocked(struct rtw89_dev *rtwdev)
const struct rtw89_regd *regd = regulatory->regd;
u8 index;
index = rtw89_regd_get_index(regd);
index = rtw89_regd_get_index(rtwdev, regd);
if (index != RTW89_REGD_MAX_COUNTRY_NUM &&
!test_bit(index, regulatory->block_6ghz))
return false;
@@ -700,7 +725,7 @@ static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev,
struct wiphy *wiphy,
struct regulatory_request *request)
{
rtwdev->regulatory.regd = rtw89_regd_find_reg_by_name(request->alpha2);
rtwdev->regulatory.regd = rtw89_regd_find_reg_by_name(rtwdev, request->alpha2);
/* This notification might be set from the system of distros,
* and it does not expect the regulatory will be modified by
* connecting to an AP (i.e. country ie).
@@ -715,12 +740,13 @@ static void rtw89_regd_notifier_apply(struct rtw89_dev *rtwdev,
rtw89_regd_apply_policy_6ghz(rtwdev, wiphy);
}
static
void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request)
{
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct rtw89_dev *rtwdev = hw->priv;
mutex_lock(&rtwdev->mutex);
wiphy_lock(wiphy);
rtw89_leave_ps_mode(rtwdev);
if (wiphy->regd) {
@@ -736,7 +762,7 @@ void rtw89_regd_notifier(struct wiphy *wiphy, struct regulatory_request *request
rtw89_core_set_chip_txpwr(rtwdev);
exit:
mutex_unlock(&rtwdev->mutex);
wiphy_unlock(wiphy);
}
/* Maximum Transmit Power field (@raw) can be EIRP or PSD.
@@ -925,7 +951,7 @@ static bool __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev)
sel = RTW89_REG_6GHZ_POWER_DFLT;
if (sel == RTW89_REG_6GHZ_POWER_STD) {
index = rtw89_regd_get_index(regd);
index = rtw89_regd_get_index(rtwdev, regd);
if (index == RTW89_REGD_MAX_COUNTRY_NUM ||
test_bit(index, regulatory->block_6ghz_sp)) {
rtw89_debug(rtwdev, RTW89_DBG_REGD,
@@ -986,7 +1012,7 @@ int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvi
unsigned int changed = 0;
int ret;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
/* The result of reg_6ghz_tpe may depend on reg_6ghz_power type,
* so must do reg_6ghz_tpe_recalc() after reg_6ghz_power_recalc().

View File

@@ -224,10 +224,17 @@ static const struct rtw89_edcca_regs rtw8851b_edcca_regs = {
.edcca_p_mask = B_EDCCA_LVL_MSK1,
.ppdu_level = R_SEG0R_EDCCA_LVL_V1,
.ppdu_mask = B_EDCCA_LVL_MSK3,
.rpt_a = R_EDCCA_RPT_A,
.rpt_b = R_EDCCA_RPT_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
.p = {{
.rpt_a = R_EDCCA_RPT_A,
.rpt_b = R_EDCCA_RPT_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
}, {
.rpt_a = R_EDCCA_RPT_P1_A,
.rpt_b = R_EDCCA_RPT_P1_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK,
}},
.tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
.tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
};
@@ -1596,10 +1603,16 @@ static void rtw8851b_rfk_channel(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw89_btc_ntfy_conn_rfk(rtwdev, true);
rtw8851b_rx_dck(rtwdev, phy_idx, chanctx_idx);
rtw8851b_iqk(rtwdev, phy_idx, chanctx_idx);
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
rtw8851b_tssi(rtwdev, phy_idx, true, chanctx_idx);
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
rtw8851b_dpk(rtwdev, phy_idx, chanctx_idx);
rtw89_btc_ntfy_conn_rfk(rtwdev, false);
}
static void rtw8851b_rfk_band_changed(struct rtw89_dev *rtwdev,

View File

@@ -522,10 +522,17 @@ static const struct rtw89_edcca_regs rtw8852a_edcca_regs = {
.edcca_p_mask = B_EDCCA_LVL_MSK1,
.ppdu_level = R_SEG0R_EDCCA_LVL,
.ppdu_mask = B_EDCCA_LVL_MSK3,
.rpt_a = R_EDCCA_RPT_A,
.rpt_b = R_EDCCA_RPT_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
.p = {{
.rpt_a = R_EDCCA_RPT_A,
.rpt_b = R_EDCCA_RPT_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
}, {
.rpt_a = R_EDCCA_RPT_P1_A,
.rpt_b = R_EDCCA_RPT_P1_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK,
}},
.tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
.tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
};
@@ -1356,10 +1363,16 @@ static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw89_btc_ntfy_conn_rfk(rtwdev, true);
rtw8852a_rx_dck(rtwdev, phy_idx, true, chanctx_idx);
rtw8852a_iqk(rtwdev, phy_idx, chanctx_idx);
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
rtw8852a_tssi(rtwdev, phy_idx, chanctx_idx);
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
rtw8852a_dpk(rtwdev, phy_idx, chanctx_idx);
rtw89_btc_ntfy_conn_rfk(rtwdev, false);
}
static void rtw8852a_rfk_band_changed(struct rtw89_dev *rtwdev,

View File

@@ -189,10 +189,17 @@ static const struct rtw89_edcca_regs rtw8852b_edcca_regs = {
.edcca_p_mask = B_EDCCA_LVL_MSK1,
.ppdu_level = R_SEG0R_EDCCA_LVL_V1,
.ppdu_mask = B_EDCCA_LVL_MSK3,
.rpt_a = R_EDCCA_RPT_A,
.rpt_b = R_EDCCA_RPT_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
.p = {{
.rpt_a = R_EDCCA_RPT_A,
.rpt_b = R_EDCCA_RPT_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
}, {
.rpt_a = R_EDCCA_RPT_P1_A,
.rpt_b = R_EDCCA_RPT_P1_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK,
}},
.tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
.tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
};
@@ -568,10 +575,16 @@ static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw89_btc_ntfy_conn_rfk(rtwdev, true);
rtw8852b_rx_dck(rtwdev, phy_idx, chanctx_idx);
rtw8852b_iqk(rtwdev, phy_idx, chanctx_idx);
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
rtw8852b_tssi(rtwdev, phy_idx, true, chanctx_idx);
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
rtw8852b_dpk(rtwdev, phy_idx, chanctx_idx);
rtw89_btc_ntfy_conn_rfk(rtwdev, false);
}
static void rtw8852b_rfk_band_changed(struct rtw89_dev *rtwdev,

View File

@@ -187,10 +187,17 @@ static const struct rtw89_edcca_regs rtw8852bt_edcca_regs = {
.edcca_p_mask = B_EDCCA_LVL_MSK1,
.ppdu_level = R_SEG0R_EDCCA_LVL_V1,
.ppdu_mask = B_EDCCA_LVL_MSK3,
.rpt_a = R_EDCCA_RPT_A,
.rpt_b = R_EDCCA_RPT_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
.p = {{
.rpt_a = R_EDCCA_RPT_A,
.rpt_b = R_EDCCA_RPT_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
}, {
.rpt_a = R_EDCCA_RPT_P1_A,
.rpt_b = R_EDCCA_RPT_P1_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK,
}},
.tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
.tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
};
@@ -541,10 +548,16 @@ static void rtw8852bt_rfk_channel(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw89_btc_ntfy_conn_rfk(rtwdev, true);
rtw8852bt_rx_dck(rtwdev, phy_idx, chanctx_idx);
rtw8852bt_iqk(rtwdev, phy_idx, chanctx_idx);
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
rtw8852bt_tssi(rtwdev, phy_idx, true, chanctx_idx);
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
rtw8852bt_dpk(rtwdev, phy_idx, chanctx_idx);
rtw89_btc_ntfy_conn_rfk(rtwdev, false);
}
static void rtw8852bt_rfk_band_changed(struct rtw89_dev *rtwdev,

View File

@@ -186,10 +186,17 @@ static const struct rtw89_edcca_regs rtw8852c_edcca_regs = {
.edcca_p_mask = B_EDCCA_LVL_MSK1,
.ppdu_level = R_SEG0R_EDCCA_LVL,
.ppdu_mask = B_EDCCA_LVL_MSK3,
.rpt_a = R_EDCCA_RPT_A,
.rpt_b = R_EDCCA_RPT_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
.p = {{
.rpt_a = R_EDCCA_RPT_A,
.rpt_b = R_EDCCA_RPT_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
}, {
.rpt_a = R_EDCCA_RPT_P1_A,
.rpt_b = R_EDCCA_RPT_P1_B,
.rpt_sel = R_EDCCA_RPT_SEL,
.rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK,
}},
.tx_collision_t2r_st = R_TX_COLLISION_T2R_ST,
.tx_collision_t2r_st_mask = B_TX_COLLISION_T2R_ST_M,
};
@@ -1853,10 +1860,16 @@ static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw8852c_mcc_get_ch_info(rtwdev, phy_idx);
rtw89_btc_ntfy_conn_rfk(rtwdev, true);
rtw8852c_rx_dck(rtwdev, phy_idx, false);
rtw8852c_iqk(rtwdev, phy_idx, chanctx_idx);
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
rtw8852c_tssi(rtwdev, phy_idx, chanctx_idx);
rtw89_btc_ntfy_preserve_bt_time(rtwdev, 30);
rtw8852c_dpk(rtwdev, phy_idx, chanctx_idx);
rtw89_btc_ntfy_conn_rfk(rtwdev, false);
rtw89_fw_h2c_rf_ntfy_mcc(rtwdev);
}

View File

@@ -205,10 +205,17 @@ static const struct rtw89_edcca_regs rtw8922a_edcca_regs = {
.edcca_p_mask = B_EDCCA_LVL_MSK1,
.ppdu_level = R_SEG0R_PPDU_LVL_BE,
.ppdu_mask = B_EDCCA_LVL_MSK1,
.rpt_a = R_EDCCA_RPT_A_BE,
.rpt_b = R_EDCCA_RPT_B_BE,
.rpt_sel = R_EDCCA_RPT_SEL_BE,
.rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
.p = {{
.rpt_a = R_EDCCA_RPT_A_BE,
.rpt_b = R_EDCCA_RPT_B_BE,
.rpt_sel = R_EDCCA_RPT_SEL_BE,
.rpt_sel_mask = B_EDCCA_RPT_SEL_MSK,
}, {
.rpt_a = R_EDCCA_RPT_P1_A_BE,
.rpt_b = R_EDCCA_RPT_P1_B_BE,
.rpt_sel = R_EDCCA_RPT_SEL_BE,
.rpt_sel_mask = B_EDCCA_RPT_SEL_P1_MSK,
}},
.rpt_sel_be = R_EDCCA_RPTREG_SEL_BE,
.rpt_sel_be_mask = B_EDCCA_RPTREG_SEL_BE_MSK,
.tx_collision_t2r_st = R_TX_COLLISION_T2R_ST_BE,

View File

@@ -99,7 +99,7 @@ struct rtw89_sar_handler rtw89_sar_handlers[RTW89_SAR_SOURCE_NR] = {
typeof(_dev) _d = (_dev); \
BUILD_BUG_ON(!rtw89_sar_handlers[_s].descr_sar_source); \
BUILD_BUG_ON(!rtw89_sar_handlers[_s].query_sar_config); \
lockdep_assert_held(&_d->mutex); \
lockdep_assert_wiphy(_d->hw->wiphy); \
_d->sar._cfg_name = *(_cfg_data); \
_d->sar.src = _s; \
} while (0)
@@ -150,7 +150,7 @@ s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq)
s32 cfg;
u8 fct;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (src == RTW89_SAR_SOURCE_NONE)
return RTW89_SAR_TXPWR_MAC_MAX;
@@ -178,72 +178,80 @@ s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq)
return rtw89_txpwr_sar_to_mac(rtwdev, fct, cfg);
}
void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev, u32 center_freq)
int rtw89_print_sar(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
u32 center_freq)
{
const enum rtw89_sar_sources src = rtwdev->sar.src;
/* its members are protected by rtw89_sar_set_src() */
const struct rtw89_sar_handler *sar_hdl = &rtw89_sar_handlers[src];
const u8 fct_mac = rtwdev->chip->txpwr_factor_mac;
char *p = buf, *end = buf + bufsz;
int ret;
s32 cfg;
u8 fct;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (src == RTW89_SAR_SOURCE_NONE) {
seq_puts(m, "no SAR is applied\n");
return;
p += scnprintf(p, end - p, "no SAR is applied\n");
goto out;
}
seq_printf(m, "source: %d (%s)\n", src, sar_hdl->descr_sar_source);
p += scnprintf(p, end - p, "source: %d (%s)\n", src,
sar_hdl->descr_sar_source);
ret = sar_hdl->query_sar_config(rtwdev, center_freq, &cfg);
if (ret) {
seq_printf(m, "config: return code: %d\n", ret);
seq_printf(m, "assign: max setting: %d (unit: 1/%lu dBm)\n",
RTW89_SAR_TXPWR_MAC_MAX, BIT(fct_mac));
return;
p += scnprintf(p, end - p, "config: return code: %d\n", ret);
p += scnprintf(p, end - p,
"assign: max setting: %d (unit: 1/%lu dBm)\n",
RTW89_SAR_TXPWR_MAC_MAX, BIT(fct_mac));
goto out;
}
fct = sar_hdl->txpwr_factor_sar;
seq_printf(m, "config: %d (unit: 1/%lu dBm)\n", cfg, BIT(fct));
p += scnprintf(p, end - p, "config: %d (unit: 1/%lu dBm)\n", cfg,
BIT(fct));
out:
return p - buf;
}
void rtw89_print_tas(struct seq_file *m, struct rtw89_dev *rtwdev)
int rtw89_print_tas(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_tas_info *tas = &rtwdev->tas;
char *p = buf, *end = buf + bufsz;
if (!tas->enable) {
seq_puts(m, "no TAS is applied\n");
return;
p += scnprintf(p, end - p, "no TAS is applied\n");
goto out;
}
seq_printf(m, "DPR gap: %d\n", tas->dpr_gap);
seq_printf(m, "TAS delta: %d\n", tas->delta);
p += scnprintf(p, end - p, "DPR gap: %d\n", tas->dpr_gap);
p += scnprintf(p, end - p, "TAS delta: %d\n", tas->delta);
out:
return p - buf;
}
static int rtw89_apply_sar_common(struct rtw89_dev *rtwdev,
const struct rtw89_sar_cfg_common *sar)
{
enum rtw89_sar_sources src;
int ret = 0;
mutex_lock(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
src = rtwdev->sar.src;
if (src != RTW89_SAR_SOURCE_NONE && src != RTW89_SAR_SOURCE_COMMON) {
rtw89_warn(rtwdev, "SAR source: %d is in use", src);
ret = -EBUSY;
goto exit;
return -EBUSY;
}
rtw89_sar_set_src(rtwdev, RTW89_SAR_SOURCE_COMMON, cfg_common, sar);
rtw89_core_set_chip_txpwr(rtwdev);
exit:
mutex_unlock(&rtwdev->mutex);
return ret;
return 0;
}
static const struct cfg80211_sar_freq_ranges rtw89_common_sar_freq_ranges[] = {
@@ -279,6 +287,8 @@ int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw,
s32 power;
u32 i, idx;
lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (sar->type != NL80211_SAR_TYPE_POWER)
return -EINVAL;
@@ -316,7 +326,7 @@ static void rtw89_tas_state_update(struct rtw89_dev *rtwdev)
const struct rtw89_chan *chan;
int ret;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
if (src == RTW89_SAR_SOURCE_NONE)
return;
@@ -411,7 +421,8 @@ static const struct rtw89_reg_def txpwr_regs[] = {
void rtw89_tas_track(struct rtw89_dev *rtwdev)
{
struct rtw89_env_monitor_info *env = &rtwdev->env_monitor;
struct rtw89_bb_ctx *bb = rtw89_get_bb_ctx(rtwdev, RTW89_PHY_0);
struct rtw89_env_monitor_info *env = &bb->env_monitor;
const enum rtw89_sar_sources src = rtwdev->sar.src;
u8 max_nss_num = rtwdev->chip->rf_path_num;
struct rtw89_tas_info *tas = &rtwdev->tas;

View File

@@ -19,8 +19,9 @@ struct rtw89_sar_handler {
extern const struct cfg80211_sar_capa rtw89_sar_capa;
s8 rtw89_query_sar(struct rtw89_dev *rtwdev, u32 center_freq);
void rtw89_print_sar(struct seq_file *m, struct rtw89_dev *rtwdev, u32 center_freq);
void rtw89_print_tas(struct seq_file *m, struct rtw89_dev *rtwdev);
int rtw89_print_sar(struct rtw89_dev *rtwdev, char *buf, size_t bufsz,
u32 center_freq);
int rtw89_print_tas(struct rtw89_dev *rtwdev, char *buf, size_t bufsz);
int rtw89_ops_set_sar_specs(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar);
void rtw89_tas_init(struct rtw89_dev *rtwdev);

View File

@@ -156,9 +156,9 @@ static void ser_state_run(struct rtw89_ser *ser, u8 evt)
rtw89_debug(rtwdev, RTW89_DBG_SER, "ser: %s receive %s\n",
ser_st_name(ser), ser_ev_name(ser, evt));
mutex_lock(&rtwdev->mutex);
wiphy_lock(rtwdev->hw->wiphy);
rtw89_leave_lps(rtwdev);
mutex_unlock(&rtwdev->mutex);
wiphy_unlock(rtwdev->hw->wiphy);
ser->st_tbl[ser->state].st_func(ser, evt);
}
@@ -483,10 +483,13 @@ static void ser_l1_reset_pre_st_hdl(struct rtw89_ser *ser, u8 evt)
static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt)
{
struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser);
struct wiphy *wiphy = rtwdev->hw->wiphy;
switch (evt) {
case SER_EV_STATE_IN:
cancel_delayed_work_sync(&rtwdev->track_work);
wiphy_lock(wiphy);
wiphy_delayed_work_cancel(wiphy, &rtwdev->track_work);
wiphy_unlock(wiphy);
drv_stop_tx(ser);
if (hal_stop_dma(ser)) {
@@ -517,8 +520,8 @@ static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt)
hal_enable_dma(ser);
drv_resume_rx(ser);
drv_resume_tx(ser);
ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work,
RTW89_TRACK_WORK_PERIOD);
wiphy_delayed_work_queue(wiphy, &rtwdev->track_work,
RTW89_TRACK_WORK_PERIOD);
break;
default:
@@ -708,9 +711,9 @@ static void ser_l2_reset_st_hdl(struct rtw89_ser *ser, u8 evt)
switch (evt) {
case SER_EV_STATE_IN:
mutex_lock(&rtwdev->mutex);
wiphy_lock(rtwdev->hw->wiphy);
ser_l2_reset_st_pre_hdl(ser);
mutex_unlock(&rtwdev->mutex);
wiphy_unlock(rtwdev->hw->wiphy);
ieee80211_restart_hw(rtwdev->hw);
ser_set_alarm(ser, SER_RECFG_TIMEOUT, SER_EV_L2_RECFG_TIMEOUT);

View File

@@ -104,3 +104,14 @@ u64 rtw89_db_2_linear(u32 db)
return linear;
}
EXPORT_SYMBOL(rtw89_db_2_linear);
void rtw89_might_trailing_ellipsis(char *buf, size_t size, ssize_t used)
{
static const char ellipsis[] = "...";
/* length of null terminiator isn't included in 'used' */
if (used + 1 < size || size < sizeof(ellipsis))
return;
memcpy(buf + size - sizeof(ellipsis), ellipsis, sizeof(ellipsis));
}

View File

@@ -12,7 +12,7 @@
ieee80211_iterate_active_interfaces_atomic((rtwdev)->hw, \
IEEE80211_IFACE_ITER_NORMAL, iterator, data)
/* call this function with rtwdev->mutex is held */
/* call this function with wiphy mutex is held */
#define rtw89_for_each_rtwvif(rtwdev, rtwvif) \
list_for_each_entry(rtwvif, &(rtwdev)->rtwvifs_list, list)
@@ -25,7 +25,7 @@ static inline bool rtw89_rtwvif_in_list(struct rtw89_dev *rtwdev,
{
struct rtw89_vif *rtwvif;
lockdep_assert_held(&rtwdev->mutex);
lockdep_assert_wiphy(rtwdev->hw->wiphy);
rtw89_for_each_rtwvif(rtwdev, rtwvif)
if (rtwvif == new)
@@ -77,5 +77,6 @@ static inline void ether_addr_copy_mask(u8 *dst, const u8 *src, u8 mask)
u32 rtw89_linear_2_db(u64 linear);
u64 rtw89_db_2_linear(u32 db);
void rtw89_might_trailing_ellipsis(char *buf, size_t size, ssize_t used);
#endif

View File

@@ -604,6 +604,8 @@ static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev,
struct ieee80211_key_conf *key;
u8 sz;
lockdep_assert_wiphy(rtwdev->hw->wiphy);
cipher_info = rtw89_cipher_alg_recognize(cipher);
sz = struct_size(rekey_conf, key, cipher_info->len);
rekey_conf = kmalloc(sz, GFP_KERNEL);
@@ -616,15 +618,10 @@ static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev,
memcpy(rekey_conf->key, gtk,
flex_array_size(rekey_conf, key, cipher_info->len));
/* ieee80211_gtk_rekey_add() will call set_key(), therefore we
* need to unlock mutex
*/
mutex_unlock(&rtwdev->mutex);
if (ieee80211_vif_is_mld(wow_vif))
key = ieee80211_gtk_rekey_add(wow_vif, rekey_conf, rtwvif_link->link_id);
else
key = ieee80211_gtk_rekey_add(wow_vif, rekey_conf, -1);
mutex_lock(&rtwdev->mutex);
kfree(rekey_conf);
if (IS_ERR(key)) {