Merge tag 'rtw-next-2024-10-10' of https://github.com/pkshih/rtw

rtw-next patches for v6.13

No big change at this point. Regular development and fixes are listed:

rtl8xxxu:
 - correct beaconing for the case of STA + AP

rtw88:
 - consolidate parser of RX descriptor as preparation to support coming
   chips

rtw89:
 - update BT-coexistence to improve user experience for RTL8852BE and
   RTL8852BE-VT
 - correct RTL8922AE RF calibration timeout time and print out firmware
   log
 - set proper PCI EQ value for RTL8852CE and RTL8922AE
 - adjust to support MLO continuously
This commit is contained in:
Kalle Valo
2024-10-17 20:21:22 +03:00
50 changed files with 4446 additions and 2409 deletions

View File

@@ -5058,10 +5058,12 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}
if (changed & BSS_CHANGED_BEACON_ENABLED) {
if (bss_conf->enable_beacon)
if (bss_conf->enable_beacon) {
rtl8xxxu_start_tx_beacon(priv);
else
schedule_delayed_work(&priv->update_beacon_work, 0);
} else {
rtl8xxxu_stop_tx_beacon(priv);
}
}
if (changed & BSS_CHANGED_BEACON)

View File

@@ -2040,31 +2040,33 @@ static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
int params[] = {RTL8723BE_EEPROM_ID, EEPROM_VID, EEPROM_DID,
EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
COUNTRY_CODE_WORLD_WIDE_13};
static const int params[] = {
RTL8723BE_EEPROM_ID, EEPROM_VID, EEPROM_DID,
EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
COUNTRY_CODE_WORLD_WIDE_13
};
u8 *hwinfo;
int i;
bool is_toshiba_smid1 = false;
bool is_toshiba_smid2 = false;
bool is_samsung_smid = false;
bool is_lenovo_smid = false;
u16 toshiba_smid1[] = {
static const u16 toshiba_smid1[] = {
0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180,
0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180,
0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185,
0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185
};
u16 toshiba_smid2[] = {
static const u16 toshiba_smid2[] = {
0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181,
0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185
};
u16 samsung_smid[] = {
static const u16 samsung_smid[] = {
0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192,
0x8193, 0x9191, 0x9192, 0x9193
};
u16 lenovo_smid[] = {
static const u16 lenovo_smid[] = {
0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200
};

View File

@@ -267,7 +267,7 @@ static void rtw_fw_scan_result(struct rtw_dev *rtwdev, u8 *payload,
static void rtw_fw_adaptivity_result(struct rtw_dev *rtwdev, u8 *payload,
u8 length)
{
struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
struct rtw_c2h_adaptivity *result = (struct rtw_c2h_adaptivity *)payload;
rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY,

View File

@@ -228,7 +228,7 @@ static int rtw_sub_pwr_seq_parser(struct rtw_dev *rtwdev, u8 intf_mask,
}
static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
const struct rtw_pwr_seq_cmd **cmd_seq)
const struct rtw_pwr_seq_cmd * const *cmd_seq)
{
u8 cut_mask;
u8 intf_mask;
@@ -271,7 +271,7 @@ static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev,
static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on)
{
const struct rtw_chip_info *chip = rtwdev->chip;
const struct rtw_pwr_seq_cmd **pwr_seq;
const struct rtw_pwr_seq_cmd * const *pwr_seq;
u32 imr = 0;
u8 rpwm;
bool cur_pwr;

View File

@@ -848,9 +848,8 @@ struct rtw_chip_ops {
void (*phy_set_param)(struct rtw_dev *rtwdev);
void (*set_channel)(struct rtw_dev *rtwdev, u8 channel,
u8 bandwidth, u8 primary_chan_idx);
void (*query_rx_desc)(struct rtw_dev *rtwdev, u8 *rx_desc,
struct rtw_rx_pkt_stat *pkt_stat,
struct ieee80211_rx_status *rx_status);
void (*query_phy_status)(struct rtw_dev *rtwdev, u8 *phy_status,
struct rtw_rx_pkt_stat *pkt_stat);
u32 (*read_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
u32 addr, u32 mask);
bool (*write_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
@@ -1167,7 +1166,7 @@ enum rtw_fwcd_item {
/* hardware configuration for each IC */
struct rtw_chip_info {
struct rtw_chip_ops *ops;
const struct rtw_chip_ops *ops;
u8 id;
const char *fw_name;
@@ -1209,8 +1208,8 @@ struct rtw_chip_info {
/* init values */
u8 sys_func_en;
const struct rtw_pwr_seq_cmd **pwr_on_seq;
const struct rtw_pwr_seq_cmd **pwr_off_seq;
const struct rtw_pwr_seq_cmd * const *pwr_on_seq;
const struct rtw_pwr_seq_cmd * const *pwr_off_seq;
const struct rtw_rqpn *rqpn_table;
const struct rtw_prioq_addrs *prioq_addrs;
const struct rtw_page_table *page_table;
@@ -1242,7 +1241,7 @@ struct rtw_chip_info {
u8 bfer_su_max_num;
u8 bfer_mu_max_num;
struct rtw_hw_reg_offset *edcca_th;
const struct rtw_hw_reg_offset *edcca_th;
s8 l2h_th_ini_cs;
s8 l2h_th_ini_ad;

View File

@@ -1065,7 +1065,7 @@ static u32 rtw_pci_rx_napi(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci,
dma_sync_single_for_cpu(rtwdev->dev, dma, RTK_PCI_RX_BUF_SIZE,
DMA_FROM_DEVICE);
rx_desc = skb->data;
chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status);
rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status);
/* offset from rx_desc to payload */
pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +

View File

@@ -123,7 +123,7 @@ static void rtw_phy_cck_pd_init(struct rtw_dev *rtwdev)
void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l)
{
struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th;
rtw_write32_mask(rtwdev,
edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr,

View File

@@ -29,9 +29,6 @@
#define TBTT_PROHIBIT_HOLD_TIME 0x80
#define TBTT_PROHIBIT_HOLD_TIME_STOP_BCN 0x64
/* raw pkt_stat->drv_info_sz is in unit of 8-bytes */
#define RX_DRV_INFO_SZ_UNIT_8703B 8
#define TRANS_SEQ_END \
0xFFFF, \
RTW_PWR_CUT_ALL_MSK, \
@@ -481,14 +478,14 @@ static const struct rtw_pwr_seq_cmd trans_act_to_lps_8703b[] = {
{TRANS_SEQ_END},
};
static const struct rtw_pwr_seq_cmd *card_enable_flow_8703b[] = {
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8703b[] = {
trans_pre_enable_8703b,
trans_carddis_to_cardemu_8703b,
trans_cardemu_to_act_8703b,
NULL
};
static const struct rtw_pwr_seq_cmd *card_disable_flow_8703b[] = {
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8703b[] = {
trans_act_to_lps_8703b,
trans_act_to_reset_mcu_8703b,
trans_act_to_cardemu_8703b,
@@ -1032,57 +1029,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
query_phy_status_ofdm(rtwdev, phy_status, pkt_stat);
}
static void rtw8703b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
struct rtw_rx_pkt_stat *pkt_stat,
struct ieee80211_rx_status *rx_status)
{
struct ieee80211_hdr *hdr;
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
u8 *phy_status = NULL;
memset(pkt_stat, 0, sizeof(*pkt_stat));
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
pkt_stat->ppdu_cnt = 0;
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
pkt_stat->drv_info_sz *= RX_DRV_INFO_SZ_UNIT_8703B;
if (pkt_stat->is_c2h)
return;
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
pkt_stat->drv_info_sz);
pkt_stat->bw = GET_RX_DESC_BW(rx_desc);
if (pkt_stat->phy_status) {
phy_status = rx_desc + desc_sz + pkt_stat->shift;
query_phy_status(rtwdev, phy_status, pkt_stat);
}
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
/* Rtl8723cs driver checks for size < 14 or size > 8192 and
* simply drops the packet. Maybe this should go into
* rtw_rx_fill_rx_status()?
*/
if (pkt_stat->pkt_len == 0) {
rx_status->flag |= RX_FLAG_NO_PSDU;
rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet");
}
}
#define ADDA_ON_VAL_8703B 0x03c00014
static
@@ -1941,14 +1887,14 @@ static const struct coex_tdma_para tdma_sant_8703b[] = {
{ {0x61, 0x08, 0x03, 0x11, 0x11} },
};
static struct rtw_chip_ops rtw8703b_ops = {
static const struct rtw_chip_ops rtw8703b_ops = {
.mac_init = rtw8723x_mac_init,
.dump_fw_crash = NULL,
.shutdown = NULL,
.read_efuse = rtw8703b_read_efuse,
.phy_set_param = rtw8703b_phy_set_param,
.set_channel = rtw8703b_set_channel,
.query_rx_desc = rtw8703b_query_rx_desc,
.query_phy_status = query_phy_status,
.read_rf = rtw_phy_read_rf_sipi,
.write_rf = rtw_phy_write_rf_reg_sipi,
.set_tx_power_index = rtw8723x_set_tx_power_index,

View File

@@ -227,47 +227,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
}
}
static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
struct rtw_rx_pkt_stat *pkt_stat,
struct ieee80211_rx_status *rx_status)
{
struct ieee80211_hdr *hdr;
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
u8 *phy_status = NULL;
memset(pkt_stat, 0, sizeof(*pkt_stat));
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
pkt_stat->ppdu_cnt = 0;
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
/* drv_info_sz is in unit of 8-bytes */
pkt_stat->drv_info_sz *= 8;
/* c2h cmd pkt's rx/phy status is not interested */
if (pkt_stat->is_c2h)
return;
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
pkt_stat->drv_info_sz);
if (pkt_stat->phy_status) {
phy_status = rx_desc + desc_sz + pkt_stat->shift;
query_phy_status(rtwdev, phy_status, pkt_stat);
}
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
}
static bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev,
u8 channel, u32 thres)
{
@@ -1430,10 +1389,10 @@ static void rtw8723d_pwr_track(struct rtw_dev *rtwdev)
dm_info->pwr_trk_triggered = false;
}
static struct rtw_chip_ops rtw8723d_ops = {
static const struct rtw_chip_ops rtw8723d_ops = {
.phy_set_param = rtw8723d_phy_set_param,
.read_efuse = rtw8723x_read_efuse,
.query_rx_desc = rtw8723d_query_rx_desc,
.query_phy_status = query_phy_status,
.set_channel = rtw8723d_set_channel,
.mac_init = rtw8723x_mac_init,
.shutdown = rtw8723d_shutdown,
@@ -1788,7 +1747,7 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8723d[] = {
RTW_PWR_CMD_END, 0, 0},
};
static const struct rtw_pwr_seq_cmd *card_enable_flow_8723d[] = {
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8723d[] = {
trans_carddis_to_cardemu_8723d,
trans_cardemu_to_act_8723d,
NULL
@@ -2004,7 +1963,7 @@ static const struct rtw_pwr_seq_cmd trans_act_to_post_carddis_8723d[] = {
RTW_PWR_CMD_END, 0, 0},
};
static const struct rtw_pwr_seq_cmd *card_disable_flow_8723d[] = {
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8723d[] = {
trans_act_to_lps_8723d,
trans_act_to_pre_carddis_8723d,
trans_act_to_cardemu_8723d,

View File

@@ -679,47 +679,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
}
}
static void rtw8821c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
struct rtw_rx_pkt_stat *pkt_stat,
struct ieee80211_rx_status *rx_status)
{
struct ieee80211_hdr *hdr;
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
u8 *phy_status = NULL;
memset(pkt_stat, 0, sizeof(*pkt_stat));
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
/* drv_info_sz is in unit of 8-bytes */
pkt_stat->drv_info_sz *= 8;
/* c2h cmd pkt's rx/phy status is not interested */
if (pkt_stat->is_c2h)
return;
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
pkt_stat->drv_info_sz);
if (pkt_stat->phy_status) {
phy_status = rx_desc + desc_sz + pkt_stat->shift;
query_phy_status(rtwdev, phy_status, pkt_stat);
}
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
}
static void
rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
{
@@ -1254,7 +1213,7 @@ static void rtw8821c_fill_txdesc_checksum(struct rtw_dev *rtwdev,
fill_txdesc_checksum_common(txdesc, 16);
}
static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
{0x0086,
RTW_PWR_CUT_ALL_MSK,
RTW_PWR_INTF_SDIO_MSK,
@@ -1292,7 +1251,7 @@ static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = {
RTW_PWR_CMD_END, 0, 0},
};
static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = {
static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = {
{0x0020,
RTW_PWR_CUT_ALL_MSK,
RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
@@ -1396,7 +1355,7 @@ static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = {
RTW_PWR_CMD_END, 0, 0},
};
static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = {
static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = {
{0x0093,
RTW_PWR_CUT_ALL_MSK,
RTW_PWR_INTF_ALL_MSK,
@@ -1454,7 +1413,7 @@ static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = {
RTW_PWR_CMD_END, 0, 0},
};
static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = {
static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = {
{0x0007,
RTW_PWR_CUT_ALL_MSK,
RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK,
@@ -1567,13 +1526,13 @@ static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = {
RTW_PWR_CMD_END, 0, 0},
};
static const struct rtw_pwr_seq_cmd *card_enable_flow_8821c[] = {
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8821c[] = {
trans_carddis_to_cardemu_8821c,
trans_cardemu_to_act_8821c,
NULL
};
static const struct rtw_pwr_seq_cmd *card_disable_flow_8821c[] = {
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8821c[] = {
trans_act_to_cardemu_8821c,
trans_cardemu_to_carddis_8821c,
NULL
@@ -1629,7 +1588,7 @@ static const struct rtw_rfe_def rtw8821c_rfe_defs[] = {
[6] = RTW_DEF_RFE(8821c, 0, 0),
};
static struct rtw_hw_reg rtw8821c_dig[] = {
static const struct rtw_hw_reg rtw8821c_dig[] = {
[0] = { .addr = 0xc50, .mask = 0x7f },
};
@@ -1639,7 +1598,7 @@ static const struct rtw_ltecoex_addr rtw8821c_ltecoex_addr = {
.rdata = LTECOEX_READ_DATA,
};
static struct rtw_page_table page_table_8821c[] = {
static const struct rtw_page_table page_table_8821c[] = {
/* not sure what [0] stands for */
{16, 16, 16, 14, 1},
{16, 16, 16, 14, 1},
@@ -1648,7 +1607,7 @@ static struct rtw_page_table page_table_8821c[] = {
{16, 16, 16, 14, 1},
};
static struct rtw_rqpn rqpn_table_8821c[] = {
static const struct rtw_rqpn rqpn_table_8821c[] = {
/* not sure what [0] stands for */
{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
@@ -1667,7 +1626,7 @@ static struct rtw_rqpn rqpn_table_8821c[] = {
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
};
static struct rtw_prioq_addrs prioq_addrs_8821c = {
static const struct rtw_prioq_addrs prioq_addrs_8821c = {
.prio[RTW_DMA_MAPPING_EXTRA] = {
.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
},
@@ -1683,10 +1642,10 @@ static struct rtw_prioq_addrs prioq_addrs_8821c = {
.wsize = true,
};
static struct rtw_chip_ops rtw8821c_ops = {
static const struct rtw_chip_ops rtw8821c_ops = {
.phy_set_param = rtw8821c_phy_set_param,
.read_efuse = rtw8821c_read_efuse,
.query_rx_desc = rtw8821c_query_rx_desc,
.query_phy_status = query_phy_status,
.set_channel = rtw8821c_set_channel,
.mac_init = rtw8821c_mac_init,
.read_rf = rtw_phy_read_rf,

View File

@@ -934,47 +934,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
}
}
static void rtw8822b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
struct rtw_rx_pkt_stat *pkt_stat,
struct ieee80211_rx_status *rx_status)
{
struct ieee80211_hdr *hdr;
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
u8 *phy_status = NULL;
memset(pkt_stat, 0, sizeof(*pkt_stat));
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
/* drv_info_sz is in unit of 8-bytes */
pkt_stat->drv_info_sz *= 8;
/* c2h cmd pkt's rx/phy status is not interested */
if (pkt_stat->is_c2h)
return;
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
pkt_stat->drv_info_sz);
if (pkt_stat->phy_status) {
phy_status = rx_desc + desc_sz + pkt_stat->shift;
query_phy_status(rtwdev, phy_status, pkt_stat);
}
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
}
static void
rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs)
{
@@ -1978,13 +1937,13 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822b[] = {
RTW_PWR_CMD_END, 0, 0},
};
static const struct rtw_pwr_seq_cmd *card_enable_flow_8822b[] = {
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822b[] = {
trans_carddis_to_cardemu_8822b,
trans_cardemu_to_act_8822b,
NULL
};
static const struct rtw_pwr_seq_cmd *card_disable_flow_8822b[] = {
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822b[] = {
trans_act_to_cardemu_8822b,
trans_cardemu_to_carddis_8822b,
NULL
@@ -2156,7 +2115,7 @@ static const struct rtw_rqpn rqpn_table_8822b[] = {
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
};
static struct rtw_prioq_addrs prioq_addrs_8822b = {
static const struct rtw_prioq_addrs prioq_addrs_8822b = {
.prio[RTW_DMA_MAPPING_EXTRA] = {
.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
},
@@ -2172,10 +2131,10 @@ static struct rtw_prioq_addrs prioq_addrs_8822b = {
.wsize = true,
};
static struct rtw_chip_ops rtw8822b_ops = {
static const struct rtw_chip_ops rtw8822b_ops = {
.phy_set_param = rtw8822b_phy_set_param,
.read_efuse = rtw8822b_read_efuse,
.query_rx_desc = rtw8822b_query_rx_desc,
.query_phy_status = query_phy_status,
.set_channel = rtw8822b_set_channel,
.mac_init = rtw8822b_mac_init,
.read_rf = rtw_phy_read_rf,
@@ -2521,7 +2480,7 @@ static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = {
{0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8},
};
static struct rtw_hw_reg_offset rtw8822b_edcca_th[] = {
static const struct rtw_hw_reg_offset rtw8822b_edcca_th[] = {
[EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0},
[EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0},
};

View File

@@ -2690,48 +2690,6 @@ static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
}
}
static void rtw8822c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc,
struct rtw_rx_pkt_stat *pkt_stat,
struct ieee80211_rx_status *rx_status)
{
struct ieee80211_hdr *hdr;
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
u8 *phy_status = NULL;
memset(pkt_stat, 0, sizeof(*pkt_stat));
pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc);
pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc);
pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc);
pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) &&
GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE;
pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc);
pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc);
pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc);
pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc);
pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc);
pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc);
pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc);
pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc);
/* drv_info_sz is in unit of 8-bytes */
pkt_stat->drv_info_sz *= 8;
/* c2h cmd pkt's rx/phy status is not interested */
if (pkt_stat->is_c2h)
return;
hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift +
pkt_stat->drv_info_sz);
pkt_stat->hdr = hdr;
if (pkt_stat->phy_status) {
phy_status = rx_desc + desc_sz + pkt_stat->shift;
query_phy_status(rtwdev, phy_status, pkt_stat);
}
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status);
}
static void
rtw8822c_set_write_tx_power_ref(struct rtw_dev *rtwdev, u8 *tx_pwr_ref_cck,
u8 *tx_pwr_ref_ofdm)
@@ -4874,13 +4832,13 @@ static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8822c[] = {
RTW_PWR_CMD_END, 0, 0},
};
static const struct rtw_pwr_seq_cmd *card_enable_flow_8822c[] = {
static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822c[] = {
trans_carddis_to_cardemu_8822c,
trans_cardemu_to_act_8822c,
NULL
};
static const struct rtw_pwr_seq_cmd *card_disable_flow_8822c[] = {
static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822c[] = {
trans_act_to_cardemu_8822c,
trans_cardemu_to_carddis_8822c,
NULL
@@ -4972,7 +4930,7 @@ static const struct rtw_rqpn rqpn_table_8822c[] = {
RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
};
static struct rtw_prioq_addrs prioq_addrs_8822c = {
static const struct rtw_prioq_addrs prioq_addrs_8822c = {
.prio[RTW_DMA_MAPPING_EXTRA] = {
.rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2,
},
@@ -4988,10 +4946,10 @@ static struct rtw_prioq_addrs prioq_addrs_8822c = {
.wsize = true,
};
static struct rtw_chip_ops rtw8822c_ops = {
static const struct rtw_chip_ops rtw8822c_ops = {
.phy_set_param = rtw8822c_phy_set_param,
.read_efuse = rtw8822c_read_efuse,
.query_rx_desc = rtw8822c_query_rx_desc,
.query_phy_status = query_phy_status,
.set_channel = rtw8822c_set_channel,
.mac_init = rtw8822c_mac_init,
.dump_fw_crash = rtw8822c_dump_fw_crash,
@@ -5301,7 +5259,7 @@ static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = {
.pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p,
};
static struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = {
[EDCCA_TH_L2H_IDX] = {
{.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80
},

View File

@@ -187,11 +187,10 @@ fill_rx_status:
}
EXPORT_SYMBOL(rtw_update_rx_freq_from_ie);
void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
struct rtw_rx_pkt_stat *pkt_stat,
struct ieee80211_hdr *hdr,
struct ieee80211_rx_status *rx_status,
u8 *phy_status)
static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
struct rtw_rx_pkt_stat *pkt_stat,
struct ieee80211_hdr *hdr,
struct ieee80211_rx_status *rx_status)
{
struct ieee80211_hw *hw = rtwdev->hw;
u8 path;
@@ -242,5 +241,64 @@ void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
}
rtw_rx_addr_match(rtwdev, pkt_stat, hdr);
/* Rtl8723cs driver checks for size < 14 or size > 8192 and
* simply drops the packet.
*/
if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B && pkt_stat->pkt_len == 0) {
rx_status->flag |= RX_FLAG_NO_PSDU;
rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet");
}
}
EXPORT_SYMBOL(rtw_rx_fill_rx_status);
void rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8,
struct rtw_rx_pkt_stat *pkt_stat,
struct ieee80211_rx_status *rx_status)
{
u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz;
struct rtw_rx_desc *rx_desc = rx_desc8;
struct ieee80211_hdr *hdr;
u32 enc_type, swdec;
void *phy_status;
memset(pkt_stat, 0, sizeof(*pkt_stat));
pkt_stat->pkt_len = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PKT_LEN);
pkt_stat->crc_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_CRC32);
pkt_stat->icv_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ICV_ERR);
pkt_stat->drv_info_sz = le32_get_bits(rx_desc->w0,
RTW_RX_DESC_W0_DRV_INFO_SIZE);
enc_type = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ENC_TYPE);
pkt_stat->shift = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SHIFT);
pkt_stat->phy_status = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PHYST);
swdec = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SWDEC);
pkt_stat->decrypted = !swdec && enc_type != RX_DESC_ENC_NONE;
pkt_stat->cam_id = le32_get_bits(rx_desc->w1, RTW_RX_DESC_W1_MACID);
pkt_stat->is_c2h = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_C2H);
pkt_stat->ppdu_cnt = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_PPDU_CNT);
pkt_stat->rate = le32_get_bits(rx_desc->w3, RTW_RX_DESC_W3_RX_RATE);
pkt_stat->bw = le32_get_bits(rx_desc->w4, RTW_RX_DESC_W4_BW);
pkt_stat->tsf_low = le32_get_bits(rx_desc->w5, RTW_RX_DESC_W5_TSFL);
/* drv_info_sz is in unit of 8-bytes */
pkt_stat->drv_info_sz *= 8;
/* c2h cmd pkt's rx/phy status is not interested */
if (pkt_stat->is_c2h)
return;
phy_status = rx_desc8 + desc_sz + pkt_stat->shift;
hdr = phy_status + pkt_stat->drv_info_sz;
pkt_stat->hdr = hdr;
if (pkt_stat->phy_status)
rtwdev->chip->ops->query_phy_status(rtwdev, phy_status, pkt_stat);
rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status);
}
EXPORT_SYMBOL(rtw_rx_query_rx_desc);

View File

@@ -14,42 +14,40 @@ enum rtw_rx_desc_enc {
RX_DESC_ENC_WEP104 = 5,
};
#define GET_RX_DESC_PHYST(rxdesc) \
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(26))
#define GET_RX_DESC_ICV_ERR(rxdesc) \
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(15))
#define GET_RX_DESC_CRC32(rxdesc) \
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(14))
#define GET_RX_DESC_SWDEC(rxdesc) \
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(27))
#define GET_RX_DESC_C2H(rxdesc) \
le32_get_bits(*((__le32 *)(rxdesc) + 0x02), BIT(28))
#define GET_RX_DESC_PKT_LEN(rxdesc) \
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(13, 0))
#define GET_RX_DESC_DRV_INFO_SIZE(rxdesc) \
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(19, 16))
#define GET_RX_DESC_SHIFT(rxdesc) \
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(25, 24))
#define GET_RX_DESC_ENC_TYPE(rxdesc) \
le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(22, 20))
#define GET_RX_DESC_RX_RATE(rxdesc) \
le32_get_bits(*((__le32 *)(rxdesc) + 0x03), GENMASK(6, 0))
#define GET_RX_DESC_MACID(rxdesc) \
le32_get_bits(*((__le32 *)(rxdesc) + 0x01), GENMASK(6, 0))
#define GET_RX_DESC_PPDU_CNT(rxdesc) \
le32_get_bits(*((__le32 *)(rxdesc) + 0x02), GENMASK(30, 29))
#define GET_RX_DESC_TSFL(rxdesc) \
le32_get_bits(*((__le32 *)(rxdesc) + 0x05), GENMASK(31, 0))
#define GET_RX_DESC_BW(rxdesc) \
(le32_get_bits(*((__le32 *)(rxdesc) + 0x04), GENMASK(5, 4)))
struct rtw_rx_desc {
__le32 w0;
__le32 w1;
__le32 w2;
__le32 w3;
__le32 w4;
__le32 w5;
} __packed;
#define RTW_RX_DESC_W0_PKT_LEN GENMASK(13, 0)
#define RTW_RX_DESC_W0_CRC32 BIT(14)
#define RTW_RX_DESC_W0_ICV_ERR BIT(15)
#define RTW_RX_DESC_W0_DRV_INFO_SIZE GENMASK(19, 16)
#define RTW_RX_DESC_W0_ENC_TYPE GENMASK(22, 20)
#define RTW_RX_DESC_W0_SHIFT GENMASK(25, 24)
#define RTW_RX_DESC_W0_PHYST BIT(26)
#define RTW_RX_DESC_W0_SWDEC BIT(27)
#define RTW_RX_DESC_W1_MACID GENMASK(6, 0)
#define RTW_RX_DESC_W2_C2H BIT(28)
#define RTW_RX_DESC_W2_PPDU_CNT GENMASK(30, 29)
#define RTW_RX_DESC_W3_RX_RATE GENMASK(6, 0)
#define RTW_RX_DESC_W4_BW GENMASK(5, 4)
#define RTW_RX_DESC_W5_TSFL GENMASK(31, 0)
void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
struct sk_buff *skb);
void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev,
struct rtw_rx_pkt_stat *pkt_stat,
struct ieee80211_hdr *hdr,
struct ieee80211_rx_status *rx_status,
u8 *phy_status);
void rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8,
struct rtw_rx_pkt_stat *pkt_stat,
struct ieee80211_rx_status *rx_status);
void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb,
struct ieee80211_rx_status *rx_status,
struct rtw_rx_pkt_stat *pkt_stat);

View File

