aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-11-16 06:00:38 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-18 17:09:15 -0500
commitc951ad3550ab40071bb0f222ba6125845769c08a (patch)
tree9db1d3c110b359a34a3d706eaf40285cfa01550b
parent3b53fde8ac40c4321389def14d7f4a9e14092fd3 (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.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c8
-rw-r--r--include/net/mac80211.h28
-rw-r--r--net/mac80211/agg-rx.c6
-rw-r--r--net/mac80211/agg-tx.c96
-rw-r--r--net/mac80211/driver-ops.h5
-rw-r--r--net/mac80211/driver-trace.h9
-rw-r--r--net/mac80211/ht.c3
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/main.c8
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
2443static int ar9170_ampdu_action(struct ieee80211_hw *hw, 2443static 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
3080static int ath9k_ampdu_action(struct ieee80211_hw *hw, 3080static 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
2693static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, 2693static 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 */
2042int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid); 2042int 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 */
2053void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid); 2053void 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 */
2065void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra, 2065void 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 */
2081int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, 2080int 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 */
2094void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid); 2092void 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 */
2106void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra, 2104void 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
199int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) 200int 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}
367EXPORT_SYMBOL(ieee80211_start_tx_ba_session); 352EXPORT_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
435void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) 421void 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}
484EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); 471EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
485 472
486void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, 473void 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
538int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, 526int 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}
563EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); 541EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
564 542
565void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) 543void 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}
628EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); 607EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
629 608
630void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, 609void 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
241static inline int drv_ampdu_action(struct ieee80211_local *local, 241static 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
635TRACE_EVENT(drv_ampdu_action, 635TRACE_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 */
775struct ieee80211_ra_tid { 775struct 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: