diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-02-15 15:38:08 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-03-07 08:33:21 -0500 |
commit | e943789edbb1f9de71b129d9992489eb79ed341f (patch) | |
tree | 68fa313de6316ee270dc7fbc08b3596bf3483497 | |
parent | 560d268220d3416a2d473bcc906ea2ccbf51e4ec (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.tmpl | 2 | ||||
-rw-r--r-- | include/net/mac80211.h | 25 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 5 | ||||
-rw-r--r-- | net/mac80211/main.c | 14 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 20 |
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 | */ |
3867 | void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta); | 3870 | void 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 { | |||
800 | enum { | 800 | enum { |
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 | |||
806 | struct skb_eosp_msg_data { | ||
807 | u8 sta[ETH_ALEN], iface[ETH_ALEN]; | ||
808 | }; | 803 | }; |
809 | 804 | ||
810 | enum queue_stop_reason { | 805 | enum 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) | |||
226 | static void ieee80211_tasklet_handler(unsigned long data) | 226 | static 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 | } |
1391 | EXPORT_SYMBOL(ieee80211_sta_block_awake); | 1391 | EXPORT_SYMBOL(ieee80211_sta_block_awake); |
1392 | 1392 | ||
1393 | void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta) | 1393 | void 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 | } |
1416 | EXPORT_SYMBOL(ieee80211_sta_eosp_irqsafe); | 1402 | EXPORT_SYMBOL(ieee80211_sta_eosp); |
1417 | 1403 | ||
1418 | void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, | 1404 | void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, |
1419 | u8 tid, bool buffered) | 1405 | u8 tid, bool buffered) |