@@ -981,8 +981,7 @@ static void rtw_sdio_rxfifo_recv(struct rtw_dev *rtwdev, u32 rx_len)
while (true) {
rx_desc = skb->data;
chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
&rx_status);
rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status);
pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
pkt_stat.shift;
@@ -1297,12 +1296,12 @@ static void rtw_sdio_deinit_tx(struct rtw_dev *rtwdev)
struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
int i;
for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++)
skb_queue_purge(&rtwsdio->tx_queue[i]);
flush_workqueue(rtwsdio->txwq);
destroy_workqueue(rtwsdio->txwq);
kfree(rtwsdio->tx_handler_data);
for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++)
ieee80211_purge_tx_queue(rtwdev->hw, &rtwsdio->tx_queue[i]);
}
int rtw_sdio_probe(struct sdio_func *sdio_func,

View File

@@ -423,10 +423,11 @@ static void rtw_usb_tx_handler(struct work_struct *work)
static void rtw_usb_tx_queue_purge(struct rtw_usb *rtwusb)
{
struct rtw_dev *rtwdev = rtwusb->rtwdev;
int i;
for (i = 0; i < ARRAY_SIZE(rtwusb->tx_queue); i++)
skb_queue_purge(&rtwusb->tx_queue[i]);
ieee80211_purge_tx_queue(rtwdev->hw, &rtwusb->tx_queue[i]);
}
static void rtw_usb_write_port_complete(struct urb *urb)
@@ -570,8 +571,8 @@ static void rtw_usb_rx_handler(struct work_struct *work)
do {
rx_desc = skb->data;
chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat,
&rx_status);
rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat,
&rx_status);
pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz +
pkt_stat.shift;
@@ -889,9 +890,9 @@ static void rtw_usb_deinit_tx(struct rtw_dev *rtwdev)
{
struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
rtw_usb_tx_queue_purge(rtwusb);
flush_workqueue(rtwusb->txwq);
destroy_workqueue(rtwusb->txwq);
rtw_usb_tx_queue_purge(rtwusb);
}
static int rtw_usb_intf_init(struct rtw_dev *rtwdev,

View File

@@ -211,25 +211,17 @@ static int rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry *addr_cam,
return 0;
}
static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
const struct rtw89_sec_cam_entry *sec_cam,
bool inform_fw)
static int __rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
const struct rtw89_sec_cam_entry *sec_cam,
bool inform_fw)
{
struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
struct rtw89_vif *rtwvif;
struct rtw89_addr_cam_entry *addr_cam;
unsigned int i;
int ret = 0;
if (!vif) {
rtw89_err(rtwdev, "No iface for deleting sec cam\n");
return -EINVAL;
}
rtwvif = (struct rtw89_vif *)vif->drv_priv;
addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
addr_cam = rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
for_each_set_bit(i, addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM) {
if (addr_cam->sec_ent[i] != sec_cam->sec_cam_idx)
@@ -239,11 +231,11 @@ static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
}
if (inform_fw) {
ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link);
if (ret)
rtw89_err(rtwdev,
"failed to update dctl cam del key: %d\n", ret);
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret)
rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret);
}
@@ -251,25 +243,17 @@ static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
return ret;
}
static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key,
struct rtw89_sec_cam_entry *sec_cam)
static int __rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
struct ieee80211_key_conf *key,
struct rtw89_sec_cam_entry *sec_cam)
{
struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
struct rtw89_vif *rtwvif;
struct rtw89_addr_cam_entry *addr_cam;
u8 key_idx = 0;
int ret;
if (!vif) {
rtw89_err(rtwdev, "No iface for adding sec cam\n");
return -EINVAL;
}
rtwvif = (struct rtw89_vif *)vif->drv_priv;
addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
addr_cam = rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
key->cipher == WLAN_CIPHER_SUITE_WEP104)
@@ -285,13 +269,13 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
addr_cam->sec_ent_keyid[key_idx] = key->keyidx;
addr_cam->sec_ent[key_idx] = sec_cam->sec_cam_idx;
set_bit(key_idx, addr_cam->sec_cam_map);
ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link);
if (ret) {
rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n",
ret);
return ret;
}
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret) {
rtw89_err(rtwdev, "failed to update addr cam sec entry: %d\n",
ret);
@@ -302,6 +286,92 @@ static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
return 0;
}
static int rtw89_cam_detach_sec_cam(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
const struct rtw89_sec_cam_entry *sec_cam,
bool inform_fw)
{
struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
struct rtw89_sta_link *rtwsta_link;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
unsigned int link_id;
int ret;
if (!vif) {
rtw89_err(rtwdev, "No iface for deleting sec cam\n");
return -EINVAL;
}
rtwvif = vif_to_rtwvif(vif);
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
rtwsta_link = rtwsta ? rtwsta->links[link_id] : NULL;
if (rtwsta && !rtwsta_link)
continue;
ret = __rtw89_cam_detach_sec_cam(rtwdev, rtwvif_link, rtwsta_link,
sec_cam, inform_fw);
if (ret)
return ret;
}
return 0;
}
static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key,
struct rtw89_sec_cam_entry *sec_cam)
{
struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
struct rtw89_sta_link *rtwsta_link;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
unsigned int link_id;
int key_link_id;
int ret;
if (!vif) {
rtw89_err(rtwdev, "No iface for adding sec cam\n");
return -EINVAL;
}
rtwvif = vif_to_rtwvif(vif);
key_link_id = ieee80211_vif_is_mld(vif) ? key->link_id : 0;
if (key_link_id >= 0) {
rtwvif_link = rtwvif->links[key_link_id];
rtwsta_link = rtwsta ? rtwsta->links[key_link_id] : NULL;
if (!rtwvif_link || (rtwsta && !rtwsta_link)) {
rtw89_err(rtwdev, "No drv link for adding sec cam\n");
return -ENOLINK;
}
return __rtw89_cam_attach_sec_cam(rtwdev, rtwvif_link,
rtwsta_link, key, sec_cam);
}
/* key_link_id < 0: MLD pairwise key */
if (!rtwsta) {
rtw89_err(rtwdev, "No sta for adding MLD pairwise sec cam\n");
return -EINVAL;
}
rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
rtwvif_link = rtwsta_link->rtwvif_link;
ret = __rtw89_cam_attach_sec_cam(rtwdev, rtwvif_link,
rtwsta_link, key, sec_cam);
if (ret)
return ret;
}
return 0;
}
static int rtw89_cam_sec_key_install(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -485,10 +555,10 @@ void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev,
clear_bit(bssid_cam->bssid_cam_idx, cam_info->bssid_cam_map);
}
void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
struct rtw89_addr_cam_entry *addr_cam = &rtwvif_link->addr_cam;
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
rtw89_cam_deinit_addr_cam(rtwdev, addr_cam);
rtw89_cam_deinit_bssid_cam(rtwdev, bssid_cam);
@@ -593,7 +663,7 @@ static int rtw89_cam_get_avail_bssid_cam(struct rtw89_dev *rtwdev,
}
int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_bssid_cam_entry *bssid_cam,
const u8 *bssid)
{
@@ -613,7 +683,7 @@ int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
}
bssid_cam->bssid_cam_idx = bssid_cam_idx;
bssid_cam->phy_idx = rtwvif->phy_idx;
bssid_cam->phy_idx = rtwvif_link->phy_idx;
bssid_cam->len = BSSID_CAM_ENT_SIZE;
bssid_cam->offset = 0;
bssid_cam->valid = true;
@@ -622,20 +692,21 @@ int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
return 0;
}
void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
ether_addr_copy(bssid_cam->bssid, rtwvif->bssid);
ether_addr_copy(bssid_cam->bssid, rtwvif_link->bssid);
}
int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
struct rtw89_addr_cam_entry *addr_cam = &rtwvif_link->addr_cam;
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
int ret;
ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif, bssid_cam, rtwvif->bssid);
ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif_link, bssid_cam,
rtwvif_link->bssid);
if (ret) {
rtw89_err(rtwdev, "failed to init bssid cam\n");
return ret;
@@ -651,19 +722,27 @@ int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
}
int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta, u8 *cmd)
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link, u8 *cmd)
{
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif, rtwsta);
u8 bss_color = vif->bss_conf.he_bss_color.color;
struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif_link,
rtwsta_link);
struct ieee80211_bss_conf *bss_conf;
u8 bss_color;
u8 bss_mask;
if (vif->bss_conf.nontransmitted)
rcu_read_lock();
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
bss_color = bss_conf->he_bss_color.color;
if (bss_conf->nontransmitted)
bss_mask = RTW89_BSSID_MATCH_5_BYTES;
else
bss_mask = RTW89_BSSID_MATCH_ALL;
rcu_read_unlock();
FWCMD_SET_ADDR_BSSID_IDX(cmd, bssid_cam->bssid_cam_idx);
FWCMD_SET_ADDR_BSSID_OFFSET(cmd, bssid_cam->offset);
FWCMD_SET_ADDR_BSSID_LEN(cmd, bssid_cam->len);
@@ -694,19 +773,30 @@ static u8 rtw89_cam_addr_hash(u8 start, const u8 *addr)
}
void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
const u8 *scan_mac_addr,
u8 *cmd)
{
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta);
const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif->mac_addr;
struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
struct rtw89_addr_cam_entry *addr_cam =
rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
struct ieee80211_sta *sta = rtwsta_link_to_sta_safe(rtwsta_link);
struct ieee80211_link_sta *link_sta;
const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif_link->mac_addr;
u8 sma_hash, tma_hash, addr_msk_start;
u8 sma_start = 0;
u8 tma_start = 0;
u8 *tma = sta ? sta->addr : rtwvif->bssid;
const u8 *tma;
rcu_read_lock();
if (sta) {
link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
tma = link_sta->addr;
} else {
tma = rtwvif_link->bssid;
}
if (addr_cam->addr_mask != 0) {
addr_msk_start = __ffs(addr_cam->addr_mask);
@@ -723,10 +813,10 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
FWCMD_SET_ADDR_LEN(cmd, addr_cam->len);
FWCMD_SET_ADDR_VALID(cmd, addr_cam->valid);
FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif->net_type);
FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif->bcn_hit_cond);
FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif->hit_rule);
FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif->phy_idx);
FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif_link->net_type);
FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif_link->bcn_hit_cond);
FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif_link->hit_rule);
FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif_link->phy_idx);
FWCMD_SET_ADDR_ADDR_MASK(cmd, addr_cam->addr_mask);
FWCMD_SET_ADDR_MASK_SEL(cmd, addr_cam->mask_sel);
FWCMD_SET_ADDR_SMA_HASH(cmd, sma_hash);
@@ -748,20 +838,21 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
FWCMD_SET_ADDR_TMA4(cmd, tma[4]);
FWCMD_SET_ADDR_TMA5(cmd, tma[5]);
FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif->port);
FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif->port);
FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif->trigger);
FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif->lsig_txop);
FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif->tgt_ind);
FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif->frm_tgt_ind);
FWCMD_SET_ADDR_MACID(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id);
if (rtwvif->net_type == RTW89_NET_TYPE_INFRA)
FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif_link->port);
FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif_link->port);
FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif_link->trigger);
FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif_link->lsig_txop);
FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif_link->tgt_ind);
FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif_link->frm_tgt_ind);
FWCMD_SET_ADDR_MACID(cmd, rtwsta_link ? rtwsta_link->mac_id :
rtwvif_link->mac_id);
if (rtwvif_link->net_type == RTW89_NET_TYPE_INFRA)
FWCMD_SET_ADDR_AID12(cmd, vif->cfg.aid & 0xfff);
else if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
else if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE)
FWCMD_SET_ADDR_AID12(cmd, sta ? sta->aid & 0xfff : 0);
FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif->wowlan_pattern);
FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif->wowlan_uc);
FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif->wowlan_magic);
FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif_link->wowlan_pattern);
FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif_link->wowlan_uc);
FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif_link->wowlan_magic);
FWCMD_SET_ADDR_WAPI(cmd, addr_cam->wapi);
FWCMD_SET_ADDR_SEC_ENT_MODE(cmd, addr_cam->sec_ent_mode);
FWCMD_SET_ADDR_SEC_ENT0_KEYID(cmd, addr_cam->sec_ent_keyid[0]);
@@ -780,18 +871,22 @@ void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
FWCMD_SET_ADDR_SEC_ENT4(cmd, addr_cam->sec_ent[4]);
FWCMD_SET_ADDR_SEC_ENT5(cmd, addr_cam->sec_ent[5]);
FWCMD_SET_ADDR_SEC_ENT6(cmd, addr_cam->sec_ent[6]);
rcu_read_unlock();
}
void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_dctlinfo_ud_v1 *h2c)
{
struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
struct rtw89_addr_cam_entry *addr_cam =
rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv;
h2c->c0 = le32_encode_bits(rtwsta ? rtwsta->mac_id : rtwvif->mac_id,
h2c->c0 = le32_encode_bits(rtwsta_link ? rtwsta_link->mac_id :
rtwvif_link->mac_id,
DCTLINFO_V1_C0_MACID) |
le32_encode_bits(1, DCTLINFO_V1_C0_OP);
@@ -862,15 +957,17 @@ void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
}
void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_dctlinfo_ud_v2 *h2c)
{
struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
struct rtw89_addr_cam_entry *addr_cam =
rtw89_get_addr_cam_of(rtwvif_link, rtwsta_link);
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
u8 *ptk_tx_iv = rtw_wow->key_info.ptk_tx_iv;
h2c->c0 = le32_encode_bits(rtwsta ? rtwsta->mac_id : rtwvif->mac_id,
h2c->c0 = le32_encode_bits(rtwsta_link ? rtwsta_link->mac_id :
rtwvif_link->mac_id,
DCTLINFO_V2_C0_MACID) |
le32_encode_bits(1, DCTLINFO_V2_C0_OP);

View File

@@ -526,34 +526,34 @@ struct rtw89_h2c_dctlinfo_ud_v2 {
#define DCTLINFO_V2_W12_MLD_TA_BSSID_H_V1 GENMASK(15, 0)
#define DCTLINFO_V2_W12_ALL GENMASK(15, 0)
int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev,
struct rtw89_addr_cam_entry *addr_cam,
const struct rtw89_bssid_cam_entry *bssid_cam);
void rtw89_cam_deinit_addr_cam(struct rtw89_dev *rtwdev,
struct rtw89_addr_cam_entry *addr_cam);
int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_bssid_cam_entry *bssid_cam,
const u8 *bssid);
void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev,
struct rtw89_bssid_cam_entry *bssid_cam);
void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
struct rtw89_vif *vif,
struct rtw89_sta *rtwsta,
struct rtw89_vif_link *vif,
struct rtw89_sta_link *rtwsta_link,
const u8 *scan_mac_addr, u8 *cmd);
void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_dctlinfo_ud_v1 *h2c);
void rtw89_cam_fill_dctl_sec_cam_info_v2(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
struct rtw89_h2c_dctlinfo_ud_v2 *h2c);
int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta, u8 *cmd);
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link, u8 *cmd);
int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -564,6 +564,6 @@ int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev,
struct ieee80211_key_conf *key,
bool inform_fw);
void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif);
struct rtw89_vif_link *rtwvif_link);
void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev);
#endif

View File

