mac80211: allow to transmit A-MSDU within A-MPDU
Advertise the capability to send A-MSDU within A-MPDU in the AddBA request sent by mac80211. Let the driver know about the peer's capabilities. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
1b09b5568e
commit
e3abc8ff0f
@ -6144,7 +6144,7 @@ static int ath10k_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||
u8 buf_size)
|
||||
u8 buf_size, bool amsdu)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
|
||||
|
@ -1659,7 +1659,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta,
|
||||
u16 tid, u16 *ssn, u8 buf_size)
|
||||
u16 tid, u16 *ssn, u8 buf_size, bool amsdu)
|
||||
{
|
||||
struct ath9k_htc_priv *priv = hw->priv;
|
||||
struct ath9k_htc_sta *ista;
|
||||
|
@ -1856,7 +1856,7 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta,
|
||||
u16 tid, u16 *ssn, u8 buf_size)
|
||||
u16 tid, u16 *ssn, u8 buf_size, bool amsdu)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
|
@ -1415,7 +1415,7 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta,
|
||||
u16 tid, u16 *ssn, u8 buf_size)
|
||||
u16 tid, u16 *ssn, u8 buf_size, bool amsdu)
|
||||
{
|
||||
struct ar9170 *ar = hw->priv;
|
||||
struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
|
||||
|
@ -859,7 +859,7 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||
u8 buf_size)
|
||||
u8 buf_size, bool amsdu)
|
||||
{
|
||||
struct wcn36xx *wcn = hw->priv;
|
||||
struct wcn36xx_sta *sta_priv = NULL;
|
||||
|
@ -820,7 +820,7 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||
u8 buf_size)
|
||||
u8 buf_size, bool amsdu)
|
||||
{
|
||||
struct brcms_info *wl = hw->priv;
|
||||
struct scb *scb = &wl->wlc->pri_scb;
|
||||
|
@ -2137,7 +2137,7 @@ int cw1200_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||
u8 buf_size)
|
||||
u8 buf_size, bool amsdu)
|
||||
{
|
||||
/* Aggregation is implemented fully in firmware,
|
||||
* including block ack negotiation. Do not allow
|
||||
|
@ -111,7 +111,7 @@ int cw1200_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||
u8 buf_size);
|
||||
u8 buf_size, bool amsdu);
|
||||
|
||||
void cw1200_suspend_resume(struct cw1200_common *priv,
|
||||
struct wsm_suspend_resume *arg);
|
||||
|
@ -5984,7 +5984,7 @@ int
|
||||
il4965_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 * ssn,
|
||||
u8 buf_size)
|
||||
u8 buf_size, bool amsdu)
|
||||
{
|
||||
struct il_priv *il = hw->priv;
|
||||
int ret = -EINVAL;
|
||||
|
@ -184,7 +184,7 @@ void il4965_mac_update_tkip_key(struct ieee80211_hw *hw,
|
||||
int il4965_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 * ssn,
|
||||
u8 buf_size);
|
||||
u8 buf_size, bool amsdu);
|
||||
int il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta);
|
||||
void
|
||||
|
@ -731,7 +731,7 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||
u8 buf_size)
|
||||
u8 buf_size, bool amsdu)
|
||||
{
|
||||
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
|
||||
int ret = -EINVAL;
|
||||
|
@ -820,7 +820,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid,
|
||||
u16 *ssn, u8 buf_size)
|
||||
u16 *ssn, u8 buf_size, bool amsdu)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
int ret;
|
||||
|
@ -1819,7 +1819,7 @@ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||
u8 buf_size)
|
||||
u8 buf_size, bool amsdu)
|
||||
{
|
||||
switch (action) {
|
||||
case IEEE80211_AMPDU_TX_START:
|
||||
|
@ -335,7 +335,8 @@ static int mt7601u_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
static int
|
||||
mt76_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size)
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size,
|
||||
bool amsdu)
|
||||
{
|
||||
struct mt7601u_dev *dev = hw->priv;
|
||||
struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv;
|
||||
|
@ -5423,7 +5423,7 @@ static int
|
||||
mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||
u8 buf_size)
|
||||
u8 buf_size, bool amsdu)
|
||||
{
|
||||
|
||||
int i, rc = 0;
|
||||
|
@ -664,6 +664,7 @@ static int rsi_mac80211_set_key(struct ieee80211_hw *hw,
|
||||
* @tid: Traffic identifier.
|
||||
* @ssn: Pointer to ssn value.
|
||||
* @buf_size: Buffer size (for kernel version > 2.6.38).
|
||||
* @amsdu: is AMSDU in AMPDU allowed
|
||||
*
|
||||
* Return: status: 0 on success, negative error code on failure.
|
||||
*/
|
||||
@ -673,7 +674,8 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
unsigned short tid,
|
||||
unsigned short *ssn,
|
||||
unsigned char buf_size)
|
||||
unsigned char buf_size,
|
||||
bool amsdu)
|
||||
{
|
||||
int status = -EOPNOTSUPP;
|
||||
struct rsi_hw *adapter = hw->priv;
|
||||
|
@ -7937,7 +7937,7 @@ EXPORT_SYMBOL_GPL(rt2800_get_tsf);
|
||||
int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||
u8 buf_size)
|
||||
u8 buf_size, bool amsdu)
|
||||
{
|
||||
struct rt2x00_sta *sta_priv = (struct rt2x00_sta *)sta->drv_priv;
|
||||
int ret = 0;
|
||||
|
@ -220,7 +220,7 @@ u64 rt2800_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
|
||||
int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||
u8 buf_size);
|
||||
u8 buf_size, bool amsdu);
|
||||
int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
|
||||
struct survey_info *survey);
|
||||
void rt2800_disable_wpdma(struct rt2x00_dev *rt2x00dev);
|
||||
|
@ -1373,7 +1373,7 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||
u8 buf_size)
|
||||
u8 buf_size, bool amsdu)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
|
@ -5263,7 +5263,7 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||
u8 buf_size)
|
||||
u8 buf_size, bool amsdu)
|
||||
{
|
||||
struct wl1271 *wl = hw->priv;
|
||||
struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
|
||||
|
@ -1379,6 +1379,7 @@ struct ieee80211_ht_operation {
|
||||
|
||||
|
||||
/* block-ack parameters */
|
||||
#define IEEE80211_ADDBA_PARAM_AMSDU_MASK 0x0001
|
||||
#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
|
||||
#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
|
||||
#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFC0
|
||||
|
@ -3026,6 +3026,9 @@ enum ieee80211_reconfig_type {
|
||||
* buffer size of 8. Correct ways to retransmit #1 would be:
|
||||
* - TX: 1 or 18 or 81
|
||||
* Even "189" would be wrong since 1 could be lost again.
|
||||
* The @amsdu parameter is valid when the action is set to
|
||||
* %IEEE80211_AMPDU_TX_OPERATIONAL and indicates the peer's ability
|
||||
* to receive A-MSDU within A-MPDU.
|
||||
*
|
||||
* Returns a negative error code on failure.
|
||||
* The callback can sleep.
|
||||
@ -3363,7 +3366,7 @@ struct ieee80211_ops {
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||
u8 buf_size);
|
||||
u8 buf_size, bool amsdu);
|
||||
int (*get_survey)(struct ieee80211_hw *hw, int idx,
|
||||
struct survey_info *survey);
|
||||
void (*rfkill_poll)(struct ieee80211_hw *hw);
|
||||
|
@ -79,7 +79,7 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
|
||||
(int)reason);
|
||||
|
||||
if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP,
|
||||
&sta->sta, tid, NULL, 0))
|
||||
&sta->sta, tid, NULL, 0, false))
|
||||
sdata_info(sta->sdata,
|
||||
"HW problem - can not stop rx aggregation for %pM tid %d\n",
|
||||
sta->sta.addr, tid);
|
||||
@ -321,7 +321,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
||||
__skb_queue_head_init(&tid_agg_rx->reorder_buf[i]);
|
||||
|
||||
ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START,
|
||||
&sta->sta, tid, &start_seq_num, 0);
|
||||
&sta->sta, tid, &start_seq_num, 0, false);
|
||||
ht_dbg(sta->sdata, "Rx A-MPDU request on %pM tid %d result %d\n",
|
||||
sta->sta.addr, tid, ret);
|
||||
if (ret) {
|
||||
|
@ -97,7 +97,8 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
|
||||
mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
|
||||
|
||||
mgmt->u.action.u.addba_req.dialog_token = dialog_token;
|
||||
capab = (u16)(1 << 1); /* bit 1 aggregation policy */
|
||||
capab = (u16)(1 << 0); /* bit 0 A-MSDU support */
|
||||
capab |= (u16)(1 << 1); /* bit 1 aggregation policy */
|
||||
capab |= (u16)(tid << 2); /* bit 5:2 TID number */
|
||||
capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */
|
||||
|
||||
@ -331,7 +332,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
|
||||
return -EALREADY;
|
||||
ret = drv_ampdu_action(local, sta->sdata,
|
||||
IEEE80211_AMPDU_TX_STOP_FLUSH_CONT,
|
||||
&sta->sta, tid, NULL, 0);
|
||||
&sta->sta, tid, NULL, 0, false);
|
||||
WARN_ON_ONCE(ret);
|
||||
return 0;
|
||||
}
|
||||
@ -381,7 +382,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
|
||||
tid_tx->tx_stop = reason == AGG_STOP_LOCAL_REQUEST;
|
||||
|
||||
ret = drv_ampdu_action(local, sta->sdata, action,
|
||||
&sta->sta, tid, NULL, 0);
|
||||
&sta->sta, tid, NULL, 0, false);
|
||||
|
||||
/* HW shall not deny going back to legacy */
|
||||
if (WARN_ON(ret)) {
|
||||
@ -469,7 +470,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
|
||||
start_seq_num = sta->tid_seq[tid] >> 4;
|
||||
|
||||
ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START,
|
||||
&sta->sta, tid, &start_seq_num, 0);
|
||||
&sta->sta, tid, &start_seq_num, 0, false);
|
||||
if (ret) {
|
||||
ht_dbg(sdata,
|
||||
"BA request denied - HW unavailable for %pM tid %d\n",
|
||||
@ -693,7 +694,8 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
|
||||
|
||||
drv_ampdu_action(local, sta->sdata,
|
||||
IEEE80211_AMPDU_TX_OPERATIONAL,
|
||||
&sta->sta, tid, NULL, tid_tx->buf_size);
|
||||
&sta->sta, tid, NULL, tid_tx->buf_size,
|
||||
tid_tx->amsdu);
|
||||
|
||||
/*
|
||||
* synchronize with TX path, while splicing the TX path
|
||||
@ -918,8 +920,10 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
|
||||
struct tid_ampdu_tx *tid_tx;
|
||||
u16 capab, tid;
|
||||
u8 buf_size;
|
||||
bool amsdu;
|
||||
|
||||
capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
|
||||
amsdu = capab & IEEE80211_ADDBA_PARAM_AMSDU_MASK;
|
||||
tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
|
||||
buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
|
||||
|
||||
@ -968,6 +972,7 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
|
||||
}
|
||||
|
||||
tid_tx->buf_size = buf_size;
|
||||
tid_tx->amsdu = amsdu;
|
||||
|
||||
if (test_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))
|
||||
ieee80211_agg_tx_operational(local, sta, tid);
|
||||
|
@ -734,7 +734,7 @@ static inline int drv_ampdu_action(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid,
|
||||
u16 *ssn, u8 buf_size)
|
||||
u16 *ssn, u8 buf_size, bool amsdu)
|
||||
{
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
@ -744,11 +744,12 @@ static inline int drv_ampdu_action(struct ieee80211_local *local,
|
||||
if (!check_sdata_in_driver(sdata))
|
||||
return -EIO;
|
||||
|
||||
trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size);
|
||||
trace_drv_ampdu_action(local, sdata, action, sta, tid,
|
||||
ssn, buf_size, amsdu);
|
||||
|
||||
if (local->ops->ampdu_action)
|
||||
ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
|
||||
sta, tid, ssn, buf_size);
|
||||
sta, tid, ssn, buf_size, amsdu);
|
||||
|
||||
trace_drv_return_int(local, ret);
|
||||
|
||||
|
@ -133,6 +133,7 @@ enum ieee80211_agg_stop_reason {
|
||||
* @buf_size: reorder buffer size at receiver
|
||||
* @failed_bar_ssn: ssn of the last failed BAR tx attempt
|
||||
* @bar_pending: BAR needs to be re-sent
|
||||
* @amsdu: support A-MSDU withing A-MDPU
|
||||
*
|
||||
* This structure's lifetime is managed by RCU, assignments to
|
||||
* the array holding it must hold the aggregation mutex.
|
||||
@ -158,6 +159,7 @@ struct tid_ampdu_tx {
|
||||
|
||||
u16 failed_bar_ssn;
|
||||
bool bar_pending;
|
||||
bool amsdu;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -974,9 +974,9 @@ TRACE_EVENT(drv_ampdu_action,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid,
|
||||
u16 *ssn, u8 buf_size),
|
||||
u16 *ssn, u8 buf_size, bool amsdu),
|
||||
|
||||
TP_ARGS(local, sdata, action, sta, tid, ssn, buf_size),
|
||||
TP_ARGS(local, sdata, action, sta, tid, ssn, buf_size, amsdu),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
LOCAL_ENTRY
|
||||
@ -985,6 +985,7 @@ TRACE_EVENT(drv_ampdu_action,
|
||||
__field(u16, tid)
|
||||
__field(u16, ssn)
|
||||
__field(u8, buf_size)
|
||||
__field(bool, amsdu)
|
||||
VIF_ENTRY
|
||||
),
|
||||
|
||||
@ -996,12 +997,13 @@ TRACE_EVENT(drv_ampdu_action,
|
||||
__entry->tid = tid;
|
||||
__entry->ssn = ssn ? *ssn : 0;
|
||||
__entry->buf_size = buf_size;
|
||||
__entry->amsdu = amsdu;
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " action:%d tid:%d buf:%d",
|
||||
LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " action:%d tid:%d buf:%d amsdu:%d",
|
||||
LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->action,
|
||||
__entry->tid, __entry->buf_size
|
||||
__entry->tid, __entry->buf_size, __entry->amsdu
|
||||
)
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user