rtw88: configure TX queue EDCA parameters
Set CWmax/CWmin, TXOP and AIFS according to ieee80211_tx_queue_params. Do note that hardware has only one group of EDCA[ac] registers, if more than one vif are added, the EDCA[ac] registers will contain value of params of the most recent set by ieee80211_ops::conf_tx(). And AIFS = AIFSN[ac] * slot_time + SIFS, so if use_short_slot is changed, need to also change AIFS. Signed-off-by: Yan-Hsuan Chuang <yhchuang@realtek.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
0649ff58a0
commit
bf06c7ec45
|
@ -269,6 +269,54 @@ static void rtw_ops_configure_filter(struct ieee80211_hw *hw,
|
|||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
/* Only have one group of EDCA parameters now */
|
||||
static const u32 ac_to_edca_param[IEEE80211_NUM_ACS] = {
|
||||
[IEEE80211_AC_VO] = REG_EDCA_VO_PARAM,
|
||||
[IEEE80211_AC_VI] = REG_EDCA_VI_PARAM,
|
||||
[IEEE80211_AC_BE] = REG_EDCA_BE_PARAM,
|
||||
[IEEE80211_AC_BK] = REG_EDCA_BK_PARAM,
|
||||
};
|
||||
|
||||
static u8 rtw_aifsn_to_aifs(struct rtw_dev *rtwdev,
|
||||
struct rtw_vif *rtwvif, u8 aifsn)
|
||||
{
|
||||
struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
|
||||
u8 slot_time;
|
||||
u8 sifs;
|
||||
|
||||
slot_time = vif->bss_conf.use_short_slot ? 9 : 20;
|
||||
sifs = rtwdev->hal.current_band_type == RTW_BAND_5G ? 16 : 10;
|
||||
|
||||
return aifsn * slot_time + sifs;
|
||||
}
|
||||
|
||||
static void __rtw_conf_tx(struct rtw_dev *rtwdev,
|
||||
struct rtw_vif *rtwvif, u16 ac)
|
||||
{
|
||||
struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
|
||||
u32 edca_param = ac_to_edca_param[ac];
|
||||
u8 ecw_max, ecw_min;
|
||||
u8 aifs;
|
||||
|
||||
/* 2^ecw - 1 = cw; ecw = log2(cw + 1) */
|
||||
ecw_max = ilog2(params->cw_max + 1);
|
||||
ecw_min = ilog2(params->cw_min + 1);
|
||||
aifs = rtw_aifsn_to_aifs(rtwdev, rtwvif, params->aifs);
|
||||
rtw_write32_mask(rtwdev, edca_param, BIT_MASK_TXOP_LMT, params->txop);
|
||||
rtw_write32_mask(rtwdev, edca_param, BIT_MASK_CWMAX, ecw_max);
|
||||
rtw_write32_mask(rtwdev, edca_param, BIT_MASK_CWMIN, ecw_min);
|
||||
rtw_write32_mask(rtwdev, edca_param, BIT_MASK_AIFS, aifs);
|
||||
}
|
||||
|
||||
static void rtw_conf_tx(struct rtw_dev *rtwdev,
|
||||
struct rtw_vif *rtwvif)
|
||||
{
|
||||
u16 ac;
|
||||
|
||||
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
|
||||
__rtw_conf_tx(rtwdev, rtwvif, ac);
|
||||
}
|
||||
|
||||
static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *conf,
|
||||
|
@ -320,11 +368,33 @@ static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
|
|||
if (changed & BSS_CHANGED_BEACON)
|
||||
rtw_fw_download_rsvd_page(rtwdev, vif);
|
||||
|
||||
if (changed & BSS_CHANGED_ERP_SLOT)
|
||||
rtw_conf_tx(rtwdev, rtwvif);
|
||||
|
||||
rtw_vif_port_config(rtwdev, rtwvif, config);
|
||||
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
}
|
||||
|
||||
static int rtw_ops_conf_tx(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif, u16 ac,
|
||||
const struct ieee80211_tx_queue_params *params)
|
||||
{
|
||||
struct rtw_dev *rtwdev = hw->priv;
|
||||
struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
|
||||
|
||||
mutex_lock(&rtwdev->mutex);
|
||||
|
||||
rtw_leave_lps_deep(rtwdev);
|
||||
|
||||
rtwvif->tx_params[ac] = *params;
|
||||
__rtw_conf_tx(rtwdev, rtwvif, ac);
|
||||
|
||||
mutex_unlock(&rtwdev->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
|
||||
{
|
||||
unsigned long mac_id;
|
||||
|
@ -612,6 +682,7 @@ const struct ieee80211_ops rtw_ops = {
|
|||
.remove_interface = rtw_ops_remove_interface,
|
||||
.configure_filter = rtw_ops_configure_filter,
|
||||
.bss_info_changed = rtw_ops_bss_info_changed,
|
||||
.conf_tx = rtw_ops_conf_tx,
|
||||
.sta_add = rtw_ops_sta_add,
|
||||
.sta_remove = rtw_ops_sta_remove,
|
||||
.set_key = rtw_ops_set_key,
|
||||
|
|
|
@ -641,6 +641,7 @@ struct rtw_vif {
|
|||
u8 bssid[ETH_ALEN];
|
||||
u8 port;
|
||||
u8 bcn_ctrl;
|
||||
struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS];
|
||||
const struct rtw_vif_port *conf;
|
||||
|
||||
struct rtw_traffic_stats stats;
|
||||
|
@ -1432,6 +1433,13 @@ static inline struct ieee80211_txq *rtwtxq_to_txq(struct rtw_txq *rtwtxq)
|
|||
return container_of(p, struct ieee80211_txq, drv_priv);
|
||||
}
|
||||
|
||||
static inline struct ieee80211_vif *rtwvif_to_vif(struct rtw_vif *rtwvif)
|
||||
{
|
||||
void *p = rtwvif;
|
||||
|
||||
return container_of(p, struct ieee80211_vif, drv_priv);
|
||||
}
|
||||
|
||||
void rtw_get_channel_params(struct cfg80211_chan_def *chandef,
|
||||
struct rtw_channel_params *ch_param);
|
||||
bool check_hw_ready(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target);
|
||||
|
|
|
@ -239,6 +239,10 @@
|
|||
#define REG_EDCA_VI_PARAM 0x0504
|
||||
#define REG_EDCA_BE_PARAM 0x0508
|
||||
#define REG_EDCA_BK_PARAM 0x050C
|
||||
#define BIT_MASK_TXOP_LMT GENMASK(26, 16)
|
||||
#define BIT_MASK_CWMAX GENMASK(15, 12)
|
||||
#define BIT_MASK_CWMIN GENMASK(11, 8)
|
||||
#define BIT_MASK_AIFS GENMASK(7, 0)
|
||||
#define REG_PIFS 0x0512
|
||||
#define REG_SIFS 0x0514
|
||||
#define BIT_SHIFT_SIFS_OFDM_CTX 8
|
||||
|
|
Loading…
Reference in New Issue