@@ -234,6 +234,18 @@ void rtw89_entity_init(struct rtw89_dev *rtwdev)
rtw89_config_default_chandef(rtwdev);
}
static bool rtw89_vif_is_active_role(struct rtw89_vif *rtwvif)
{
struct rtw89_vif_link *rtwvif_link;
unsigned int link_id;
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
if (rtwvif_link->chanctx_assigned)
return true;
return false;
}
static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev,
struct rtw89_entity_weight *w)
{
@@ -255,7 +267,7 @@ static void rtw89_entity_calculate_weight(struct rtw89_dev *rtwdev,
}
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
if (rtwvif->chanctx_assigned)
if (rtw89_vif_is_active_role(rtwvif))
w->active_roles++;
}
}
@@ -387,9 +399,9 @@ int rtw89_iterate_mcc_roles(struct rtw89_dev *rtwdev,
static u32 rtw89_mcc_get_tbtt_ofst(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *role, u64 tsf)
{
struct rtw89_vif *rtwvif = role->rtwvif;
struct rtw89_vif_link *rtwvif_link = role->rtwvif_link;
u32 bcn_intvl_us = ieee80211_tu_to_usec(role->beacon_interval);
u64 sync_tsf = READ_ONCE(rtwvif->sync_bcn_tsf);
u64 sync_tsf = READ_ONCE(rtwvif_link->sync_bcn_tsf);
u32 remainder;
if (tsf < sync_tsf) {
@@ -413,8 +425,8 @@ static int __mcc_fw_req_tsf(struct rtw89_dev *rtwdev, u64 *tsf_ref, u64 *tsf_aux
int ret;
req.group = mcc->group;
req.macid_x = ref->rtwvif->mac_id;
req.macid_y = aux->rtwvif->mac_id;
req.macid_x = ref->rtwvif_link->mac_id;
req.macid_y = aux->rtwvif_link->mac_id;
ret = rtw89_fw_h2c_mcc_req_tsf(rtwdev, &req, &rpt);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
@@ -440,10 +452,10 @@ static int __mrc_fw_req_tsf(struct rtw89_dev *rtwdev, u64 *tsf_ref, u64 *tsf_aux
BUILD_BUG_ON(RTW89_MAC_MRC_MAX_REQ_TSF_NUM < NUM_OF_RTW89_MCC_ROLES);
arg.num = 2;
arg.infos[0].band = ref->rtwvif->mac_idx;
arg.infos[0].port = ref->rtwvif->port;
arg.infos[1].band = aux->rtwvif->mac_idx;
arg.infos[1].port = aux->rtwvif->port;
arg.infos[0].band = ref->rtwvif_link->mac_idx;
arg.infos[0].port = ref->rtwvif_link->port;
arg.infos[1].band = aux->rtwvif_link->mac_idx;
arg.infos[1].port = aux->rtwvif_link->port;
ret = rtw89_fw_h2c_mrc_req_tsf(rtwdev, &arg, &rpt);
if (ret) {
@@ -522,23 +534,31 @@ out:
static void rtw89_mcc_role_macid_sta_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_mcc_role *mcc_role = data;
struct rtw89_vif *target = mcc_role->rtwvif;
struct rtw89_vif *target = mcc_role->rtwvif_link->rtwvif;
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_dev *rtwdev = rtwsta->rtwdev;
struct rtw89_sta_link *rtwsta_link;
if (rtwvif != target)
return;
rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwsta->mac_id);
rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0);
if (unlikely(!rtwsta_link)) {
rtw89_err(rtwdev, "mcc sta macid: find no link on HW-0\n");
return;
}
rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwsta_link->mac_id);
}
static void rtw89_mcc_fill_role_macid_bitmap(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *mcc_role)
{
struct rtw89_vif *rtwvif = mcc_role->rtwvif;
struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link;
rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwvif->mac_id);
rtw89_mcc_role_fw_macid_bitmap_set_bit(mcc_role, rtwvif_link->mac_id);
ieee80211_iterate_stations_atomic(rtwdev->hw,
rtw89_mcc_role_macid_sta_iter,
mcc_role);
@@ -564,8 +584,9 @@ static void rtw89_mcc_fill_role_policy(struct rtw89_dev *rtwdev,
static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev,
struct rtw89_mcc_role *mcc_role)
{
struct ieee80211_vif *vif = rtwvif_to_vif(mcc_role->rtwvif);
struct rtw89_vif_link *rtwvif_link = mcc_role->rtwvif_link;
struct ieee80211_p2p_noa_desc *noa_desc;
struct ieee80211_bss_conf *bss_conf;
u32 bcn_intvl_us = ieee80211_tu_to_usec(mcc_role->beacon_interval);
u32 max_toa_us, max_tob_us, max_dur_us;
u32 start_time, interval, duration;
@@ -576,13 +597,18 @@ static void rtw89_mcc_fill_role_limit(struct rtw89_dev *rtwdev,
if (!mcc_role->is_go && !mcc_role->is_gc)
return;
rcu_read_lock();
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
/* find the first periodic NoA */
for (i = 0; i < RTW89_P2P_MAX_NOA_NUM; i++) {
noa_desc = &vif->bss_conf.p2p_noa_attr.desc[i];
noa_desc = &bss_conf->p2p_noa_attr.desc[i];
if (noa_desc->count == 255)
goto fill;
}
rcu_read_unlock();
return;
fill:
@@ -590,6 +616,8 @@ fill:
interval = le32_to_cpu(noa_desc->interval);
duration = le32_to_cpu(noa_desc->duration);
rcu_read_unlock();
if (interval != bcn_intvl_us) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
"MCC role limit: mismatch interval: %d vs. %d\n",
@@ -597,7 +625,7 @@ fill:
return;
}
ret = rtw89_mac_port_get_tsf(rtwdev, mcc_role->rtwvif, &tsf);
ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
if (ret) {
rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret);
return;
@@ -632,15 +660,21 @@ fill:
}
static int rtw89_mcc_fill_role(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_mcc_role *role)
{
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
struct ieee80211_bss_conf *bss_conf;
const struct rtw89_chan *chan;
memset(role, 0, sizeof(*role));
role->rtwvif = rtwvif;
role->beacon_interval = vif->bss_conf.beacon_int;
role->rtwvif_link = rtwvif_link;
rcu_read_lock();
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
role->beacon_interval = bss_conf->beacon_int;
rcu_read_unlock();
if (!role->beacon_interval) {
rtw89_warn(rtwdev,
@@ -650,10 +684,10 @@ static int rtw89_mcc_fill_role(struct rtw89_dev *rtwdev,
role->duration = role->beacon_interval / 2;
chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx);
chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
role->is_2ghz = chan->band_type == RTW89_BAND_2G;
role->is_go = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_GO;
role->is_gc = rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
role->is_go = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_GO;
role->is_gc = rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT;
rtw89_mcc_fill_role_macid_bitmap(rtwdev, role);
rtw89_mcc_fill_role_policy(rtwdev, role);
@@ -678,7 +712,7 @@ static void rtw89_mcc_fill_bt_role(struct rtw89_dev *rtwdev)
}
struct rtw89_mcc_fill_role_selector {
struct rtw89_vif *bind_vif[NUM_OF_RTW89_CHANCTX];
struct rtw89_vif_link *bind_vif[NUM_OF_RTW89_CHANCTX];
};
static_assert((u8)NUM_OF_RTW89_CHANCTX >= NUM_OF_RTW89_MCC_ROLES);
@@ -689,7 +723,7 @@ static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
void *data)
{
struct rtw89_mcc_fill_role_selector *sel = data;
struct rtw89_vif *role_vif = sel->bind_vif[ordered_idx];
struct rtw89_vif_link *role_vif = sel->bind_vif[ordered_idx];
int ret;
if (!role_vif) {
@@ -712,21 +746,28 @@ static int rtw89_mcc_fill_role_iterator(struct rtw89_dev *rtwdev,
static int rtw89_mcc_fill_all_roles(struct rtw89_dev *rtwdev)
{
struct rtw89_mcc_fill_role_selector sel = {};
struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
int ret;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
if (!rtwvif->chanctx_assigned)
if (!rtw89_vif_is_active_role(rtwvif))
continue;
if (sel.bind_vif[rtwvif->chanctx_idx]) {
rtw89_warn(rtwdev,
"MCC skip extra vif <macid %d> on chanctx[%d]\n",
rtwvif->mac_id, rtwvif->chanctx_idx);
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev, "mcc fill roles: find no link on HW-0\n");
continue;
}
sel.bind_vif[rtwvif->chanctx_idx] = rtwvif;
if (sel.bind_vif[rtwvif_link->chanctx_idx]) {
rtw89_warn(rtwdev,
"MCC skip extra vif <macid %d> on chanctx[%d]\n",
rtwvif_link->mac_id, rtwvif_link->chanctx_idx);
continue;
}
sel.bind_vif[rtwvif_link->chanctx_idx] = rtwvif_link;
}
ret = rtw89_iterate_mcc_roles(rtwdev, rtw89_mcc_fill_role_iterator, &sel);
@@ -754,13 +795,13 @@ static void rtw89_mcc_assign_pattern(struct rtw89_dev *rtwdev,
memset(&pattern->courtesy, 0, sizeof(pattern->courtesy));
if (pattern->tob_aux <= 0 || pattern->toa_aux <= 0) {
pattern->courtesy.macid_tgt = aux->rtwvif->mac_id;
pattern->courtesy.macid_src = ref->rtwvif->mac_id;
pattern->courtesy.macid_tgt = aux->rtwvif_link->mac_id;
pattern->courtesy.macid_src = ref->rtwvif_link->mac_id;
pattern->courtesy.slot_num = RTW89_MCC_DFLT_COURTESY_SLOT;
pattern->courtesy.enable = true;
} else if (pattern->tob_ref <= 0 || pattern->toa_ref <= 0) {
pattern->courtesy.macid_tgt = ref->rtwvif->mac_id;
pattern->courtesy.macid_src = aux->rtwvif->mac_id;
pattern->courtesy.macid_tgt = ref->rtwvif_link->mac_id;
pattern->courtesy.macid_src = aux->rtwvif_link->mac_id;
pattern->courtesy.slot_num = RTW89_MCC_DFLT_COURTESY_SLOT;
pattern->courtesy.enable = true;
}
@@ -1263,7 +1304,7 @@ static void rtw89_mcc_sync_tbtt(struct rtw89_dev *rtwdev,
u64 tsf_src;
int ret;
ret = rtw89_mac_port_get_tsf(rtwdev, src->rtwvif, &tsf_src);
ret = rtw89_mac_port_get_tsf(rtwdev, src->rtwvif_link, &tsf_src);
if (ret) {
rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret);
return;
@@ -1280,12 +1321,12 @@ static void rtw89_mcc_sync_tbtt(struct rtw89_dev *rtwdev,
div_u64_rem(tbtt_tgt, bcn_intvl_src_us, &remainder);
tsf_ofst_tgt = bcn_intvl_src_us - remainder;
config->sync.macid_tgt = tgt->rtwvif->mac_id;
config->sync.band_tgt = tgt->rtwvif->mac_idx;
config->sync.port_tgt = tgt->rtwvif->port;
config->sync.macid_src = src->rtwvif->mac_id;
config->sync.band_src = src->rtwvif->mac_idx;
config->sync.port_src = src->rtwvif->port;
config->sync.macid_tgt = tgt->rtwvif_link->mac_id;
config->sync.band_tgt = tgt->rtwvif_link->mac_idx;
config->sync.port_tgt = tgt->rtwvif_link->port;
config->sync.macid_src = src->rtwvif_link->mac_id;
config->sync.band_src = src->rtwvif_link->mac_idx;
config->sync.port_src = src->rtwvif_link->port;
config->sync.offset = tsf_ofst_tgt / 1024;
config->sync.enable = true;
@@ -1294,7 +1335,7 @@ static void rtw89_mcc_sync_tbtt(struct rtw89_dev *rtwdev,
config->sync.macid_tgt, config->sync.macid_src,
config->sync.offset);
rtw89_mac_port_tsf_sync(rtwdev, tgt->rtwvif, src->rtwvif,
rtw89_mac_port_tsf_sync(rtwdev, tgt->rtwvif_link, src->rtwvif_link,
config->sync.offset);
}
@@ -1305,13 +1346,13 @@ static int rtw89_mcc_fill_start_tsf(struct rtw89_dev *rtwdev)
struct rtw89_mcc_config *config = &mcc->config;
u32 bcn_intvl_ref_us = ieee80211_tu_to_usec(ref->beacon_interval);
u32 tob_ref_us = ieee80211_tu_to_usec(config->pattern.tob_ref);
struct rtw89_vif *rtwvif = ref->rtwvif;
struct rtw89_vif_link *rtwvif_link = ref->rtwvif_link;
u64 tsf, start_tsf;
u32 cur_tbtt_ofst;
u64 min_time;
int ret;
ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif, &tsf);
ret = rtw89_mac_port_get_tsf(rtwdev, rtwvif_link, &tsf);
if (ret) {
rtw89_warn(rtwdev, "MCC failed to get port tsf: %d\n", ret);
return ret;
@@ -1390,13 +1431,13 @@ static int __mcc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *ro
const struct rtw89_chan *chan;
int ret;
chan = rtw89_chan_get(rtwdev, role->rtwvif->chanctx_idx);
chan = rtw89_chan_get(rtwdev, role->rtwvif_link->chanctx_idx);
req.central_ch_seg0 = chan->channel;
req.primary_ch = chan->primary_channel;
req.bandwidth = chan->band_width;
req.ch_band_type = chan->band_type;
req.macid = role->rtwvif->mac_id;
req.macid = role->rtwvif_link->mac_id;
req.group = mcc->group;
req.c2h_rpt = policy->c2h_rpt;
req.tx_null_early = policy->tx_null_early;
@@ -1421,7 +1462,7 @@ static int __mcc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *ro
}
ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group,
role->rtwvif->mac_id,
role->rtwvif_link->mac_id,
role->macid_bitmap);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
@@ -1448,7 +1489,7 @@ void __mrc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role,
slot_arg->duration = role->duration;
slot_arg->role_num = 1;
chan = rtw89_chan_get(rtwdev, role->rtwvif->chanctx_idx);
chan = rtw89_chan_get(rtwdev, role->rtwvif_link->chanctx_idx);
slot_arg->roles[0].role_type = RTW89_H2C_MRC_ROLE_WIFI;
slot_arg->roles[0].is_master = role == ref;
@@ -1458,7 +1499,7 @@ void __mrc_fw_add_role(struct rtw89_dev *rtwdev, struct rtw89_mcc_role *role,
slot_arg->roles[0].primary_ch = chan->primary_channel;
slot_arg->roles[0].en_tx_null = !policy->dis_tx_null;
slot_arg->roles[0].null_early = policy->tx_null_early;
slot_arg->roles[0].macid = role->rtwvif->mac_id;
slot_arg->roles[0].macid = role->rtwvif_link->mac_id;
slot_arg->roles[0].macid_main_bitmap =
rtw89_mcc_role_fw_macid_bitmap_to_u32(role);
}
@@ -1569,7 +1610,7 @@ static int __mcc_fw_start(struct rtw89_dev *rtwdev, bool replace)
}
}
req.macid = ref->rtwvif->mac_id;
req.macid = ref->rtwvif_link->mac_id;
req.tsf_high = config->start_tsf >> 32;
req.tsf_low = config->start_tsf;
@@ -1598,7 +1639,7 @@ static void __mrc_fw_add_courtesy(struct rtw89_dev *rtwdev,
if (!courtesy->enable)
return;
if (courtesy->macid_src == ref->rtwvif->mac_id) {
if (courtesy->macid_src == ref->rtwvif_link->mac_id) {
slot_arg_src = &arg->slots[ref->slot_idx];
slot_idx_tgt = aux->slot_idx;
} else {
@@ -1717,9 +1758,9 @@ static int __mcc_fw_set_duration_no_bt(struct rtw89_dev *rtwdev, bool sync_chang
struct rtw89_fw_mcc_duration req = {
.group = mcc->group,
.btc_in_group = false,
.start_macid = ref->rtwvif->mac_id,
.macid_x = ref->rtwvif->mac_id,
.macid_y = aux->rtwvif->mac_id,
.start_macid = ref->rtwvif_link->mac_id,
.macid_x = ref->rtwvif_link->mac_id,
.macid_y = aux->rtwvif_link->mac_id,
.duration_x = ref->duration,
.duration_y = aux->duration,
.start_tsf_high = config->start_tsf >> 32,
@@ -1813,18 +1854,18 @@ static void rtw89_mcc_handle_beacon_noa(struct rtw89_dev *rtwdev, bool enable)
struct ieee80211_p2p_noa_desc noa_desc = {};
u64 start_time = config->start_tsf;
u32 interval = config->mcc_interval;
struct rtw89_vif *rtwvif_go;
struct rtw89_vif_link *rtwvif_go;
u32 duration;
if (mcc->mode != RTW89_MCC_MODE_GO_STA)
return;
if (ref->is_go) {
rtwvif_go = ref->rtwvif;
rtwvif_go = ref->rtwvif_link;
start_time += ieee80211_tu_to_usec(ref->duration);
duration = config->mcc_interval - ref->duration;
} else if (aux->is_go) {
rtwvif_go = aux->rtwvif;
rtwvif_go = aux->rtwvif_link;
start_time += ieee80211_tu_to_usec(pattern->tob_ref) +
ieee80211_tu_to_usec(config->beacon_offset) +
ieee80211_tu_to_usec(pattern->toa_aux);
@@ -1865,9 +1906,9 @@ static void rtw89_mcc_start_beacon_noa(struct rtw89_dev *rtwdev)
return;
if (ref->is_go)
rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif, true);
rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif_link, true);
else if (aux->is_go)
rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif, true);
rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif_link, true);
rtw89_mcc_handle_beacon_noa(rtwdev, true);
}
@@ -1882,9 +1923,9 @@ static void rtw89_mcc_stop_beacon_noa(struct rtw89_dev *rtwdev)
return;
if (ref->is_go)
rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif, false);
rtw89_fw_h2c_tsf32_toggle(rtwdev, ref->rtwvif_link, false);
else if (aux->is_go)
rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif, false);
rtw89_fw_h2c_tsf32_toggle(rtwdev, aux->rtwvif_link, false);
rtw89_mcc_handle_beacon_noa(rtwdev, false);
}
@@ -1942,7 +1983,7 @@ struct rtw89_mcc_stop_sel {
static void rtw89_mcc_stop_sel_fill(struct rtw89_mcc_stop_sel *sel,
const struct rtw89_mcc_role *mcc_role)
{
sel->mac_id = mcc_role->rtwvif->mac_id;
sel->mac_id = mcc_role->rtwvif_link->mac_id;
sel->slot_idx = mcc_role->slot_idx;
}
@@ -1953,7 +1994,7 @@ static int rtw89_mcc_stop_sel_iterator(struct rtw89_dev *rtwdev,
{
struct rtw89_mcc_stop_sel *sel = data;
if (!mcc_role->rtwvif->chanctx_assigned)
if (!mcc_role->rtwvif_link->chanctx_assigned)
return 0;
rtw89_mcc_stop_sel_fill(sel, mcc_role);
@@ -2081,7 +2122,7 @@ static int __mcc_fw_upd_macid_bitmap(struct rtw89_dev *rtwdev,
int ret;
ret = rtw89_fw_h2c_mcc_macid_bitmap(rtwdev, mcc->group,
upd->rtwvif->mac_id,
upd->rtwvif_link->mac_id,
upd->macid_bitmap);
if (ret) {
rtw89_debug(rtwdev, RTW89_DBG_CHAN,
@@ -2106,7 +2147,7 @@ static int __mrc_fw_upd_macid_bitmap(struct rtw89_dev *rtwdev,
int i;
arg.sch_idx = mcc->group;
arg.macid = upd->rtwvif->mac_id;
arg.macid = upd->rtwvif_link->mac_id;
for (i = 0; i < 32; i++) {
if (add & BIT(i)) {
@@ -2144,7 +2185,7 @@ static int rtw89_mcc_upd_map_iterator(struct rtw89_dev *rtwdev,
void *data)
{
struct rtw89_mcc_role upd = {
.rtwvif = mcc_role->rtwvif,
.rtwvif_link = mcc_role->rtwvif_link,
};
int ret;
@@ -2370,6 +2411,24 @@ void rtw89_chanctx_proceed(struct rtw89_dev *rtwdev)
rtw89_queue_chanctx_work(rtwdev);
}
static void __rtw89_swap_chanctx(struct rtw89_vif *rtwvif,
enum rtw89_chanctx_idx idx1,
enum rtw89_chanctx_idx idx2)
{
struct rtw89_vif_link *rtwvif_link;
unsigned int link_id;
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
if (!rtwvif_link->chanctx_assigned)
continue;
if (rtwvif_link->chanctx_idx == idx1)
rtwvif_link->chanctx_idx = idx2;
else if (rtwvif_link->chanctx_idx == idx2)
rtwvif_link->chanctx_idx = idx1;
}
}
static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev,
enum rtw89_chanctx_idx idx1,
enum rtw89_chanctx_idx idx2)
@@ -2386,14 +2445,8 @@ static void rtw89_swap_chanctx(struct rtw89_dev *rtwdev,
swap(hal->chanctx[idx1], hal->chanctx[idx2]);
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
if (!rtwvif->chanctx_assigned)
continue;
if (rtwvif->chanctx_idx == idx1)
rtwvif->chanctx_idx = idx2;
else if (rtwvif->chanctx_idx == idx2)
rtwvif->chanctx_idx = idx1;
}
rtw89_for_each_rtwvif(rtwdev, rtwvif)
__rtw89_swap_chanctx(rtwvif, idx1, idx2);
cur = atomic_read(&hal->roc_chanctx_idx);
if (cur == idx1)
@@ -2444,14 +2497,14 @@ void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
}
int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
struct rtw89_entity_weight w = {};
rtwvif->chanctx_idx = cfg->idx;
rtwvif->chanctx_assigned = true;
rtwvif_link->chanctx_idx = cfg->idx;
rtwvif_link->chanctx_assigned = true;
cfg->ref_count++;
if (cfg->idx == RTW89_CHANCTX_0)
@@ -2469,7 +2522,7 @@ out:
}
void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
@@ -2479,8 +2532,8 @@ void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
enum rtw89_entity_mode new;
int ret;
rtwvif->chanctx_idx = RTW89_CHANCTX_0;
rtwvif->chanctx_assigned = false;
rtwvif_link->chanctx_idx = RTW89_CHANCTX_0;
rtwvif_link->chanctx_assigned = false;
cfg->ref_count--;
if (cfg->ref_count != 0)

View File

@@ -43,18 +43,21 @@ struct rtw89_entity_weight {
unsigned int active_roles;
};
static inline bool rtw89_get_entity_state(struct rtw89_dev *rtwdev)
static inline bool rtw89_get_entity_state(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
struct rtw89_hal *hal = &rtwdev->hal;
return READ_ONCE(hal->entity_active);
return READ_ONCE(hal->entity_active[phy_idx]);
}
static inline void rtw89_set_entity_state(struct rtw89_dev *rtwdev, bool active)
static inline void rtw89_set_entity_state(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
bool active)
{
struct rtw89_hal *hal = &rtwdev->hal;
WRITE_ONCE(hal->entity_active, active);
WRITE_ONCE(hal->entity_active[phy_idx], active);
}
static inline
@@ -106,10 +109,10 @@ void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
struct ieee80211_chanctx_conf *ctx,
u32 changed);
int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx);
void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_chanctx_conf *ctx);
#endif

View File

@@ -125,6 +125,9 @@ static const u32 cxtbl[] = {
0xfafaaafa, /* 23 */
0xfafffaff, /* 24 */
0xea6a5a5a, /* 25 */
0xfaff5aff, /* 26 */
0xffffdfff, /* 27 */
0xe6555555, /* 28 */
};
static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
@@ -134,77 +137,88 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
.fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
.fwlrole = 7, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
.fwevntrptl = 1, .drvinfo_type = 1, .info_buf = 1800, .max_role_num = 6,
.fwevntrptl = 1, .fwc2hfunc = 2, .drvinfo_type = 1, .info_buf = 1800,
.max_role_num = 6,
},
{RTL8922A, RTW89_FW_VER_CODE(0, 35, 8, 0),
.fcxbtcrpt = 8, .fcxtdma = 7, .fcxslots = 7, .fcxcysta = 7,
.fcxstep = 7, .fcxnullsta = 7, .fcxmreg = 7, .fcxgpiodbg = 7,
.fcxbtver = 7, .fcxbtscan = 7, .fcxbtafh = 7, .fcxbtdevinfo = 7,
.fwlrole = 8, .frptmap = 3, .fcxctrl = 7, .fcxinit = 7,
.fwevntrptl = 1, .drvinfo_type = 1, .info_buf = 1800, .max_role_num = 6,
.fwevntrptl = 1, .fwc2hfunc = 1, .drvinfo_type = 1, .info_buf = 1800,
.max_role_num = 6,
},
{RTL8851B, RTW89_FW_VER_CODE(0, 29, 29, 0),
.fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
.max_role_num = 6,
},
{RTL8852C, RTW89_FW_VER_CODE(0, 27, 57, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
.max_role_num = 5,
},
{RTL8852C, RTW89_FW_VER_CODE(0, 27, 42, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
.max_role_num = 5,
},
{RTL8852C, RTW89_FW_VER_CODE(0, 27, 0, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 2, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
.max_role_num = 5,
},
{RTL8852B, RTW89_FW_VER_CODE(0, 29, 29, 0),
.fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
.max_role_num = 6,
},
{RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0),
.fcxbtcrpt = 5, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 4,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1800, .max_role_num = 6,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1800,
.max_role_num = 6,
},
{RTL8852B, RTW89_FW_VER_CODE(0, 27, 0, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 1, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1280,
.max_role_num = 5,
},
{RTL8852A, RTW89_FW_VER_CODE(0, 13, 37, 0),
.fcxbtcrpt = 4, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 3,
.fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 2, .fcxbtdevinfo = 1,
.fwlrole = 1, .frptmap = 3, .fcxctrl = 1, .fcxinit = 0,
.fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1280, .max_role_num = 5,
.fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_type = 0, .info_buf = 1280,
.max_role_num = 5,
},
{RTL8852A, RTW89_FW_VER_CODE(0, 13, 0, 0),
.fcxbtcrpt = 1, .fcxtdma = 1, .fcxslots = 1, .fcxcysta = 2,
.fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0,
.fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1024, .max_role_num = 5,
.fwevntrptl = 0, .fwc2hfunc = 0, .drvinfo_type = 0, .info_buf = 1024,
.max_role_num = 5,
},
/* keep it to be the last as default entry */
@@ -213,7 +227,8 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
.fcxstep = 2, .fcxnullsta = 1, .fcxmreg = 1, .fcxgpiodbg = 1,
.fcxbtver = 1, .fcxbtscan = 1, .fcxbtafh = 1, .fcxbtdevinfo = 1,
.fwlrole = 0, .frptmap = 0, .fcxctrl = 0, .fcxinit = 0,
.fwevntrptl = 0, .drvinfo_type = 0, .info_buf = 1024, .max_role_num = 5,
.fwevntrptl = 0, .fwc2hfunc = 1, .drvinfo_type = 0, .info_buf = 1024,
.max_role_num = 5,
},
};
@@ -224,7 +239,7 @@ static const union rtw89_btc_wl_state_map btc_scanning_map = {
.scan = 1,
.connecting = 1,
.roaming = 1,
.transacting = 1,
.dbccing = 1,
._4way = 1,
},
};
@@ -3017,7 +3032,7 @@ static void _update_btc_state_map(struct rtw89_dev *rtwdev)
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
if (wl->status.map.connecting || wl->status.map._4way ||
wl->status.map.roaming) {
wl->status.map.roaming || wl->status.map.dbccing) {
cx->state_map = BTC_WLINKING;
} else if (wl->status.map.scan) { /* wl scan */
if (bt_linfo->status.map.inq_pag)
@@ -3721,8 +3736,6 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
tbl_w1 = cxtbl[16];
}
btc->bt_req_en = false;
switch (type) {
case BTC_CXP_USERDEF0:
btc->update_policy_force = true;
@@ -3744,6 +3757,10 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
case BTC_CXP_OFF_WL:
_slot_set_tbl(btc, CXST_OFF, cxtbl[1]);
break;
case BTC_CXP_OFF_WL2:
_slot_set_tbl(btc, CXST_OFF, cxtbl[1]);
_slot_set_type(btc, CXST_OFF, SLOT_ISO);
break;
case BTC_CXP_OFF_EQ0:
_slot_set_tbl(btc, CXST_OFF, cxtbl[0]);
_slot_set_type(btc, CXST_OFF, SLOT_ISO);
@@ -3757,6 +3774,12 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
case BTC_CXP_OFF_EQ3:
_slot_set_tbl(btc, CXST_OFF, cxtbl[24]);
break;
case BTC_CXP_OFF_EQ4:
_slot_set_tbl(btc, CXST_OFF, cxtbl[26]);
break;
case BTC_CXP_OFF_EQ5:
_slot_set_tbl(btc, CXST_OFF, cxtbl[27]);
break;
case BTC_CXP_OFF_BWB0:
_slot_set_tbl(btc, CXST_OFF, cxtbl[5]);
break;
@@ -3788,7 +3811,6 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
}
break;
case BTC_CXP_OFFE: /* TDMA off + beacon protect + Ext_control */
btc->bt_req_en = true;
_write_scbd(rtwdev, BTC_WSCB_TDMA, true);
*t = t_def[CXTD_OFF_EXT];
@@ -3831,9 +3853,9 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
s_def[CXST_ENULL].cxtbl, s_def[CXST_ENULL].cxtype);
break;
case BTC_CXP_OFFE_2GBWMIXB:
_slot_set(btc, CXST_E2G, 0, 0x55555555, SLOT_MIX);
_slot_set(btc, CXST_E2G, 0, 0xea5a5555, SLOT_MIX);
_slot_set_le(btc, CXST_EBT, s_def[CXST_EBT].dur,
cpu_to_le32(0x55555555), s_def[CXST_EBT].cxtype);
s_def[CXST_EBT].cxtbl, s_def[CXST_EBT].cxtype);
break;
case BTC_CXP_OFFE_WL: /* for 4-way */
_slot_set(btc, CXST_E2G, 0, cxtbl[1], SLOT_MIX);
@@ -3842,6 +3864,8 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
default:
break;
}
_slot_set_le(btc, CXST_E5G, s_def[CXST_E5G].dur,
s_def[CXST_E5G].cxtbl, s_def[CXST_E5G].cxtype);
_slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur,
s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype);
break;
@@ -4246,6 +4270,7 @@ static void _set_ant_v0(struct rtw89_dev *rtwdev, bool force_exec,
_set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE);
break;
case BTC_ANT_WRFK:
case BTC_ANT_WRFK2:
rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
_set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO);
_set_bt_plut(rtwdev, phy_map, BTC_PLT_NONE, BTC_PLT_NONE);
@@ -4623,12 +4648,21 @@ static void _action_bt_a2dpsink(struct rtw89_dev *rtwdev)
static void _action_bt_pan(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt.link_info;
struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc;
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
switch (btc->cx.state_map) {
case BTC_WBUSY_BNOSCAN: /* wl-busy + bt-PAN */
_set_policy(rtwdev, BTC_CXP_PFIX_TD5050, BTC_ACT_BT_PAN);
if (a2dp.active || !pan.exist) {
btc->dm.slot_dur[CXST_W1] = 80;
btc->dm.slot_dur[CXST_B1] = 20;
_set_policy(rtwdev, BTC_CXP_PFIX_TDW1B1, BTC_ACT_BT_PAN);
} else {
_set_policy(rtwdev, BTC_CXP_PFIX_TD5050, BTC_ACT_BT_PAN);
}
break;
case BTC_WBUSY_BSCAN: /* wl-busy + bt-inq + bt-PAN */
_set_policy(rtwdev, BTC_CXP_PFIX_TD3070, BTC_ACT_BT_PAN);
@@ -4814,8 +4848,16 @@ static void _action_wl_rfk(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): band = %d\n",
__func__, rfk.band);
_set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK);
_set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_WL_RFK);
btc->dm.tdma_instant_excute = 1;
if (rfk.state == BTC_WRFK_ONESHOT_START ||
btc->ant_type == BTC_ANT_SHARED) {
_set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK2);
_set_policy(rtwdev, BTC_CXP_OFF_WL2, BTC_ACT_WL_RFK);
} else {
_set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WRFK);
_set_policy(rtwdev, BTC_CXP_OFF_WL, BTC_ACT_WL_RFK);
}
}
static void _set_btg_ctrl(struct rtw89_dev *rtwdev)
@@ -4855,6 +4897,8 @@ static void _set_btg_ctrl(struct rtw89_dev *rtwdev)
if (rtwdev->dbcc_en) {
if (ver->fwlrole == 0) {
wl_rinfo.dbcc_2g_phy = RTW89_PHY_MAX;
for (i = 0; i < RTW89_PHY_MAX; i++) {
if (wl_dinfo->real_band[i] == RTW89_BAND_2G)
wl_rinfo.dbcc_2g_phy = i;
@@ -4989,18 +5033,16 @@ struct rtw89_txtime_data {
bool reenable;
};
static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta)
static void __rtw89_tx_time_iter(struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
struct rtw89_txtime_data *iter_data)
{
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_txtime_data *iter_data =
(struct rtw89_txtime_data *)data;
struct rtw89_dev *rtwdev = iter_data->rtwdev;
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &cx->wl;
struct rtw89_btc_wl_link_info *plink = NULL;
u8 port = rtwvif->port;
u8 port = rtwvif_link->port;
u32 tx_time = iter_data->tx_time;
u8 tx_retry = iter_data->tx_retry;
u16 enable = iter_data->enable;
@@ -5023,8 +5065,8 @@ static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta)
/* backup the original tx time before tx-limit on */
if (reenable) {
rtw89_mac_get_tx_time(rtwdev, rtwsta, &plink->tx_time);
rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta, &plink->tx_retry);
rtw89_mac_get_tx_time(rtwdev, rtwsta_link, &plink->tx_time);
rtw89_mac_get_tx_retry_limit(rtwdev, rtwsta_link, &plink->tx_retry);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): reenable, tx_time=%d tx_retry= %d\n",
__func__, plink->tx_time, plink->tx_retry);
@@ -5032,22 +5074,37 @@ static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta)
/* restore the original tx time if no tx-limit */
if (!enable) {
rtw89_mac_set_tx_time(rtwdev, rtwsta, true, plink->tx_time);
rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta, true,
rtw89_mac_set_tx_time(rtwdev, rtwsta_link, true, plink->tx_time);
rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, true,
plink->tx_retry);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): restore, tx_time=%d tx_retry= %d\n",
__func__, plink->tx_time, plink->tx_retry);
} else {
rtw89_mac_set_tx_time(rtwdev, rtwsta, false, tx_time);
rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta, false, tx_retry);
rtw89_mac_set_tx_time(rtwdev, rtwsta_link, false, tx_time);
rtw89_mac_set_tx_retry_limit(rtwdev, rtwsta_link, false, tx_retry);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): set, tx_time=%d tx_retry= %d\n",
__func__, tx_time, tx_retry);
}
}
static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_txtime_data *iter_data =
(struct rtw89_txtime_data *)data;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_sta_link *rtwsta_link;
unsigned int link_id;
rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
rtwvif_link = rtwsta_link->rtwvif_link;
__rtw89_tx_time_iter(rtwvif_link, rtwsta_link, iter_data);
}
}
static void _set_wl_tx_limit(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
@@ -5231,8 +5288,14 @@ static void _action_by_bt(struct rtw89_dev *rtwdev)
struct rtw89_btc_bt_hid_desc hid = bt_linfo->hid_desc;
struct rtw89_btc_bt_a2dp_desc a2dp = bt_linfo->a2dp_desc;
struct rtw89_btc_bt_pan_desc pan = bt_linfo->pan_desc;
struct rtw89_btc_dm *dm = &btc->dm;
u8 profile_map = 0;
if (dm->freerun_chk) {
_action_freerun(rtwdev);
return;
}
if (bt_linfo->hfp_desc.exist)
profile_map |= BTC_BT_HFP;
@@ -5247,30 +5310,20 @@ static void _action_by_bt(struct rtw89_dev *rtwdev)
switch (profile_map) {
case BTC_BT_NOPROFILE:
if (_check_freerun(rtwdev))
_action_freerun(rtwdev);
else if (pan.active)
if (pan.active)
_action_bt_pan(rtwdev);
else
_action_bt_idle(rtwdev);
break;
case BTC_BT_HFP:
if (_check_freerun(rtwdev))
_action_freerun(rtwdev);
else
_action_bt_hfp(rtwdev);
_action_bt_hfp(rtwdev);
break;
case BTC_BT_HFP | BTC_BT_HID:
case BTC_BT_HID:
if (_check_freerun(rtwdev))
_action_freerun(rtwdev);
else
_action_bt_hid(rtwdev);
_action_bt_hid(rtwdev);
break;
case BTC_BT_A2DP:
if (_check_freerun(rtwdev))
_action_freerun(rtwdev);
else if (a2dp.sink)
if (a2dp.sink)
_action_bt_a2dpsink(rtwdev);
else if (bt_linfo->multi_link.now && !hid.pair_cnt)
_action_bt_a2dp_pan(rtwdev);
@@ -5283,13 +5336,18 @@ static void _action_by_bt(struct rtw89_dev *rtwdev)
case BTC_BT_A2DP | BTC_BT_HFP:
case BTC_BT_A2DP | BTC_BT_HID:
case BTC_BT_A2DP | BTC_BT_HFP | BTC_BT_HID:
if (_check_freerun(rtwdev))
_action_freerun(rtwdev);
if (a2dp.sink)
_action_bt_a2dpsink(rtwdev);
else if (pan.active)
_action_bt_a2dp_pan_hid(rtwdev);
else
_action_bt_a2dp_hid(rtwdev);
break;
case BTC_BT_A2DP | BTC_BT_PAN:
_action_bt_a2dp_pan(rtwdev);
if (a2dp.sink)
_action_bt_a2dpsink(rtwdev);
else
_action_bt_a2dp_pan(rtwdev);
break;
case BTC_BT_PAN | BTC_BT_HFP:
case BTC_BT_PAN | BTC_BT_HID:
@@ -5299,7 +5357,10 @@ static void _action_by_bt(struct rtw89_dev *rtwdev)
case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HID:
case BTC_BT_A2DP | BTC_BT_PAN | BTC_BT_HFP:
default:
_action_bt_a2dp_pan_hid(rtwdev);
if (a2dp.sink)
_action_bt_a2dpsink(rtwdev);
else
_action_bt_a2dp_pan_hid(rtwdev);
break;
}
}
@@ -5319,7 +5380,7 @@ static void _action_wl_25g_mcc(struct rtw89_dev *rtwdev)
policy_type = BTC_CXP_OFFE_WL;
else if (btc->cx.wl.status.val & btc_scanning_map.val)
policy_type = BTC_CXP_OFFE_2GBWMIXB;
else if (btc->cx.bt.link_info.profile_cnt.now == 0)
else if (btc->cx.bt.link_info.status.map.connect == 0)
policy_type = BTC_CXP_OFFE_2GISOB;
else
policy_type = BTC_CXP_OFFE_2GBWISOB;
@@ -6891,6 +6952,8 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
bt->scan_rx_low_pri = false;
igno_bt = false;
dm->freerun_chk = _check_freerun(rtwdev); /* check if meet freerun */
if (always_freerun) {
_action_freerun(rtwdev);
igno_bt = true;
@@ -6929,18 +6992,9 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
goto exit;
}
if (cx->state_map == BTC_WLINKING) {
if (mode == BTC_WLINK_NOLINK || mode == BTC_WLINK_2G_STA ||
mode == BTC_WLINK_5G) {
_action_wl_scan(rtwdev);
bt->scan_rx_low_pri = false;
goto exit;
}
}
if (wl->status.map.scan) {
if (wl->status.val & btc_scanning_map.val) {
_action_wl_scan(rtwdev);
bt->scan_rx_low_pri = false;
bt->scan_rx_low_pri = true;
goto exit;
}
@@ -7176,10 +7230,6 @@ void rtw89_btc_ntfy_switch_band(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band)
btc->dm.cnt_notify[BTC_NCNT_SWITCH_BAND]++;
wl->scan_info.band[phy_idx] = band;
wl->scan_info.phy_map |= BIT(phy_idx);
_fw_set_drv_info(rtwdev, CXDRVINFO_SCAN);
if (rtwdev->dbcc_en) {
wl->dbcc_info.scan_band[phy_idx] = band;
_update_dbcc_band(rtwdev, phy_idx);
@@ -7374,13 +7424,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
"[BTC], %s(): bt_info[2]=0x%02x\n",
__func__, bt->raw_info[2]);
/* reset to mo-connect before update */
b->status.val = BTC_BLINK_NOCONNECT;
b->profile_cnt.last = b->profile_cnt.now;
b->relink.last = b->relink.now;
a2dp->exist_last = a2dp->exist;
b->multi_link.last = b->multi_link.now;
bt->inq_pag.last = bt->inq_pag.now;
b->profile_cnt.now = 0;
hid->type = 0;
@@ -7399,7 +7443,8 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
b->profile_cnt.now += (u8)hid->exist;
a2dp->exist = btinfo.lb2.a2dp;
b->profile_cnt.now += (u8)a2dp->exist;
pan->active = btinfo.lb2.pan;
pan->exist = btinfo.lb2.pan;
b->profile_cnt.now += (u8)pan->exist;
btc->dm.trx_info.bt_profile = u32_get_bits(btinfo.val, BT_PROFILE_PROTOCOL_MASK);
/* parse raw info low-Byte3 */
@@ -7423,8 +7468,14 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
/* parse raw info high-Byte1 */
btinfo.val = bt->raw_info[BTC_BTINFO_H1];
b->status.map.ble_connect = btinfo.hb1.ble_connect;
if (btinfo.hb1.ble_connect)
hid->type |= (hid->exist ? BTC_HID_BLE : BTC_HID_RCU);
if (btinfo.hb1.ble_connect) {
if (hid->exist)
hid->type |= BTC_HID_BLE;
else if (btinfo.hb1.voice)
hid->type |= BTC_HID_RCU_VOICE;
else
hid->type |= BTC_HID_RCU;
}
cx->cnt_bt[BTC_BCNT_REINIT] += !!(btinfo.hb1.reinit && !bt->reinit);
bt->reinit = btinfo.hb1.reinit;
@@ -7436,7 +7487,6 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
if (bt->igno_wl && !cx->wl.status.map.rf_off)
_set_bt_ignore_wlan_act(rtwdev, false);
hid->type |= (btinfo.hb1.voice ? BTC_HID_RCU_VOICE : 0);
bt->ble_scan_en = btinfo.hb1.ble_scan;
cx->cnt_bt[BTC_BCNT_ROLESW] += !!(btinfo.hb1.role_sw && !b->role_sw);
@@ -7446,8 +7496,7 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
/* parse raw info high-Byte2 */
btinfo.val = bt->raw_info[BTC_BTINFO_H2];
pan->exist = btinfo.hb2.pan_active;
b->profile_cnt.now += (u8)pan->exist;
pan->active = !!btinfo.hb2.pan_active;
cx->cnt_bt[BTC_BCNT_AFH] += !!(btinfo.hb2.afh_update && !b->afh_update);
b->afh_update = btinfo.hb2.afh_update;
@@ -7455,8 +7504,9 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
b->slave_role = btinfo.hb2.slave;
hid->slot_info = btinfo.hb2.hid_slot;
hid->pair_cnt = btinfo.hb2.hid_cnt;
hid->type |= (hid->slot_info == BTC_HID_218 ?
BTC_HID_218 : BTC_HID_418);
if (!b->status.map.ble_connect || hid->pair_cnt > 1)
hid->type |= (hid->slot_info == BTC_HID_218 ?
BTC_HID_218 : BTC_HID_418);
/* parse raw info high-Byte3 */
btinfo.val = bt->raw_info[BTC_BTINFO_H3];
a2dp->bitpool = btinfo.hb3.a2dp_bitpool;
@@ -7479,13 +7529,16 @@ static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
_run_coex(rtwdev, BTC_RSN_UPDATE_BT_INFO);
}
void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta, enum btc_role_state state)
void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
enum btc_role_state state)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
rtwvif->chanctx_idx);
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
rtwvif_link->chanctx_idx);
struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
struct ieee80211_bss_conf *bss_conf;
struct ieee80211_link_sta *link_sta;
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
@@ -7493,51 +7546,59 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif
struct rtw89_btc_wl_link_info *wlinfo = NULL;
u8 mode = 0, rlink_id, link_mode_ori, pta_req_mac_ori, wa_type;
rcu_read_lock();
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, false);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], state=%d\n", state);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], role is STA=%d\n",
vif->type == NL80211_IFTYPE_STATION);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", rtwvif->port);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], port=%d\n", rtwvif_link->port);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], band=%d ch=%d bw=%d\n",
chan->band_type, chan->channel, chan->band_width);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], associated=%d\n",
state == BTC_ROLE_MSTS_STA_CONN_END);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], bcn_period=%d dtim_period=%d\n",
vif->bss_conf.beacon_int, vif->bss_conf.dtim_period);
bss_conf->beacon_int, bss_conf->dtim_period);
if (rtwsta_link) {
link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, false);
if (rtwsta) {
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], STA mac_id=%d\n",
rtwsta->mac_id);
rtwsta_link->mac_id);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], STA support HE=%d VHT=%d HT=%d\n",
sta->deflink.he_cap.has_he,
sta->deflink.vht_cap.vht_supported,
sta->deflink.ht_cap.ht_supported);
if (sta->deflink.he_cap.has_he)
link_sta->he_cap.has_he,
link_sta->vht_cap.vht_supported,
link_sta->ht_cap.ht_supported);
if (link_sta->he_cap.has_he)
mode |= BIT(BTC_WL_MODE_HE);
if (sta->deflink.vht_cap.vht_supported)
if (link_sta->vht_cap.vht_supported)
mode |= BIT(BTC_WL_MODE_VHT);
if (sta->deflink.ht_cap.ht_supported)
if (link_sta->ht_cap.ht_supported)
mode |= BIT(BTC_WL_MODE_HT);
r.mode = mode;
}
if (rtwvif->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX)
if (rtwvif_link->wifi_role >= RTW89_WIFI_ROLE_MLME_MAX) {
rcu_read_unlock();
return;
}
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], wifi_role=%d\n", rtwvif->wifi_role);
"[BTC], wifi_role=%d\n", rtwvif_link->wifi_role);
r.role = rtwvif->wifi_role;
r.phy = rtwvif->phy_idx;
r.pid = rtwvif->port;
r.role = rtwvif_link->wifi_role;
r.phy = rtwvif_link->phy_idx;
r.pid = rtwvif_link->port;
r.active = true;
r.connected = MLME_LINKED;
r.bcn_period = vif->bss_conf.beacon_int;
r.dtim_period = vif->bss_conf.dtim_period;
r.bcn_period = bss_conf->beacon_int;
r.dtim_period = bss_conf->dtim_period;
r.band = chan->band_type;
r.ch = chan->channel;
r.bw = chan->band_width;
@@ -7545,10 +7606,12 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif
r.chdef.center_ch = chan->channel;
r.chdef.bw = chan->band_width;
r.chdef.chan = chan->primary_channel;
ether_addr_copy(r.mac_addr, rtwvif->mac_addr);
ether_addr_copy(r.mac_addr, rtwvif_link->mac_addr);
if (rtwsta && vif->type == NL80211_IFTYPE_STATION)
r.mac_id = rtwsta->mac_id;
rcu_read_unlock();
if (rtwsta_link && vif->type == NL80211_IFTYPE_STATION)
r.mac_id = rtwsta_link->mac_id;
btc->dm.cnt_notify[BTC_NCNT_ROLE_INFO]++;
@@ -7779,26 +7842,26 @@ struct rtw89_btc_wl_sta_iter_data {
bool is_traffic_change;
};
static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
static
void __rtw89_btc_ntfy_wl_sta_iter(struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
struct rtw89_btc_wl_sta_iter_data *iter_data)
{
struct rtw89_btc_wl_sta_iter_data *iter_data =
(struct rtw89_btc_wl_sta_iter_data *)data;
struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
struct rtw89_dev *rtwdev = iter_data->rtwdev;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &btc->dm;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_link_info *link_info = NULL;
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_traffic_stats *link_info_t = NULL;
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_traffic_stats *stats = &rtwvif->stats;
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc_wl_role_info *r;
struct rtw89_btc_wl_role_info_v1 *r1;
u32 last_tx_rate, last_rx_rate;
u16 last_tx_lvl, last_rx_lvl;
u8 port = rtwvif->port;
u8 port = rtwvif_link->port;
u8 rssi;
u8 busy = 0;
u8 dir = 0;
@@ -7806,11 +7869,11 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
u8 i = 0;
bool is_sta_change = false, is_traffic_change = false;
rssi = ewma_rssi_read(&rtwsta->avg_rssi) >> RSSI_FACTOR;
rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR;
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], rssi=%d\n", rssi);
link_info = &wl->link_info[port];
link_info->stat.traffic = rtwvif->stats;
link_info->stat.traffic = *stats;
link_info_t = &link_info->stat.traffic;
if (link_info->connected == MLME_NO_LINK) {
@@ -7858,19 +7921,19 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
iter_data->busy_all |= busy;
iter_data->dir_all |= BIT(dir);
if (rtwsta->rx_hw_rate <= RTW89_HW_RATE_CCK2 &&
if (rtwsta_link->rx_hw_rate <= RTW89_HW_RATE_CCK2 &&
last_rx_rate > RTW89_HW_RATE_CCK2 &&
link_info_t->rx_tfc_lv > RTW89_TFC_IDLE)
link_info->rx_rate_drop_cnt++;
if (last_tx_rate != rtwsta->ra_report.hw_rate ||
last_rx_rate != rtwsta->rx_hw_rate ||
if (last_tx_rate != rtwsta_link->ra_report.hw_rate ||
last_rx_rate != rtwsta_link->rx_hw_rate ||
last_tx_lvl != link_info_t->tx_tfc_lv ||
last_rx_lvl != link_info_t->rx_tfc_lv)
is_traffic_change = true;
link_info_t->tx_rate = rtwsta->ra_report.hw_rate;
link_info_t->rx_rate = rtwsta->rx_hw_rate;
link_info_t->tx_rate = rtwsta_link->ra_report.hw_rate;
link_info_t->rx_rate = rtwsta_link->rx_hw_rate;
if (link_info->role == RTW89_WIFI_ROLE_STATION ||
link_info->role == RTW89_WIFI_ROLE_P2P_CLIENT) {
@@ -7882,19 +7945,19 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
r = &wl->role_info;
r->active_role[port].tx_lvl = stats->tx_tfc_lv;
r->active_role[port].rx_lvl = stats->rx_tfc_lv;
r->active_role[port].tx_rate = rtwsta->ra_report.hw_rate;
r->active_role[port].rx_rate = rtwsta->rx_hw_rate;
r->active_role[port].tx_rate = rtwsta_link->ra_report.hw_rate;
r->active_role[port].rx_rate = rtwsta_link->rx_hw_rate;
} else if (ver->fwlrole == 1) {
r1 = &wl->role_info_v1;
r1->active_role_v1[port].tx_lvl = stats->tx_tfc_lv;
r1->active_role_v1[port].rx_lvl = stats->rx_tfc_lv;
r1->active_role_v1[port].tx_rate = rtwsta->ra_report.hw_rate;
r1->active_role_v1[port].rx_rate = rtwsta->rx_hw_rate;
r1->active_role_v1[port].tx_rate = rtwsta_link->ra_report.hw_rate;
r1->active_role_v1[port].rx_rate = rtwsta_link->rx_hw_rate;
} else if (ver->fwlrole == 2) {
dm->trx_info.tx_lvl = stats->tx_tfc_lv;
dm->trx_info.rx_lvl = stats->rx_tfc_lv;
dm->trx_info.tx_rate = rtwsta->ra_report.hw_rate;
dm->trx_info.rx_rate = rtwsta->rx_hw_rate;
dm->trx_info.tx_rate = rtwsta_link->ra_report.hw_rate;
dm->trx_info.rx_rate = rtwsta_link->rx_hw_rate;
}
dm->trx_info.tx_tp = link_info_t->tx_throughput;
@@ -7914,6 +7977,21 @@ static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
iter_data->is_traffic_change = true;
}
static void rtw89_btc_ntfy_wl_sta_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_btc_wl_sta_iter_data *iter_data =
(struct rtw89_btc_wl_sta_iter_data *)data;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_sta_link *rtwsta_link;
unsigned int link_id;
rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
rtwvif_link = rtwsta_link->rtwvif_link;
__rtw89_btc_ntfy_wl_sta_iter(rtwvif_link, rtwsta_link, iter_data);
}
}
#define BTC_NHM_CHK_INTVL 20
void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev)
@@ -7963,6 +8041,53 @@ void rtw89_btc_ntfy_wl_sta(struct rtw89_dev *rtwdev)
}
}
static u8 rtw89_btc_c2h_get_index_by_ver(struct rtw89_dev *rtwdev, u8 func)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
switch (func) {
case BTF_EVNT_RPT:
case BTF_EVNT_BT_INFO:
case BTF_EVNT_BT_SCBD:
case BTF_EVNT_BT_REG:
case BTF_EVNT_CX_RUNINFO:
case BTF_EVNT_BT_PSD:
return func;
case BTF_EVNT_BT_DEV_INFO:
if (ver->fwc2hfunc == 0)
return BTF_EVNT_BUF_OVERFLOW;
else
return BTF_EVNT_BT_DEV_INFO;
case BTF_EVNT_BT_LEAUDIO_INFO:
if (ver->fwc2hfunc == 0)
return BTF_EVNT_C2H_LOOPBACK;
else if (ver->fwc2hfunc == 1)
return BTF_EVNT_BUF_OVERFLOW;
else if (ver->fwc2hfunc == 2)
return func;
else
return BTF_EVNT_MAX;
case BTF_EVNT_BUF_OVERFLOW:
if (ver->fwc2hfunc == 0)
return BTF_EVNT_MAX;
else if (ver->fwc2hfunc == 1)
return BTF_EVNT_C2H_LOOPBACK;
else if (ver->fwc2hfunc == 2)
return func;
else
return BTF_EVNT_MAX;
case BTF_EVNT_C2H_LOOPBACK:
if (ver->fwc2hfunc == 2)
return func;
else
return BTF_EVNT_MAX;
case BTF_EVNT_MAX:
default:
return BTF_EVNT_MAX;
}
}
void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u32 len, u8 class, u8 func)
{
@@ -7979,9 +8104,13 @@ void rtw89_btc_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
if (class != BTFC_FW_EVENT)
return;
func = rtw89_btc_c2h_get_index_by_ver(rtwdev, func);
switch (func) {
case BTF_EVNT_RPT:
case BTF_EVNT_BUF_OVERFLOW:
pfwinfo->event[func]++;
break;
case BTF_EVNT_RPT:
pfwinfo->event[func]++;
/* Don't need rtw89_leave_ps_mode() */
btc_fw_event(rtwdev, func, buf, len);

View File

@@ -271,8 +271,10 @@ 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_role_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta, enum btc_role_state state);
void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
enum btc_role_state state);
void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_state);
void rtw89_btc_ntfy_wl_rfk(struct rtw89_dev *rtwdev, u8 phy_map,
enum btc_wl_rfk_type type,

File diff suppressed because it is too large Load Diff

View File

@@ -829,6 +829,8 @@ enum rtw89_phy_idx {
RTW89_PHY_MAX
};
#define __RTW89_MLD_MAX_LINK_NUM 2
enum rtw89_chanctx_idx {
RTW89_CHANCTX_0 = 0,
RTW89_CHANCTX_1 = 1,
@@ -1166,8 +1168,8 @@ struct rtw89_core_tx_request {
enum rtw89_core_tx_type tx_type;
struct sk_buff *skb;
struct ieee80211_vif *vif;
struct ieee80211_sta *sta;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_sta_link *rtwsta_link;
struct rtw89_tx_desc_info desc_info;
};
@@ -1350,7 +1352,6 @@ struct rtw89_btc_wl_smap {
u32 connecting: 1;
u32 roaming: 1;
u32 dbccing: 1;
u32 transacting: 1;
u32 _4way: 1;
u32 rf_off: 1;
u32 lps: 2;
@@ -2937,6 +2938,7 @@ struct rtw89_btc_dm {
u8 wl_pre_agc: 2;
u8 wl_lna2: 1;
u8 freerun_chk: 1;
u8 wl_pre_agc_rb: 2;
u8 bt_select: 2; /* 0:s0, 1:s1, 2:s0 & s1, refer to enum btc_bt_index */
u8 slot_req_more: 1;
@@ -2975,6 +2977,8 @@ enum rtw89_btc_btf_fw_event {
BTF_EVNT_BT_REG = 3,
BTF_EVNT_CX_RUNINFO = 4,
BTF_EVNT_BT_PSD = 5,
BTF_EVNT_BT_DEV_INFO = 6, /* fwc2hfunc > 0 */
BTF_EVNT_BT_LEAUDIO_INFO = 7, /* fwc2hfunc > 1 */
BTF_EVNT_BUF_OVERFLOW,
BTF_EVNT_C2H_LOOPBACK,
BTF_EVNT_MAX,
@@ -3141,6 +3145,7 @@ struct rtw89_btc_ver {
u8 fcxinit;
u8 fwevntrptl;
u8 fwc2hfunc;
u8 drvinfo_type;
u16 info_buf;
u8 max_role_num;
@@ -3354,12 +3359,13 @@ struct rtw89_sec_cam_entry {
u8 key[32];
};
struct rtw89_sta {
struct rtw89_sta_link {
struct rtw89_sta *rtwsta;
unsigned int link_id;
u8 mac_id;
bool disassoc;
bool er_cap;
struct rtw89_dev *rtwdev;
struct rtw89_vif *rtwvif;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_ra_info ra;
struct rtw89_ra_report ra_report;
int max_agg_wait;
@@ -3370,15 +3376,12 @@ struct rtw89_sta {
struct ewma_evm evm_1ss;
struct ewma_evm evm_min[RF_PATH_MAX];
struct ewma_evm evm_max[RF_PATH_MAX];
struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS];
DECLARE_BITMAP(ampdu_map, IEEE80211_NUM_TIDS);
struct ieee80211_rx_status rx_status;
u16 rx_hw_rate;
__le32 htc_template;
struct rtw89_addr_cam_entry addr_cam; /* AP mode or TDLS peer only */
struct rtw89_bssid_cam_entry bssid_cam; /* TDLS peer only */
struct list_head ba_cam_list;
struct sk_buff_head roc_queue;
bool use_cfg_mask;
struct cfg80211_bitrate_mask mask;
@@ -3460,10 +3463,10 @@ struct rtw89_p2p_noa_setter {
u8 noa_index;
};
struct rtw89_vif {
struct list_head list;
struct rtw89_dev *rtwdev;
struct rtw89_roc roc;
struct rtw89_vif_link {
struct rtw89_vif *rtwvif;
unsigned int link_id;
bool chanctx_assigned; /* only valid when running with chanctx_ops */
enum rtw89_chanctx_idx chanctx_idx;
enum rtw89_reg_6ghz_power reg_6ghz_power;
@@ -3473,7 +3476,6 @@ struct rtw89_vif {
u8 port;
u8 mac_addr[ETH_ALEN];
u8 bssid[ETH_ALEN];
__be32 ip_addr;
u8 phy_idx;
u8 mac_idx;
u8 net_type;
@@ -3484,7 +3486,6 @@ struct rtw89_vif {
u8 hit_rule;
u8 last_noa_nr;
u64 sync_bcn_tsf;
bool offchan;
bool trigger;
bool lsig_txop;
u8 tgt_ind;
@@ -3498,15 +3499,11 @@ struct rtw89_vif {
bool pre_pwr_diff_en;
bool pwr_diff_en;
u8 def_tri_idx;
u32 tdls_peer;
struct work_struct 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];
struct rtw89_traffic_stats stats;
struct rtw89_phy_rate_pattern rate_pattern;
struct cfg80211_scan_request *scan_req;
struct ieee80211_scan_ies *scan_ies;
struct list_head general_pkt_list;
struct rtw89_p2p_noa_setter p2p_noa;
};
@@ -3599,11 +3596,11 @@ struct rtw89_chip_ops {
void (*rfk_hw_init)(struct rtw89_dev *rtwdev);
void (*rfk_init)(struct rtw89_dev *rtwdev);
void (*rfk_init_late)(struct rtw89_dev *rtwdev);
void (*rfk_channel)(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
void (*rfk_channel)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
void (*rfk_band_changed)(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
const struct rtw89_chan *chan);
void (*rfk_scan)(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
void (*rfk_scan)(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool start);
void (*rfk_track)(struct rtw89_dev *rtwdev);
void (*power_trim)(struct rtw89_dev *rtwdev);
@@ -3646,23 +3643,25 @@ struct rtw89_chip_ops {
u32 *tx_en, enum rtw89_sch_tx_sel sel);
int (*resume_sch_tx)(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en);
int (*h2c_dctl_sec_cam)(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta);
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int (*h2c_default_cmac_tbl)(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta);
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int (*h2c_assoc_cmac_tbl)(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int (*h2c_ampdu_cmac_tbl)(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int (*h2c_default_dmac_tbl)(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta);
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int (*h2c_update_beacon)(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif);
int (*h2c_ba_cam)(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
struct rtw89_vif_link *rtwvif_link);
int (*h2c_ba_cam)(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
bool valid, struct ieee80211_ampdu_params *params);
void (*btc_set_rfe)(struct rtw89_dev *rtwdev);
@@ -4445,6 +4444,8 @@ enum rtw89_fw_feature {
RTW89_FW_FEATURE_SCAN_OFFLOAD_BE_V0,
RTW89_FW_FEATURE_WOW_REASON_V1,
RTW89_FW_FEATURE_RFK_PRE_NOTIFY_V0,
RTW89_FW_FEATURE_RFK_RXDCK_V0,
RTW89_FW_FEATURE_NO_WOW_CPU_IO_RX,
};
struct rtw89_fw_suit {
@@ -4672,7 +4673,7 @@ struct rtw89_hal {
struct rtw89_chanctx chanctx[NUM_OF_RTW89_CHANCTX];
struct cfg80211_chan_def roc_chandef;
bool entity_active;
bool entity_active[RTW89_PHY_MAX];
bool entity_pause;
enum rtw89_entity_mode entity_mode;
@@ -4750,6 +4751,7 @@ DECLARE_EWMA(thermal, 4, 4);
struct rtw89_phy_stat {
struct ewma_thermal avg_thermal[RF_PATH_MAX];
struct ewma_rssi bcn_rssi;
struct rtw89_pkt_stat cur_pkt_stat;
struct rtw89_pkt_stat last_pkt_stat;
};
@@ -5196,7 +5198,7 @@ struct rtw89_early_h2c {
};
struct rtw89_hw_scan_info {
struct ieee80211_vif *scanning_vif;
struct rtw89_vif_link *scanning_vif;
struct list_head pkt_list[NUM_NL80211_BANDS];
struct rtw89_chan op_chan;
bool abort;
@@ -5371,7 +5373,7 @@ struct rtw89_wow_aoac_report {
};
struct rtw89_wow_param {
struct ieee80211_vif *wow_vif;
struct rtw89_vif_link *rtwvif_link;
DECLARE_BITMAP(flags, RTW89_WOW_FLAG_NUM);
struct rtw89_wow_cam_info patterns[RTW89_MAX_PATTERN_NUM];
struct rtw89_wow_key_info key_info;
@@ -5408,7 +5410,7 @@ struct rtw89_mcc_policy {
};
struct rtw89_mcc_role {
struct rtw89_vif *rtwvif;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_mcc_policy policy;
struct rtw89_mcc_limit limit;
@@ -5608,6 +5610,121 @@ struct rtw89_dev {
u8 priv[] __aligned(sizeof(void *));
};
struct rtw89_vif {
struct rtw89_dev *rtwdev;
struct list_head list;
u8 mac_addr[ETH_ALEN];
__be32 ip_addr;
struct rtw89_traffic_stats stats;
u32 tdls_peer;
struct ieee80211_scan_ies *scan_ies;
struct cfg80211_scan_request *scan_req;
struct rtw89_roc roc;
bool offchan;
u8 links_inst_valid_num;
DECLARE_BITMAP(links_inst_map, __RTW89_MLD_MAX_LINK_NUM);
struct rtw89_vif_link *links[IEEE80211_MLD_MAX_NUM_LINKS];
struct rtw89_vif_link links_inst[] __counted_by(links_inst_valid_num);
};
static inline bool rtw89_vif_assign_link_is_valid(struct rtw89_vif_link **rtwvif_link,
const struct rtw89_vif *rtwvif,
unsigned int link_id)
{
*rtwvif_link = rtwvif->links[link_id];
return !!*rtwvif_link;
}
#define rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) \
for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) \
if (rtw89_vif_assign_link_is_valid(&(rtwvif_link), rtwvif, link_id))
struct rtw89_sta {
struct rtw89_dev *rtwdev;
struct rtw89_vif *rtwvif;
bool disassoc;
struct sk_buff_head roc_queue;
struct rtw89_ampdu_params ampdu_params[IEEE80211_NUM_TIDS];
DECLARE_BITMAP(ampdu_map, IEEE80211_NUM_TIDS);
u8 links_inst_valid_num;
DECLARE_BITMAP(links_inst_map, __RTW89_MLD_MAX_LINK_NUM);
struct rtw89_sta_link *links[IEEE80211_MLD_MAX_NUM_LINKS];
struct rtw89_sta_link links_inst[] __counted_by(links_inst_valid_num);
};
static inline bool rtw89_sta_assign_link_is_valid(struct rtw89_sta_link **rtwsta_link,
const struct rtw89_sta *rtwsta,
unsigned int link_id)
{
*rtwsta_link = rtwsta->links[link_id];
return !!*rtwsta_link;
}
#define rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) \
for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) \
if (rtw89_sta_assign_link_is_valid(&(rtwsta_link), rtwsta, link_id))
static inline u8 rtw89_vif_get_main_macid(struct rtw89_vif *rtwvif)
{
/* const after init, so no need to check if active first */
return rtwvif->links_inst[0].mac_id;
}
static inline u8 rtw89_vif_get_main_port(struct rtw89_vif *rtwvif)
{
/* const after init, so no need to check if active first */
return rtwvif->links_inst[0].port;
}
static inline struct rtw89_vif_link *
rtw89_vif_get_link_inst(struct rtw89_vif *rtwvif, u8 index)
{
if (index >= rtwvif->links_inst_valid_num ||
!test_bit(index, rtwvif->links_inst_map))
return NULL;
return &rtwvif->links_inst[index];
}
static inline
u8 rtw89_vif_link_inst_get_index(struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_vif *rtwvif = rtwvif_link->rtwvif;
return rtwvif_link - rtwvif->links_inst;
}
static inline u8 rtw89_sta_get_main_macid(struct rtw89_sta *rtwsta)
{
/* const after init, so no need to check if active first */
return rtwsta->links_inst[0].mac_id;
}
static inline struct rtw89_sta_link *
rtw89_sta_get_link_inst(struct rtw89_sta *rtwsta, u8 index)
{
if (index >= rtwsta->links_inst_valid_num ||
!test_bit(index, rtwsta->links_inst_map))
return NULL;
return &rtwsta->links_inst[index];
}
static inline
u8 rtw89_sta_link_inst_get_index(struct rtw89_sta_link *rtwsta_link)
{
struct rtw89_sta *rtwsta = rtwsta_link->rtwsta;
return rtwsta_link - rtwsta->links_inst;
}
static inline int rtw89_hci_tx_write(struct rtw89_dev *rtwdev,
struct rtw89_core_tx_request *tx_req)
{
@@ -5972,9 +6089,26 @@ static inline struct ieee80211_vif *rtwvif_to_vif_safe(struct rtw89_vif *rtwvif)
return rtwvif ? rtwvif_to_vif(rtwvif) : NULL;
}
static inline
struct ieee80211_vif *rtwvif_link_to_vif(struct rtw89_vif_link *rtwvif_link)
{
return rtwvif_to_vif(rtwvif_link->rtwvif);
}
static inline
struct ieee80211_vif *rtwvif_link_to_vif_safe(struct rtw89_vif_link *rtwvif_link)
{
return rtwvif_link ? rtwvif_link_to_vif(rtwvif_link) : NULL;
}
static inline struct rtw89_vif *vif_to_rtwvif(struct ieee80211_vif *vif)
{
return (struct rtw89_vif *)vif->drv_priv;
}
static inline struct rtw89_vif *vif_to_rtwvif_safe(struct ieee80211_vif *vif)
{
return vif ? (struct rtw89_vif *)vif->drv_priv : NULL;
return vif ? vif_to_rtwvif(vif) : NULL;
}
static inline struct ieee80211_sta *rtwsta_to_sta(struct rtw89_sta *rtwsta)
@@ -5989,11 +6123,88 @@ static inline struct ieee80211_sta *rtwsta_to_sta_safe(struct rtw89_sta *rtwsta)
return rtwsta ? rtwsta_to_sta(rtwsta) : NULL;
}
static inline
struct ieee80211_sta *rtwsta_link_to_sta(struct rtw89_sta_link *rtwsta_link)
{
return rtwsta_to_sta(rtwsta_link->rtwsta);
}
static inline
struct ieee80211_sta *rtwsta_link_to_sta_safe(struct rtw89_sta_link *rtwsta_link)
{
return rtwsta_link ? rtwsta_link_to_sta(rtwsta_link) : NULL;
}
static inline struct rtw89_sta *sta_to_rtwsta(struct ieee80211_sta *sta)
{
return (struct rtw89_sta *)sta->drv_priv;
}
static inline struct rtw89_sta *sta_to_rtwsta_safe(struct ieee80211_sta *sta)
{
return sta ? (struct rtw89_sta *)sta->drv_priv : NULL;
return sta ? sta_to_rtwsta(sta) : NULL;
}
static inline struct ieee80211_bss_conf *
__rtw89_vif_rcu_dereference_link(struct rtw89_vif_link *rtwvif_link, bool *nolink)
{
struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
struct ieee80211_bss_conf *bss_conf;
bss_conf = rcu_dereference(vif->link_conf[rtwvif_link->link_id]);
if (unlikely(!bss_conf)) {
*nolink = true;
return &vif->bss_conf;
}
*nolink = false;
return bss_conf;
}
#define rtw89_vif_rcu_dereference_link(rtwvif_link, assert) \
({ \
typeof(rtwvif_link) p = rtwvif_link; \
struct ieee80211_bss_conf *bss_conf; \
bool nolink; \
\
bss_conf = __rtw89_vif_rcu_dereference_link(p, &nolink); \
if (unlikely(nolink) && (assert)) \
rtw89_err(p->rtwvif->rtwdev, \
"%s: cannot find exact bss_conf for link_id %u\n",\
__func__, p->link_id); \
bss_conf; \
})
static inline struct ieee80211_link_sta *
__rtw89_sta_rcu_dereference_link(struct rtw89_sta_link *rtwsta_link, bool *nolink)
{
struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
struct ieee80211_link_sta *link_sta;
link_sta = rcu_dereference(sta->link[rtwsta_link->link_id]);
if (unlikely(!link_sta)) {
*nolink = true;
return &sta->deflink;
}
*nolink = false;
return link_sta;
}
#define rtw89_sta_rcu_dereference_link(rtwsta_link, assert) \
({ \
typeof(rtwsta_link) p = rtwsta_link; \
struct ieee80211_link_sta *link_sta; \
bool nolink; \
\
link_sta = __rtw89_sta_rcu_dereference_link(p, &nolink); \
if (unlikely(nolink) && (assert)) \
rtw89_err(p->rtwsta->rtwdev, \
"%s: cannot find exact link_sta for link_id %u\n",\
__func__, p->link_id); \
link_sta; \
})
static inline u8 rtw89_hw_to_rate_info_bw(enum rtw89_bandwidth hw_bw)
{
if (hw_bw == RTW89_CHANNEL_WIDTH_160)
@@ -6078,29 +6289,29 @@ enum nl80211_he_ru_alloc rtw89_he_rua_to_ru_alloc(u16 rua)
}
static inline
struct rtw89_addr_cam_entry *rtw89_get_addr_cam_of(struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta)
struct rtw89_addr_cam_entry *rtw89_get_addr_cam_of(struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link)
{
if (rtwsta) {
struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
if (rtwsta_link) {
struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
return &rtwsta->addr_cam;
if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
return &rtwsta_link->addr_cam;
}
return &rtwvif->addr_cam;
return &rtwvif_link->addr_cam;
}
static inline
struct rtw89_bssid_cam_entry *rtw89_get_bssid_cam_of(struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta)
struct rtw89_bssid_cam_entry *rtw89_get_bssid_cam_of(struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link)
{
if (rtwsta) {
struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
if (rtwsta_link) {
struct ieee80211_sta *sta = rtwsta_link_to_sta(rtwsta_link);
if (sta->tdls)
return &rtwsta->bssid_cam;
return &rtwsta_link->bssid_cam;
}
return &rtwvif->bssid_cam;
return &rtwvif_link->bssid_cam;
}
static inline
@@ -6159,11 +6370,10 @@ const struct rtw89_chan_rcd *rtw89_chan_rcd_get(struct rtw89_dev *rtwdev,
static inline
const struct rtw89_chan *rtw89_scan_chan_get(struct rtw89_dev *rtwdev)
{
struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif;
struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
struct rtw89_vif_link *rtwvif_link = rtwdev->scan_info.scanning_vif;
if (rtwvif)
return rtw89_chan_get(rtwdev, rtwvif->chanctx_idx);
if (rtwvif_link)
return rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
else
return rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
}
@@ -6240,12 +6450,12 @@ static inline void rtw89_chip_rfk_init_late(struct rtw89_dev *rtwdev)
}
static inline void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif)
struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (chip->ops->rfk_channel)
chip->ops->rfk_channel(rtwdev, rtwvif);
chip->ops->rfk_channel(rtwdev, rtwvif_link);
}
static inline void rtw89_chip_rfk_band_changed(struct rtw89_dev *rtwdev,
@@ -6259,12 +6469,12 @@ static inline void rtw89_chip_rfk_band_changed(struct rtw89_dev *rtwdev,
}
static inline void rtw89_chip_rfk_scan(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool start)
struct rtw89_vif_link *rtwvif_link, bool start)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (chip->ops->rfk_scan)
chip->ops->rfk_scan(rtwdev, rtwvif, start);
chip->ops->rfk_scan(rtwdev, rtwvif_link, start);
}
static inline void rtw89_chip_rfk_track(struct rtw89_dev *rtwdev)
@@ -6279,8 +6489,12 @@ static inline void rtw89_chip_set_txpwr_ctrl(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (chip->ops->set_txpwr_ctrl)
chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_0);
if (!chip->ops->set_txpwr_ctrl)
return;
chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_0);
if (rtwdev->dbcc_en)
chip->ops->set_txpwr_ctrl(rtwdev, RTW89_PHY_1);
}
static inline void rtw89_chip_power_trim(struct rtw89_dev *rtwdev)
@@ -6291,8 +6505,8 @@ static inline void rtw89_chip_power_trim(struct rtw89_dev *rtwdev)
chip->ops->power_trim(rtwdev);
}
static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
static inline void __rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
@@ -6300,6 +6514,13 @@ static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev,
chip->ops->init_txpwr_unit(rtwdev, phy_idx);
}
static inline void rtw89_chip_init_txpwr_unit(struct rtw89_dev *rtwdev)
{
__rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_0);
if (rtwdev->dbcc_en)
__rtw89_chip_init_txpwr_unit(rtwdev, RTW89_PHY_1);
}
static inline u8 rtw89_chip_get_thermal(struct rtw89_dev *rtwdev,
enum rtw89_rf_path rf_path)
{
@@ -6347,20 +6568,6 @@ static inline void rtw89_chip_cfg_txrx_path(struct rtw89_dev *rtwdev)
chip->ops->cfg_txrx_path(rtwdev);
}
static inline
void rtw89_chip_cfg_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif)
{
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
const struct rtw89_chip_info *chip = rtwdev->chip;
if (!vif->bss_conf.he_support || !vif->cfg.assoc)
return;
if (chip->ops->set_txpwr_ul_tb_offset)
chip->ops->set_txpwr_ul_tb_offset(rtwdev, 0, rtwvif->mac_idx);
}
static inline void rtw89_chip_digital_pwr_comp(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
@@ -6457,14 +6664,14 @@ int rtw89_chip_resume_sch_tx(struct rtw89_dev *rtwdev, u8 mac_idx, u32 tx_en)
static inline
int rtw89_chip_h2c_dctl_sec_cam(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta)
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (!chip->ops->h2c_dctl_sec_cam)
return 0;
return chip->ops->h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
return chip->ops->h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link);
}
static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr)
@@ -6479,13 +6686,14 @@ static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr)
return hdr->addr3;
}
static inline bool rtw89_sta_has_beamformer_cap(struct ieee80211_sta *sta)
static inline
bool rtw89_sta_has_beamformer_cap(struct ieee80211_link_sta *link_sta)
{
if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) ||
(sta->deflink.he_cap.he_cap_elem.phy_cap_info[3] &
if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) ||
(link_sta->he_cap.he_cap_elem.phy_cap_info[3] &
IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) ||
(sta->deflink.he_cap.he_cap_elem.phy_cap_info[4] &
(link_sta->he_cap.he_cap_elem.phy_cap_info[4] &
IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER))
return true;
return false;
@@ -6605,21 +6813,21 @@ void rtw89_core_napi_start(struct rtw89_dev *rtwdev);
void rtw89_core_napi_stop(struct rtw89_dev *rtwdev);
int rtw89_core_napi_init(struct rtw89_dev *rtwdev);
void rtw89_core_napi_deinit(struct rtw89_dev *rtwdev);
int rtw89_core_sta_add(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
int rtw89_core_sta_disassoc(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
int rtw89_core_sta_remove(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
int rtw89_core_sta_link_add(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int rtw89_core_sta_link_assoc(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int rtw89_core_sta_link_disassoc(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int rtw89_core_sta_link_disconnect(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int rtw89_core_sta_link_remove(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
void rtw89_core_set_tid_config(struct rtw89_dev *rtwdev,
struct ieee80211_sta *sta,
struct cfg80211_tid_config *tid_config);
@@ -6635,22 +6843,40 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device,
void rtw89_free_ieee80211_hw(struct rtw89_dev *rtwdev);
u8 rtw89_acquire_mac_id(struct rtw89_dev *rtwdev);
void rtw89_release_mac_id(struct rtw89_dev *rtwdev, u8 mac_id);
void rtw89_init_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
u8 mac_id, u8 port);
void rtw89_init_sta(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta, u8 mac_id);
struct rtw89_vif_link *rtw89_vif_set_link(struct rtw89_vif *rtwvif,
unsigned int link_id);
void rtw89_vif_unset_link(struct rtw89_vif *rtwvif, unsigned int link_id);
struct rtw89_sta_link *rtw89_sta_set_link(struct rtw89_sta *rtwsta,
unsigned int link_id);
void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id);
void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev);
void rtw89_get_default_chandef(struct cfg80211_chan_def *chandef);
void rtw89_get_channel_params(const struct cfg80211_chan_def *chandef,
struct rtw89_chan *chan);
int rtw89_set_channel(struct rtw89_dev *rtwdev);
void rtw89_get_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
struct rtw89_chan *chan);
u8 rtw89_core_acquire_bit_map(unsigned long *addr, unsigned long size);
void rtw89_core_release_bit_map(unsigned long *addr, u8 bit);
void rtw89_core_release_all_bits_map(unsigned long *addr, unsigned int nbits);
int rtw89_core_acquire_sta_ba_entry(struct rtw89_dev *rtwdev,
struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx);
struct rtw89_sta_link *rtwsta_link, u8 tid,
u8 *cam_idx);
int rtw89_core_release_sta_ba_entry(struct rtw89_dev *rtwdev,
struct rtw89_sta *rtwsta, u8 tid, u8 *cam_idx);
void rtw89_vif_type_mapping(struct ieee80211_vif *vif, bool assoc);
struct rtw89_sta_link *rtwsta_link, u8 tid,
u8 *cam_idx);
void rtw89_core_free_sta_pending_ba(struct rtw89_dev *rtwdev,
struct ieee80211_sta *sta);
void rtw89_core_free_sta_pending_forbid_ba(struct rtw89_dev *rtwdev,
struct ieee80211_sta *sta);
void rtw89_core_free_sta_pending_roc_tx(struct rtw89_dev *rtwdev,
struct ieee80211_sta *sta);
void rtw89_vif_type_mapping(struct rtw89_vif_link *rtwvif_link, bool assoc);
int rtw89_chip_info_setup(struct rtw89_dev *rtwdev);
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,
@@ -6667,13 +6893,15 @@ void rtw89_core_update_beacon_work(struct work_struct *work);
void rtw89_roc_work(struct work_struct *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 *rtwvif,
void rtw89_core_scan_start(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
const u8 *mac_addr, bool hw_scan);
void rtw89_core_scan_complete(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif, bool hw_scan);
int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link, bool hw_scan);
int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool active);
void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf);
void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, enum rtw89_btc_hmsg event);
#endif

View File

@@ -3506,7 +3506,9 @@ out:
return count;
}
static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
static void rtw89_sta_link_info_get_iter(struct seq_file *m,
struct rtw89_dev *rtwdev,
struct rtw89_sta_link *rtwsta_link)
{
static const char * const he_gi_str[] = {
[NL80211_RATE_INFO_HE_GI_0_8] = "0.8",
@@ -3518,20 +3520,26 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
[NL80211_RATE_INFO_EHT_GI_1_6] = "1.6",
[NL80211_RATE_INFO_EHT_GI_3_2] = "3.2",
};
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rate_info *rate = &rtwsta->ra_report.txrate;
struct ieee80211_rx_status *status = &rtwsta->rx_status;
struct seq_file *m = (struct seq_file *)data;
struct rtw89_dev *rtwdev = rtwsta->rtwdev;
struct rate_info *rate = &rtwsta_link->ra_report.txrate;
struct ieee80211_rx_status *status = &rtwsta_link->rx_status;
struct rtw89_hal *hal = &rtwdev->hal;
u8 ant_num = hal->ant_diversity ? 2 : rtwdev->chip->rf_path_num;
bool ant_asterisk = hal->tx_path_diversity || hal->ant_diversity;
struct ieee80211_link_sta *link_sta;
u8 evm_min, evm_max, evm_1ss;
u16 max_rc_amsdu_len;
u8 rssi;
u8 snr;
int i;
seq_printf(m, "TX rate [%d]: ", rtwsta->mac_id);
rcu_read_lock();
link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
max_rc_amsdu_len = link_sta->agg.max_rc_amsdu_len;
rcu_read_unlock();
seq_printf(m, "TX rate [%u, %u]: ", rtwsta_link->mac_id, rtwsta_link->link_id);
if (rate->flags & RATE_INFO_FLAGS_MCS)
seq_printf(m, "HT MCS-%d%s", rate->mcs,
@@ -3549,13 +3557,13 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
eht_gi_str[rate->eht_gi] : "N/A");
else
seq_printf(m, "Legacy %d", rate->legacy);
seq_printf(m, "%s", rtwsta->ra_report.might_fallback_legacy ? " FB_G" : "");
seq_printf(m, "%s", rtwsta_link->ra_report.might_fallback_legacy ? " FB_G" : "");
seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(rate->bw));
seq_printf(m, "\t(hw_rate=0x%x)", rtwsta->ra_report.hw_rate);
seq_printf(m, "\t==> agg_wait=%d (%d)\n", rtwsta->max_agg_wait,
sta->deflink.agg.max_rc_amsdu_len);
seq_printf(m, " (hw_rate=0x%x)", rtwsta_link->ra_report.hw_rate);
seq_printf(m, " ==> agg_wait=%d (%d)\n", rtwsta_link->max_agg_wait,
max_rc_amsdu_len);
seq_printf(m, "RX rate [%d]: ", rtwsta->mac_id);
seq_printf(m, "RX rate [%u, %u]: ", rtwsta_link->mac_id, rtwsta_link->link_id);
switch (status->encoding) {
case RX_ENC_LEGACY:
@@ -3582,24 +3590,24 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
break;
}
seq_printf(m, " BW:%u", rtw89_rate_info_bw_to_mhz(status->bw));
seq_printf(m, "\t(hw_rate=0x%x)\n", rtwsta->rx_hw_rate);
seq_printf(m, " (hw_rate=0x%x)\n", rtwsta_link->rx_hw_rate);
rssi = ewma_rssi_read(&rtwsta->avg_rssi);
rssi = ewma_rssi_read(&rtwsta_link->avg_rssi);
seq_printf(m, "RSSI: %d dBm (raw=%d, prev=%d) [",
RTW89_RSSI_RAW_TO_DBM(rssi), rssi, rtwsta->prev_rssi);
RTW89_RSSI_RAW_TO_DBM(rssi), rssi, rtwsta_link->prev_rssi);
for (i = 0; i < ant_num; i++) {
rssi = ewma_rssi_read(&rtwsta->rssi[i]);
rssi = ewma_rssi_read(&rtwsta_link->rssi[i]);
seq_printf(m, "%d%s%s", RTW89_RSSI_RAW_TO_DBM(rssi),
ant_asterisk && (hal->antenna_tx & BIT(i)) ? "*" : "",
i + 1 == ant_num ? "" : ", ");
}
seq_puts(m, "]\n");
evm_1ss = ewma_evm_read(&rtwsta->evm_1ss);
evm_1ss = ewma_evm_read(&rtwsta_link->evm_1ss);
seq_printf(m, "EVM: [%2u.%02u, ", evm_1ss >> 2, (evm_1ss & 0x3) * 25);
for (i = 0; i < (hal->ant_diversity ? 2 : 1); i++) {
evm_min = ewma_evm_read(&rtwsta->evm_min[i]);
evm_max = ewma_evm_read(&rtwsta->evm_max[i]);
evm_min = ewma_evm_read(&rtwsta_link->evm_min[i]);
evm_max = ewma_evm_read(&rtwsta_link->evm_max[i]);
seq_printf(m, "%s(%2u.%02u, %2u.%02u)", i == 0 ? "" : " ",
evm_min >> 2, (evm_min & 0x3) * 25,
@@ -3607,10 +3615,22 @@ static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
}
seq_puts(m, "]\t");
snr = ewma_snr_read(&rtwsta->avg_snr);
snr = ewma_snr_read(&rtwsta_link->avg_snr);
seq_printf(m, "SNR: %u\n", snr);
}
static void rtw89_sta_info_get_iter(void *data, struct ieee80211_sta *sta)
{
struct seq_file *m = (struct seq_file *)data;
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_dev *rtwdev = rtwsta->rtwdev;
struct rtw89_sta_link *rtwsta_link;
unsigned int link_id;
rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id)
rtw89_sta_link_info_get_iter(m, rtwdev, rtwsta_link);
}
static void
rtw89_debug_append_rx_rate(struct seq_file *m, struct rtw89_pkt_stat *pkt_stat,
enum rtw89_hw_rate first_rate, int len)
@@ -3653,13 +3673,16 @@ static int rtw89_debug_priv_phy_info_get(struct seq_file *m, void *v)
const struct rtw89_chip_info *chip = rtwdev->chip;
const struct rtw89_rx_rate_cnt_info *info;
enum rtw89_hw_rate first_rate;
u8 rssi;
int i;
rssi = ewma_rssi_read(&rtwdev->phystat.bcn_rssi);
seq_printf(m, "TP TX: %u [%u] Mbps (lv: %d), RX: %u [%u] Mbps (lv: %d)\n",
stats->tx_throughput, stats->tx_throughput_raw, stats->tx_tfc_lv,
stats->rx_throughput, stats->rx_throughput_raw, stats->rx_tfc_lv);
seq_printf(m, "Beacon: %u, TF: %u\n", pkt_stat->beacon_nr,
stats->rx_tf_periodic);
seq_printf(m, "Beacon: %u (%d dBm), TF: %u\n", pkt_stat->beacon_nr,
RTW89_RSSI_RAW_TO_DBM(rssi), stats->rx_tf_periodic);
seq_printf(m, "Avg packet length: TX=%u, RX=%u\n", stats->tx_avg_len,
stats->rx_avg_len);
@@ -3737,28 +3760,41 @@ static void rtw89_dump_pkt_offload(struct seq_file *m, struct list_head *pkt_lis
seq_puts(m, "\n");
}
static void rtw89_vif_link_ids_get(struct seq_file *m, u8 *mac,
struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif_link->bssid_cam;
seq_printf(m, " [%u] %pM\n", rtwvif_link->mac_id, rtwvif_link->mac_addr);
seq_printf(m, "\tlink_id=%u\n", rtwvif_link->link_id);
seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx);
rtw89_dump_addr_cam(m, rtwdev, &rtwvif_link->addr_cam);
rtw89_dump_pkt_offload(m, &rtwvif_link->general_pkt_list,
"\tpkt_ofld[GENERAL]: ");
}
static
void rtw89_vif_ids_get_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
{
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_dev *rtwdev = rtwvif->rtwdev;
struct seq_file *m = (struct seq_file *)data;
struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_dev *rtwdev = rtwvif->rtwdev;
struct rtw89_vif_link *rtwvif_link;
unsigned int link_id;
seq_printf(m, "VIF [%d] %pM\n", rtwvif->mac_id, rtwvif->mac_addr);
seq_printf(m, "\tbssid_cam_idx=%u\n", bssid_cam->bssid_cam_idx);
rtw89_dump_addr_cam(m, rtwdev, &rtwvif->addr_cam);
rtw89_dump_pkt_offload(m, &rtwvif->general_pkt_list, "\tpkt_ofld[GENERAL]: ");
seq_printf(m, "VIF %pM\n", rtwvif->mac_addr);
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
rtw89_vif_link_ids_get(m, mac, rtwdev, rtwvif_link);
}
static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta *rtwsta)
static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_dev *rtwdev,
struct rtw89_sta_link *rtwsta_link)
{
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_dev *rtwdev = rtwvif->rtwdev;
struct rtw89_ba_cam_entry *entry;
bool first = true;
list_for_each_entry(entry, &rtwsta->ba_cam_list, list) {
list_for_each_entry(entry, &rtwsta_link->ba_cam_list, list) {
if (first) {
seq_puts(m, "\tba_cam ");
first = false;
@@ -3771,16 +3807,36 @@ static void rtw89_dump_ba_cam(struct seq_file *m, struct rtw89_sta *rtwsta)
seq_puts(m, "\n");
}
static void rtw89_sta_link_ids_get(struct seq_file *m,
struct rtw89_dev *rtwdev,
struct rtw89_sta_link *rtwsta_link)
{
struct ieee80211_link_sta *link_sta;
rcu_read_lock();
link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
seq_printf(m, " [%u] %pM\n", rtwsta_link->mac_id, link_sta->addr);
rcu_read_unlock();
seq_printf(m, "\tlink_id=%u\n", rtwsta_link->link_id);
rtw89_dump_addr_cam(m, rtwdev, &rtwsta_link->addr_cam);
rtw89_dump_ba_cam(m, rtwdev, rtwsta_link);
}
static void rtw89_sta_ids_get_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_dev *rtwdev = rtwsta->rtwdev;
struct seq_file *m = (struct seq_file *)data;
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_dev *rtwdev = rtwsta->rtwdev;
struct rtw89_sta_link *rtwsta_link;
unsigned int link_id;
seq_printf(m, "STA [%d] %pM %s\n", rtwsta->mac_id, sta->addr,
sta->tdls ? "(TDLS)" : "");
rtw89_dump_addr_cam(m, rtwdev, &rtwsta->addr_cam);
rtw89_dump_ba_cam(m, rtwsta);
seq_printf(m, "STA %pM %s\n", sta->addr, sta->tdls ? "(TDLS)" : "");
rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id)
rtw89_sta_link_ids_get(m, rtwdev, rtwsta_link);
}
static int rtw89_debug_priv_stations_get(struct seq_file *m, void *v)

File diff suppressed because it is too large Load Diff

View File

@@ -4286,7 +4286,7 @@ struct rtw89_h2c_rf_dack {
__le32 type;
} __packed;
struct rtw89_h2c_rf_rxdck {
struct rtw89_h2c_rf_rxdck_v0 {
u8 len;
u8 phy;
u8 is_afe;
@@ -4297,6 +4297,11 @@ struct rtw89_h2c_rf_rxdck {
u8 rxdck_dbg_en;
} __packed;
struct rtw89_h2c_rf_rxdck {
struct rtw89_h2c_rf_rxdck_v0 v0;
u8 is_chl_k;
} __packed;
enum rtw89_rf_log_type {
RTW89_RF_RUN_LOG = 0,
RTW89_RF_RPT_LOG = 1,
@@ -4313,6 +4318,42 @@ struct rtw89_c2h_rf_run_log {
__le32 arg[4];
} __packed;
struct rtw89_c2h_rf_iqk_rpt_log {
bool iqk_tx_fail[2];
bool iqk_rx_fail[2];
bool is_iqk_init;
bool is_reload;
bool is_wb_txiqk[2];
bool is_wb_rxiqk[2];
bool is_nbiqk;
bool txiqk_en;
bool rxiqk_en;
bool lok_en;
bool iqk_xym_en;
bool iqk_sram_en;
bool iqk_fft_en;
bool is_fw_iqk;
bool is_iqk_enable;
bool iqk_cfir_en;
bool thermal_rek_en;
u8 iqk_band[2];
u8 iqk_ch[2];
u8 iqk_bw[2];
u8 iqk_times;
u8 version;
u8 phy;
u8 fwk_status;
u8 rsvd;
__le32 reload_cnt;
__le32 iqk_fail_cnt;
__le32 lok_idac[2];
__le32 lok_vbuf[2];
__le32 rftxgain[2][4];
__le32 rfrxgain[2][4];
__le32 tx_xym[2][4];
__le32 rx_xym[2][4];
} __packed;
struct rtw89_c2h_rf_dpk_rpt_log {
u8 ver;
u8 idx[2];
@@ -4334,19 +4375,25 @@ struct rtw89_c2h_rf_dpk_rpt_log {
struct rtw89_c2h_rf_dack_rpt_log {
u8 fwdack_ver;
u8 fwdack_rpt_ver;
u8 fwdack_info_ver;
u8 msbk_d[2][2][16];
u8 dadck_d[2][2];
u8 cdack_d[2][2][2];
__le16 addck2_d[2][2][2];
u8 addck2_hd[2][2][2];
u8 addck2_ld[2][2][2];
u8 adgaink_d[2][2];
__le16 biask_d[2][2];
u8 biask_hd[2][2];
u8 biask_ld[2][2];
u8 addck_timeout;
u8 cdack_timeout;
u8 dadck_timeout;
u8 msbk_timeout;
u8 adgaink_timeout;
u8 wbadcdck_timeout;
u8 drck_timeout;
u8 dack_fail;
u8 wbdck_d[2];
u8 rck_d;
} __packed;
struct rtw89_c2h_rf_rxdck_rpt_log {
@@ -4357,6 +4404,14 @@ struct rtw89_c2h_rf_rxdck_rpt_log {
u8 timeout[2];
} __packed;
struct rtw89_c2h_rf_tssi_rpt_log {
s8 alignment_power[2][2][4];
u8 alignment_power_cw_h[2][2][4];
u8 alignment_power_cw_l[2][2][4];
u8 tssi_alimk_state[2][2];
u8 default_txagc_offset[2][2];
} __packed;
struct rtw89_c2h_rf_txgapk_rpt_log {
__le32 r0x8010[2];
__le32 chk_cnt;
@@ -4404,59 +4459,59 @@ void rtw89_h2c_pkt_set_hdr(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u8 type, u8 cat, u8 class, u8 func,
bool rack, bool dack, u32 len);
int rtw89_fw_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta);
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_default_cmac_tbl_g7(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta);
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_default_dmac_tbl_v2(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta);
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_assoc_cmac_tbl_g7(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_ampdu_cmac_tbl_g7(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_txtime_cmac_tbl(struct rtw89_dev *rtwdev,
struct rtw89_sta *rtwsta);
struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_txpath_cmac_tbl(struct rtw89_dev *rtwdev,
struct rtw89_sta *rtwsta);
struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_update_beacon(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif);
struct rtw89_vif_link *rtwvif_link);
int rtw89_fw_h2c_update_beacon_be(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif);
int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *vif,
struct rtw89_sta *rtwsta, const u8 *scan_mac_addr);
struct rtw89_vif_link *rtwvif_link);
int rtw89_fw_h2c_cam(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif,
struct rtw89_sta_link *rtwsta_link, const u8 *scan_mac_addr);
int rtw89_fw_h2c_dctl_sec_cam_v1(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta);
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int rtw89_fw_h2c_dctl_sec_cam_v2(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta);
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);
int rtw89_fw_h2c_role_maintain(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
enum rtw89_upd_mode upd_mode);
int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta, bool dis_conn);
int rtw89_fw_h2c_join_info(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link, bool dis_conn);
int rtw89_fw_h2c_notify_dbcc(struct rtw89_dev *rtwdev, bool en);
int rtw89_fw_h2c_macid_pause(struct rtw89_dev *rtwdev, u8 sh, u8 grp,
bool pause);
int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
int rtw89_fw_h2c_set_edca(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u8 ac, u32 val);
int rtw89_fw_h2c_set_ofld_cfg(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_set_bcn_fltr_cfg(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct rtw89_vif_link *rtwvif_link,
bool connect);
int rtw89_fw_h2c_rssi_offload(struct rtw89_dev *rtwdev,
struct rtw89_rx_phy_ppdu *phy_ppdu);
int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
int rtw89_fw_h2c_tp_offload(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
int rtw89_fw_h2c_ra(struct rtw89_dev *rtwdev, struct rtw89_ra_info *ra, bool csi);
int rtw89_fw_h2c_cxdrv_init(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_init_v7(struct rtw89_dev *rtwdev, u8 type);
@@ -4472,17 +4527,13 @@ int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_del_pkt_offload(struct rtw89_dev *rtwdev, u8 id);
int rtw89_fw_h2c_add_pkt_offload(struct rtw89_dev *rtwdev, u8 *id,
struct sk_buff *skb_ofld);
int rtw89_fw_h2c_scan_list_offload(struct rtw89_dev *rtwdev, int ch_num,
struct list_head *chan_list);
int rtw89_fw_h2c_scan_list_offload_be(struct rtw89_dev *rtwdev, int ch_num,
struct list_head *chan_list);
int rtw89_fw_h2c_scan_offload_ax(struct rtw89_dev *rtwdev,
struct rtw89_scan_option *opt,
struct rtw89_vif *vif,
struct rtw89_vif_link *vif,
bool wowlan);
int rtw89_fw_h2c_scan_offload_be(struct rtw89_dev *rtwdev,
struct rtw89_scan_option *opt,
struct rtw89_vif *vif,
struct rtw89_vif_link *vif,
bool wowlan);
int rtw89_fw_h2c_rf_reg(struct rtw89_dev *rtwdev,
struct rtw89_fw_h2c_rf_reg_info *info,
@@ -4501,21 +4552,26 @@ int rtw89_fw_h2c_rf_txgapk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
int rtw89_fw_h2c_rf_dack(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
const struct rtw89_chan *chan);
int rtw89_fw_h2c_rf_rxdck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
const struct rtw89_chan *chan);
const struct rtw89_chan *chan, bool is_chl_k);
int rtw89_fw_h2c_raw_with_hdr(struct rtw89_dev *rtwdev,
u8 h2c_class, u8 h2c_func, u8 *buf, u16 len,
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);
int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
int rtw89_fw_h2c_general_pkt(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u8 macid);
void rtw89_fw_release_general_pkt_list_vif(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool notify_fw);
struct rtw89_vif_link *rtwvif_link,
bool notify_fw);
void rtw89_fw_release_general_pkt_list(struct rtw89_dev *rtwdev, bool notify_fw);
int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
int rtw89_fw_h2c_ba_cam(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
bool valid, struct ieee80211_ampdu_params *params);
int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
int rtw89_fw_h2c_ba_cam_v1(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link,
bool valid, struct ieee80211_ampdu_params *params);
void rtw89_fw_h2c_init_dynamic_ba_cam_v0_ext(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users,
@@ -4524,8 +4580,8 @@ int rtw89_fw_h2c_init_ba_cam_users(struct rtw89_dev *rtwdev, u8 users,
int rtw89_fw_h2c_lps_parm(struct rtw89_dev *rtwdev,
struct rtw89_lps_parm *lps_param);
int rtw89_fw_h2c_lps_ch_info(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif);
int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link);
int rtw89_fw_h2c_fwips(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable);
struct sk_buff *rtw89_fw_h2c_alloc_skb_with_hdr(struct rtw89_dev *rtwdev, u32 len);
struct sk_buff *rtw89_fw_h2c_alloc_skb_no_hdr(struct rtw89_dev *rtwdev, u32 len);
@@ -4534,49 +4590,56 @@ int rtw89_fw_msg_reg(struct rtw89_dev *rtwdev,
struct rtw89_mac_c2h_info *c2h_info);
int rtw89_fw_h2c_fw_log(struct rtw89_dev *rtwdev, bool enable);
void rtw89_fw_st_dbg_dump(struct rtw89_dev *rtwdev);
void rtw89_hw_scan_start(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_scan_request *req);
void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
void rtw89_hw_scan_start(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_scan_request *scan_req);
void rtw89_hw_scan_complete(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool aborted);
int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool enable);
void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
void rtw89_hw_scan_abort(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link);
int rtw89_hw_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool connected);
struct rtw89_vif_link *rtwvif_link, bool connected);
int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif);
struct rtw89_vif_link *rtwvif_link);
int rtw89_hw_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool connected);
struct rtw89_vif_link *rtwvif_link, bool connected);
int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif);
struct rtw89_vif_link *rtwvif_link);
int rtw89_fw_h2c_trigger_cpu_exception(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_pkt_drop(struct rtw89_dev *rtwdev,
const struct rtw89_pkt_drop_params *params);
int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
int rtw89_fw_h2c_p2p_act(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf,
struct ieee80211_p2p_noa_desc *desc,
u8 act, u8 noa_id);
int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
int rtw89_fw_h2c_tsf32_toggle(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool en);
int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable);
int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool enable);
int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link, bool enable);
int rtw89_fw_h2c_cfg_pno(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable);
int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
int rtw89_fw_h2c_keep_alive(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable);
int rtw89_fw_h2c_arp_offload(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool enable);
struct rtw89_vif_link *rtwvif_link, bool enable);
int rtw89_fw_h2c_disconnect_detect(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool enable);
int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link, bool enable);
int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool enable);
int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool enable);
struct rtw89_vif_link *rtwvif_link, bool enable);
int rtw89_fw_wow_cam_update(struct rtw89_dev *rtwdev,
struct rtw89_wow_cam_info *cam_info);
int rtw89_fw_h2c_wow_gtk_ofld(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link,
bool enable);
int rtw89_fw_h2c_wow_request_aoac(struct rtw89_dev *rtwdev);
int rtw89_fw_h2c_add_mcc(struct rtw89_dev *rtwdev,
@@ -4621,51 +4684,73 @@ static inline void rtw89_fw_h2c_init_ba_cam(struct rtw89_dev *rtwdev)
}
static inline int rtw89_chip_h2c_default_cmac_tbl(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta)
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
return chip->ops->h2c_default_cmac_tbl(rtwdev, rtwvif, rtwsta);
return chip->ops->h2c_default_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
}
static inline int rtw89_chip_h2c_default_dmac_tbl(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta)
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (chip->ops->h2c_default_dmac_tbl)
return chip->ops->h2c_default_dmac_tbl(rtwdev, rtwvif, rtwsta);
return chip->ops->h2c_default_dmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
return 0;
}
static inline int rtw89_chip_h2c_update_beacon(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif)
struct rtw89_vif_link *rtwvif_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
return chip->ops->h2c_update_beacon(rtwdev, rtwvif);
return chip->ops->h2c_update_beacon(rtwdev, rtwvif_link);
}
static inline int rtw89_chip_h2c_assoc_cmac_tbl(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
return chip->ops->h2c_assoc_cmac_tbl(rtwdev, vif, sta);
return chip->ops->h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
}
static inline int rtw89_chip_h2c_ampdu_cmac_tbl(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
static inline
int rtw89_chip_h2c_ampdu_link_cmac_tbl(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
if (chip->ops->h2c_ampdu_cmac_tbl)
return chip->ops->h2c_ampdu_cmac_tbl(rtwdev, vif, sta);
return chip->ops->h2c_ampdu_cmac_tbl(rtwdev, rtwvif_link,
rtwsta_link);
return 0;
}
static inline int rtw89_chip_h2c_ampdu_cmac_tbl(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_sta *rtwsta)
{
struct rtw89_vif_link *rtwvif_link;
struct rtw89_sta_link *rtwsta_link;
unsigned int link_id;
int ret;
rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
rtwvif_link = rtwsta_link->rtwvif_link;
ret = rtw89_chip_h2c_ampdu_link_cmac_tbl(rtwdev, rtwvif_link,
rtwsta_link);
if (ret)
return ret;
}
return 0;
}
@@ -4675,8 +4760,20 @@ int rtw89_chip_h2c_ba_cam(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
bool valid, struct ieee80211_ampdu_params *params)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_sta_link *rtwsta_link;
unsigned int link_id;
int ret;
return chip->ops->h2c_ba_cam(rtwdev, rtwsta, valid, params);
rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
rtwvif_link = rtwsta_link->rtwvif_link;
ret = chip->ops->h2c_ba_cam(rtwdev, rtwvif_link, rtwsta_link,
valid, params);
if (ret)
return ret;
}
return 0;
}
/* must consider compatibility; don't insert new in the mid */

