mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
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 <[email protected]> Signed-off-by: John W. Linville <[email protected]>
This commit is contained in:
parent
3b53fde8ac
commit
c951ad3550
14 changed files with 84 additions and 97 deletions
|
|
@ -41,7 +41,8 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
|
|||
sta->sta.addr, tid);
|
||||
#endif /* CONFIG_MAC80211_HT_DEBUG */
|
||||
|
||||
if (drv_ampdu_action(local, IEEE80211_AMPDU_RX_STOP,
|
||||
if (drv_ampdu_action(local, &sta->sdata->vif,
|
||||
IEEE80211_AMPDU_RX_STOP,
|
||||
&sta->sta, tid, NULL))
|
||||
printk(KERN_DEBUG "HW problem - can not stop rx "
|
||||
"aggregation for tid %d\n", tid);
|
||||
|
|
@ -284,7 +285,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
|
|||
goto end;
|
||||
}
|
||||
|
||||
ret = drv_ampdu_action(local, IEEE80211_AMPDU_RX_START,
|
||||
ret = drv_ampdu_action(local, &sta->sdata->vif,
|
||||
IEEE80211_AMPDU_RX_START,
|
||||
&sta->sta, tid, &start_seq_num);
|
||||
#ifdef CONFIG_MAC80211_HT_DEBUG
|
||||
printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -239,15 +239,16 @@ static inline int drv_tx_last_beacon(struct ieee80211_local *local)
|
|||
}
|
||||
|
||||
static inline int drv_ampdu_action(struct ieee80211_local *local,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid,
|
||||
u16 *ssn)
|
||||
{
|
||||
int ret = -EOPNOTSUPP;
|
||||
if (local->ops->ampdu_action)
|
||||
ret = local->ops->ampdu_action(&local->hw, action,
|
||||
ret = local->ops->ampdu_action(&local->hw, vif, action,
|
||||
sta, tid, ssn);
|
||||
trace_drv_ampdu_action(local, action, sta, tid, ssn, ret);
|
||||
trace_drv_ampdu_action(local, vif, action, sta, tid, ssn, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -634,11 +634,12 @@ TRACE_EVENT(drv_tx_last_beacon,
|
|||
|
||||
TRACE_EVENT(drv_ampdu_action,
|
||||
TP_PROTO(struct ieee80211_local *local,
|
||||
struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
struct ieee80211_sta *sta, u16 tid,
|
||||
u16 *ssn, int ret),
|
||||
|
||||
TP_ARGS(local, action, sta, tid, ssn, ret),
|
||||
TP_ARGS(local, vif, action, sta, tid, ssn, ret),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
LOCAL_ENTRY
|
||||
|
|
@ -647,10 +648,12 @@ TRACE_EVENT(drv_ampdu_action,
|
|||
__field(u16, tid)
|
||||
__field(u16, ssn)
|
||||
__field(int, ret)
|
||||
VIF_ENTRY
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
LOCAL_ASSIGN;
|
||||
VIF_ASSIGN;
|
||||
STA_ASSIGN;
|
||||
__entry->ret = ret;
|
||||
__entry->action = action;
|
||||
|
|
@ -659,8 +662,8 @@ TRACE_EVENT(drv_ampdu_action,
|
|||
),
|
||||
|
||||
TP_printk(
|
||||
LOCAL_PR_FMT STA_PR_FMT " action:%d tid:%d ret:%d",
|
||||
LOCAL_PR_ARG, STA_PR_ARG, __entry->action, __entry->tid, __entry->ret
|
||||
LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " action:%d tid:%d ret:%d",
|
||||
LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->action, __entry->tid, __entry->ret
|
||||
)
|
||||
);
|
||||
#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
|
||||
|
|
|
|||
|
|
@ -141,7 +141,6 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
|
|||
struct sta_info *sta,
|
||||
struct ieee80211_mgmt *mgmt, size_t len)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
u16 tid, params;
|
||||
u16 initiator;
|
||||
|
||||
|
|
@ -164,7 +163,7 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
|
|||
sta->ampdu_mlme.tid_state_tx[tid] =
|
||||
HT_AGG_STATE_OPERATIONAL;
|
||||
spin_unlock_bh(&sta->lock);
|
||||
ieee80211_stop_tx_ba_session(&local->hw, sta->sta.addr, tid,
|
||||
ieee80211_stop_tx_ba_session(&sta->sta, tid,
|
||||
WLAN_BACK_RECIPIENT);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -771,8 +771,9 @@ IEEE80211_DEV_TO_SUB_IF(struct net_device *dev)
|
|||
return netdev_priv(dev);
|
||||
}
|
||||
|
||||
/* this struct represents 802.11n's RA/TID combination */
|
||||
/* this struct represents 802.11n's RA/TID combination along with our vif */
|
||||
struct ieee80211_ra_tid {
|
||||
struct ieee80211_vif *vif;
|
||||
u8 ra[ETH_ALEN];
|
||||
u16 tid;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -296,14 +296,14 @@ static void ieee80211_tasklet_handler(unsigned long data)
|
|||
break;
|
||||
case IEEE80211_DELBA_MSG:
|
||||
ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
|
||||
ieee80211_stop_tx_ba_cb(local_to_hw(local),
|
||||
ra_tid->ra, ra_tid->tid);
|
||||
ieee80211_stop_tx_ba_cb(ra_tid->vif, ra_tid->ra,
|
||||
ra_tid->tid);
|
||||
dev_kfree_skb(skb);
|
||||
break;
|
||||
case IEEE80211_ADDBA_MSG:
|
||||
ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
|
||||
ieee80211_start_tx_ba_cb(local_to_hw(local),
|
||||
ra_tid->ra, ra_tid->tid);
|
||||
ieee80211_start_tx_ba_cb(ra_tid->vif, ra_tid->ra,
|
||||
ra_tid->tid);
|
||||
dev_kfree_skb(skb);
|
||||
break ;
|
||||
default:
|
||||
|
|
|
|||
Loading…
Reference in a new issue