aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-02-15 15:38:08 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-03-07 08:33:21 -0500
commite943789edbb1f9de71b129d9992489eb79ed341f (patch)
tree68fa313de6316ee270dc7fbc08b3596bf3483497
parent560d268220d3416a2d473bcc906ea2ccbf51e4ec (diff)
mac80211: provide ieee80211_sta_eosp()
The irqsafe version ieee80211_sta_eosp_irqsafe() exists, but drivers must not mix calls to any irqsafe/non-irqsafe function. Both ath9k and iwlwifi, the likely first users of this interface, use non-irqsafe RX/TX/TX status so must also use a non-irqsafe version of this function. Since no driver uses the _irqsafe() version, remove that. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--Documentation/DocBook/80211.tmpl2
-rw-r--r--include/net/mac80211.h25
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/main.c14
-rw-r--r--net/mac80211/sta_info.c20
5 files changed, 18 insertions, 48 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl
index 284ced7a228f..0f6a3edcd44b 100644
--- a/Documentation/DocBook/80211.tmpl
+++ b/Documentation/DocBook/80211.tmpl
@@ -437,7 +437,7 @@
437 </section> 437 </section>
438!Finclude/net/mac80211.h ieee80211_get_buffered_bc 438!Finclude/net/mac80211.h ieee80211_get_buffered_bc
439!Finclude/net/mac80211.h ieee80211_beacon_get 439!Finclude/net/mac80211.h ieee80211_beacon_get
440!Finclude/net/mac80211.h ieee80211_sta_eosp_irqsafe 440!Finclude/net/mac80211.h ieee80211_sta_eosp
441!Finclude/net/mac80211.h ieee80211_frame_release_type 441!Finclude/net/mac80211.h ieee80211_frame_release_type
442!Finclude/net/mac80211.h ieee80211_sta_ps_transition 442!Finclude/net/mac80211.h ieee80211_sta_ps_transition
443!Finclude/net/mac80211.h ieee80211_sta_ps_transition_ni 443!Finclude/net/mac80211.h ieee80211_sta_ps_transition_ni
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index cdd7cea1fd4c..8c0ca11a39c4 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1946,14 +1946,14 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
1946 * filter those response frames except in the case of frames that 1946 * filter those response frames except in the case of frames that
1947 * are buffered in the driver -- those must remain buffered to avoid 1947 * are buffered in the driver -- those must remain buffered to avoid
1948 * reordering. Because it is possible that no frames are released 1948 * reordering. Because it is possible that no frames are released
1949 * in this case, the driver must call ieee80211_sta_eosp_irqsafe() 1949 * in this case, the driver must call ieee80211_sta_eosp()
1950 * to indicate to mac80211 that the service period ended anyway. 1950 * to indicate to mac80211 that the service period ended anyway.
1951 * 1951 *
1952 * Finally, if frames from multiple TIDs are released from mac80211 1952 * Finally, if frames from multiple TIDs are released from mac80211
1953 * but the driver might reorder them, it must clear & set the flags 1953 * but the driver might reorder them, it must clear & set the flags
1954 * appropriately (only the last frame may have %IEEE80211_TX_STATUS_EOSP) 1954 * appropriately (only the last frame may have %IEEE80211_TX_STATUS_EOSP)
1955 * and also take care of the EOSP and MORE_DATA bits in the frame. 1955 * and also take care of the EOSP and MORE_DATA bits in the frame.
1956 * The driver may also use ieee80211_sta_eosp_irqsafe() in this case. 1956 * The driver may also use ieee80211_sta_eosp() in this case.
1957 */ 1957 */
1958 1958
1959/** 1959/**
@@ -2506,7 +2506,7 @@ enum ieee80211_roc_type {
2506 * setting the EOSP flag in the QoS header of the frames. Also, when the 2506 * setting the EOSP flag in the QoS header of the frames. Also, when the
2507 * service period ends, the driver must set %IEEE80211_TX_STATUS_EOSP 2507 * service period ends, the driver must set %IEEE80211_TX_STATUS_EOSP
2508 * on the last frame in the SP. Alternatively, it may call the function 2508 * on the last frame in the SP. Alternatively, it may call the function
2509 * ieee80211_sta_eosp_irqsafe() to inform mac80211 of the end of the SP. 2509 * ieee80211_sta_eosp() to inform mac80211 of the end of the SP.
2510 * This callback must be atomic. 2510 * This callback must be atomic.
2511 * @allow_buffered_frames: Prepare device to allow the given number of frames 2511 * @allow_buffered_frames: Prepare device to allow the given number of frames
2512 * to go out to the given station. The frames will be sent by mac80211 2512 * to go out to the given station. The frames will be sent by mac80211
@@ -2517,7 +2517,7 @@ enum ieee80211_roc_type {
2517 * them between the TIDs, it must set the %IEEE80211_TX_STATUS_EOSP flag 2517 * them between the TIDs, it must set the %IEEE80211_TX_STATUS_EOSP flag
2518 * on the last frame and clear it on all others and also handle the EOSP 2518 * on the last frame and clear it on all others and also handle the EOSP
2519 * bit in the QoS header correctly. Alternatively, it can also call the 2519 * bit in the QoS header correctly. Alternatively, it can also call the
2520 * ieee80211_sta_eosp_irqsafe() function. 2520 * ieee80211_sta_eosp() function.
2521 * The @tids parameter is a bitmap and tells the driver which TIDs the 2521 * The @tids parameter is a bitmap and tells the driver which TIDs the
2522 * frames will be on; it will at most have two bits set. 2522 * frames will be on; it will at most have two bits set.
2523 * This callback must be atomic. 2523 * This callback must be atomic.
@@ -3857,14 +3857,17 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
3857 * %IEEE80211_TX_STATUS_EOSP bit and call this function instead. 3857 * %IEEE80211_TX_STATUS_EOSP bit and call this function instead.
3858 * This applies for PS-Poll as well as uAPSD. 3858 * This applies for PS-Poll as well as uAPSD.
3859 * 3859 *
3860 * Note that there is no non-_irqsafe version right now as 3860 * Note that just like with _tx_status() and _rx() drivers must
3861 * it wasn't needed, but just like _tx_status() and _rx() 3861 * not mix calls to irqsafe/non-irqsafe versions, this function
3862 * must not be mixed in irqsafe/non-irqsafe versions, this 3862 * must not be mixed with those either. Use the all irqsafe, or
3863 * function must not be mixed with those either. Use the 3863 * all non-irqsafe, don't mix!
3864 * all irqsafe, or all non-irqsafe, don't mix! If you need 3864 *
3865 * the non-irqsafe version of this, you need to add it. 3865 * NB: the _irqsafe version of this function doesn't exist, no
3866 * driver needs it right now. Don't call this function if
3867 * you'd need the _irqsafe version, look at the git history
3868 * and restore the _irqsafe version!
3866 */ 3869 */
3867void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta); 3870void ieee80211_sta_eosp(struct ieee80211_sta *pubsta);
3868 3871
3869/** 3872/**
3870 * ieee80211_iter_keys - iterate keys programmed into the device 3873 * ieee80211_iter_keys - iterate keys programmed into the device
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f4433f081e77..95beb18588f6 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -800,11 +800,6 @@ enum sdata_queue_type {
800enum { 800enum {
801 IEEE80211_RX_MSG = 1, 801 IEEE80211_RX_MSG = 1,
802 IEEE80211_TX_STATUS_MSG = 2, 802 IEEE80211_TX_STATUS_MSG = 2,
803 IEEE80211_EOSP_MSG = 3,
804};
805
806struct skb_eosp_msg_data {
807 u8 sta[ETH_ALEN], iface[ETH_ALEN];
808}; 803};
809 804
810enum queue_stop_reason { 805enum queue_stop_reason {
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 5a53aa5ede80..5531c89909d8 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -226,8 +226,6 @@ u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
226static void ieee80211_tasklet_handler(unsigned long data) 226static void ieee80211_tasklet_handler(unsigned long data)
227{ 227{
228 struct ieee80211_local *local = (struct ieee80211_local *) data; 228 struct ieee80211_local *local = (struct ieee80211_local *) data;
229 struct sta_info *sta, *tmp;
230 struct skb_eosp_msg_data *eosp_data;
231 struct sk_buff *skb; 229 struct sk_buff *skb;
232 230
233 while ((skb = skb_dequeue(&local->skb_queue)) || 231 while ((skb = skb_dequeue(&local->skb_queue)) ||
@@ -243,18 +241,6 @@ static void ieee80211_tasklet_handler(unsigned long data)
243 skb->pkt_type = 0; 241 skb->pkt_type = 0;
244 ieee80211_tx_status(&local->hw, skb); 242 ieee80211_tx_status(&local->hw, skb);
245 break; 243 break;
246 case IEEE80211_EOSP_MSG:
247 eosp_data = (void *)skb->cb;
248 for_each_sta_info(local, eosp_data->sta, sta, tmp) {
249 /* skip wrong virtual interface */
250 if (memcmp(eosp_data->iface,
251 sta->sdata->vif.addr, ETH_ALEN))
252 continue;
253 clear_sta_flag(sta, WLAN_STA_SP);
254 break;
255 }
256 dev_kfree_skb(skb);
257 break;
258 default: 244 default:
259 WARN(1, "mac80211: Packet is of unknown type %d\n", 245 WARN(1, "mac80211: Packet is of unknown type %d\n",
260 skb->pkt_type); 246 skb->pkt_type);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 3644ad79688a..852bf45fcfa3 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1390,30 +1390,16 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
1390} 1390}
1391EXPORT_SYMBOL(ieee80211_sta_block_awake); 1391EXPORT_SYMBOL(ieee80211_sta_block_awake);
1392 1392
1393void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta) 1393void ieee80211_sta_eosp(struct ieee80211_sta *pubsta)
1394{ 1394{
1395 struct sta_info *sta = container_of(pubsta, struct sta_info, sta); 1395 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
1396 struct ieee80211_local *local = sta->local; 1396 struct ieee80211_local *local = sta->local;
1397 struct sk_buff *skb;
1398 struct skb_eosp_msg_data *data;
1399 1397
1400 trace_api_eosp(local, pubsta); 1398 trace_api_eosp(local, pubsta);
1401 1399
1402 skb = alloc_skb(0, GFP_ATOMIC); 1400 clear_sta_flag(sta, WLAN_STA_SP);
1403 if (!skb) {
1404 /* too bad ... but race is better than loss */
1405 clear_sta_flag(sta, WLAN_STA_SP);
1406 return;
1407 }
1408
1409 data = (void *)skb->cb;
1410 memcpy(data->sta, pubsta->addr, ETH_ALEN);
1411 memcpy(data->iface, sta->sdata->vif.addr, ETH_ALEN);
1412 skb->pkt_type = IEEE80211_EOSP_MSG;
1413 skb_queue_tail(&local->skb_queue, skb);
1414 tasklet_schedule(&local->tasklet);
1415} 1401}
1416EXPORT_SYMBOL(ieee80211_sta_eosp_irqsafe); 1402EXPORT_SYMBOL(ieee80211_sta_eosp);
1417 1403
1418void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, 1404void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
1419 u8 tid, bool buffered) 1405 u8 tid, bool buffered)