File diff suppressed because it is too large Load Diff

View File

@@ -951,8 +951,9 @@ struct rtw89_mac_gen_def {
void (*dmac_func_pre_en)(struct rtw89_dev *rtwdev);
void (*dle_func_en)(struct rtw89_dev *rtwdev, bool enable);
void (*dle_clk_en)(struct rtw89_dev *rtwdev, bool enable);
void (*bf_assoc)(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
void (*bf_assoc)(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
int (*typ_fltr_opt)(struct rtw89_dev *rtwdev,
enum rtw89_machdr_frame_type type,
@@ -1004,12 +1005,12 @@ struct rtw89_mac_gen_def {
bool (*is_txq_empty)(struct rtw89_dev *rtwdev);
int (*add_chan_list)(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool connected);
struct rtw89_vif_link *rtwvif_link, bool connected);
int (*add_chan_list_pno)(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif);
struct rtw89_vif_link *rtwvif_link);
int (*scan_offload)(struct rtw89_dev *rtwdev,
struct rtw89_scan_option *option,
struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link,
bool wowlan);
int (*wow_config_mac)(struct rtw89_dev *rtwdev, bool enable_wow);
@@ -1033,81 +1034,89 @@ u32 rtw89_mac_reg_by_port(struct rtw89_dev *rtwdev, u32 base, u8 port, u8 mac_id
}
static inline u32
rtw89_read32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base)
rtw89_read32_port(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base)
{
u32 reg;
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
rtwvif_link->mac_idx);
return rtw89_read32(rtwdev, reg);
}
static inline u32
rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
rtw89_read32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 mask)
{
u32 reg;
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
rtwvif_link->mac_idx);
return rtw89_read32_mask(rtwdev, reg, mask);
}
static inline void
rtw89_write32_port(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif, u32 base,
rtw89_write32_port(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link, u32 base,
u32 data)
{
u32 reg;
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
rtwvif_link->mac_idx);
rtw89_write32(rtwdev, reg, data);
}
static inline void
rtw89_write32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
rtw89_write32_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 mask, u32 data)
{
u32 reg;
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
rtwvif_link->mac_idx);
rtw89_write32_mask(rtwdev, reg, mask, data);
}
static inline void
rtw89_write16_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
rtw89_write16_port_mask(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 mask, u16 data)
{
u32 reg;
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
rtwvif_link->mac_idx);
rtw89_write16_mask(rtwdev, reg, mask, data);
}
static inline void
rtw89_write32_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
rtw89_write32_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 bit)
{
u32 reg;
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
rtwvif_link->mac_idx);
rtw89_write32_clr(rtwdev, reg, bit);
}
static inline void
rtw89_write16_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
rtw89_write16_port_clr(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u16 bit)
{
u32 reg;
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
rtwvif_link->mac_idx);
rtw89_write16_clr(rtwdev, reg, bit);
}
static inline void
rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u32 base, u32 bit)
{
u32 reg;
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif->port, rtwvif->mac_idx);
reg = rtw89_mac_reg_by_port(rtwdev, base, rtwvif_link->port,
rtwvif_link->mac_idx);
rtw89_write32_set(rtwdev, reg, bit);
}
@@ -1139,21 +1148,21 @@ int rtw89_mac_dle_dfi_qempty_cfg(struct rtw89_dev *rtwdev,
struct rtw89_mac_dle_dfi_qempty *qempty);
void rtw89_mac_dump_l0_to_l1(struct rtw89_dev *rtwdev,
enum mac_ax_err_info err);
int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
int rtw89_mac_add_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
int rtw89_mac_port_update(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
void rtw89_mac_port_tsf_sync(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_vif *rtwvif_src,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_vif_link *rtwvif_src,
u16 offset_tu);
int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
int rtw89_mac_port_get_tsf(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
u64 *tsf);
void rtw89_mac_port_cfg_rx_sync(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool en);
struct rtw89_vif_link *rtwvif_link, bool en);
void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif);
void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
struct rtw89_vif_link *rtwvif_link);
void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en);
int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif);
int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif_link *vif);
int rtw89_mac_enable_bb_rf(struct rtw89_dev *rtwdev);
int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev);
@@ -1213,7 +1222,22 @@ int rtw89_mac_cfg_ppdu_status(struct rtw89_dev *rtwdev, u8 mac_idx, bool enable)
return mac->cfg_ppdu_status(rtwdev, mac_idx, enable);
}
void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev, u8 mac_idx);
static inline
int rtw89_mac_cfg_ppdu_status_bands(struct rtw89_dev *rtwdev, bool enable)
{
int ret;
ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, enable);
if (ret)
return ret;
if (!rtwdev->dbcc_en)
return 0;
return rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_1, enable);
}
void rtw89_mac_update_rts_threshold(struct rtw89_dev *rtwdev);
void rtw89_mac_flush_txq(struct rtw89_dev *rtwdev, u32 queues, bool drop);
int rtw89_mac_coex_init(struct rtw89_dev *rtwdev, const struct rtw89_mac_ax_coex *coex);
int rtw89_mac_coex_init_v1(struct rtw89_dev *rtwdev,
@@ -1251,27 +1275,30 @@ void rtw89_mac_power_mode_change(struct rtw89_dev *rtwdev, bool enter);
void rtw89_mac_notify_wake(struct rtw89_dev *rtwdev);
static inline
void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
void rtw89_mac_bf_assoc(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
if (mac->bf_assoc)
mac->bf_assoc(rtwdev, vif, sta);
mac->bf_assoc(rtwdev, rtwvif_link, rtwsta_link);
}
void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
void rtw89_mac_bf_disassoc(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link);
void rtw89_mac_bf_set_gid_table(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *conf);
void rtw89_mac_bf_monitor_calc(struct rtw89_dev *rtwdev,
struct ieee80211_sta *sta, bool disconnect);
struct rtw89_sta_link *rtwsta_link,
bool disconnect);
void _rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev);
void rtw89_mac_bfee_ctrl(struct rtw89_dev *rtwdev, u8 mac_idx, bool en);
int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
int rtw89_mac_vif_init(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
int rtw89_mac_vif_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
int rtw89_mac_set_hw_muedca_ctrl(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool en);
struct rtw89_vif_link *rtwvif_link, bool en);
int rtw89_mac_set_macid_pause(struct rtw89_dev *rtwdev, u8 macid, bool pause);
static inline void rtw89_mac_bf_monitor_track(struct rtw89_dev *rtwdev)
@@ -1376,15 +1403,15 @@ static inline bool rtw89_mac_get_power_state(struct rtw89_dev *rtwdev)
return !!val;
}
int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
int rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
bool resume, u32 tx_time);
int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta *rtwsta,
int rtw89_mac_get_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link,
u32 *tx_time);
int rtw89_mac_set_tx_retry_limit(struct rtw89_dev *rtwdev,
struct rtw89_sta *rtwsta,
struct rtw89_sta_link *rtwsta_link,
bool resume, u8 tx_retry);
int rtw89_mac_get_tx_retry_limit(struct rtw89_dev *rtwdev,
struct rtw89_sta *rtwsta, u8 *tx_retry);
struct rtw89_sta_link *rtwsta_link, u8 *tx_retry);
enum rtw89_mac_xtal_si_offset {
XTAL0 = 0x0,

View File

@@ -23,13 +23,13 @@ static void rtw89_ops_tx(struct ieee80211_hw *hw,
struct rtw89_dev *rtwdev = hw->priv;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_vif *vif = info->control.vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct ieee80211_sta *sta = control->sta;
u32 flags = IEEE80211_SKB_CB(skb)->flags;
int ret, qsel;
if (rtwvif->offchan && !(flags & IEEE80211_TX_CTL_TX_OFFCHAN) && sta) {
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
rtw89_debug(rtwdev, RTW89_DBG_TXRX, "ops_tx during offchan\n");
skb_queue_tail(&rtwsta->roc_queue, skb);
@@ -105,11 +105,61 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
return 0;
}
static int __rtw89_ops_add_iface_link(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
struct ieee80211_bss_conf *bss_conf;
int ret;
rtw89_leave_ps_mode(rtwdev);
rtw89_vif_type_mapping(rtwvif_link, false);
INIT_WORK(&rtwvif_link->update_beacon_work, rtw89_core_update_beacon_work);
INIT_LIST_HEAD(&rtwvif_link->general_pkt_list);
rtwvif_link->hit_rule = 0;
rtwvif_link->bcn_hit_cond = 0;
rtwvif_link->chanctx_assigned = false;
rtwvif_link->chanctx_idx = RTW89_CHANCTX_0;
rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
rcu_read_lock();
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
ether_addr_copy(rtwvif_link->mac_addr, bss_conf->addr);
rcu_read_unlock();
ret = rtw89_mac_add_vif(rtwdev, rtwvif_link);
if (ret)
return ret;
rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, NULL, BTC_ROLE_START);
return 0;
}
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);
rtw89_leave_ps_mode(rtwdev);
rtw89_btc_ntfy_role_info(rtwdev, rtwvif_link, NULL, BTC_ROLE_STOP);
rtw89_mac_remove_vif(rtwdev, rtwvif_link);
}
static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
u8 mac_id, port;
int ret = 0;
rtw89_debug(rtwdev, RTW89_DBG_STATE, "add vif %pM type %d, p2p %d\n",
@@ -123,49 +173,56 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
IEEE80211_VIF_SUPPORTS_CQM_RSSI;
rtwvif->rtwdev = rtwdev;
rtwvif->roc.state = RTW89_ROC_IDLE;
rtwvif->offchan = false;
if (!rtw89_rtwvif_in_list(rtwdev, rtwvif))
list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
INIT_WORK(&rtwvif->update_beacon_work, rtw89_core_update_beacon_work);
INIT_DELAYED_WORK(&rtwvif->roc.roc_work, rtw89_roc_work);
rtw89_leave_ps_mode(rtwdev);
rtw89_traffic_stats_init(rtwdev, &rtwvif->stats);
rtw89_vif_type_mapping(vif, false);
rtwvif->port = rtw89_core_acquire_bit_map(rtwdev->hw_port,
RTW89_PORT_NUM);
if (rtwvif->port == RTW89_PORT_NUM) {
mac_id = rtw89_acquire_mac_id(rtwdev);
if (mac_id == RTW89_MAX_MAC_ID_NUM) {
ret = -ENOSPC;
list_del_init(&rtwvif->list);
goto out;
goto err;
}
rtwvif->bcn_hit_cond = 0;
rtwvif->mac_idx = RTW89_MAC_0;
rtwvif->phy_idx = RTW89_PHY_0;
rtwvif->chanctx_idx = RTW89_CHANCTX_0;
rtwvif->chanctx_assigned = false;
rtwvif->hit_rule = 0;
rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
ether_addr_copy(rtwvif->mac_addr, vif->addr);
INIT_LIST_HEAD(&rtwvif->general_pkt_list);
ret = rtw89_mac_add_vif(rtwdev, rtwvif);
if (ret) {
rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
list_del_init(&rtwvif->list);
goto out;
port = rtw89_core_acquire_bit_map(rtwdev->hw_port, RTW89_PORT_NUM);
if (port == RTW89_PORT_NUM) {
ret = -ENOSPC;
goto release_macid;
}
rtw89_init_vif(rtwdev, rtwvif, mac_id, port);
rtw89_core_txq_init(rtwdev, vif->txq);
rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_START);
if (!rtw89_rtwvif_in_list(rtwdev, rtwvif))
list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list);
ether_addr_copy(rtwvif->mac_addr, vif->addr);
rtwvif->offchan = false;
rtwvif->roc.state = RTW89_ROC_IDLE;
INIT_DELAYED_WORK(&rtwvif->roc.roc_work, rtw89_roc_work);
rtw89_traffic_stats_init(rtwdev, &rtwvif->stats);
rtwvif_link = rtw89_vif_set_link(rtwvif, 0);
if (!rtwvif_link) {
ret = -EINVAL;
goto release_port;
}
ret = __rtw89_ops_add_iface_link(rtwdev, rtwvif_link);
if (ret)
goto unset_link;
rtw89_recalc_lps(rtwdev);
out:
mutex_unlock(&rtwdev->mutex);
return 0;
unset_link:
rtw89_vif_unset_link(rtwvif, 0);
release_port:
list_del_init(&rtwvif->list);
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;
@@ -175,20 +232,35 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
u8 macid = rtw89_vif_get_main_macid(rtwvif);
u8 port = rtw89_vif_get_main_port(rtwvif);
struct rtw89_vif_link *rtwvif_link;
rtw89_debug(rtwdev, RTW89_DBG_STATE, "remove vif %pM type %d p2p %d\n",
vif->addr, vif->type, vif->p2p);
cancel_work_sync(&rtwvif->update_beacon_work);
cancel_delayed_work_sync(&rtwvif->roc.roc_work);
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_STOP);
rtw89_mac_remove_vif(rtwdev, rtwvif);
rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
rtwvif_link = rtwvif->links[0];
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev,
"%s: rtwvif link (link_id %u) is not active\n",
__func__, 0);
goto bottom;
}
__rtw89_ops_remove_iface_link(rtwdev, rtwvif_link);
rtw89_vif_unset_link(rtwvif, 0);
bottom:
list_del_init(&rtwvif->list);
rtw89_core_release_bit_map(rtwdev->hw_port, port);
rtw89_release_mac_id(rtwdev, macid);
rtw89_recalc_lps(rtwdev);
rtw89_enter_ips_by_hwflags(rtwdev);
@@ -311,24 +383,30 @@ static const u8 ac_to_fw_idx[IEEE80211_NUM_ACS] = {
};
static u8 rtw89_aifsn_to_aifs(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, u8 aifsn)
struct rtw89_vif_link *rtwvif_link, u8 aifsn)
{
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev,
rtwvif->chanctx_idx);
rtwvif_link->chanctx_idx);
struct ieee80211_bss_conf *bss_conf;
u8 slot_time;
u8 sifs;
slot_time = vif->bss_conf.use_short_slot ? 9 : 20;
rcu_read_lock();
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
slot_time = bss_conf->use_short_slot ? 9 : 20;
rcu_read_unlock();
sifs = chan->band_type == RTW89_BAND_2G ? 10 : 16;
return aifsn * slot_time + sifs;
}
static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, u16 ac)
struct rtw89_vif_link *rtwvif_link, u16 ac)
{
struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
struct ieee80211_tx_queue_params *params = &rtwvif_link->tx_params[ac];
u32 val;
u8 ecw_max, ecw_min;
u8 aifs;
@@ -336,12 +414,12 @@ static void ____rtw89_conf_tx_edca(struct rtw89_dev *rtwdev,
/* 2^ecw - 1 = cw; ecw = log2(cw + 1) */
ecw_max = ilog2(params->cw_max + 1);
ecw_min = ilog2(params->cw_min + 1);
aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif, params->aifs);
aifs = rtw89_aifsn_to_aifs(rtwdev, rtwvif_link, params->aifs);
val = FIELD_PREP(FW_EDCA_PARAM_TXOPLMT_MSK, params->txop) |
FIELD_PREP(FW_EDCA_PARAM_CWMAX_MSK, ecw_max) |
FIELD_PREP(FW_EDCA_PARAM_CWMIN_MSK, ecw_min) |
FIELD_PREP(FW_EDCA_PARAM_AIFS_MSK, aifs);
rtw89_fw_h2c_set_edca(rtwdev, rtwvif, ac_to_fw_idx[ac], val);
rtw89_fw_h2c_set_edca(rtwdev, rtwvif_link, ac_to_fw_idx[ac], val);
}
#define R_MUEDCA_ACS_PARAM(acs) {R_AX_MUEDCA_ ## acs ## _PARAM_0, \
@@ -355,9 +433,9 @@ static const u32 ac_to_mu_edca_param[IEEE80211_NUM_ACS][RTW89_CHIP_GEN_NUM] = {
};
static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, u16 ac)
struct rtw89_vif_link *rtwvif_link, u16 ac)
{
struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
struct ieee80211_tx_queue_params *params = &rtwvif_link->tx_params[ac];
struct ieee80211_he_mu_edca_param_ac_rec *mu_edca;
int gen = rtwdev->chip->chip_gen;
u8 aifs, aifsn;
@@ -370,32 +448,199 @@ static void ____rtw89_conf_tx_mu_edca(struct rtw89_dev *rtwdev,
mu_edca = &params->mu_edca_param_rec;
aifsn = FIELD_GET(GENMASK(3, 0), mu_edca->aifsn);
aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif, aifsn) : 0;
aifs = aifsn ? rtw89_aifsn_to_aifs(rtwdev, rtwvif_link, aifsn) : 0;
timer_32us = mu_edca->mu_edca_timer << 8;
val = FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_TIMER_MASK, timer_32us) |
FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_CW_MASK, mu_edca->ecw_min_max) |
FIELD_PREP(B_AX_MUEDCA_BE_PARAM_0_AIFS_MASK, aifs);
reg = rtw89_mac_reg_by_idx(rtwdev, ac_to_mu_edca_param[ac][gen], rtwvif->mac_idx);
reg = rtw89_mac_reg_by_idx(rtwdev, ac_to_mu_edca_param[ac][gen],
rtwvif_link->mac_idx);
rtw89_write32(rtwdev, reg, val);
rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif, true);
rtw89_mac_set_hw_muedca_ctrl(rtwdev, rtwvif_link, true);
}
static void __rtw89_conf_tx(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, u16 ac)
struct rtw89_vif_link *rtwvif_link, u16 ac)
{
____rtw89_conf_tx_edca(rtwdev, rtwvif, ac);
____rtw89_conf_tx_mu_edca(rtwdev, rtwvif, ac);
____rtw89_conf_tx_edca(rtwdev, rtwvif_link, ac);
____rtw89_conf_tx_mu_edca(rtwdev, rtwvif_link, ac);
}
static void rtw89_conf_tx(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif)
struct rtw89_vif_link *rtwvif_link)
{
u16 ac;
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
__rtw89_conf_tx(rtwdev, rtwvif, ac);
__rtw89_conf_tx(rtwdev, rtwvif_link, ac);
}
static int __rtw89_ops_sta_add(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_vif_link *rtwvif_link;
struct rtw89_sta_link *rtwsta_link;
bool acquire_macid = false;
u8 macid;
int ret;
int i;
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
/* for station mode, assign the mac_id from itself */
macid = rtw89_vif_get_main_macid(rtwvif);
} else {
macid = rtw89_acquire_mac_id(rtwdev);
if (macid == RTW89_MAX_MAC_ID_NUM)
return -ENOSPC;
acquire_macid = true;
}
rtw89_init_sta(rtwdev, rtwvif, rtwsta, macid);
for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
rtw89_core_txq_init(rtwdev, sta->txq[i]);
skb_queue_head_init(&rtwsta->roc_queue);
rtwsta_link = rtw89_sta_set_link(rtwsta, sta->deflink.link_id);
if (!rtwsta_link) {
ret = -EINVAL;
goto err;
}
rtwvif_link = rtwsta_link->rtwvif_link;
ret = rtw89_core_sta_link_add(rtwdev, rtwvif_link, rtwsta_link);
if (ret)
goto unset_link;
if (vif->type == NL80211_IFTYPE_AP || sta->tdls)
rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE);
return 0;
unset_link:
rtw89_sta_unset_link(rtwsta, sta->deflink.link_id);
err:
if (acquire_macid)
rtw89_release_mac_id(rtwdev, macid);
return ret;
}
static int __rtw89_ops_sta_assoc(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
bool station_mode)
{
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_vif_link *rtwvif_link;
struct rtw89_sta_link *rtwsta_link;
unsigned int link_id;
int ret;
rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
rtwvif_link = rtwsta_link->rtwvif_link;
if (station_mode)
rtw89_vif_type_mapping(rtwvif_link, true);
ret = rtw89_core_sta_link_assoc(rtwdev, rtwvif_link, rtwsta_link);
if (ret)
return ret;
}
rtwdev->total_sta_assoc++;
if (sta->tdls)
rtwvif->tdls_peer++;
return 0;
}
static int __rtw89_ops_sta_disassoc(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_vif_link *rtwvif_link;
struct rtw89_sta_link *rtwsta_link;
unsigned int link_id;
int ret;
rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
rtwvif_link = rtwsta_link->rtwvif_link;
ret = rtw89_core_sta_link_disassoc(rtwdev, rtwvif_link, rtwsta_link);
if (ret)
return ret;
}
rtwsta->disassoc = true;
rtwdev->total_sta_assoc--;
if (sta->tdls)
rtwvif->tdls_peer--;
return 0;
}
static int __rtw89_ops_sta_disconnect(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_vif_link *rtwvif_link;
struct rtw89_sta_link *rtwsta_link;
unsigned int link_id;
int ret;
rtw89_core_free_sta_pending_ba(rtwdev, sta);
rtw89_core_free_sta_pending_forbid_ba(rtwdev, sta);
rtw89_core_free_sta_pending_roc_tx(rtwdev, sta);
rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
rtwvif_link = rtwsta_link->rtwvif_link;
ret = rtw89_core_sta_link_disconnect(rtwdev, rtwvif_link, rtwsta_link);
if (ret)
return ret;
}
return 0;
}
static int __rtw89_ops_sta_remove(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
u8 macid = rtw89_sta_get_main_macid(rtwsta);
struct rtw89_vif_link *rtwvif_link;
struct rtw89_sta_link *rtwsta_link;
unsigned int link_id;
int ret;
rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
rtwvif_link = rtwsta_link->rtwvif_link;
ret = rtw89_core_sta_link_remove(rtwdev, rtwvif_link, rtwsta_link);
if (ret)
return ret;
rtw89_sta_unset_link(rtwsta, link_id);
}
if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
rtw89_release_mac_id(rtwdev, macid);
rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_REMOTE_STA_CHANGE);
}
return 0;
}
static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev,
@@ -412,16 +657,34 @@ static void rtw89_station_mode_sta_assoc(struct rtw89_dev *rtwdev,
return;
}
rtw89_vif_type_mapping(vif, true);
__rtw89_ops_sta_assoc(rtwdev, vif, sta, true);
}
rtw89_core_sta_assoc(rtwdev, vif, sta);
static void __rtw89_ops_bss_link_assoc(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
rtw89_phy_set_bss_color(rtwdev, rtwvif_link);
rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, rtwvif_link);
rtw89_mac_port_update(rtwdev, rtwvif_link);
rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, rtwvif_link);
}
static void __rtw89_ops_bss_assoc(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif)
{
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
unsigned int link_id;
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
__rtw89_ops_bss_link_assoc(rtwdev, rtwvif_link);
}
static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, u64 changed)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
@@ -429,10 +692,7 @@ static void rtw89_ops_vif_cfg_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_ASSOC) {
if (vif->cfg.assoc) {
rtw89_station_mode_sta_assoc(rtwdev, vif);
rtw89_phy_set_bss_color(rtwdev, vif);
rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, vif);
rtw89_mac_port_update(rtwdev, rtwvif);
rtw89_mac_set_he_obss_narrow_bw_ru(rtwdev, vif);
__rtw89_ops_bss_assoc(rtwdev, vif);
rtw89_queue_chanctx_work(rtwdev);
} else {
@@ -459,39 +719,49 @@ static void rtw89_ops_link_info_changed(struct ieee80211_hw *hw,
u64 changed)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
rtwvif_link = rtwvif->links[conf->link_id];
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev,
"%s: rtwvif link (link_id %u) is not active\n",
__func__, conf->link_id);
goto out;
}
if (changed & BSS_CHANGED_BSSID) {
ether_addr_copy(rtwvif->bssid, conf->bssid);
rtw89_cam_bssid_changed(rtwdev, rtwvif);
rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
WRITE_ONCE(rtwvif->sync_bcn_tsf, 0);
ether_addr_copy(rtwvif_link->bssid, conf->bssid);
rtw89_cam_bssid_changed(rtwdev, rtwvif_link);
rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
WRITE_ONCE(rtwvif_link->sync_bcn_tsf, 0);
}
if (changed & BSS_CHANGED_BEACON)
rtw89_chip_h2c_update_beacon(rtwdev, rtwvif);
rtw89_chip_h2c_update_beacon(rtwdev, rtwvif_link);
if (changed & BSS_CHANGED_ERP_SLOT)
rtw89_conf_tx(rtwdev, rtwvif);
rtw89_conf_tx(rtwdev, rtwvif_link);
if (changed & BSS_CHANGED_HE_BSS_COLOR)
rtw89_phy_set_bss_color(rtwdev, vif);
rtw89_phy_set_bss_color(rtwdev, rtwvif_link);
if (changed & BSS_CHANGED_MU_GROUPS)
rtw89_mac_bf_set_gid_table(rtwdev, vif, conf);
if (changed & BSS_CHANGED_P2P_PS)
rtw89_core_update_p2p_ps(rtwdev, vif);
rtw89_core_update_p2p_ps(rtwdev, rtwvif_link, conf);
if (changed & BSS_CHANGED_CQM)
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true);
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
if (changed & BSS_CHANGED_TPE)
rtw89_reg_6ghz_recalc(rtwdev, rtwvif, true);
rtw89_reg_6ghz_recalc(rtwdev, rtwvif_link, true);
out:
mutex_unlock(&rtwdev->mutex);
}
@@ -500,12 +770,21 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *link_conf)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
const struct rtw89_chan *chan;
mutex_lock(&rtwdev->mutex);
chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx);
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;
}
chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
if (chan->band_type == RTW89_BAND_6G) {
mutex_unlock(&rtwdev->mutex);
return -EOPNOTSUPP;
@@ -514,16 +793,18 @@ static int rtw89_ops_start_ap(struct ieee80211_hw *hw,
if (rtwdev->scanning)
rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
ether_addr_copy(rtwvif->bssid, vif->bss_conf.bssid);
rtw89_cam_bssid_changed(rtwdev, rtwvif);
rtw89_mac_port_update(rtwdev, rtwvif);
rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, NULL, RTW89_ROLE_TYPE_CHANGE);
rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
rtw89_fw_h2c_cam(rtwdev, rtwvif, NULL, NULL);
rtw89_chip_rfk_channel(rtwdev, rtwvif);
ether_addr_copy(rtwvif_link->bssid, link_conf->bssid);
rtw89_cam_bssid_changed(rtwdev, rtwvif_link);
rtw89_mac_port_update(rtwdev, rtwvif_link);
rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, NULL);
rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, NULL, RTW89_ROLE_TYPE_CHANGE);
rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, NULL, true);
rtw89_fw_h2c_cam(rtwdev, rtwvif_link, NULL, NULL);
rtw89_chip_rfk_channel(rtwdev, rtwvif_link);
rtw89_queue_chanctx_work(rtwdev);
out:
mutex_unlock(&rtwdev->mutex);
return 0;
@@ -534,12 +815,24 @@ void rtw89_ops_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
rtw89_mac_stop_ap(rtwdev, rtwvif);
rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, vif, NULL);
rtw89_fw_h2c_join_info(rtwdev, rtwvif, NULL, true);
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;
}
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);
}
@@ -547,10 +840,13 @@ 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 = (struct rtw89_sta *)sta->drv_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;
ieee80211_queue_work(rtwdev->hw, &rtwvif->update_beacon_work);
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
ieee80211_queue_work(rtwdev->hw, &rtwvif_link->update_beacon_work);
return 0;
}
@@ -561,15 +857,29 @@ static int rtw89_ops_conf_tx(struct ieee80211_hw *hw,
const struct ieee80211_tx_queue_params *params)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
int ret = 0;
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
rtwvif->tx_params[ac] = *params;
__rtw89_conf_tx(rtwdev, rtwvif, ac);
rtwvif_link = rtwvif->links[link_id];
if (unlikely(!rtwvif_link)) {
rtw89_err(rtwdev,
"%s: rtwvif link (link_id %u) is not active\n",
__func__, link_id);
ret = -ENOLINK;
goto out;
}
rtwvif_link->tx_params[ac] = *params;
__rtw89_conf_tx(rtwdev, rtwvif_link, ac);
out:
mutex_unlock(&rtwdev->mutex);
return 0;
return ret;
}
static int __rtw89_ops_sta_state(struct ieee80211_hw *hw,
@@ -582,26 +892,26 @@ static int __rtw89_ops_sta_state(struct ieee80211_hw *hw,
if (old_state == IEEE80211_STA_NOTEXIST &&
new_state == IEEE80211_STA_NONE)
return rtw89_core_sta_add(rtwdev, vif, sta);
return __rtw89_ops_sta_add(rtwdev, vif, sta);
if (old_state == IEEE80211_STA_AUTH &&
new_state == IEEE80211_STA_ASSOC) {
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
return 0; /* defer to bss_info_changed to have vif info */
return rtw89_core_sta_assoc(rtwdev, vif, sta);
return __rtw89_ops_sta_assoc(rtwdev, vif, sta, false);
}
if (old_state == IEEE80211_STA_ASSOC &&
new_state == IEEE80211_STA_AUTH)
return rtw89_core_sta_disassoc(rtwdev, vif, sta);
return __rtw89_ops_sta_disassoc(rtwdev, vif, sta);
if (old_state == IEEE80211_STA_AUTH &&
new_state == IEEE80211_STA_NONE)
return rtw89_core_sta_disconnect(rtwdev, vif, sta);
return __rtw89_ops_sta_disconnect(rtwdev, vif, sta);
if (old_state == IEEE80211_STA_NONE &&
new_state == IEEE80211_STA_NOTEXIST)
return rtw89_core_sta_remove(rtwdev, vif, sta);
return __rtw89_ops_sta_remove(rtwdev, vif, sta);
return 0;
}
@@ -667,7 +977,8 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
{
struct rtw89_dev *rtwdev = hw->priv;
struct ieee80211_sta *sta = params->sta;
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
u16 tid = params->tid;
struct ieee80211_txq *txq = sta->txq[tid];
struct rtw89_txq *rtwtxq = (struct rtw89_txq *)txq->drv_priv;
@@ -681,7 +992,7 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
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, vif, sta);
rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta);
mutex_unlock(&rtwdev->mutex);
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
break;
@@ -692,7 +1003,7 @@ static int rtw89_ops_ampdu_action(struct ieee80211_hw *hw,
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, vif, sta);
rtw89_chip_h2c_ampdu_cmac_tbl(rtwdev, rtwvif, rtwsta);
mutex_unlock(&rtwdev->mutex);
break;
case IEEE80211_AMPDU_RX_START:
@@ -720,7 +1031,7 @@ static int rtw89_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
mutex_lock(&rtwdev->mutex);
rtw89_leave_ps_mode(rtwdev);
if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
rtw89_mac_update_rts_threshold(rtwdev, RTW89_MAC_0);
rtw89_mac_update_rts_threshold(rtwdev);
mutex_unlock(&rtwdev->mutex);
return 0;
@@ -731,9 +1042,14 @@ static void rtw89_ops_sta_statistics(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
struct station_info *sinfo)
{
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_sta_link *rtwsta_link;
sinfo->txrate = rtwsta->ra_report.txrate;
rtwsta_link = rtw89_sta_get_link_inst(rtwsta, 0);
if (unlikely(!rtwsta_link))
return;
sinfo->txrate = rtwsta_link->ra_report.txrate;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
}
@@ -743,7 +1059,7 @@ void __rtw89_drop_packets(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
struct rtw89_vif *rtwvif;
if (vif) {
rtwvif = (struct rtw89_vif *)vif->drv_priv;
rtwvif = vif_to_rtwvif(vif);
rtw89_mac_pkt_drop_vif(rtwdev, rtwvif);
} else {
rtw89_for_each_rtwvif(rtwdev, rtwvif)
@@ -777,14 +1093,20 @@ struct rtw89_iter_bitrate_mask_data {
static void rtw89_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_iter_bitrate_mask_data *br_data = data;
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct ieee80211_vif *vif = rtwvif_to_vif(rtwsta->rtwvif);
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
struct rtw89_sta_link *rtwsta_link;
unsigned int link_id;
if (vif != br_data->vif || vif->p2p)
return;
rtwsta->use_cfg_mask = true;
rtwsta->mask = *br_data->mask;
rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
rtwsta_link->use_cfg_mask = true;
rtwsta_link->mask = *br_data->mask;
}
rtw89_phy_ra_update_sta(br_data->rtwdev, sta, IEEE80211_RC_SUPP_RATES_CHANGED);
}
@@ -854,10 +1176,20 @@ static void rtw89_ops_sw_scan_start(struct ieee80211_hw *hw,
const u8 *mac_addr)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
rtw89_core_scan_start(rtwdev, rtwvif, mac_addr, false);
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;
}
rtw89_core_scan_start(rtwdev, rtwvif_link, mac_addr, false);
out:
mutex_unlock(&rtwdev->mutex);
}
@@ -865,9 +1197,20 @@ static void rtw89_ops_sw_scan_complete(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
rtw89_core_scan_complete(rtwdev, vif, false);
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;
}
rtw89_core_scan_complete(rtwdev, rtwvif_link, false);
out:
mutex_unlock(&rtwdev->mutex);
}
@@ -884,22 +1227,35 @@ static int rtw89_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_scan_request *req)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif);
int ret = 0;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
int ret;
if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
return 1;
if (rtwdev->scanning || rtwvif->offchan)
return -EBUSY;
mutex_lock(&rtwdev->mutex);
rtw89_hw_scan_start(rtwdev, vif, req);
ret = rtw89_hw_scan_offload(rtwdev, vif, true);
if (rtwdev->scanning || rtwvif->offchan) {
ret = -EBUSY;
goto out;
}
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;
}
rtw89_hw_scan_start(rtwdev, rtwvif_link, req);
ret = rtw89_hw_scan_offload(rtwdev, rtwvif_link, true);
if (ret) {
rtw89_hw_scan_abort(rtwdev, vif);
rtw89_hw_scan_abort(rtwdev, rtwvif_link);
rtw89_err(rtwdev, "HW scan failed with status: %d\n", ret);
}
out:
mutex_unlock(&rtwdev->mutex);
return ret;
@@ -909,6 +1265,8 @@ static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
if (!RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
return;
@@ -917,7 +1275,16 @@ static void rtw89_ops_cancel_hw_scan(struct ieee80211_hw *hw,
return;
mutex_lock(&rtwdev->mutex);
rtw89_hw_scan_abort(rtwdev, vif);
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;
}
rtw89_hw_scan_abort(rtwdev, rtwvif_link);
out:
mutex_unlock(&rtwdev->mutex);
}
@@ -970,11 +1337,24 @@ static int rtw89_ops_assign_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
int ret;
mutex_lock(&rtwdev->mutex);
ret = rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif, ctx);
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;
}
ret = rtw89_chanctx_ops_assign_vif(rtwdev, rtwvif_link, ctx);
out:
mutex_unlock(&rtwdev->mutex);
return ret;
@@ -986,10 +1366,20 @@ static void rtw89_ops_unassign_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx)
{
struct rtw89_dev *rtwdev = hw->priv;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct rtw89_vif *rtwvif = vif_to_rtwvif(vif);
struct rtw89_vif_link *rtwvif_link;
mutex_lock(&rtwdev->mutex);
rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif, ctx);
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);
return;
}
rtw89_chanctx_ops_unassign_vif(rtwdev, rtwvif_link, ctx);
mutex_unlock(&rtwdev->mutex);
}
@@ -1003,7 +1393,7 @@ 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;
if (!vif)
if (!rtwvif)
return -EINVAL;
mutex_lock(&rtwdev->mutex);
@@ -1053,8 +1443,8 @@ static int rtw89_ops_cancel_remain_on_channel(struct ieee80211_hw *hw,
static void rtw89_set_tid_config_iter(void *data, struct ieee80211_sta *sta)
{
struct cfg80211_tid_config *tid_config = data;
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_dev *rtwdev = rtwsta->rtwvif->rtwdev;
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_dev *rtwdev = rtwsta->rtwdev;
rtw89_core_set_tid_config(rtwdev, sta, tid_config);
}

View File

@@ -773,7 +773,7 @@ static int dmac_init_be(struct rtw89_dev *rtwdev, u8 mac_idx)
return ret;
}
ret = rtw89_mac_preload_init(rtwdev, RTW89_MAC_0, rtwdev->mac.qta_mode);
ret = rtw89_mac_preload_init(rtwdev, mac_idx, rtwdev->mac.qta_mode);
if (ret) {
rtw89_err(rtwdev, "[ERR]preload init %d\n", ret);
return ret;
@@ -2091,13 +2091,13 @@ static int rtw89_mac_init_bfee_be(struct rtw89_dev *rtwdev, u8 mac_idx)
}
static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link)
{
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
u8 nc = 1, nr = 3, ng = 0, cb = 1, cs = 1, ldpc_en = 1, stbc_en = 1;
u8 mac_idx = rtwvif->mac_idx;
u8 port_sel = rtwvif->port;
struct ieee80211_link_sta *link_sta;
u8 mac_idx = rtwvif_link->mac_idx;
u8 port_sel = rtwvif_link->port;
u8 sound_dim = 3, t;
u8 *phy_cap;
u32 reg;
@@ -2108,7 +2108,10 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
if (ret)
return ret;
phy_cap = sta->deflink.he_cap.he_cap_elem.phy_cap_info;
rcu_read_lock();
link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
phy_cap = link_sta->he_cap.he_cap_elem.phy_cap_info;
if ((phy_cap[3] & IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER) ||
(phy_cap[4] & IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER)) {
@@ -2119,11 +2122,11 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
sound_dim = min(sound_dim, t);
}
if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
ldpc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
stbc_en &= !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK);
t = u32_get_bits(sta->deflink.vht_cap.cap,
if ((link_sta->vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) ||
(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) {
ldpc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
stbc_en &= !!(link_sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK);
t = u32_get_bits(link_sta->vht_cap.cap,
IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK);
sound_dim = min(sound_dim, t);
}
@@ -2131,6 +2134,8 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
nc = min(nc, sound_dim);
nr = min(nr, sound_dim);
rcu_read_unlock();
reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL);
@@ -2155,12 +2160,12 @@ static int rtw89_mac_set_csi_para_reg_be(struct rtw89_dev *rtwdev,
}
static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link)
{
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
u32 rrsc = BIT(RTW89_MAC_BF_RRSC_6M) | BIT(RTW89_MAC_BF_RRSC_24M);
u8 mac_idx = rtwvif->mac_idx;
struct ieee80211_link_sta *link_sta;
u8 mac_idx = rtwvif_link->mac_idx;
int ret;
u32 reg;
@@ -2168,22 +2173,28 @@ static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev,
if (ret)
return ret;
if (sta->deflink.he_cap.has_he) {
rcu_read_lock();
link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
if (link_sta->he_cap.has_he) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_HE_MSC0) |
BIT(RTW89_MAC_BF_RRSC_HE_MSC3) |
BIT(RTW89_MAC_BF_RRSC_HE_MSC5));
}
if (sta->deflink.vht_cap.vht_supported) {
if (link_sta->vht_cap.vht_supported) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_VHT_MSC0) |
BIT(RTW89_MAC_BF_RRSC_VHT_MSC3) |
BIT(RTW89_MAC_BF_RRSC_VHT_MSC5));
}
if (sta->deflink.ht_cap.ht_supported) {
if (link_sta->ht_cap.ht_supported) {
rrsc |= (BIT(RTW89_MAC_BF_RRSC_HT_MSC0) |
BIT(RTW89_MAC_BF_RRSC_HT_MSC3) |
BIT(RTW89_MAC_BF_RRSC_HT_MSC5));
}
rcu_read_unlock();
reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_TRXPTCL_RESP_CSI_CTRL_0, mac_idx);
rtw89_write32_set(rtwdev, reg, B_BE_BFMEE_BFPARAM_SEL);
rtw89_write32_clr(rtwdev, reg, B_BE_BFMEE_CSI_FORCE_RETE_EN);
@@ -2195,17 +2206,25 @@ static int rtw89_mac_csi_rrsc_be(struct rtw89_dev *rtwdev,
}
static void rtw89_mac_bf_assoc_be(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
struct rtw89_vif_link *rtwvif_link,
struct rtw89_sta_link *rtwsta_link)
{
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct ieee80211_link_sta *link_sta;
bool has_beamformer_cap;
if (rtw89_sta_has_beamformer_cap(sta)) {
rcu_read_lock();
link_sta = rtw89_sta_rcu_dereference_link(rtwsta_link, true);
has_beamformer_cap = rtw89_sta_has_beamformer_cap(link_sta);
rcu_read_unlock();
if (has_beamformer_cap) {
rtw89_debug(rtwdev, RTW89_DBG_BF,
"initialize bfee for new association\n");
rtw89_mac_init_bfee_be(rtwdev, rtwvif->mac_idx);
rtw89_mac_set_csi_para_reg_be(rtwdev, vif, sta);
rtw89_mac_csi_rrsc_be(rtwdev, vif, sta);
rtw89_mac_init_bfee_be(rtwdev, rtwvif_link->mac_idx);
rtw89_mac_set_csi_para_reg_be(rtwdev, rtwvif_link, rtwsta_link);
rtw89_mac_csi_rrsc_be(rtwdev, rtwvif_link, rtwsta_link);
}
}

View File

@@ -2358,13 +2358,15 @@ static int rtw89_pci_deglitch_setting(struct rtw89_dev *rtwdev)
return 0;
}
static void rtw89_pci_disable_eq(struct rtw89_dev *rtwdev)
static void rtw89_pci_disable_eq_ax(struct rtw89_dev *rtwdev)
{
u16 g1_oobs, g2_oobs;
u32 backup_aspm;
u32 phy_offset;
u16 offset_cal;
u16 oobs_val;
int ret;
u8 gen;
if (rtwdev->chip->chip_id != RTL8852C)
return;
@@ -2400,6 +2402,28 @@ static void rtw89_pci_disable_eq(struct rtw89_dev *rtwdev)
rtw89_write16_set(rtwdev, R_RAC_DIRECT_OFFSET_G2 + RAC_ANA09 * RAC_MULT,
BAC_OOBS_SEL);
/* offset K */
for (gen = 1; gen <= 2; gen++) {
phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_G1 :
R_RAC_DIRECT_OFFSET_G2;
rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT,
B_PCIE_BIT_RD_SEL);
}
offset_cal = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_G1 +
RAC_ANA1F * RAC_MULT, OFFSET_CAL_MASK);
for (gen = 1; gen <= 2; gen++) {
phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_G1 :
R_RAC_DIRECT_OFFSET_G2;
rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA0B * RAC_MULT,
MANUAL_LVL_MASK, offset_cal);
rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT,
OFFSET_CAL_MODE);
}
out:
rtw89_write32(rtwdev, R_AX_PCIE_MIX_CFG_V1, backup_aspm);
}
@@ -3724,19 +3748,16 @@ static void rtw89_pci_free_irq(struct rtw89_dev *rtwdev,
pci_free_irq_vectors(pdev);
}
static u16 gray_code_to_bin(u16 gray_code, u32 bit_num)
static u16 gray_code_to_bin(u16 gray_code)
{
u16 bin = 0, gray_bit;
u32 bit_idx;
u16 binary = gray_code;
for (bit_idx = 0; bit_idx < bit_num; bit_idx++) {
gray_bit = (gray_code >> bit_idx) & 0x1;
if (bit_num - bit_idx > 1)
gray_bit ^= (gray_code >> (bit_idx + 1)) & 0x1;
bin |= (gray_bit << bit_idx);
while (gray_code) {
gray_code >>= 1;
binary ^= gray_code;
}
return bin;
return binary;
}
static int rtw89_pci_filter_out(struct rtw89_dev *rtwdev)
@@ -3772,7 +3793,7 @@ static int rtw89_pci_filter_out(struct rtw89_dev *rtwdev)
val16 = rtw89_read16_mask(rtwdev,
phy_offset + RAC_ANA1F * RAC_MULT,
FILTER_OUT_EQ_MASK);
val16 = gray_code_to_bin(val16, hweight16(val16));
val16 = gray_code_to_bin(val16);
filter_out_val = rtw89_read16(rtwdev, phy_offset + RAC_ANA24 *
RAC_MULT);
filter_out_val &= ~REG_FILTER_OUT_MASK;
@@ -4188,6 +4209,17 @@ static void rtw89_pci_l2_hci_ldo(struct rtw89_dev *rtwdev)
RTW89_PCIE_BIT_CFG_RST_MSTATE);
}
void rtw89_pci_basic_cfg(struct rtw89_dev *rtwdev, bool resume)
{
if (resume)
rtw89_pci_cfg_dac(rtwdev);
rtw89_pci_disable_eq(rtwdev);
rtw89_pci_filter_out(rtwdev);
rtw89_pci_link_cfg(rtwdev);
rtw89_pci_l1ss_cfg(rtwdev);
}
static int __maybe_unused rtw89_pci_resume(struct device *dev)
{
struct ieee80211_hw *hw = dev_get_drvdata(dev);
@@ -4209,11 +4241,8 @@ static int __maybe_unused rtw89_pci_resume(struct device *dev)
B_AX_SEL_REQ_ENTR_L1);
}
rtw89_pci_l2_hci_ldo(rtwdev);
rtw89_pci_disable_eq(rtwdev);
rtw89_pci_cfg_dac(rtwdev);
rtw89_pci_filter_out(rtwdev);
rtw89_pci_link_cfg(rtwdev);
rtw89_pci_l1ss_cfg(rtwdev);
rtw89_pci_basic_cfg(rtwdev, true);
return 0;
}
@@ -4246,6 +4275,8 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_ax = {
.aspm_set = rtw89_pci_aspm_set_ax,
.clkreq_set = rtw89_pci_clkreq_set_ax,
.l1ss_set = rtw89_pci_l1ss_set_ax,
.disable_eq = rtw89_pci_disable_eq_ax,
};
EXPORT_SYMBOL(rtw89_pci_gen_ax);
@@ -4345,10 +4376,7 @@ int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_clear_resource;
}
rtw89_pci_disable_eq(rtwdev);
rtw89_pci_filter_out(rtwdev);
rtw89_pci_link_cfg(rtwdev);
rtw89_pci_l1ss_cfg(rtwdev);
rtw89_pci_basic_cfg(rtwdev, false);
ret = rtw89_core_napi_init(rtwdev);
if (ret) {

View File

@@ -18,11 +18,16 @@
#define BAC_OOBS_SEL BIT(4)
#define RAC_ANA0A 0x0A
#define B_BAC_EQ_SEL BIT(5)
#define RAC_ANA0B 0x0B
#define MANUAL_LVL_MASK GENMASK(8, 5)
#define RAC_ANA0C 0x0C
#define B_PCIE_BIT_PSAVE BIT(15)
#define RAC_ANA0D 0x0D
#define OFFSET_CAL_MODE BIT(13)
#define BAC_RX_TEST_EN BIT(6)
#define RAC_ANA10 0x10
#define ADDR_SEL_MASK GENMASK(9, 4)
#define ADDR_SEL_VAL 0x3C
#define ADDR_SEL_PINOUT_DIS_VAL 0x3C4
#define B_PCIE_BIT_PINOUT_DIS BIT(3)
#define RAC_REG_REV2 0x1B
@@ -38,6 +43,7 @@
#define RAC_ANA1E_G2_VAL 0x6EEA
#define RAC_ANA1F 0x1F
#define OOBS_LEVEL_MASK GENMASK(12, 8)
#define OFFSET_CAL_MASK GENMASK(7, 4)
#define RAC_ANA24 0x24
#define B_AX_DEGLITCH GENMASK(11, 8)
#define RAC_ANA26 0x26
@@ -134,6 +140,11 @@
#define REG_FILTER_OUT_MASK GENMASK(6, 2)
#define RAC_MULT 2
#define R_RAC_DIRECT_OFFSET_BE_LANE0_G1 0x3800
#define R_RAC_DIRECT_OFFSET_BE_LANE1_G1 0x3880
#define R_RAC_DIRECT_OFFSET_BE_LANE0_G2 0x3900
#define R_RAC_DIRECT_OFFSET_BE_LANE1_G2 0x3980
#define RTW89_PCI_WR_RETRY_CNT 20
/* Interrupts */
@@ -299,6 +310,7 @@
#define B_BE_L1SS_TIMEOUT_CTRL BIT(18)
#define B_BE_ASPM_CTRL_L1 BIT(17)
#define B_BE_ASPM_CTRL_L0 BIT(16)
#define B_BE_RTK_ASPM_CTRL_MASK GENMASK(17, 16)
#define B_BE_XFER_PENDING_FW BIT(11)
#define B_BE_XFER_PENDING BIT(10)
#define B_BE_REQ_EXIT_L1 BIT(9)
@@ -1276,6 +1288,8 @@ struct rtw89_pci_gen_def {
void (*aspm_set)(struct rtw89_dev *rtwdev, bool enable);
void (*clkreq_set)(struct rtw89_dev *rtwdev, bool enable);
void (*l1ss_set)(struct rtw89_dev *rtwdev, bool enable);
void (*disable_eq)(struct rtw89_dev *rtwdev);
};
struct rtw89_pci_info {
@@ -1600,6 +1614,7 @@ struct pci_device_id;
int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id);
void rtw89_pci_remove(struct pci_dev *pdev);
void rtw89_pci_basic_cfg(struct rtw89_dev *rtwdev, bool resume);
void rtw89_pci_ops_reset(struct rtw89_dev *rtwdev);
int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev, bool en);
int rtw89_pci_ltr_set_v1(struct rtw89_dev *rtwdev, bool en);
@@ -1766,4 +1781,13 @@ static inline int rtw89_pci_poll_txdma_ch_idle(struct rtw89_dev *rtwdev)
return gen_def->poll_txdma_ch_idle(rtwdev);
}
static inline void rtw89_pci_disable_eq(struct rtw89_dev *rtwdev)
{
const struct rtw89_pci_info *info = rtwdev->pci_info;
const struct rtw89_pci_gen_def *gen_def = info->gen_def;
gen_def->disable_eq(rtwdev);
}
#endif

