summaryrefslogtreecommitdiffstats
path: root/net/mac80211/agg-tx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-11-16 12:00:38 +0100
committerJohn W. Linville <linville@tuxdriver.com>2009-11-18 17:09:15 -0500
commitc951ad3550ab40071bb0f222ba6125845769c08a (patch)
tree9db1d3c110b359a34a3d706eaf40285cfa01550b /net/mac80211/agg-tx.c
parent3b53fde8ac40c4321389def14d7f4a9e14092fd3 (diff)
downloadlinux-stable-c951ad3550ab40071bb0f222ba6125845769c08a.tar.gz
linux-stable-c951ad3550ab40071bb0f222ba6125845769c08a.tar.bz2
linux-stable-c951ad3550ab40071bb0f222ba6125845769c08a.zip
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>
Diffstat (limited to 'net/mac80211/agg-tx.c')
-rw-r--r--net/mac80211/agg-tx.c96
1 files changed, 38 insertions, 58 deletions
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,
*state = HT_AGG_STATE_REQ_STOP_BA_MSK |
(initiator << HT_AGG_STATE_INITIATOR_SHIFT);
- ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_STOP,
+ ret = drv_ampdu_action(local, &sta->sdata->vif,
+ IEEE80211_AMPDU_TX_STOP,
&sta->sta, tid, NULL);
/* HW shall not deny going back to legacy */
@@ -196,11 +197,11 @@ static inline int ieee80211_ac_from_tid(int tid)
return ieee802_1d_to_ac[tid & 7];
}
-int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
+int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
{
- struct ieee80211_local *local = hw_to_local(hw);
- struct sta_info *sta;
- struct ieee80211_sub_if_data *sdata;
+ struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+ struct ieee80211_sub_if_data *sdata = sta->sdata;
+ struct ieee80211_local *local = sdata->local;
u8 *state;
int ret = 0;
u16 start_seq_num;
@@ -208,52 +209,37 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
if (WARN_ON(!local->ops->ampdu_action))
return -EINVAL;
- if ((tid >= STA_TID_NUM) || !(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
+ if ((tid >= STA_TID_NUM) ||
+ !(local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION))
return -EINVAL;
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n",
- ra, tid);
+ pubsta->addr, tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
- rcu_read_lock();
-
- sta = sta_info_get(local, ra);
- if (!sta) {
-#ifdef CONFIG_MAC80211_HT_DEBUG
- printk(KERN_DEBUG "Could not find the station\n");
-#endif
- ret = -ENOENT;
- goto unlock;
- }
-
/*
* The aggregation code is not prepared to handle
* anything but STA/AP due to the BSSID handling.
* IBSS could work in the code but isn't supported
* by drivers or the standard.
*/
- if (sta->sdata->vif.type != NL80211_IFTYPE_STATION &&
- sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
- sta->sdata->vif.type != NL80211_IFTYPE_AP) {
- ret = -EINVAL;
- goto unlock;
- }
+ if (sdata->vif.type != NL80211_IFTYPE_STATION &&
+ sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
+ sdata->vif.type != NL80211_IFTYPE_AP)
+ return -EINVAL;
if (test_sta_flags(sta, WLAN_STA_SUSPEND)) {
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "Suspend in progress. "
"Denying BA session request\n");
#endif
- ret = -EINVAL;
- goto unlock;
+ return -EINVAL;
}
spin_lock_bh(&sta->lock);
spin_lock(&local->ampdu_lock);
- sdata = sta->sdata;
-
/* we have tried too many times, receiver does not want A-MPDU */
if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
ret = -EBUSY;
@@ -310,8 +296,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
start_seq_num = sta->tid_seq[tid];
- ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_START,
- &sta->sta, tid, &start_seq_num);
+ ret = drv_ampdu_action(local, &sdata->vif,
+ IEEE80211_AMPDU_TX_START,
+ pubsta, tid, &start_seq_num);
if (ret) {
#ifdef CONFIG_MAC80211_HT_DEBUG
@@ -336,7 +323,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
sta->ampdu_mlme.dialog_token_allocator;
sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
- ieee80211_send_addba_request(sta->sdata, ra, tid,
+ ieee80211_send_addba_request(sdata, pubsta->addr, tid,
sta->ampdu_mlme.tid_tx[tid]->dialog_token,
sta->ampdu_mlme.tid_tx[tid]->ssn,
0x40, 5000);
@@ -348,7 +335,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
#endif
- goto unlock;
+ return 0;
err_free:
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)
err_unlock_sta:
spin_unlock(&local->ampdu_lock);
spin_unlock_bh(&sta->lock);
- unlock:
- rcu_read_unlock();
return ret;
}
EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
@@ -428,13 +413,15 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
ieee80211_agg_splice_finish(local, sta, tid);
spin_unlock(&local->ampdu_lock);
- drv_ampdu_action(local, IEEE80211_AMPDU_TX_OPERATIONAL,
+ drv_ampdu_action(local, &sta->sdata->vif,
+ IEEE80211_AMPDU_TX_OPERATIONAL,
&sta->sta, tid, NULL);
}
-void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
+void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
{
- struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+ struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
u8 *state;
@@ -483,10 +470,11 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
}
EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
-void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
+void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
const u8 *ra, u16 tid)
{
- struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+ struct ieee80211_local *local = sdata->local;
struct ieee80211_ra_tid *ra_tid;
struct sk_buff *skb = dev_alloc_skb(0);
@@ -535,13 +523,12 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
return ret;
}
-int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
- u8 *ra, u16 tid,
+int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
enum ieee80211_back_parties initiator)
{
- struct ieee80211_local *local = hw_to_local(hw);
- struct sta_info *sta;
- int ret = 0;
+ struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+ struct ieee80211_sub_if_data *sdata = sta->sdata;
+ struct ieee80211_local *local = sdata->local;
if (WARN_ON(!local->ops->ampdu_action))
return -EINVAL;
@@ -549,22 +536,14 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
if (tid >= STA_TID_NUM)
return -EINVAL;
- rcu_read_lock();
- sta = sta_info_get(local, ra);
- if (!sta) {
- rcu_read_unlock();
- return -ENOENT;
- }
-
- ret = __ieee80211_stop_tx_ba_session(sta, tid, initiator);
- rcu_read_unlock();
- return ret;
+ return __ieee80211_stop_tx_ba_session(sta, tid, initiator);
}
EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
-void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
+void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
{
- struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+ struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
u8 *state;
@@ -627,10 +606,11 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
}
EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
-void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
+void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
const u8 *ra, u16 tid)
{
- struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+ struct ieee80211_local *local = sdata->local;
struct ieee80211_ra_tid *ra_tid;
struct sk_buff *skb = dev_alloc_skb(0);