diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-11-16 06:00:38 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-11-18 17:09:15 -0500 |
commit | c951ad3550ab40071bb0f222ba6125845769c08a (patch) | |
tree | 9db1d3c110b359a34a3d706eaf40285cfa01550b | |
parent | 3b53fde8ac40c4321389def14d7f4a9e14092fd3 (diff) |
mac80211: convert aggregation to operate on vifs/stas
The entire aggregation code currently operates on the
hw pointer and station addresses, but that needs to
change to make stations purely per-vif; As one step
preparing for that make the aggregation code callable
with the station, or by the combination of virtual
interface and station address.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ar9170/main.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/rc.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 8 | ||||
-rw-r--r-- | include/net/mac80211.h | 28 | ||||
-rw-r--r-- | net/mac80211/agg-rx.c | 6 | ||||
-rw-r--r-- | net/mac80211/agg-tx.c | 96 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 5 | ||||
-rw-r--r-- | net/mac80211/driver-trace.h | 9 | ||||
-rw-r--r-- | net/mac80211/ht.c | 3 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/main.c | 8 |
14 files changed, 84 insertions, 97 deletions
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index bd2a276c870a..f9d6db8d013e 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -2441,6 +2441,7 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
2441 | } | 2441 | } |
2442 | 2442 | ||
2443 | static int ar9170_ampdu_action(struct ieee80211_hw *hw, | 2443 | static int ar9170_ampdu_action(struct ieee80211_hw *hw, |
2444 | struct ieee80211_vif *vif, | ||
2444 | enum ieee80211_ampdu_mlme_action action, | 2445 | enum ieee80211_ampdu_mlme_action action, |
2445 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 2446 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) |
2446 | { | 2447 | { |
@@ -2470,7 +2471,7 @@ static int ar9170_ampdu_action(struct ieee80211_hw *hw, | |||
2470 | tid_info->state = AR9170_TID_STATE_PROGRESS; | 2471 | tid_info->state = AR9170_TID_STATE_PROGRESS; |
2471 | tid_info->active = false; | 2472 | tid_info->active = false; |
2472 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | 2473 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); |
2473 | ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 2474 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
2474 | break; | 2475 | break; |
2475 | 2476 | ||
2476 | case IEEE80211_AMPDU_TX_STOP: | 2477 | case IEEE80211_AMPDU_TX_STOP: |
@@ -2480,7 +2481,7 @@ static int ar9170_ampdu_action(struct ieee80211_hw *hw, | |||
2480 | tid_info->active = false; | 2481 | tid_info->active = false; |
2481 | skb_queue_purge(&tid_info->queue); | 2482 | skb_queue_purge(&tid_info->queue); |
2482 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | 2483 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); |
2483 | ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 2484 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
2484 | break; | 2485 | break; |
2485 | 2486 | ||
2486 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 2487 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3229c3993568..16bdb1b549b4 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -3078,6 +3078,7 @@ static void ath9k_reset_tsf(struct ieee80211_hw *hw) | |||
3078 | } | 3078 | } |
3079 | 3079 | ||
3080 | static int ath9k_ampdu_action(struct ieee80211_hw *hw, | 3080 | static int ath9k_ampdu_action(struct ieee80211_hw *hw, |
3081 | struct ieee80211_vif *vif, | ||
3081 | enum ieee80211_ampdu_mlme_action action, | 3082 | enum ieee80211_ampdu_mlme_action action, |
3082 | struct ieee80211_sta *sta, | 3083 | struct ieee80211_sta *sta, |
3083 | u16 tid, u16 *ssn) | 3084 | u16 tid, u16 *ssn) |
@@ -3095,11 +3096,11 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
3095 | break; | 3096 | break; |
3096 | case IEEE80211_AMPDU_TX_START: | 3097 | case IEEE80211_AMPDU_TX_START: |
3097 | ath_tx_aggr_start(sc, sta, tid, ssn); | 3098 | ath_tx_aggr_start(sc, sta, tid, ssn); |
3098 | ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 3099 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
3099 | break; | 3100 | break; |
3100 | case IEEE80211_AMPDU_TX_STOP: | 3101 | case IEEE80211_AMPDU_TX_STOP: |
3101 | ath_tx_aggr_stop(sc, sta, tid); | 3102 | ath_tx_aggr_stop(sc, sta, tid); |
3102 | ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); | 3103 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
3103 | break; | 3104 | break; |
3104 | case IEEE80211_AMPDU_TX_OPERATIONAL: | 3105 | case IEEE80211_AMPDU_TX_OPERATIONAL: |
3105 | ath_tx_aggr_resume(sc, sta, tid); | 3106 | ath_tx_aggr_resume(sc, sta, tid); |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index ea4b9081b4d0..1d96777b4cd2 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -1353,7 +1353,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1353 | an = (struct ath_node *)sta->drv_priv; | 1353 | an = (struct ath_node *)sta->drv_priv; |
1354 | 1354 | ||
1355 | if(ath_tx_aggr_check(sc, an, tid)) | 1355 | if(ath_tx_aggr_check(sc, an, tid)) |
1356 | ieee80211_start_tx_ba_session(sc->hw, hdr->addr1, tid); | 1356 | ieee80211_start_tx_ba_session(sta, tid); |
1357 | } | 1357 | } |
1358 | } | 1358 | } |
1359 | 1359 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 43edd8fd4405..2f09e3b7f0eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -301,7 +301,7 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, | |||
301 | if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { | 301 | if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { |
302 | IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", | 302 | IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", |
303 | sta->addr, tid); | 303 | sta->addr, tid); |
304 | ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid); | 304 | ieee80211_start_tx_ba_session(sta, tid); |
305 | } | 305 | } |
306 | } | 306 | } |
307 | 307 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 6385cdf24d13..b80cd0bc5845 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -2691,6 +2691,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2691 | } | 2691 | } |
2692 | 2692 | ||
2693 | static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, | 2693 | static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, |
2694 | struct ieee80211_vif *vif, | ||
2694 | enum ieee80211_ampdu_mlme_action action, | 2695 | enum ieee80211_ampdu_mlme_action action, |
2695 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 2696 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) |
2696 | { | 2697 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index ebfc460115d6..f3dff2ecc406 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -1312,7 +1312,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn) | |||
1312 | if (tid_data->tfds_in_queue == 0) { | 1312 | if (tid_data->tfds_in_queue == 0) { |
1313 | IWL_DEBUG_HT(priv, "HW queue is empty\n"); | 1313 | IWL_DEBUG_HT(priv, "HW queue is empty\n"); |
1314 | tid_data->agg.state = IWL_AGG_ON; | 1314 | tid_data->agg.state = IWL_AGG_ON; |
1315 | ieee80211_start_tx_ba_cb_irqsafe(priv->hw, ra, tid); | 1315 | ieee80211_start_tx_ba_cb_irqsafe(priv->vif, ra, tid); |
1316 | } else { | 1316 | } else { |
1317 | IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n", | 1317 | IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n", |
1318 | tid_data->tfds_in_queue); | 1318 | tid_data->tfds_in_queue); |
@@ -1377,7 +1377,7 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid) | |||
1377 | if (ret) | 1377 | if (ret) |
1378 | return ret; | 1378 | return ret; |
1379 | 1379 | ||
1380 | ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, ra, tid); | 1380 | ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid); |
1381 | 1381 | ||
1382 | return 0; | 1382 | return 0; |
1383 | } | 1383 | } |
@@ -1401,7 +1401,7 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id) | |||
1401 | priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, | 1401 | priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, |
1402 | ssn, tx_fifo); | 1402 | ssn, tx_fifo); |
1403 | tid_data->agg.state = IWL_AGG_OFF; | 1403 | tid_data->agg.state = IWL_AGG_OFF; |
1404 | ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, addr, tid); | 1404 | ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, addr, tid); |
1405 | } | 1405 | } |
1406 | break; | 1406 | break; |
1407 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | 1407 | case IWL_EMPTYING_HW_QUEUE_ADDBA: |
@@ -1409,7 +1409,7 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id) | |||
1409 | if (tid_data->tfds_in_queue == 0) { | 1409 | if (tid_data->tfds_in_queue == 0) { |
1410 | IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n"); | 1410 | IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n"); |
1411 | tid_data->agg.state = IWL_AGG_ON; | 1411 | tid_data->agg.state = IWL_AGG_ON; |
1412 | ieee80211_start_tx_ba_cb_irqsafe(priv->hw, addr, tid); | 1412 | ieee80211_start_tx_ba_cb_irqsafe(priv->vif, addr, tid); |
1413 | } | 1413 | } |
1414 | break; | 1414 | break; |
1415 | } | 1415 | } |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 3b3defbe6fc1..4af0ffb98aaf 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -1508,6 +1508,7 @@ struct ieee80211_ops { | |||
1508 | void (*reset_tsf)(struct ieee80211_hw *hw); | 1508 | void (*reset_tsf)(struct ieee80211_hw *hw); |
1509 | int (*tx_last_beacon)(struct ieee80211_hw *hw); | 1509 | int (*tx_last_beacon)(struct ieee80211_hw *hw); |
1510 | int (*ampdu_action)(struct ieee80211_hw *hw, | 1510 | int (*ampdu_action)(struct ieee80211_hw *hw, |
1511 | struct ieee80211_vif *vif, | ||
1511 | enum ieee80211_ampdu_mlme_action action, | 1512 | enum ieee80211_ampdu_mlme_action action, |
1512 | struct ieee80211_sta *sta, u16 tid, u16 *ssn); | 1513 | struct ieee80211_sta *sta, u16 tid, u16 *ssn); |
1513 | 1514 | ||
@@ -2029,8 +2030,7 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, | |||
2029 | 2030 | ||
2030 | /** | 2031 | /** |
2031 | * ieee80211_start_tx_ba_session - Start a tx Block Ack session. | 2032 | * ieee80211_start_tx_ba_session - Start a tx Block Ack session. |
2032 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | 2033 | * @sta: the station for which to start a BA session |
2033 | * @ra: receiver address of the BA session recipient | ||
2034 | * @tid: the TID to BA on. | 2034 | * @tid: the TID to BA on. |
2035 | * | 2035 | * |
2036 | * Return: success if addBA request was sent, failure otherwise | 2036 | * Return: success if addBA request was sent, failure otherwise |
@@ -2039,22 +2039,22 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, | |||
2039 | * the need to start aggregation on a certain RA/TID, the session level | 2039 | * the need to start aggregation on a certain RA/TID, the session level |
2040 | * will be managed by the mac80211. | 2040 | * will be managed by the mac80211. |
2041 | */ | 2041 | */ |
2042 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid); | 2042 | int ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, u16 tid); |
2043 | 2043 | ||
2044 | /** | 2044 | /** |
2045 | * ieee80211_start_tx_ba_cb - low level driver ready to aggregate. | 2045 | * ieee80211_start_tx_ba_cb - low level driver ready to aggregate. |
2046 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | 2046 | * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf |
2047 | * @ra: receiver address of the BA session recipient. | 2047 | * @ra: receiver address of the BA session recipient. |
2048 | * @tid: the TID to BA on. | 2048 | * @tid: the TID to BA on. |
2049 | * | 2049 | * |
2050 | * This function must be called by low level driver once it has | 2050 | * This function must be called by low level driver once it has |
2051 | * finished with preparations for the BA session. | 2051 | * finished with preparations for the BA session. |
2052 | */ | 2052 | */ |
2053 | void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid); | 2053 | void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid); |
2054 | 2054 | ||
2055 | /** | 2055 | /** |
2056 | * ieee80211_start_tx_ba_cb_irqsafe - low level driver ready to aggregate. | 2056 | * ieee80211_start_tx_ba_cb_irqsafe - low level driver ready to aggregate. |
2057 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | 2057 | * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf |
2058 | * @ra: receiver address of the BA session recipient. | 2058 | * @ra: receiver address of the BA session recipient. |
2059 | * @tid: the TID to BA on. | 2059 | * @tid: the TID to BA on. |
2060 | * | 2060 | * |
@@ -2062,13 +2062,12 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid); | |||
2062 | * finished with preparations for the BA session. | 2062 | * finished with preparations for the BA session. |
2063 | * This version of the function is IRQ-safe. | 2063 | * This version of the function is IRQ-safe. |
2064 | */ | 2064 | */ |
2065 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra, | 2065 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, const u8 *ra, |
2066 | u16 tid); | 2066 | u16 tid); |
2067 | 2067 | ||
2068 | /** | 2068 | /** |
2069 | * ieee80211_stop_tx_ba_session - Stop a Block Ack session. | 2069 | * ieee80211_stop_tx_ba_session - Stop a Block Ack session. |
2070 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | 2070 | * @sta: the station whose BA session to stop |
2071 | * @ra: receiver address of the BA session recipient | ||
2072 | * @tid: the TID to stop BA. | 2071 | * @tid: the TID to stop BA. |
2073 | * @initiator: if indicates initiator DELBA frame will be sent. | 2072 | * @initiator: if indicates initiator DELBA frame will be sent. |
2074 | * | 2073 | * |
@@ -2078,24 +2077,23 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra, | |||
2078 | * the need to stop aggregation on a certain RA/TID, the session level | 2077 | * the need to stop aggregation on a certain RA/TID, the session level |
2079 | * will be managed by the mac80211. | 2078 | * will be managed by the mac80211. |
2080 | */ | 2079 | */ |
2081 | int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | 2080 | int ieee80211_stop_tx_ba_session(struct ieee80211_sta *sta, u16 tid, |
2082 | u8 *ra, u16 tid, | ||
2083 | enum ieee80211_back_parties initiator); | 2081 | enum ieee80211_back_parties initiator); |
2084 | 2082 | ||
2085 | /** | 2083 | /** |
2086 | * ieee80211_stop_tx_ba_cb - low level driver ready to stop aggregate. | 2084 | * ieee80211_stop_tx_ba_cb - low level driver ready to stop aggregate. |
2087 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | 2085 | * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf |
2088 | * @ra: receiver address of the BA session recipient. | 2086 | * @ra: receiver address of the BA session recipient. |
2089 | * @tid: the desired TID to BA on. | 2087 | * @tid: the desired TID to BA on. |
2090 | * | 2088 | * |
2091 | * This function must be called by low level driver once it has | 2089 | * This function must be called by low level driver once it has |
2092 | * finished with preparations for the BA session tear down. | 2090 | * finished with preparations for the BA session tear down. |
2093 | */ | 2091 | */ |
2094 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid); | 2092 | void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); |
2095 | 2093 | ||
2096 | /** | 2094 | /** |
2097 | * ieee80211_stop_tx_ba_cb_irqsafe - low level driver ready to stop aggregate. | 2095 | * ieee80211_stop_tx_ba_cb_irqsafe - low level driver ready to stop aggregate. |
2098 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | 2096 | * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf |
2099 | * @ra: receiver address of the BA session recipient. | 2097 | * @ra: receiver address of the BA session recipient. |
2100 | * @tid: the desired TID to BA on. | 2098 | * @tid: the desired TID to BA on. |
2101 | * | 2099 | * |
@@ -2103,7 +2101,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid); | |||
2103 | * finished with preparations for the BA session tear down. | 2101 | * finished with preparations for the BA session tear down. |
2104 | * This version of the function is IRQ-safe. | 2102 | * This version of the function is IRQ-safe. |
2105 | */ | 2103 | */ |
2106 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra, | 2104 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, const u8 *ra, |
2107 | u16 tid); | 2105 | u16 tid); |
2108 | 2106 | ||
2109 | /** | 2107 | /** |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index bc064d7933ff..f3a5c9e0578d 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -41,7 +41,8 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
41 | sta->sta.addr, tid); | 41 | sta->sta.addr, tid); |
42 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 42 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
43 | 43 | ||
44 | if (drv_ampdu_action(local, IEEE80211_AMPDU_RX_STOP, | 44 | if (drv_ampdu_action(local, &sta->sdata->vif, |
45 | IEEE80211_AMPDU_RX_STOP, | ||
45 | &sta->sta, tid, NULL)) | 46 | &sta->sta, tid, NULL)) |
46 | printk(KERN_DEBUG "HW problem - can not stop rx " | 47 | printk(KERN_DEBUG "HW problem - can not stop rx " |
47 | "aggregation for tid %d\n", tid); | 48 | "aggregation for tid %d\n", tid); |
@@ -284,7 +285,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
284 | goto end; | 285 | goto end; |
285 | } | 286 | } |
286 | 287 | ||
287 | ret = drv_ampdu_action(local, IEEE80211_AMPDU_RX_START, | 288 | ret = drv_ampdu_action(local, &sta->sdata->vif, |
289 | IEEE80211_AMPDU_RX_START, | ||
288 | &sta->sta, tid, &start_seq_num); | 290 | &sta->sta, tid, &start_seq_num); |
289 | #ifdef CONFIG_MAC80211_HT_DEBUG | 291 | #ifdef CONFIG_MAC80211_HT_DEBUG |
290 | printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret); | 292 | printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index b09948ceec4a..6ddd11466df2 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -138,7 +138,8 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
138 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | | 138 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | |
139 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 139 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); |
140 | 140 | ||
141 | ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_STOP, | 141 | ret = drv_ampdu_action(local, &sta->sdata->vif, |
142 | IEEE80211_AMPDU_TX_STOP, | ||
142 | &sta->sta, tid, NULL); | 143 | &sta->sta, tid, NULL); |
143 | 144 | ||
144 | /* HW shall not deny going back to legacy */ | 145 | /* HW shall not deny going back to legacy */ |
@@ -196,11 +197,11 @@ static inline int ieee80211_ac_from_tid(int tid) | |||
196 | return ieee802_1d_to_ac[tid & 7]; | 197 | return ieee802_1d_to_ac[tid & 7]; |
197 | } | 198 | } |
198 | 199 | ||
199 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 200 | int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) |
200 | { | 201 | { |
201 | struct ieee80211_local *local = hw_to_local(hw); | 202 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); |
202 | struct sta_info *sta; | 203 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
203 | struct ieee80211_sub_if_data *sdata; | 204 | struct ieee80211_local *local = sdata->local; |
204 | u8 *state; | 205 | u8 *state; |
205 | int ret = 0; | 206 | int ret = 0; |
206 | u16 start_seq_num; | 207 | u16 start_seq_num; |
@@ -208,52 +209,37 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
208 | if (WARN_ON(!local->ops->ampdu_action)) | 209 | if (WARN_ON(!local->ops->ampdu_action)) |
209 | return -EINVAL; | 210 | return -EINVAL; |
210 | 211 | ||
211 | if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) | 212 | if ((tid >= STA_TID_NUM) || |
213 | !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) | ||
212 | return -EINVAL; | 214 | return -EINVAL; |
213 | 215 | ||
214 | #ifdef CONFIG_MAC80211_HT_DEBUG | 216 | #ifdef CONFIG_MAC80211_HT_DEBUG |
215 | printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", | 217 | printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", |
216 | ra, tid); | 218 | pubsta->addr, tid); |
217 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 219 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
218 | 220 | ||
219 | rcu_read_lock(); | ||
220 | |||
221 | sta = sta_info_get(local, ra); | ||
222 | if (!sta) { | ||
223 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
224 | printk(KERN_DEBUG "Could not find the station\n"); | ||
225 | #endif | ||
226 | ret = -ENOENT; | ||
227 | goto unlock; | ||
228 | } | ||
229 | |||
230 | /* | 221 | /* |
231 | * The aggregation code is not prepared to handle | 222 | * The aggregation code is not prepared to handle |
232 | * anything but STA/AP due to the BSSID handling. | 223 | * anything but STA/AP due to the BSSID handling. |
233 | * IBSS could work in the code but isn't supported | 224 | * IBSS could work in the code but isn't supported |
234 | * by drivers or the standard. | 225 | * by drivers or the standard. |
235 | */ | 226 | */ |
236 | if (sta->sdata->vif.type != NL80211_IFTYPE_STATION && | 227 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
237 | sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 228 | sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
238 | sta->sdata->vif.type != NL80211_IFTYPE_AP) { | 229 | sdata->vif.type != NL80211_IFTYPE_AP) |
239 | ret = -EINVAL; | 230 | return -EINVAL; |
240 | goto unlock; | ||
241 | } | ||
242 | 231 | ||
243 | if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { | 232 | if (test_sta_flags(sta, WLAN_STA_SUSPEND)) { |
244 | #ifdef CONFIG_MAC80211_HT_DEBUG | 233 | #ifdef CONFIG_MAC80211_HT_DEBUG |
245 | printk(KERN_DEBUG "Suspend in progress. " | 234 | printk(KERN_DEBUG "Suspend in progress. " |
246 | "Denying BA session request\n"); | 235 | "Denying BA session request\n"); |
247 | #endif | 236 | #endif |
248 | ret = -EINVAL; | 237 | return -EINVAL; |
249 | goto unlock; | ||
250 | } | 238 | } |
251 | 239 | ||
252 | spin_lock_bh(&sta->lock); | 240 | spin_lock_bh(&sta->lock); |
253 | spin_lock(&local->ampdu_lock); | 241 | spin_lock(&local->ampdu_lock); |
254 | 242 | ||
255 | sdata = sta->sdata; | ||
256 | |||
257 | /* we have tried too many times, receiver does not want A-MPDU */ | 243 | /* we have tried too many times, receiver does not want A-MPDU */ |
258 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { | 244 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { |
259 | ret = -EBUSY; | 245 | ret = -EBUSY; |
@@ -310,8 +296,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
310 | 296 | ||
311 | start_seq_num = sta->tid_seq[tid]; | 297 | start_seq_num = sta->tid_seq[tid]; |
312 | 298 | ||
313 | ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_START, | 299 | ret = drv_ampdu_action(local, &sdata->vif, |
314 | &sta->sta, tid, &start_seq_num); | 300 | IEEE80211_AMPDU_TX_START, |
301 | pubsta, tid, &start_seq_num); | ||
315 | 302 | ||
316 | if (ret) { | 303 | if (ret) { |
317 | #ifdef CONFIG_MAC80211_HT_DEBUG | 304 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -336,7 +323,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
336 | sta->ampdu_mlme.dialog_token_allocator; | 323 | sta->ampdu_mlme.dialog_token_allocator; |
337 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; | 324 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; |
338 | 325 | ||
339 | ieee80211_send_addba_request(sta->sdata, ra, tid, | 326 | ieee80211_send_addba_request(sdata, pubsta->addr, tid, |
340 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, | 327 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, |
341 | sta->ampdu_mlme.tid_tx[tid]->ssn, | 328 | sta->ampdu_mlme.tid_tx[tid]->ssn, |
342 | 0x40, 5000); | 329 | 0x40, 5000); |
@@ -348,7 +335,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
348 | #ifdef CONFIG_MAC80211_HT_DEBUG | 335 | #ifdef CONFIG_MAC80211_HT_DEBUG |
349 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); | 336 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); |
350 | #endif | 337 | #endif |
351 | goto unlock; | 338 | return 0; |
352 | 339 | ||
353 | err_free: | 340 | err_free: |
354 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 341 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
@@ -360,8 +347,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
360 | err_unlock_sta: | 347 | err_unlock_sta: |
361 | spin_unlock(&local->ampdu_lock); | 348 | spin_unlock(&local->ampdu_lock); |
362 | spin_unlock_bh(&sta->lock); | 349 | spin_unlock_bh(&sta->lock); |
363 | unlock: | ||
364 | rcu_read_unlock(); | ||
365 | return ret; | 350 | return ret; |
366 | } | 351 | } |
367 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); | 352 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); |
@@ -428,13 +413,15 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, | |||
428 | ieee80211_agg_splice_finish(local, sta, tid); | 413 | ieee80211_agg_splice_finish(local, sta, tid); |
429 | spin_unlock(&local->ampdu_lock); | 414 | spin_unlock(&local->ampdu_lock); |
430 | 415 | ||
431 | drv_ampdu_action(local, IEEE80211_AMPDU_TX_OPERATIONAL, | 416 | drv_ampdu_action(local, &sta->sdata->vif, |
417 | IEEE80211_AMPDU_TX_OPERATIONAL, | ||
432 | &sta->sta, tid, NULL); | 418 | &sta->sta, tid, NULL); |
433 | } | 419 | } |
434 | 420 | ||
435 | void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | 421 | void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) |
436 | { | 422 | { |
437 | struct ieee80211_local *local = hw_to_local(hw); | 423 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
424 | struct ieee80211_local *local = sdata->local; | ||
438 | struct sta_info *sta; | 425 | struct sta_info *sta; |
439 | u8 *state; | 426 | u8 *state; |
440 | 427 | ||
@@ -483,10 +470,11 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
483 | } | 470 | } |
484 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | 471 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); |
485 | 472 | ||
486 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | 473 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, |
487 | const u8 *ra, u16 tid) | 474 | const u8 *ra, u16 tid) |
488 | { | 475 | { |
489 | struct ieee80211_local *local = hw_to_local(hw); | 476 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
477 | struct ieee80211_local *local = sdata->local; | ||
490 | struct ieee80211_ra_tid *ra_tid; | 478 | struct ieee80211_ra_tid *ra_tid; |
491 | struct sk_buff *skb = dev_alloc_skb(0); | 479 | struct sk_buff *skb = dev_alloc_skb(0); |
492 | 480 | ||
@@ -535,13 +523,12 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
535 | return ret; | 523 | return ret; |
536 | } | 524 | } |
537 | 525 | ||
538 | int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | 526 | int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, |
539 | u8 *ra, u16 tid, | ||
540 | enum ieee80211_back_parties initiator) | 527 | enum ieee80211_back_parties initiator) |
541 | { | 528 | { |
542 | struct ieee80211_local *local = hw_to_local(hw); | 529 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); |
543 | struct sta_info *sta; | 530 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
544 | int ret = 0; | 531 | struct ieee80211_local *local = sdata->local; |
545 | 532 | ||
546 | if (WARN_ON(!local->ops->ampdu_action)) | 533 | if (WARN_ON(!local->ops->ampdu_action)) |
547 | return -EINVAL; | 534 | return -EINVAL; |
@@ -549,22 +536,14 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
549 | if (tid >= STA_TID_NUM) | 536 | if (tid >= STA_TID_NUM) |
550 | return -EINVAL; | 537 | return -EINVAL; |
551 | 538 | ||
552 | rcu_read_lock(); | 539 | return __ieee80211_stop_tx_ba_session(sta, tid, initiator); |
553 | sta = sta_info_get(local, ra); | ||
554 | if (!sta) { | ||
555 | rcu_read_unlock(); | ||
556 | return -ENOENT; | ||
557 | } | ||
558 | |||
559 | ret = __ieee80211_stop_tx_ba_session(sta, tid, initiator); | ||
560 | rcu_read_unlock(); | ||
561 | return ret; | ||
562 | } | 540 | } |
563 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); | 541 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); |
564 | 542 | ||
565 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | 543 | void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) |
566 | { | 544 | { |
567 | struct ieee80211_local *local = hw_to_local(hw); | 545 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
546 | struct ieee80211_local *local = sdata->local; | ||
568 | struct sta_info *sta; | 547 | struct sta_info *sta; |
569 | u8 *state; | 548 | u8 *state; |
570 | 549 | ||
@@ -627,10 +606,11 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
627 | } | 606 | } |
628 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); | 607 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); |
629 | 608 | ||
630 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | 609 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, |
631 | const u8 *ra, u16 tid) | 610 | const u8 *ra, u16 tid) |
632 | { | 611 | { |
633 | struct ieee80211_local *local = hw_to_local(hw); | 612 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
613 | struct ieee80211_local *local = sdata->local; | ||
634 | struct ieee80211_ra_tid *ra_tid; | 614 | struct ieee80211_ra_tid *ra_tid; |
635 | struct sk_buff *skb = dev_alloc_skb(0); | 615 | struct sk_buff *skb = dev_alloc_skb(0); |
636 | 616 | ||
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 020a94a31106..921dd9c9ff62 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -239,15 +239,16 @@ static inline int drv_tx_last_beacon(struct ieee80211_local *local) | |||
239 | } | 239 | } |
240 | 240 | ||
241 | static inline int drv_ampdu_action(struct ieee80211_local *local, | 241 | static inline int drv_ampdu_action(struct ieee80211_local *local, |
242 | struct ieee80211_vif *vif, | ||
242 | enum ieee80211_ampdu_mlme_action action, | 243 | enum ieee80211_ampdu_mlme_action action, |
243 | struct ieee80211_sta *sta, u16 tid, | 244 | struct ieee80211_sta *sta, u16 tid, |
244 | u16 *ssn) | 245 | u16 *ssn) |
245 | { | 246 | { |
246 | int ret = -EOPNOTSUPP; | 247 | int ret = -EOPNOTSUPP; |
247 | if (local->ops->ampdu_action) | 248 | if (local->ops->ampdu_action) |
248 | ret = local->ops->ampdu_action(&local->hw, action, | 249 | ret = local->ops->ampdu_action(&local->hw, vif, action, |
249 | sta, tid, ssn); | 250 | sta, tid, ssn); |
250 | trace_drv_ampdu_action(local, action, sta, tid, ssn, ret); | 251 | trace_drv_ampdu_action(local, vif, action, sta, tid, ssn, ret); |
251 | return ret; | 252 | return ret; |
252 | } | 253 | } |
253 | 254 | ||
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 37b9051afcf3..b8fef1d11369 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -634,11 +634,12 @@ TRACE_EVENT(drv_tx_last_beacon, | |||
634 | 634 | ||
635 | TRACE_EVENT(drv_ampdu_action, | 635 | TRACE_EVENT(drv_ampdu_action, |
636 | TP_PROTO(struct ieee80211_local *local, | 636 | TP_PROTO(struct ieee80211_local *local, |
637 | struct ieee80211_vif *vif, | ||
637 | enum ieee80211_ampdu_mlme_action action, | 638 | enum ieee80211_ampdu_mlme_action action, |
638 | struct ieee80211_sta *sta, u16 tid, | 639 | struct ieee80211_sta *sta, u16 tid, |
639 | u16 *ssn, int ret), | 640 | u16 *ssn, int ret), |
640 | 641 | ||
641 | TP_ARGS(local, action, sta, tid, ssn, ret), | 642 | TP_ARGS(local, vif, action, sta, tid, ssn, ret), |
642 | 643 | ||
643 | TP_STRUCT__entry( | 644 | TP_STRUCT__entry( |
644 | LOCAL_ENTRY | 645 | LOCAL_ENTRY |
@@ -647,10 +648,12 @@ TRACE_EVENT(drv_ampdu_action, | |||
647 | __field(u16, tid) | 648 | __field(u16, tid) |
648 | __field(u16, ssn) | 649 | __field(u16, ssn) |
649 | __field(int, ret) | 650 | __field(int, ret) |
651 | VIF_ENTRY | ||
650 | ), | 652 | ), |
651 | 653 | ||
652 | TP_fast_assign( | 654 | TP_fast_assign( |
653 | LOCAL_ASSIGN; | 655 | LOCAL_ASSIGN; |
656 | VIF_ASSIGN; | ||
654 | STA_ASSIGN; | 657 | STA_ASSIGN; |
655 | __entry->ret = ret; | 658 | __entry->ret = ret; |
656 | __entry->action = action; | 659 | __entry->action = action; |
@@ -659,8 +662,8 @@ TRACE_EVENT(drv_ampdu_action, | |||
659 | ), | 662 | ), |
660 | 663 | ||
661 | TP_printk( | 664 | TP_printk( |
662 | LOCAL_PR_FMT STA_PR_FMT " action:%d tid:%d ret:%d", | 665 | LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " action:%d tid:%d ret:%d", |
663 | LOCAL_PR_ARG, STA_PR_ARG, __entry->action, __entry->tid, __entry->ret | 666 | LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->action, __entry->tid, __entry->ret |
664 | ) | 667 | ) |
665 | ); | 668 | ); |
666 | #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ | 669 | #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 48ef1a282b91..345c8ee50175 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -141,7 +141,6 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
141 | struct sta_info *sta, | 141 | struct sta_info *sta, |
142 | struct ieee80211_mgmt *mgmt, size_t len) | 142 | struct ieee80211_mgmt *mgmt, size_t len) |
143 | { | 143 | { |
144 | struct ieee80211_local *local = sdata->local; | ||
145 | u16 tid, params; | 144 | u16 tid, params; |
146 | u16 initiator; | 145 | u16 initiator; |
147 | 146 | ||
@@ -164,7 +163,7 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
164 | sta->ampdu_mlme.tid_state_tx[tid] = | 163 | sta->ampdu_mlme.tid_state_tx[tid] = |
165 | HT_AGG_STATE_OPERATIONAL; | 164 | HT_AGG_STATE_OPERATIONAL; |
166 | spin_unlock_bh(&sta->lock); | 165 | spin_unlock_bh(&sta->lock); |
167 | ieee80211_stop_tx_ba_session(&local->hw, sta->sta.addr, tid, | 166 | ieee80211_stop_tx_ba_session(&sta->sta, tid, |
168 | WLAN_BACK_RECIPIENT); | 167 | WLAN_BACK_RECIPIENT); |
169 | } | 168 | } |
170 | } | 169 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index b63b99fb2fd3..b7598db5ade2 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -771,8 +771,9 @@ IEEE80211_DEV_TO_SUB_IF(struct net_device *dev) | |||
771 | return netdev_priv(dev); | 771 | return netdev_priv(dev); |
772 | } | 772 | } |
773 | 773 | ||
774 | /* this struct represents 802.11n's RA/TID combination */ | 774 | /* this struct represents 802.11n's RA/TID combination along with our vif */ |
775 | struct ieee80211_ra_tid { | 775 | struct ieee80211_ra_tid { |
776 | struct ieee80211_vif *vif; | ||
776 | u8 ra[ETH_ALEN]; | 777 | u8 ra[ETH_ALEN]; |
777 | u16 tid; | 778 | u16 tid; |
778 | }; | 779 | }; |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index c74a6a1935b3..f4be97c3b747 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -296,14 +296,14 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
296 | break; | 296 | break; |
297 | case IEEE80211_DELBA_MSG: | 297 | case IEEE80211_DELBA_MSG: |
298 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 298 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
299 | ieee80211_stop_tx_ba_cb(local_to_hw(local), | 299 | ieee80211_stop_tx_ba_cb(ra_tid->vif, ra_tid->ra, |
300 | ra_tid->ra, ra_tid->tid); | 300 | ra_tid->tid); |
301 | dev_kfree_skb(skb); | 301 | dev_kfree_skb(skb); |
302 | break; | 302 | break; |
303 | case IEEE80211_ADDBA_MSG: | 303 | case IEEE80211_ADDBA_MSG: |
304 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 304 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
305 | ieee80211_start_tx_ba_cb(local_to_hw(local), | 305 | ieee80211_start_tx_ba_cb(ra_tid->vif, ra_tid->ra, |
306 | ra_tid->ra, ra_tid->tid); | 306 | ra_tid->tid); |
307 | dev_kfree_skb(skb); | 307 | dev_kfree_skb(skb); |
308 | break ; | 308 | break ; |
309 | default: | 309 | default: |