View File

@@ -550,6 +550,79 @@ static int rtw89_pci_lv1rst_start_dma_be(struct rtw89_dev *rtwdev)
return 0;
}
static void rtw89_pci_disable_eq_be(struct rtw89_dev *rtwdev)
{
u32 backup_aspm, phy_offset;
u16 oobs_val, offset_cal;
u16 g1_oobs, g2_oobs;
u8 gen;
if (rtwdev->chip->chip_id != RTL8922A)
return;
g1_oobs = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 +
RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL);
g2_oobs = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G2 +
RAC_ANA09 * RAC_MULT, BAC_OOBS_SEL);
if (g1_oobs && g2_oobs)
return;
backup_aspm = rtw89_read32(rtwdev, R_BE_PCIE_MIX_CFG);
rtw89_write32_clr(rtwdev, R_BE_PCIE_MIX_CFG, B_BE_RTK_ASPM_CTRL_MASK);
/* offset K */
for (gen = 1; gen <= 2; gen++) {
phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 :
R_RAC_DIRECT_OFFSET_BE_LANE0_G2;
rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT,
B_PCIE_BIT_RD_SEL);
}
offset_cal = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 +
RAC_ANA1F * RAC_MULT, OFFSET_CAL_MASK);
for (gen = 1; gen <= 2; gen++) {
phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 :
R_RAC_DIRECT_OFFSET_BE_LANE0_G2;
rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA0B * RAC_MULT,
MANUAL_LVL_MASK, offset_cal);
rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT,
OFFSET_CAL_MODE);
}
/* OOBS */
for (gen = 1; gen <= 2; gen++) {
phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 :
R_RAC_DIRECT_OFFSET_BE_LANE0_G2;
rtw89_write16_set(rtwdev, phy_offset + RAC_ANA0D * RAC_MULT,
BAC_RX_TEST_EN);
rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA10 * RAC_MULT,
ADDR_SEL_MASK, ADDR_SEL_VAL);
rtw89_write16_clr(rtwdev, phy_offset + RAC_ANA10 * RAC_MULT,
B_PCIE_BIT_PINOUT_DIS);
rtw89_write16_set(rtwdev, phy_offset + RAC_ANA19 * RAC_MULT,
B_PCIE_BIT_RD_SEL);
}
oobs_val = rtw89_read16_mask(rtwdev, R_RAC_DIRECT_OFFSET_BE_LANE0_G1 +
RAC_ANA1F * RAC_MULT, OOBS_LEVEL_MASK);
for (gen = 1; gen <= 2; gen++) {
phy_offset = gen == 1 ? R_RAC_DIRECT_OFFSET_BE_LANE0_G1 :
R_RAC_DIRECT_OFFSET_BE_LANE0_G2;
rtw89_write16_mask(rtwdev, phy_offset + RAC_ANA03 * RAC_MULT,
OOBS_SEN_MASK, oobs_val);
rtw89_write16_set(rtwdev, phy_offset + RAC_ANA09 * RAC_MULT,
BAC_OOBS_SEL);
}
rtw89_write32(rtwdev, R_BE_PCIE_MIX_CFG, backup_aspm);
}
static int __maybe_unused rtw89_pci_suspend_be(struct device *dev)
{
struct ieee80211_hw *hw = dev_get_drvdata(dev);
@@ -584,6 +657,8 @@ static int __maybe_unused rtw89_pci_resume_be(struct device *dev)
rtw89_write32_set(rtwdev, R_BE_SER_PL1_CTRL, B_BE_PL1_SER_PL1_EN);
rtw89_write32_set(rtwdev, R_BE_REG_PL1_MASK, B_BE_SER_PM_MASTER_IMR);
rtw89_pci_basic_cfg(rtwdev, true);
return 0;
}
@@ -614,5 +689,7 @@ const struct rtw89_pci_gen_def rtw89_pci_gen_be = {
.aspm_set = rtw89_pci_aspm_set_be,
.clkreq_set = rtw89_pci_clkreq_set_be,
.l1ss_set = rtw89_pci_l1ss_set_be,
.disable_eq = rtw89_pci_disable_eq_be,
};
EXPORT_SYMBOL(rtw89_pci_gen_be);

