mirror of https://gitee.com/openkylin/linux.git
iwlwifi: mvm: support offload of AMSDU rate control
Support the new APIs and activate AMSDU based on the offloaded TLC decisions. Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:
parent
cf58c9e091
commit
84226ca1c5
|
@ -92,6 +92,11 @@ enum iwl_data_path_subcmd_ids {
|
||||||
*/
|
*/
|
||||||
TLC_MNG_NOTIF_REQ_CMD = 0x10,
|
TLC_MNG_NOTIF_REQ_CMD = 0x10,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @TLC_MNG_AMSDU_ENABLE_NOTIF: &struct iwl_tlc_amsdu_notif
|
||||||
|
*/
|
||||||
|
TLC_MNG_AMSDU_ENABLE_NOTIF = 0xF6,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @TLC_MNG_UPDATE_NOTIF: &struct iwl_tlc_update_notif
|
* @TLC_MNG_UPDATE_NOTIF: &struct iwl_tlc_update_notif
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -205,7 +205,7 @@ enum iwl_tlc_mng_ht_rates {
|
||||||
* @non_ht_supp_rates: bitmap of supported legacy rates
|
* @non_ht_supp_rates: bitmap of supported legacy rates
|
||||||
* @ht_supp_rates: bitmap of supported HT/VHT rates, valid bits are 0-9
|
* @ht_supp_rates: bitmap of supported HT/VHT rates, valid bits are 0-9
|
||||||
* @mode: &enum iwl_tlc_mng_cfg_mode
|
* @mode: &enum iwl_tlc_mng_cfg_mode
|
||||||
* @reserved2: reserved
|
* @amsdu: TX amsdu is supported
|
||||||
* @he_supp_rates: bitmap of supported HE rates
|
* @he_supp_rates: bitmap of supported HE rates
|
||||||
* @sgi_ch_width_supp: bitmap of SGI support per channel width
|
* @sgi_ch_width_supp: bitmap of SGI support per channel width
|
||||||
* @he_gi_support: 11ax HE guard interval
|
* @he_gi_support: 11ax HE guard interval
|
||||||
|
@ -222,13 +222,27 @@ struct iwl_tlc_config_cmd {
|
||||||
__le16 non_ht_supp_rates;
|
__le16 non_ht_supp_rates;
|
||||||
__le16 ht_supp_rates[MAX_RS_ANT_NUM];
|
__le16 ht_supp_rates[MAX_RS_ANT_NUM];
|
||||||
u8 mode;
|
u8 mode;
|
||||||
u8 reserved2;
|
u8 amsdu;
|
||||||
__le16 he_supp_rates;
|
__le16 he_supp_rates;
|
||||||
u8 sgi_ch_width_supp;
|
u8 sgi_ch_width_supp;
|
||||||
u8 he_gi_support;
|
u8 he_gi_support;
|
||||||
__le32 max_ampdu_cnt;
|
__le32 max_ampdu_cnt;
|
||||||
} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_1 */
|
} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_1 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct iwl_tlc_amsdu_notif - TLC AMSDU configuration
|
||||||
|
* @sta_id: station id
|
||||||
|
* @reserved: reserved
|
||||||
|
* @amsdu_size: Max AMSDU size, in bytes
|
||||||
|
* @amsdu_enabled: bitmap for per-TID AMSDU enablement
|
||||||
|
*/
|
||||||
|
struct iwl_tlc_amsdu_notif {
|
||||||
|
u8 sta_id;
|
||||||
|
u8 reserved[3];
|
||||||
|
__le16 amsdu_size;
|
||||||
|
__le16 amsdu_enabled;
|
||||||
|
} __packed; /* TLC_MNG_AMSDU_ENABLE_NTFY_API_S_VER_1 */
|
||||||
|
|
||||||
#define IWL_TLC_NOTIF_INIT_RATE_POS 0
|
#define IWL_TLC_NOTIF_INIT_RATE_POS 0
|
||||||
#define IWL_TLC_NOTIF_INIT_RATE_MSK BIT(IWL_TLC_NOTIF_INIT_RATE_POS)
|
#define IWL_TLC_NOTIF_INIT_RATE_MSK BIT(IWL_TLC_NOTIF_INIT_RATE_POS)
|
||||||
#define IWL_TLC_NOTIF_REQ_INTERVAL (500)
|
#define IWL_TLC_NOTIF_REQ_INTERVAL (500)
|
||||||
|
|
|
@ -250,6 +250,9 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
|
||||||
RX_HANDLER(TX_CMD, iwl_mvm_rx_tx_cmd, RX_HANDLER_SYNC),
|
RX_HANDLER(TX_CMD, iwl_mvm_rx_tx_cmd, RX_HANDLER_SYNC),
|
||||||
RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, RX_HANDLER_SYNC),
|
RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, RX_HANDLER_SYNC),
|
||||||
|
|
||||||
|
RX_HANDLER_GRP(DATA_PATH_GROUP, TLC_MNG_UPDATE_NOTIF,
|
||||||
|
iwl_mvm_tlc_update_notif, RX_HANDLER_SYNC),
|
||||||
|
|
||||||
RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif,
|
RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif,
|
||||||
RX_HANDLER_ASYNC_LOCKED),
|
RX_HANDLER_ASYNC_LOCKED),
|
||||||
RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif,
|
RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif,
|
||||||
|
@ -309,6 +312,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
|
||||||
iwl_mvm_mu_mimo_grp_notif, RX_HANDLER_SYNC),
|
iwl_mvm_mu_mimo_grp_notif, RX_HANDLER_SYNC),
|
||||||
RX_HANDLER_GRP(DATA_PATH_GROUP, STA_PM_NOTIF,
|
RX_HANDLER_GRP(DATA_PATH_GROUP, STA_PM_NOTIF,
|
||||||
iwl_mvm_sta_pm_notif, RX_HANDLER_SYNC),
|
iwl_mvm_sta_pm_notif, RX_HANDLER_SYNC),
|
||||||
|
RX_HANDLER_GRP(DATA_PATH_GROUP, TLC_MNG_AMSDU_ENABLE_NOTIF,
|
||||||
|
iwl_mvm_tlc_amsdu_notif, RX_HANDLER_SYNC),
|
||||||
};
|
};
|
||||||
#undef RX_HANDLER
|
#undef RX_HANDLER
|
||||||
#undef RX_HANDLER_GRP
|
#undef RX_HANDLER_GRP
|
||||||
|
@ -445,6 +450,7 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
|
||||||
HCMD_NAME(DQA_ENABLE_CMD),
|
HCMD_NAME(DQA_ENABLE_CMD),
|
||||||
HCMD_NAME(UPDATE_MU_GROUPS_CMD),
|
HCMD_NAME(UPDATE_MU_GROUPS_CMD),
|
||||||
HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD),
|
HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD),
|
||||||
|
HCMD_NAME(TLC_MNG_AMSDU_ENABLE_NOTIF),
|
||||||
HCMD_NAME(STA_PM_NOTIF),
|
HCMD_NAME(STA_PM_NOTIF),
|
||||||
HCMD_NAME(MU_GROUP_MGMT_NOTIF),
|
HCMD_NAME(MU_GROUP_MGMT_NOTIF),
|
||||||
HCMD_NAME(RX_QUEUES_NOTIFICATION),
|
HCMD_NAME(RX_QUEUES_NOTIFICATION),
|
||||||
|
@ -1034,8 +1040,6 @@ static void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode,
|
||||||
iwl_mvm_rx_queue_notif(mvm, rxb, 0);
|
iwl_mvm_rx_queue_notif(mvm, rxb, 0);
|
||||||
else if (cmd == WIDE_ID(LEGACY_GROUP, FRAME_RELEASE))
|
else if (cmd == WIDE_ID(LEGACY_GROUP, FRAME_RELEASE))
|
||||||
iwl_mvm_rx_frame_release(mvm, napi, rxb, 0);
|
iwl_mvm_rx_frame_release(mvm, napi, rxb, 0);
|
||||||
else if (cmd == WIDE_ID(DATA_PATH_GROUP, TLC_MNG_UPDATE_NOTIF))
|
|
||||||
iwl_mvm_tlc_update_notif(mvm, pkt);
|
|
||||||
else
|
else
|
||||||
iwl_mvm_rx_common(mvm, rxb, pkt);
|
iwl_mvm_rx_common(mvm, rxb, pkt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,8 +228,47 @@ static void rs_fw_tlc_mng_notif_req_config(struct iwl_mvm *mvm, u8 sta_id)
|
||||||
IWL_ERR(mvm, "Failed to send TLC notif request (%d)\n", ret);
|
IWL_ERR(mvm, "Failed to send TLC notif request (%d)\n", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt)
|
void iwl_mvm_tlc_amsdu_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
|
||||||
{
|
{
|
||||||
|
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||||
|
struct iwl_tlc_amsdu_notif *notif;
|
||||||
|
struct ieee80211_sta *sta;
|
||||||
|
struct iwl_mvm_sta *mvmsta;
|
||||||
|
u16 size;
|
||||||
|
|
||||||
|
notif = (void *)pkt->data;
|
||||||
|
|
||||||
|
if (WARN_ON(notif->sta_id >= ARRAY_SIZE(mvm->fw_id_to_mac_id)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
|
||||||
|
sta = rcu_dereference(mvm->fw_id_to_mac_id[notif->sta_id]);
|
||||||
|
if (IS_ERR_OR_NULL(sta)) {
|
||||||
|
rcu_read_unlock();
|
||||||
|
IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n",
|
||||||
|
notif->sta_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||||
|
|
||||||
|
size = min(le16_to_cpu(notif->amsdu_size), sta->max_amsdu_len);
|
||||||
|
mvmsta->amsdu_enabled = le16_to_cpu(notif->amsdu_enabled);
|
||||||
|
mvmsta->max_amsdu_len = size;
|
||||||
|
|
||||||
|
IWL_DEBUG_RATE(mvm,
|
||||||
|
"AMSDU notification. AMSDU size: %d, AMSDU selected size: %d, AMSDU TID bitmap 0x%X\n",
|
||||||
|
le16_to_cpu(notif->amsdu_size), size,
|
||||||
|
mvmsta->amsdu_enabled);
|
||||||
|
|
||||||
|
rcu_read_unlock();
|
||||||
|
};
|
||||||
|
|
||||||
|
void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
|
||||||
|
struct iwl_rx_cmd_buffer *rxb)
|
||||||
|
{
|
||||||
|
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||||
struct iwl_tlc_update_notif *notif;
|
struct iwl_tlc_update_notif *notif;
|
||||||
struct iwl_mvm_sta *mvmsta;
|
struct iwl_mvm_sta *mvmsta;
|
||||||
struct iwl_lq_sta_rs_fw *lq_sta;
|
struct iwl_lq_sta_rs_fw *lq_sta;
|
||||||
|
@ -273,6 +312,7 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||||
.max_supp_ss = sta->rx_nss,
|
.max_supp_ss = sta->rx_nss,
|
||||||
.max_ampdu_cnt = cpu_to_le32(mvmsta->max_agg_bufsize),
|
.max_ampdu_cnt = cpu_to_le32(mvmsta->max_agg_bufsize),
|
||||||
.sgi_ch_width_supp = rs_fw_sgi_cw_support(sta),
|
.sgi_ch_width_supp = rs_fw_sgi_cw_support(sta),
|
||||||
|
.amsdu = iwl_mvm_is_csum_supported(mvm),
|
||||||
};
|
};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
|
@ -1715,12 +1715,18 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||||
{
|
{
|
||||||
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In case TLC offload is not active amsdu_enabled is either 0xFFFF
|
||||||
|
* or 0, since there is no per-TID alg.
|
||||||
|
*/
|
||||||
if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) ||
|
if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) ||
|
||||||
tbl->rate.index < IWL_RATE_MCS_5_INDEX ||
|
tbl->rate.index < IWL_RATE_MCS_5_INDEX ||
|
||||||
scale_action == RS_ACTION_DOWNSCALE)
|
scale_action == RS_ACTION_DOWNSCALE)
|
||||||
mvmsta->tlc_amsdu = false;
|
mvmsta->amsdu_enabled = 0;
|
||||||
else
|
else
|
||||||
mvmsta->tlc_amsdu = true;
|
mvmsta->amsdu_enabled = 0xFFFF;
|
||||||
|
|
||||||
|
mvmsta->max_amsdu_len = sta->max_amsdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3134,7 +3140,8 @@ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||||
sband = hw->wiphy->bands[band];
|
sband = hw->wiphy->bands[band];
|
||||||
|
|
||||||
lq_sta->lq.sta_id = mvmsta->sta_id;
|
lq_sta->lq.sta_id = mvmsta->sta_id;
|
||||||
mvmsta->tlc_amsdu = false;
|
mvmsta->amsdu_enabled = 0;
|
||||||
|
mvmsta->max_amsdu_len = sta->max_amsdu_len;
|
||||||
|
|
||||||
for (j = 0; j < LQ_SIZE; j++)
|
for (j = 0; j < LQ_SIZE; j++)
|
||||||
rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]);
|
rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]);
|
||||||
|
@ -3744,7 +3751,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
|
||||||
(rate->sgi) ? "SGI" : "NGI",
|
(rate->sgi) ? "SGI" : "NGI",
|
||||||
(rate->ldpc) ? "LDPC" : "BCC",
|
(rate->ldpc) ? "LDPC" : "BCC",
|
||||||
(lq_sta->is_agg) ? "AGG on" : "",
|
(lq_sta->is_agg) ? "AGG on" : "",
|
||||||
(mvmsta->tlc_amsdu) ? "AMSDU on" : "");
|
(mvmsta->amsdu_enabled) ? "AMSDU on" : "");
|
||||||
}
|
}
|
||||||
desc += scnprintf(buff + desc, bufsz - desc, "last tx rate=0x%X\n",
|
desc += scnprintf(buff + desc, bufsz - desc, "last tx rate=0x%X\n",
|
||||||
lq_sta->last_rate_n_flags);
|
lq_sta->last_rate_n_flags);
|
||||||
|
|
|
@ -454,5 +454,8 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||||
enum nl80211_band band);
|
enum nl80211_band band);
|
||||||
int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
|
int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
|
||||||
bool enable);
|
bool enable);
|
||||||
void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt);
|
void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
|
||||||
|
struct iwl_rx_cmd_buffer *rxb);
|
||||||
|
void iwl_mvm_tlc_amsdu_notif(struct iwl_mvm *mvm,
|
||||||
|
struct iwl_rx_cmd_buffer *rxb);
|
||||||
#endif /* __rs__ */
|
#endif /* __rs__ */
|
||||||
|
|
|
@ -391,7 +391,9 @@ struct iwl_mvm_rxq_dup_data {
|
||||||
* @tx_protection: reference counter for controlling the Tx protection.
|
* @tx_protection: reference counter for controlling the Tx protection.
|
||||||
* @tt_tx_protection: is thermal throttling enable Tx protection?
|
* @tt_tx_protection: is thermal throttling enable Tx protection?
|
||||||
* @disable_tx: is tx to this STA disabled?
|
* @disable_tx: is tx to this STA disabled?
|
||||||
* @tlc_amsdu: true if A-MSDU is allowed
|
* @amsdu_enabled: bitmap of TX AMSDU allowed TIDs.
|
||||||
|
* In case TLC offload is not active it is either 0xFFFF or 0.
|
||||||
|
* @max_amsdu_len: max AMSDU length
|
||||||
* @agg_tids: bitmap of tids whose status is operational aggregated (IWL_AGG_ON)
|
* @agg_tids: bitmap of tids whose status is operational aggregated (IWL_AGG_ON)
|
||||||
* @sleep_tx_count: the number of frames that we told the firmware to let out
|
* @sleep_tx_count: the number of frames that we told the firmware to let out
|
||||||
* even when that station is asleep. This is useful in case the queue
|
* even when that station is asleep. This is useful in case the queue
|
||||||
|
@ -436,7 +438,8 @@ struct iwl_mvm_sta {
|
||||||
bool tt_tx_protection;
|
bool tt_tx_protection;
|
||||||
|
|
||||||
bool disable_tx;
|
bool disable_tx;
|
||||||
bool tlc_amsdu;
|
u16 amsdu_enabled;
|
||||||
|
u16 max_amsdu_len;
|
||||||
bool sleeping;
|
bool sleeping;
|
||||||
bool associated;
|
bool associated;
|
||||||
u8 agg_tids;
|
u8 agg_tids;
|
||||||
|
|
|
@ -774,9 +774,9 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||||
|
|
||||||
dbg_max_amsdu_len = READ_ONCE(mvm->max_amsdu_len);
|
dbg_max_amsdu_len = READ_ONCE(mvm->max_amsdu_len);
|
||||||
|
|
||||||
if (!sta->max_amsdu_len ||
|
if (!mvmsta->max_amsdu_len ||
|
||||||
!ieee80211_is_data_qos(hdr->frame_control) ||
|
!ieee80211_is_data_qos(hdr->frame_control) ||
|
||||||
(!mvmsta->tlc_amsdu && !dbg_max_amsdu_len))
|
(!mvmsta->amsdu_enabled && !dbg_max_amsdu_len))
|
||||||
return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
|
return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -803,7 +803,12 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
|
||||||
!mvmsta->tid_data[tid].amsdu_in_ampdu_allowed)
|
!mvmsta->tid_data[tid].amsdu_in_ampdu_allowed)
|
||||||
return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
|
return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
|
||||||
|
|
||||||
max_amsdu_len = sta->max_amsdu_len;
|
if (iwl_mvm_vif_low_latency(iwl_mvm_vif_from_mac80211(mvmsta->vif)) ||
|
||||||
|
tid_to_mac80211_ac[tid] < IEEE80211_AC_BE ||
|
||||||
|
!(mvmsta->amsdu_enabled & BIT(tid)))
|
||||||
|
return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);
|
||||||
|
|
||||||
|
max_amsdu_len = mvmsta->max_amsdu_len;
|
||||||
|
|
||||||
/* the Tx FIFO to which this A-MSDU will be routed */
|
/* the Tx FIFO to which this A-MSDU will be routed */
|
||||||
txf = iwl_mvm_mac_ac_to_tx_fifo(mvm, tid_to_mac80211_ac[tid]);
|
txf = iwl_mvm_mac_ac_to_tx_fifo(mvm, tid_to_mac80211_ac[tid]);
|
||||||
|
|
Loading…
Reference in New Issue