aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorLiad Kaufman <liad.kaufman@intel.com>2014-11-19 06:47:38 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-11-19 12:45:36 -0500
commitb6da911b3cf1d342f2f7123c9eb6463d299bca4e (patch)
tree7e90aaf36e8149ca731e4d8589d9d18556de933b /net/mac80211/tx.c
parent4f9610d528a6aa5642fa350fa93fbd905a753ae8 (diff)
mac80211: synchronously reserve TID per station
In TDLS (e.g., TDLS off-channel) there is a requirement for some drivers to supply an unused TID between the AP and the device to the FW, to allow sending PTI requests and to allow the FW to aggregate on a specific TID for better throughput. To ensure that the allocated TID is indeed unused, this patch introduces an API for blocking the driver from TXing on that TID. Signed-off-by: Liad Kaufman <liad.kaufman@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 2dd89670e1cd..0cb41d1a1f20 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3107,6 +3107,97 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
3107} 3107}
3108EXPORT_SYMBOL(ieee80211_get_buffered_bc); 3108EXPORT_SYMBOL(ieee80211_get_buffered_bc);
3109 3109
3110int ieee80211_reserve_tid(struct ieee80211_sta *pubsta, u8 tid)
3111{
3112 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
3113 struct ieee80211_sub_if_data *sdata = sta->sdata;
3114 struct ieee80211_local *local = sdata->local;
3115 int ret;
3116 u32 queues;
3117
3118 lockdep_assert_held(&local->sta_mtx);
3119
3120 /* only some cases are supported right now */
3121 switch (sdata->vif.type) {
3122 case NL80211_IFTYPE_STATION:
3123 case NL80211_IFTYPE_AP:
3124 case NL80211_IFTYPE_AP_VLAN:
3125 break;
3126 default:
3127 WARN_ON(1);
3128 return -EINVAL;
3129 }
3130
3131 if (WARN_ON(tid >= IEEE80211_NUM_UPS))
3132 return -EINVAL;
3133
3134 if (sta->reserved_tid == tid) {
3135 ret = 0;
3136 goto out;
3137 }
3138
3139 if (sta->reserved_tid != IEEE80211_TID_UNRESERVED) {
3140 sdata_err(sdata, "TID reservation already active\n");
3141 ret = -EALREADY;
3142 goto out;
3143 }
3144
3145 ieee80211_stop_vif_queues(sdata->local, sdata,
3146 IEEE80211_QUEUE_STOP_REASON_RESERVE_TID);
3147
3148 synchronize_net();
3149
3150 /* Tear down BA sessions so we stop aggregating on this TID */
3151 if (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION) {
3152 set_sta_flag(sta, WLAN_STA_BLOCK_BA);
3153 __ieee80211_stop_tx_ba_session(sta, tid,
3154 AGG_STOP_LOCAL_REQUEST);
3155 }
3156
3157 queues = BIT(sdata->vif.hw_queue[ieee802_1d_to_ac[tid]]);
3158 __ieee80211_flush_queues(local, sdata, queues);
3159
3160 sta->reserved_tid = tid;
3161
3162 ieee80211_wake_vif_queues(local, sdata,
3163 IEEE80211_QUEUE_STOP_REASON_RESERVE_TID);
3164
3165 if (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)
3166 clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
3167
3168 ret = 0;
3169 out:
3170 return ret;
3171}
3172EXPORT_SYMBOL(ieee80211_reserve_tid);
3173
3174void ieee80211_unreserve_tid(struct ieee80211_sta *pubsta, u8 tid)
3175{
3176 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
3177 struct ieee80211_sub_if_data *sdata = sta->sdata;
3178
3179 lockdep_assert_held(&sdata->local->sta_mtx);
3180
3181 /* only some cases are supported right now */
3182 switch (sdata->vif.type) {
3183 case NL80211_IFTYPE_STATION:
3184 case NL80211_IFTYPE_AP:
3185 case NL80211_IFTYPE_AP_VLAN:
3186 break;
3187 default:
3188 WARN_ON(1);
3189 return;
3190 }
3191
3192 if (tid != sta->reserved_tid) {
3193 sdata_err(sdata, "TID to unreserve (%d) isn't reserved\n", tid);
3194 return;
3195 }
3196
3197 sta->reserved_tid = IEEE80211_TID_UNRESERVED;
3198}
3199EXPORT_SYMBOL(ieee80211_unreserve_tid);
3200
3110void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, 3201void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata,
3111 struct sk_buff *skb, int tid, 3202 struct sk_buff *skb, int tid,
3112 enum ieee80211_band band) 3203 enum ieee80211_band band)