File diff suppressed because it is too large Load Diff

View File

@@ -815,6 +815,10 @@ void rtw89_phy_config_rf_reg_v1(struct rtw89_dev *rtwdev,
void rtw89_phy_dm_init(struct rtw89_dev *rtwdev);
void rtw89_phy_write32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
u32 data, enum rtw89_phy_idx phy_idx);
void rtw89_phy_write32_idx_set(struct rtw89_dev *rtwdev, u32 addr, u32 bits,
enum rtw89_phy_idx phy_idx);
void rtw89_phy_write32_idx_clr(struct rtw89_dev *rtwdev, u32 addr, u32 bits,
enum rtw89_phy_idx phy_idx);
u32 rtw89_phy_read32_idx(struct rtw89_dev *rtwdev, u32 addr, u32 mask,
enum rtw89_phy_idx phy_idx);
s8 *rtw89_phy_raw_byr_seek(struct rtw89_dev *rtwdev,
@@ -892,7 +896,7 @@ void rtw89_phy_set_txpwr_limit_ru(struct rtw89_dev *rtwdev,
phy->set_txpwr_limit_ru(rtwdev, chan, phy_idx);
}
void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta);
void rtw89_phy_ra_assoc(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_link);
void rtw89_phy_ra_update(struct rtw89_dev *rtwdev);
void rtw89_phy_ra_update_sta(struct rtw89_dev *rtwdev, struct ieee80211_sta *sta,
u32 changed);
@@ -929,7 +933,7 @@ int rtw89_phy_rfk_dack_and_wait(struct rtw89_dev *rtwdev,
int rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
const struct rtw89_chan *chan,
unsigned int ms);
bool is_chl_k, unsigned int ms);
void rtw89_phy_rfk_tssi_fill_fwcmd_efuse_to_de(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy,
const struct rtw89_chan *chan,
@@ -953,11 +957,12 @@ 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_set_bss_color(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
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,
enum rtw89_mac_idx mac_idx,
enum rtw89_tssi_bandedge_cfg bandedge_cfg);
void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
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,

View File

@@ -398,10 +398,9 @@ static void rtw89_phy_bb_wrap_ul_pwr(struct rtw89_dev *rtwdev)
}
}
static void rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev)
static void __rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev,
enum rtw89_mac_idx mac_idx)
{
enum rtw89_mac_idx mac_idx = RTW89_MAC_0;
rtw89_phy_bb_wrap_pwr_by_macid_init(rtwdev);
rtw89_phy_bb_wrap_tx_path_by_macid_init(rtwdev);
rtw89_phy_bb_wrap_listen_path_en_init(rtwdev);
@@ -411,6 +410,13 @@ static void rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev)
rtw89_phy_bb_wrap_ul_pwr(rtwdev);
}
static void rtw89_phy_bb_wrap_init_be(struct rtw89_dev *rtwdev)
{
__rtw89_phy_bb_wrap_init_be(rtwdev, RTW89_MAC_0);
if (rtwdev->dbcc_en)
__rtw89_phy_bb_wrap_init_be(rtwdev, RTW89_MAC_1);
}
static void rtw89_phy_ch_info_init_be(struct rtw89_dev *rtwdev)
{
rtw89_phy_write32_mask(rtwdev, R_CHINFO_SEG, B_CHINFO_SEG_LEN, 0x0);

View File

@@ -62,9 +62,9 @@ static void rtw89_ps_power_mode_change(struct rtw89_dev *rtwdev, bool enter)
rtw89_mac_power_mode_change(rtwdev, enter);
}
void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
{
if (rtwvif->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)
if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)
return;
if (!rtwdev->ps_mode)
@@ -85,23 +85,25 @@ void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
rtw89_ps_power_mode_change(rtwdev, false);
}
static void __rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
static void __rtw89_enter_lps(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_lps_parm lps_param = {
.macid = rtwvif->mac_id,
.macid = rtwvif_link->mac_id,
.psmode = RTW89_MAC_AX_PS_MODE_LEGACY,
.lastrpwm = RTW89_LAST_RPWM_PS,
};
rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_FW_CTRL);
rtw89_fw_h2c_lps_parm(rtwdev, &lps_param);
rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif);
rtw89_fw_h2c_lps_ch_info(rtwdev, rtwvif_link);
}
static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
static void __rtw89_leave_lps(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_lps_parm lps_param = {
.macid = rtwvif->mac_id,
.macid = rtwvif_link->mac_id,
.psmode = RTW89_MAC_AX_PS_MODE_ACTIVE,
.lastrpwm = RTW89_LAST_RPWM_ACTIVE,
};
@@ -109,7 +111,7 @@ static void __rtw89_leave_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif
rtw89_fw_h2c_lps_parm(rtwdev, &lps_param);
rtw89_fw_leave_lps_check(rtwdev, 0);
rtw89_btc_ntfy_radio_state(rtwdev, BTC_RFCTRL_WL_ON);
rtw89_chip_digital_pwr_comp(rtwdev, rtwvif->phy_idx);
rtw89_chip_digital_pwr_comp(rtwdev, rtwvif_link->phy_idx);
}
void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
@@ -119,7 +121,7 @@ void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
__rtw89_leave_ps_mode(rtwdev);
}
void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool ps_mode)
{
lockdep_assert_held(&rtwdev->mutex);
@@ -127,23 +129,26 @@ void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
if (test_and_set_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags))
return;
__rtw89_enter_lps(rtwdev, rtwvif);
__rtw89_enter_lps(rtwdev, rtwvif_link);
if (ps_mode)
__rtw89_enter_ps_mode(rtwdev, rtwvif);
__rtw89_enter_ps_mode(rtwdev, rtwvif_link);
}
static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
if (rtwvif->wifi_role != RTW89_WIFI_ROLE_STATION &&
rtwvif->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT)
if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION &&
rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT)
return;
__rtw89_leave_lps(rtwdev, rtwvif);
__rtw89_leave_lps(rtwdev, rtwvif_link);
}
void rtw89_leave_lps(struct rtw89_dev *rtwdev)
{
struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
unsigned int link_id;
lockdep_assert_held(&rtwdev->mutex);
@@ -153,12 +158,15 @@ void rtw89_leave_lps(struct rtw89_dev *rtwdev)
__rtw89_leave_ps_mode(rtwdev);
rtw89_for_each_rtwvif(rtwdev, rtwvif)
rtw89_leave_lps_vif(rtwdev, rtwvif);
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
rtw89_leave_lps_vif(rtwdev, rtwvif_link);
}
void rtw89_enter_ips(struct rtw89_dev *rtwdev)
{
struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
unsigned int link_id;
set_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags);
@@ -166,14 +174,17 @@ void rtw89_enter_ips(struct rtw89_dev *rtwdev)
return;
rtw89_for_each_rtwvif(rtwdev, rtwvif)
rtw89_mac_vif_deinit(rtwdev, rtwvif);
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
rtw89_mac_vif_deinit(rtwdev, rtwvif_link);
rtw89_core_stop(rtwdev);
}
void rtw89_leave_ips(struct rtw89_dev *rtwdev)
{
struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
unsigned int link_id;
int ret;
if (test_bit(RTW89_FLAG_POWERON, rtwdev->flags))
@@ -186,7 +197,8 @@ void rtw89_leave_ips(struct rtw89_dev *rtwdev)
rtw89_set_channel(rtwdev);
rtw89_for_each_rtwvif(rtwdev, rtwvif)
rtw89_mac_vif_init(rtwdev, rtwvif);
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
rtw89_mac_vif_init(rtwdev, rtwvif_link);
clear_bit(RTW89_FLAG_INACTIVE_PS, rtwdev->flags);
}
@@ -197,48 +209,50 @@ void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl)
rtw89_leave_lps(rtwdev);
}
static void rtw89_tsf32_toggle(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
static void rtw89_tsf32_toggle(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
enum rtw89_p2pps_action act)
{
if (act == RTW89_P2P_ACT_UPDATE || act == RTW89_P2P_ACT_REMOVE)
return;
if (act == RTW89_P2P_ACT_INIT)
rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif, true);
rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif_link, true);
else if (act == RTW89_P2P_ACT_TERMINATE)
rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif, false);
rtw89_fw_h2c_tsf32_toggle(rtwdev, rtwvif_link, false);
}
static void rtw89_p2p_disable_all_noa(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif)
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf)
{
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
enum rtw89_p2pps_action act;
u8 noa_id;
if (rtwvif->last_noa_nr == 0)
if (rtwvif_link->last_noa_nr == 0)
return;
for (noa_id = 0; noa_id < rtwvif->last_noa_nr; noa_id++) {
if (noa_id == rtwvif->last_noa_nr - 1)
for (noa_id = 0; noa_id < rtwvif_link->last_noa_nr; noa_id++) {
if (noa_id == rtwvif_link->last_noa_nr - 1)
act = RTW89_P2P_ACT_TERMINATE;
else
act = RTW89_P2P_ACT_REMOVE;
rtw89_tsf32_toggle(rtwdev, rtwvif, act);
rtw89_fw_h2c_p2p_act(rtwdev, vif, NULL, act, noa_id);
rtw89_tsf32_toggle(rtwdev, rtwvif_link, act);
rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, bss_conf,
NULL, act, noa_id);
}
}
static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev,
struct ieee80211_vif *vif)
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf)
{
struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
struct ieee80211_p2p_noa_desc *desc;
enum rtw89_p2pps_action act;
u8 noa_id;
for (noa_id = 0; noa_id < RTW89_P2P_MAX_NOA_NUM; noa_id++) {
desc = &vif->bss_conf.p2p_noa_attr.desc[noa_id];
desc = &bss_conf->p2p_noa_attr.desc[noa_id];
if (!desc->count || !desc->duration)
break;
@@ -246,16 +260,19 @@ static void rtw89_p2p_update_noa(struct rtw89_dev *rtwdev,
act = RTW89_P2P_ACT_INIT;
else
act = RTW89_P2P_ACT_UPDATE;
rtw89_tsf32_toggle(rtwdev, rtwvif, act);
rtw89_fw_h2c_p2p_act(rtwdev, vif, desc, act, noa_id);
rtw89_tsf32_toggle(rtwdev, rtwvif_link, act);
rtw89_fw_h2c_p2p_act(rtwdev, rtwvif_link, bss_conf,
desc, act, noa_id);
}
rtwvif->last_noa_nr = noa_id;
rtwvif_link->last_noa_nr = noa_id;
}
void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf)
{
rtw89_p2p_disable_all_noa(rtwdev, vif);
rtw89_p2p_update_noa(rtwdev, vif);
rtw89_p2p_disable_all_noa(rtwdev, rtwvif_link, bss_conf);
rtw89_p2p_update_noa(rtwdev, rtwvif_link, bss_conf);
}
void rtw89_recalc_lps(struct rtw89_dev *rtwdev)
@@ -265,6 +282,12 @@ void rtw89_recalc_lps(struct rtw89_dev *rtwdev)
enum rtw89_entity_mode mode;
int count = 0;
/* FIXME: Fix rtw89_enter_lps() and __rtw89_enter_ps_mode()
* to take MLO cases into account before doing the following.
*/
if (rtwdev->support_mlo)
goto disable_lps;
mode = rtw89_get_entity_mode(rtwdev);
if (mode == RTW89_ENTITY_MODE_MCC)
goto disable_lps;
@@ -291,9 +314,9 @@ disable_lps:
rtwdev->lps_enabled = false;
}
void rtw89_p2p_noa_renew(struct rtw89_vif *rtwvif)
void rtw89_p2p_noa_renew(struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa;
struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa;
struct rtw89_p2p_noa_ie *ie = &setter->ie;
struct rtw89_p2p_ie_head *p2p_head = &ie->p2p_head;
struct rtw89_noa_attr_head *noa_head = &ie->noa_head;
@@ -318,10 +341,10 @@ void rtw89_p2p_noa_renew(struct rtw89_vif *rtwvif)
noa_head->oppps_ctwindow = 0;
}
void rtw89_p2p_noa_append(struct rtw89_vif *rtwvif,
void rtw89_p2p_noa_append(struct rtw89_vif_link *rtwvif_link,
const struct ieee80211_p2p_noa_desc *desc)
{
struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa;
struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa;
struct rtw89_p2p_noa_ie *ie = &setter->ie;
struct rtw89_p2p_ie_head *p2p_head = &ie->p2p_head;
struct rtw89_noa_attr_head *noa_head = &ie->noa_head;
@@ -338,9 +361,9 @@ void rtw89_p2p_noa_append(struct rtw89_vif *rtwvif,
ie->noa_desc[setter->noa_count++] = *desc;
}
u8 rtw89_p2p_noa_fetch(struct rtw89_vif *rtwvif, void **data)
u8 rtw89_p2p_noa_fetch(struct rtw89_vif_link *rtwvif_link, void **data)
{
struct rtw89_p2p_noa_setter *setter = &rtwvif->p2p_noa;
struct rtw89_p2p_noa_setter *setter = &rtwvif_link->p2p_noa;
struct rtw89_p2p_noa_ie *ie = &setter->ie;
void *tail;

View File

@@ -5,21 +5,23 @@
#ifndef __RTW89_PS_H_
#define __RTW89_PS_H_
void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool ps_mode);
void rtw89_leave_lps(struct rtw89_dev *rtwdev);
void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev);
void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif);
void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev);
void rtw89_enter_ips(struct rtw89_dev *rtwdev);
void rtw89_leave_ips(struct rtw89_dev *rtwdev);
void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl);
void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif);
void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf);
void rtw89_recalc_lps(struct rtw89_dev *rtwdev);
void rtw89_p2p_noa_renew(struct rtw89_vif *rtwvif);
void rtw89_p2p_noa_append(struct rtw89_vif *rtwvif,
void rtw89_p2p_noa_renew(struct rtw89_vif_link *rtwvif_link);
void rtw89_p2p_noa_append(struct rtw89_vif_link *rtwvif_link,
const struct ieee80211_p2p_noa_desc *desc);
u8 rtw89_p2p_noa_fetch(struct rtw89_vif *rtwvif, void **data);
u8 rtw89_p2p_noa_fetch(struct rtw89_vif_link *rtwvif_link, void **data);
static inline void rtw89_leave_ips_by_hwflags(struct rtw89_dev *rtwdev)
{

View File

@@ -793,22 +793,26 @@ static bool __rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev)
{
struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
struct rtw89_reg_6ghz_tpe new = {};
struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
unsigned int link_id;
bool changed = false;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
const struct rtw89_reg_6ghz_tpe *tmp;
const struct rtw89_chan *chan;
chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx);
if (chan->band_type != RTW89_BAND_6G)
continue;
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
if (chan->band_type != RTW89_BAND_6G)
continue;
tmp = &rtwvif->reg_6ghz_tpe;
if (!tmp->valid)
continue;
tmp = &rtwvif_link->reg_6ghz_tpe;
if (!tmp->valid)
continue;
tpe_intersect_constraint(&new, tmp->constraint);
tpe_intersect_constraint(&new, tmp->constraint);
}
}
if (memcmp(&regulatory->reg_6ghz_tpe, &new,
@@ -831,19 +835,24 @@ static bool __rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev)
}
static int rtw89_reg_6ghz_tpe_recalc(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool active,
struct rtw89_vif_link *rtwvif_link, bool active,
unsigned int *changed)
{
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
struct rtw89_reg_6ghz_tpe *tpe = &rtwvif->reg_6ghz_tpe;
struct rtw89_reg_6ghz_tpe *tpe = &rtwvif_link->reg_6ghz_tpe;
struct ieee80211_bss_conf *bss_conf;
memset(tpe, 0, sizeof(*tpe));
if (!active || rtwvif->reg_6ghz_power != RTW89_REG_6GHZ_POWER_STD)
if (!active || rtwvif_link->reg_6ghz_power != RTW89_REG_6GHZ_POWER_STD)
goto bottom;
rcu_read_lock();
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
rtw89_calculate_tpe(rtwdev, tpe, &bss_conf->tpe);
rcu_read_unlock();
if (!tpe->valid)
goto bottom;
@@ -867,20 +876,24 @@ static bool __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev)
const struct rtw89_regd *regd = regulatory->regd;
enum rtw89_reg_6ghz_power sel;
const struct rtw89_chan *chan;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
unsigned int link_id;
int count = 0;
u8 index;
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
chan = rtw89_chan_get(rtwdev, rtwvif->chanctx_idx);
if (chan->band_type != RTW89_BAND_6G)
continue;
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
chan = rtw89_chan_get(rtwdev, rtwvif_link->chanctx_idx);
if (chan->band_type != RTW89_BAND_6G)
continue;
if (count != 0 && rtwvif->reg_6ghz_power == sel)
continue;
if (count != 0 && rtwvif_link->reg_6ghz_power == sel)
continue;
sel = rtwvif->reg_6ghz_power;
count++;
sel = rtwvif_link->reg_6ghz_power;
count++;
}
}
if (count != 1)
@@ -908,35 +921,41 @@ static bool __rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev)
}
static int rtw89_reg_6ghz_power_recalc(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif, bool active,
struct rtw89_vif_link *rtwvif_link, bool active,
unsigned int *changed)
{
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
struct ieee80211_bss_conf *bss_conf;
rcu_read_lock();
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
if (active) {
switch (vif->bss_conf.power_type) {
switch (bss_conf->power_type) {
case IEEE80211_REG_VLP_AP:
rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP;
rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_VLP;
break;
case IEEE80211_REG_LPI_AP:
rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_LPI;
rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_LPI;
break;
case IEEE80211_REG_SP_AP:
rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_STD;
rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_STD;
break;
default:
rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
break;
}
} else {
rtwvif->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
rtwvif_link->reg_6ghz_power = RTW89_REG_6GHZ_POWER_DFLT;
}
rcu_read_unlock();
*changed += __rtw89_reg_6ghz_power_recalc(rtwdev);
return 0;
}
int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
bool active)
{
unsigned int changed = 0;
@@ -948,11 +967,11 @@ int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
* so must do reg_6ghz_tpe_recalc() after reg_6ghz_power_recalc().
*/
ret = rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif, active, &changed);
ret = rtw89_reg_6ghz_power_recalc(rtwdev, rtwvif_link, active, &changed);
if (ret)
return ret;
ret = rtw89_reg_6ghz_tpe_recalc(rtwdev, rtwvif, active, &changed);
ret = rtw89_reg_6ghz_tpe_recalc(rtwdev, rtwvif_link, active, &changed);
if (ret)
return ret;

