diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-11-05 21:49:02 +0100 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-11-05 21:49:02 +0100 |
commit | 353c78152c10027b8da5de446bad3472f977fcdc (patch) | |
tree | 8663ca32b912e8b3df428f570b7fd376aa3aa0cb /net/mac80211/tx.c | |
parent | Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linvil... (diff) | |
parent | nl80211: fix channel switch parsing (diff) | |
download | linux-353c78152c10027b8da5de446bad3472f977fcdc.tar.xz linux-353c78152c10027b8da5de446bad3472f977fcdc.zip |
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Conflicts:
net/wireless/reg.c
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 9993fcb19ecd..c558b246ef00 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1367,6 +1367,35 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) return 0; } +bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, struct sk_buff *skb, + int band, struct ieee80211_sta **sta) +{ + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_data tx; + + if (ieee80211_tx_prepare(sdata, &tx, skb) == TX_DROP) + return false; + + info->band = band; + info->control.vif = vif; + info->hw_queue = vif->hw_queue[skb_get_queue_mapping(skb)]; + + if (invoke_tx_handlers(&tx)) + return false; + + if (sta) { + if (tx.sta) + *sta = &tx.sta->sta; + else + *sta = NULL; + } + + return true; +} +EXPORT_SYMBOL(ieee80211_tx_prepare_skb); + /* * Returns false if the frame couldn't be transmitted but was queued instead. */ @@ -2370,6 +2399,10 @@ static void ieee80211_update_csa(struct ieee80211_sub_if_data *sdata, beacon_data = beacon->head; beacon_data_len = beacon->head_len; break; + case NL80211_IFTYPE_MESH_POINT: + beacon_data = beacon->head; + beacon_data_len = beacon->head_len; + break; default: return; } @@ -2426,6 +2459,15 @@ bool ieee80211_csa_is_complete(struct ieee80211_vif *vif) beacon_data = beacon->head; beacon_data_len = beacon->head_len; + } else if (vif->type == NL80211_IFTYPE_MESH_POINT) { + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; + + beacon = rcu_dereference(ifmsh->beacon); + if (!beacon) + goto out; + + beacon_data = beacon->head; + beacon_data_len = beacon->head_len; } else { WARN_ON(1); goto out; @@ -2531,6 +2573,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, if (!bcn) goto out; + if (sdata->vif.csa_active) + ieee80211_update_csa(sdata, bcn); + if (ifmsh->sync_ops) ifmsh->sync_ops->adjust_tbtt( sdata); |