View File

@@ -1590,10 +1590,11 @@ static void rtw8851b_rfk_init(struct rtw89_dev *rtwdev)
rtw8851b_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0);
}
static void rtw8851b_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
static void rtw8851b_rfk_channel(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif->phy_idx;
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw8851b_rx_dck(rtwdev, phy_idx, chanctx_idx);
rtw8851b_iqk(rtwdev, phy_idx, chanctx_idx);
@@ -1608,10 +1609,12 @@ static void rtw8851b_rfk_band_changed(struct rtw89_dev *rtwdev,
rtw8851b_tssi_scan(rtwdev, phy_idx, chan);
}
static void rtw8851b_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
static void rtw8851b_rfk_scan(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool start)
{
rtw8851b_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx, rtwvif->chanctx_idx);
rtw8851b_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx,
rtwvif_link->chanctx_idx);
}
static void rtw8851b_rfk_track(struct rtw89_dev *rtwdev)

View File

@@ -1350,10 +1350,11 @@ static void rtw8852a_rfk_init(struct rtw89_dev *rtwdev)
rtw8852a_rx_dck(rtwdev, RTW89_PHY_0, true, RTW89_CHANCTX_0);
}
static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
static void rtw8852a_rfk_channel(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif->phy_idx;
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw8852a_rx_dck(rtwdev, phy_idx, true, chanctx_idx);
rtw8852a_iqk(rtwdev, phy_idx, chanctx_idx);
@@ -1368,10 +1369,11 @@ static void rtw8852a_rfk_band_changed(struct rtw89_dev *rtwdev,
rtw8852a_tssi_scan(rtwdev, phy_idx, chan);
}
static void rtw8852a_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
static void rtw8852a_rfk_scan(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool start)
{
rtw8852a_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx);
rtw8852a_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx);
}
static void rtw8852a_rfk_track(struct rtw89_dev *rtwdev)

View File

@@ -562,10 +562,11 @@ static void rtw8852b_rfk_init(struct rtw89_dev *rtwdev)
rtw8852b_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0);
}
static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
static void rtw8852b_rfk_channel(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif->phy_idx;
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw8852b_rx_dck(rtwdev, phy_idx, chanctx_idx);
rtw8852b_iqk(rtwdev, phy_idx, chanctx_idx);
@@ -580,10 +581,12 @@ static void rtw8852b_rfk_band_changed(struct rtw89_dev *rtwdev,
rtw8852b_tssi_scan(rtwdev, phy_idx, chan);
}
static void rtw8852b_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
static void rtw8852b_rfk_scan(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool start)
{
rtw8852b_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx, rtwvif->chanctx_idx);
rtw8852b_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx,
rtwvif_link->chanctx_idx);
}
static void rtw8852b_rfk_track(struct rtw89_dev *rtwdev)

View File

@@ -535,10 +535,11 @@ static void rtw8852bt_rfk_init(struct rtw89_dev *rtwdev)
rtw8852bt_rx_dck(rtwdev, RTW89_PHY_0, RTW89_CHANCTX_0);
}
static void rtw8852bt_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
static void rtw8852bt_rfk_channel(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif->phy_idx;
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw8852bt_rx_dck(rtwdev, phy_idx, chanctx_idx);
rtw8852bt_iqk(rtwdev, phy_idx, chanctx_idx);
@@ -553,10 +554,12 @@ static void rtw8852bt_rfk_band_changed(struct rtw89_dev *rtwdev,
rtw8852bt_tssi_scan(rtwdev, phy_idx, chan);
}
static void rtw8852bt_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
static void rtw8852bt_rfk_scan(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool start)
{
rtw8852bt_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx, rtwvif->chanctx_idx);
rtw8852bt_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx,
rtwvif_link->chanctx_idx);
}
static void rtw8852bt_rfk_track(struct rtw89_dev *rtwdev)

View File

@@ -1846,10 +1846,11 @@ static void rtw8852c_rfk_init(struct rtw89_dev *rtwdev)
rtw8852c_rx_dck(rtwdev, RTW89_PHY_0, false);
}
static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
static void rtw8852c_rfk_channel(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif->phy_idx;
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
rtw8852c_mcc_get_ch_info(rtwdev, phy_idx);
rtw8852c_rx_dck(rtwdev, phy_idx, false);
@@ -1866,10 +1867,11 @@ static void rtw8852c_rfk_band_changed(struct rtw89_dev *rtwdev,
rtw8852c_tssi_scan(rtwdev, phy_idx, chan);
}
static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
static void rtw8852c_rfk_scan(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool start)
{
rtw8852c_wifi_scan_notify(rtwdev, start, rtwvif->phy_idx);
rtw8852c_wifi_scan_notify(rtwdev, start, rtwvif_link->phy_idx);
}
static void rtw8852c_rfk_track(struct rtw89_dev *rtwdev)

View File

@@ -2350,7 +2350,7 @@ static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
if (dgain > 0x5fc || dgain < 0x556) {
_dpk_one_shot(rtwdev, phy, path, D_SYNC);
dgain = _dpk_dgain_read(rtwdev);
_dpk_dgain_read(rtwdev);
}
if (agc_cnt == 0) {

View File

@@ -13,7 +13,7 @@
#include "rtw8922a_rfk.h"
#include "util.h"
#define RTW8922A_FW_FORMAT_MAX 1
#define RTW8922A_FW_FORMAT_MAX 2
#define RTW8922A_FW_BASENAME "rtw89/rtw8922a_fw"
#define RTW8922A_MODULE_FIRMWARE \
RTW8922A_FW_BASENAME "-" __stringify(RTW8922A_FW_FORMAT_MAX) ".bin"
@@ -1991,14 +1991,23 @@ static void rtw8922a_rfk_init(struct rtw89_dev *rtwdev)
memset(rfk_mcc, 0, sizeof(*rfk_mcc));
}
static void __rtw8922a_rfk_init_late(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
const struct rtw89_chan *chan)
{
rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5);
rtw89_phy_rfk_dack_and_wait(rtwdev, phy_idx, chan, 58);
rtw89_phy_rfk_rxdck_and_wait(rtwdev, phy_idx, chan, false, 32);
}
static void rtw8922a_rfk_init_late(struct rtw89_dev *rtwdev)
{
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_CHANCTX_0);
rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, RTW89_PHY_0, 5);
rtw89_phy_rfk_dack_and_wait(rtwdev, RTW89_PHY_0, chan, 58);
rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, 32);
__rtw8922a_rfk_init_late(rtwdev, RTW89_PHY_0, chan);
if (rtwdev->dbcc_en)
__rtw8922a_rfk_init_late(rtwdev, RTW89_PHY_1, chan);
}
static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
@@ -2020,11 +2029,12 @@ static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
}
}
static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
enum rtw89_chanctx_idx chanctx_idx = rtwvif->chanctx_idx;
enum rtw89_chanctx_idx chanctx_idx = rtwvif_link->chanctx_idx;
const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx);
enum rtw89_phy_idx phy_idx = rtwvif->phy_idx;
enum rtw89_phy_idx phy_idx = rtwvif_link->phy_idx;
u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx);
u32 tx_en;
@@ -2035,9 +2045,9 @@ static void rtw8922a_rfk_channel(struct rtw89_dev *rtwdev, struct rtw89_vif *rtw
rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, phy_idx, 5);
rtw89_phy_rfk_txgapk_and_wait(rtwdev, phy_idx, chan, 54);
rtw89_phy_rfk_iqk_and_wait(rtwdev, phy_idx, chan, 84);
rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_NORMAL, 6);
rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_NORMAL, 20);
rtw89_phy_rfk_dpk_and_wait(rtwdev, phy_idx, chan, 34);
rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, 32);
rtw89_phy_rfk_rxdck_and_wait(rtwdev, RTW89_PHY_0, chan, true, 32);
rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_CHLK, BTC_WRFK_STOP);
@@ -2050,7 +2060,8 @@ static void rtw8922a_rfk_band_changed(struct rtw89_dev *rtwdev,
rtw89_phy_rfk_tssi_and_wait(rtwdev, phy_idx, chan, RTW89_TSSI_SCAN, 6);
}
static void rtw8922a_rfk_scan(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
static void rtw8922a_rfk_scan(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool start)
{
}

View File

@@ -300,37 +300,54 @@ static void drv_resume_rx(struct rtw89_ser *ser)
static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port);
rtwvif->net_type = RTW89_NET_TYPE_NO_LINK;
rtwvif->trigger = false;
struct rtw89_vif_link *rtwvif_link;
unsigned int link_id;
rtwvif->tdls_peer = 0;
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif_link->port);
rtwvif_link->net_type = RTW89_NET_TYPE_NO_LINK;
rtwvif_link->trigger = false;
}
}
static void ser_sta_deinit_cam_iter(void *data, struct ieee80211_sta *sta)
{
struct rtw89_vif *target_rtwvif = (struct rtw89_vif *)data;
struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
struct rtw89_sta *rtwsta = sta_to_rtwsta(sta);
struct rtw89_vif *rtwvif = rtwsta->rtwvif;
struct rtw89_dev *rtwdev = rtwvif->rtwdev;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_sta_link *rtwsta_link;
unsigned int link_id;
if (rtwvif != target_rtwvif)
return;
if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam);
if (sta->tdls)
rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta->bssid_cam);
rtw89_sta_for_each_link(rtwsta, rtwsta_link, link_id) {
rtwvif_link = rtwsta_link->rtwvif_link;
INIT_LIST_HEAD(&rtwsta->ba_cam_list);
if (rtwvif_link->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta_link->addr_cam);
if (sta->tdls)
rtw89_cam_deinit_bssid_cam(rtwdev, &rtwsta_link->bssid_cam);
INIT_LIST_HEAD(&rtwsta_link->ba_cam_list);
}
}
static void ser_deinit_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
{
struct rtw89_vif_link *rtwvif_link;
unsigned int link_id;
ieee80211_iterate_stations_atomic(rtwdev->hw,
ser_sta_deinit_cam_iter,
rtwvif);
rtw89_cam_deinit(rtwdev, rtwvif);
rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
rtw89_cam_deinit(rtwdev, rtwvif_link);
bitmap_zero(rtwdev->cam_info.ba_cam_map, RTW89_MAX_BA_CAM_NUM);
}

View File

@@ -421,7 +421,8 @@ static void rtw89_wow_construct_key_info(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_wow_key_info *key_info = &rtw_wow->key_info;
struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
bool err = false;
rcu_read_lock();
@@ -596,7 +597,8 @@ static int rtw89_wow_get_aoac_rpt(struct rtw89_dev *rtwdev, bool rx_ready)
static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev,
u32 cipher, u8 keyidx, u8 *gtk)
{
struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
const struct rtw89_cipher_info *cipher_info;
struct ieee80211_key_conf *rekey_conf;
struct ieee80211_key_conf *key;
@@ -632,11 +634,13 @@ static struct ieee80211_key_conf *rtw89_wow_gtk_rekey(struct rtw89_dev *rtwdev,
static void rtw89_wow_update_key_info(struct rtw89_dev *rtwdev, bool rx_ready)
{
struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
struct rtw89_set_key_info_iter_data data = {.error = false,
.rx_ready = rx_ready};
struct ieee80211_bss_conf *bss_conf;
struct ieee80211_key_conf *key;
rcu_read_lock();
@@ -669,9 +673,15 @@ static void rtw89_wow_update_key_info(struct rtw89_dev *rtwdev, bool rx_ready)
return;
rtw89_rx_pn_set_pmf(rtwdev, key, aoac_rpt->igtk_ipn);
ieee80211_gtk_rekey_notify(wow_vif, wow_vif->bss_conf.bssid,
rcu_read_lock();
bss_conf = rtw89_vif_rcu_dereference_link(rtwvif_link, true);
ieee80211_gtk_rekey_notify(wow_vif, bss_conf->bssid,
aoac_rpt->eapol_key_replay_count,
GFP_KERNEL);
GFP_ATOMIC);
rcu_read_unlock();
}
static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev)
@@ -681,27 +691,24 @@ static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev)
static void rtw89_wow_enter_deep_ps(struct rtw89_dev *rtwdev)
{
struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
__rtw89_enter_ps_mode(rtwdev, rtwvif);
__rtw89_enter_ps_mode(rtwdev, rtwvif_link);
}
static void rtw89_wow_enter_ps(struct rtw89_dev *rtwdev)
{
struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
if (rtw89_wow_mgd_linked(rtwdev))
rtw89_enter_lps(rtwdev, rtwvif, false);
rtw89_enter_lps(rtwdev, rtwvif_link, false);
else if (rtw89_wow_no_link(rtwdev))
rtw89_fw_h2c_fwips(rtwdev, rtwvif, true);
rtw89_fw_h2c_fwips(rtwdev, rtwvif_link, true);
}
static void rtw89_wow_leave_ps(struct rtw89_dev *rtwdev, bool enable_wow)
{
struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
if (rtw89_wow_mgd_linked(rtwdev)) {
rtw89_leave_lps(rtwdev);
@@ -709,7 +716,7 @@ static void rtw89_wow_leave_ps(struct rtw89_dev *rtwdev, bool enable_wow)
if (enable_wow)
rtw89_leave_ips(rtwdev);
else
rtw89_fw_h2c_fwips(rtwdev, rtwvif, false);
rtw89_fw_h2c_fwips(rtwdev, rtwvif_link, false);
}
}
@@ -734,6 +741,8 @@ static void rtw89_wow_set_rx_filter(struct rtw89_dev *rtwdev, bool enable)
static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev)
{
struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_wow_aoac_report *aoac_rpt = &rtw_wow->aoac_rpt;
struct cfg80211_wowlan_nd_info nd_info;
@@ -780,35 +789,34 @@ static void rtw89_wow_show_wakeup_reason(struct rtw89_dev *rtwdev)
break;
default:
rtw89_warn(rtwdev, "Unknown wakeup reason %x\n", reason);
ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, NULL,
GFP_KERNEL);
ieee80211_report_wowlan_wakeup(wow_vif, NULL, GFP_KERNEL);
return;
}
ieee80211_report_wowlan_wakeup(rtwdev->wow.wow_vif, &wakeup,
GFP_KERNEL);
ieee80211_report_wowlan_wakeup(wow_vif, &wakeup, GFP_KERNEL);
}
static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
static void rtw89_wow_vif_iter(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
struct ieee80211_vif *vif = rtwvif_link_to_vif(rtwvif_link);
/* Current WoWLAN function support setting of only vif in
* infra mode or no link mode. When one suitable vif is found,
* stop the iteration.
*/
if (rtw_wow->wow_vif || vif->type != NL80211_IFTYPE_STATION)
if (rtw_wow->rtwvif_link || vif->type != NL80211_IFTYPE_STATION)
return;
switch (rtwvif->net_type) {
switch (rtwvif_link->net_type) {
case RTW89_NET_TYPE_INFRA:
if (rtw_wow_has_mgd_features(rtwdev))
rtw_wow->wow_vif = vif;
rtw_wow->rtwvif_link = rtwvif_link;
break;
case RTW89_NET_TYPE_NO_LINK:
if (rtw_wow->pno_inited)
rtw_wow->wow_vif = vif;
rtw_wow->rtwvif_link = rtwvif_link;
break;
default:
break;
@@ -865,7 +873,7 @@ static u16 rtw89_calc_crc(u8 *pdata, int length)
return ~crc;
}
static int rtw89_wow_pattern_get_type(struct rtw89_vif *rtwvif,
static int rtw89_wow_pattern_get_type(struct rtw89_vif_link *rtwvif_link,
struct rtw89_wow_cam_info *rtw_pattern,
const u8 *pattern, u8 da_mask)
{
@@ -885,7 +893,7 @@ static int rtw89_wow_pattern_get_type(struct rtw89_vif *rtwvif,
rtw_pattern->bc = true;
else if (is_multicast_ether_addr(da))
rtw_pattern->mc = true;
else if (ether_addr_equal(da, rtwvif->mac_addr) &&
else if (ether_addr_equal(da, rtwvif_link->mac_addr) &&
da_mask == GENMASK(5, 0))
rtw_pattern->uc = true;
else if (!da_mask) /*da_mask == 0 mean wildcard*/
@@ -897,7 +905,7 @@ static int rtw89_wow_pattern_get_type(struct rtw89_vif *rtwvif,
}
static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link,
const struct cfg80211_pkt_pattern *pkt_pattern,
struct rtw89_wow_cam_info *rtw_pattern)
{
@@ -916,7 +924,7 @@ static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev,
mask_len = DIV_ROUND_UP(len, 8);
memset(rtw_pattern, 0, sizeof(*rtw_pattern));
ret = rtw89_wow_pattern_get_type(rtwvif, rtw_pattern, pattern,
ret = rtw89_wow_pattern_get_type(rtwvif_link, rtw_pattern, pattern,
mask[0] & GENMASK(5, 0));
if (ret)
return ret;
@@ -970,7 +978,7 @@ static int rtw89_wow_pattern_generate(struct rtw89_dev *rtwdev,
}
static int rtw89_wow_parse_patterns(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif,
struct rtw89_vif_link *rtwvif_link,
struct cfg80211_wowlan *wowlan)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
@@ -983,7 +991,7 @@ static int rtw89_wow_parse_patterns(struct rtw89_dev *rtwdev,
for (i = 0; i < wowlan->n_patterns; i++) {
rtw_pattern = &rtw_wow->patterns[i];
ret = rtw89_wow_pattern_generate(rtwdev, rtwvif,
ret = rtw89_wow_pattern_generate(rtwdev, rtwvif_link,
&wowlan->patterns[i],
rtw_pattern);
if (ret) {
@@ -1040,7 +1048,7 @@ static void rtw89_wow_clear_wakeups(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
rtw_wow->wow_vif = NULL;
rtw_wow->rtwvif_link = NULL;
rtw89_core_release_all_bits_map(rtw_wow->flags, RTW89_WOW_FLAG_NUM);
rtw_wow->pattern_cnt = 0;
rtw_wow->pno_inited = false;
@@ -1066,6 +1074,7 @@ static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev,
struct cfg80211_wowlan *wowlan)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct rtw89_vif_link *rtwvif_link;
struct rtw89_vif *rtwvif;
if (wowlan->disconnect)
@@ -1078,36 +1087,40 @@ static int rtw89_wow_set_wakeups(struct rtw89_dev *rtwdev,
if (wowlan->nd_config)
rtw89_wow_init_pno(rtwdev, wowlan->nd_config);
rtw89_for_each_rtwvif(rtwdev, rtwvif)
rtw89_wow_vif_iter(rtwdev, rtwvif);
rtw89_for_each_rtwvif(rtwdev, rtwvif) {
/* use the link on HW-0 to do wow flow */
rtwvif_link = rtw89_vif_get_link_inst(rtwvif, 0);
if (!rtwvif_link)
continue;
if (!rtw_wow->wow_vif)
rtw89_wow_vif_iter(rtwdev, rtwvif_link);
}
rtwvif_link = rtw_wow->rtwvif_link;
if (!rtwvif_link)
return -EPERM;
rtwvif = (struct rtw89_vif *)rtw_wow->wow_vif->drv_priv;
return rtw89_wow_parse_patterns(rtwdev, rtwvif, wowlan);
return rtw89_wow_parse_patterns(rtwdev, rtwvif_link, wowlan);
}
static int rtw89_wow_cfg_wake_pno(struct rtw89_dev *rtwdev, bool wow)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
int ret;
ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif, true);
ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif_link, true);
if (ret) {
rtw89_err(rtwdev, "failed to config pno\n");
return ret;
}
ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif, wow);
ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif_link, wow);
if (ret) {
rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n");
return ret;
}
ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif, wow);
ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif_link, wow);
if (ret) {
rtw89_err(rtwdev, "failed to fw wow global\n");
return ret;
@@ -1119,34 +1132,39 @@ static int rtw89_wow_cfg_wake_pno(struct rtw89_dev *rtwdev, bool wow)
static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link;
struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
struct ieee80211_sta *wow_sta;
struct rtw89_sta *rtwsta = NULL;
struct rtw89_sta_link *rtwsta_link = NULL;
struct rtw89_sta *rtwsta;
int ret;
wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid);
if (wow_sta)
rtwsta = (struct rtw89_sta *)wow_sta->drv_priv;
wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr);
if (wow_sta) {
rtwsta = sta_to_rtwsta(wow_sta);
rtwsta_link = rtwsta->links[rtwvif_link->link_id];
if (!rtwsta_link)
return -ENOLINK;
}
if (wow) {
if (rtw_wow->pattern_cnt)
rtwvif->wowlan_pattern = true;
rtwvif_link->wowlan_pattern = true;
if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags))
rtwvif->wowlan_magic = true;
rtwvif_link->wowlan_magic = true;
} else {
rtwvif->wowlan_pattern = false;
rtwvif->wowlan_magic = false;
rtwvif_link->wowlan_pattern = false;
rtwvif_link->wowlan_magic = false;
}
ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif, wow);
ret = rtw89_fw_h2c_wow_wakeup_ctrl(rtwdev, rtwvif_link, wow);
if (ret) {
rtw89_err(rtwdev, "failed to fw wow wakeup ctrl\n");
return ret;
}
if (wow) {
ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif_link, rtwsta_link);
if (ret) {
rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n",
ret);
@@ -1154,13 +1172,13 @@ static int rtw89_wow_cfg_wake(struct rtw89_dev *rtwdev, bool wow)
}
}
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cam\n");
return ret;
}
ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif, wow);
ret = rtw89_fw_h2c_wow_global(rtwdev, rtwvif_link, wow);
if (ret) {
rtw89_err(rtwdev, "failed to fw wow global\n");
return ret;
@@ -1190,25 +1208,30 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
enum rtw89_fw_type fw_type = wow ? RTW89_FW_WOWLAN : RTW89_FW_NORMAL;
enum rtw89_chip_gen chip_gen = rtwdev->chip->chip_gen;
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link;
struct ieee80211_vif *wow_vif = rtwvif_link_to_vif(rtwvif_link);
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
const struct rtw89_chip_info *chip = rtwdev->chip;
bool include_bb = !!chip->bbmcu_nr;
bool disable_intr_for_dlfw = false;
struct ieee80211_sta *wow_sta;
struct rtw89_sta *rtwsta = NULL;
struct rtw89_sta_link *rtwsta_link = NULL;
struct rtw89_sta *rtwsta;
bool is_conn = true;
int ret;
if (chip_id == RTL8852C || chip_id == RTL8922A)
disable_intr_for_dlfw = true;
wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid);
if (wow_sta)
rtwsta = (struct rtw89_sta *)wow_sta->drv_priv;
else
wow_sta = ieee80211_find_sta(wow_vif, wow_vif->cfg.ap_addr);
if (wow_sta) {
rtwsta = sta_to_rtwsta(wow_sta);
rtwsta_link = rtwsta->links[rtwvif_link->link_id];
if (!rtwsta_link)
return -ENOLINK;
} else {
is_conn = false;
}
if (disable_intr_for_dlfw)
rtw89_hci_disable_intr(rtwdev);
@@ -1224,14 +1247,14 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
rtw89_phy_init_rf_reg(rtwdev, true);
ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta,
ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif_link, rtwsta_link,
RTW89_ROLE_FW_RESTORE);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c role maintain\n");
return ret;
}
ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, wow_vif, wow_sta);
ret = rtw89_chip_h2c_assoc_cmac_tbl(rtwdev, rtwvif_link, rtwsta_link);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c assoc cmac tbl\n");
return ret;
@@ -1240,27 +1263,27 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
if (!is_conn)
rtw89_cam_reset_keys(rtwdev);
ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif, rtwsta, !is_conn);
ret = rtw89_fw_h2c_join_info(rtwdev, rtwvif_link, rtwsta_link, !is_conn);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c join info\n");
return ret;
}
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
ret = rtw89_fw_h2c_cam(rtwdev, rtwvif_link, rtwsta_link, NULL);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c cam\n");
return ret;
}
if (is_conn) {
ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif, rtwsta->mac_id);
ret = rtw89_fw_h2c_general_pkt(rtwdev, rtwvif_link, rtwsta_link->mac_id);
if (ret) {
rtw89_warn(rtwdev, "failed to send h2c general packet\n");
return ret;
}
rtw89_phy_ra_assoc(rtwdev, wow_sta);
rtw89_phy_set_bss_color(rtwdev, wow_vif);
rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, wow_vif);
rtw89_phy_ra_assoc(rtwdev, rtwsta_link);
rtw89_phy_set_bss_color(rtwdev, rtwvif_link);
rtw89_chip_cfg_txpwr_ul_tb_offset(rtwdev, rtwvif_link);
}
if (chip_gen == RTW89_CHIP_BE)
@@ -1363,21 +1386,20 @@ static int rtw89_wow_disable_trx_pre(struct rtw89_dev *rtwdev)
static int rtw89_wow_disable_trx_post(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct ieee80211_vif *vif = rtw_wow->wow_vif;
struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
int ret;
ret = rtw89_mac_cfg_ppdu_status(rtwdev, RTW89_MAC_0, true);
if (ret)
rtw89_err(rtwdev, "cfg ppdu status\n");
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, vif, true);
rtw89_fw_h2c_set_bcn_fltr_cfg(rtwdev, rtwvif_link, true);
return ret;
}
static void rtw89_fw_release_pno_pkt_list(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif)
struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct list_head *pkt_list = &rtw_wow->pno_pkt_list;
@@ -1391,7 +1413,7 @@ static void rtw89_fw_release_pno_pkt_list(struct rtw89_dev *rtwdev,
}
static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev,
struct rtw89_vif *rtwvif)
struct rtw89_vif_link *rtwvif_link)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct cfg80211_sched_scan_request *nd_config = rtw_wow->nd_config;
@@ -1401,7 +1423,7 @@ static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev,
int ret;
for (i = 0; i < num; i++) {
skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr,
skb = ieee80211_probereq_get(rtwdev->hw, rtwvif_link->mac_addr,
nd_config->match_sets[i].ssid.ssid,
nd_config->match_sets[i].ssid.ssid_len,
nd_config->ie_len);
@@ -1413,7 +1435,7 @@ static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev,
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
kfree_skb(skb);
rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif);
rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link);
return -ENOMEM;
}
@@ -1421,7 +1443,7 @@ static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev,
if (ret) {
kfree_skb(skb);
kfree(info);
rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif);
rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link);
return ret;
}
@@ -1436,20 +1458,19 @@ static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
int interval = rtw_wow->nd_config->scan_plans[0].interval;
struct rtw89_scan_option opt = {};
int ret;
if (enable) {
ret = rtw89_pno_scan_update_probe_req(rtwdev, rtwvif);
ret = rtw89_pno_scan_update_probe_req(rtwdev, rtwvif_link);
if (ret) {
rtw89_err(rtwdev, "Update probe request failed\n");
return ret;
}
ret = mac->add_chan_list_pno(rtwdev, rtwvif);
ret = mac->add_chan_list_pno(rtwdev, rtwvif_link);
if (ret) {
rtw89_err(rtwdev, "Update channel list failed\n");
return ret;
@@ -1471,7 +1492,7 @@ static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable)
opt.opch_end = RTW89_CHAN_INVALID;
}
mac->scan_offload(rtwdev, &opt, rtwvif, true);
mac->scan_offload(rtwdev, &opt, rtwvif_link, true);
return 0;
}
@@ -1479,8 +1500,7 @@ static int rtw89_pno_scan_offload(struct rtw89_dev *rtwdev, bool enable)
static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link;
int ret;
if (rtw89_wow_no_link(rtwdev)) {
@@ -1499,25 +1519,25 @@ static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev)
rtw89_wow_pattern_write(rtwdev);
rtw89_wow_construct_key_info(rtwdev);
ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, true);
ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif_link, true);
if (ret) {
rtw89_err(rtwdev, "wow: failed to enable keep alive\n");
return ret;
}
ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, true);
ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif_link, true);
if (ret) {
rtw89_err(rtwdev, "wow: failed to enable disconnect detect\n");
return ret;
}
ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif, true);
ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif_link, true);
if (ret) {
rtw89_err(rtwdev, "wow: failed to enable GTK offload\n");
return ret;
}
ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif, true);
ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif_link, true);
if (ret)
rtw89_warn(rtwdev, "wow: failed to enable arp offload\n");
}
@@ -1548,8 +1568,7 @@ static int rtw89_wow_fw_start(struct rtw89_dev *rtwdev)
static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
struct rtw89_vif_link *rtwvif_link = rtw_wow->rtwvif_link;
int ret;
if (rtw89_wow_no_link(rtwdev)) {
@@ -1559,35 +1578,35 @@ static int rtw89_wow_fw_stop(struct rtw89_dev *rtwdev)
return ret;
}
ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif, false);
ret = rtw89_fw_h2c_cfg_pno(rtwdev, rtwvif_link, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable pno\n");
return ret;
}
rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif);
rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link);
} else {
rtw89_wow_pattern_clear(rtwdev);
ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif, false);
ret = rtw89_fw_h2c_keep_alive(rtwdev, rtwvif_link, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable keep alive\n");
return ret;
}
ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif, false);
ret = rtw89_fw_h2c_disconnect_detect(rtwdev, rtwvif_link, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable disconnect detect\n");
return ret;
}
ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif, false);
ret = rtw89_fw_h2c_wow_gtk_ofld(rtwdev, rtwvif_link, false);
if (ret) {
rtw89_err(rtwdev, "wow: failed to disable GTK offload\n");
return ret;
}
ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif, false);
ret = rtw89_fw_h2c_arp_offload(rtwdev, rtwvif_link, false);
if (ret)
rtw89_warn(rtwdev, "wow: failed to disable arp offload\n");

View File

@@ -97,18 +97,16 @@ static inline int rtw89_wow_get_sec_hdr_len(struct rtw89_dev *rtwdev)
#ifdef CONFIG_PM
static inline bool rtw89_wow_mgd_linked(struct rtw89_dev *rtwdev)
{
struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
return rtwvif->net_type == RTW89_NET_TYPE_INFRA;
return rtwvif_link->net_type == RTW89_NET_TYPE_INFRA;
}
static inline bool rtw89_wow_no_link(struct rtw89_dev *rtwdev)
{
struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
return rtwvif->net_type == RTW89_NET_TYPE_NO_LINK;
return rtwvif_link->net_type == RTW89_NET_TYPE_NO_LINK;
}
static inline bool rtw_wow_has_mgd_features(struct rtw89_dev *rtwdev)