Commit e943789e authored by Johannes Berg's avatar Johannes Berg

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: default avatarJohannes Berg <johannes.berg@intel.com>
parent 560d2682
...@@ -437,7 +437,7 @@ ...@@ -437,7 +437,7 @@
</section> </section>
!Finclude/net/mac80211.h ieee80211_get_buffered_bc !Finclude/net/mac80211.h ieee80211_get_buffered_bc
!Finclude/net/mac80211.h ieee80211_beacon_get !Finclude/net/mac80211.h ieee80211_beacon_get
!Finclude/net/mac80211.h ieee80211_sta_eosp_irqsafe !Finclude/net/mac80211.h ieee80211_sta_eosp
!Finclude/net/mac80211.h ieee80211_frame_release_type !Finclude/net/mac80211.h ieee80211_frame_release_type
!Finclude/net/mac80211.h ieee80211_sta_ps_transition !Finclude/net/mac80211.h ieee80211_sta_ps_transition
!Finclude/net/mac80211.h ieee80211_sta_ps_transition_ni !Finclude/net/mac80211.h ieee80211_sta_ps_transition_ni
......
...@@ -1946,14 +1946,14 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb); ...@@ -1946,14 +1946,14 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
* filter those response frames except in the case of frames that * filter those response frames except in the case of frames that
* are buffered in the driver -- those must remain buffered to avoid * are buffered in the driver -- those must remain buffered to avoid
* reordering. Because it is possible that no frames are released * reordering. Because it is possible that no frames are released
* in this case, the driver must call ieee80211_sta_eosp_irqsafe() * in this case, the driver must call ieee80211_sta_eosp()
* to indicate to mac80211 that the service period ended anyway. * to indicate to mac80211 that the service period ended anyway.
* *
* Finally, if frames from multiple TIDs are released from mac80211 * Finally, if frames from multiple TIDs are released from mac80211
* but the driver might reorder them, it must clear & set the flags * but the driver might reorder them, it must clear & set the flags
* appropriately (only the last frame may have %IEEE80211_TX_STATUS_EOSP) * appropriately (only the last frame may have %IEEE80211_TX_STATUS_EOSP)
* and also take care of the EOSP and MORE_DATA bits in the frame. * and also take care of the EOSP and MORE_DATA bits in the frame.
* The driver may also use ieee80211_sta_eosp_irqsafe() in this case. * The driver may also use ieee80211_sta_eosp() in this case.
*/ */
/** /**
...@@ -2506,7 +2506,7 @@ enum ieee80211_roc_type { ...@@ -2506,7 +2506,7 @@ enum ieee80211_roc_type {
* setting the EOSP flag in the QoS header of the frames. Also, when the * setting the EOSP flag in the QoS header of the frames. Also, when the
* service period ends, the driver must set %IEEE80211_TX_STATUS_EOSP * service period ends, the driver must set %IEEE80211_TX_STATUS_EOSP
* on the last frame in the SP. Alternatively, it may call the function * on the last frame in the SP. Alternatively, it may call the function
* ieee80211_sta_eosp_irqsafe() to inform mac80211 of the end of the SP. * ieee80211_sta_eosp() to inform mac80211 of the end of the SP.
* This callback must be atomic. * This callback must be atomic.
* @allow_buffered_frames: Prepare device to allow the given number of frames * @allow_buffered_frames: Prepare device to allow the given number of frames
* to go out to the given station. The frames will be sent by mac80211 * to go out to the given station. The frames will be sent by mac80211
...@@ -2517,7 +2517,7 @@ enum ieee80211_roc_type { ...@@ -2517,7 +2517,7 @@ enum ieee80211_roc_type {
* them between the TIDs, it must set the %IEEE80211_TX_STATUS_EOSP flag * them between the TIDs, it must set the %IEEE80211_TX_STATUS_EOSP flag
* on the last frame and clear it on all others and also handle the EOSP * on the last frame and clear it on all others and also handle the EOSP
* bit in the QoS header correctly. Alternatively, it can also call the * bit in the QoS header correctly. Alternatively, it can also call the
* ieee80211_sta_eosp_irqsafe() function. * ieee80211_sta_eosp() function.
* The @tids parameter is a bitmap and tells the driver which TIDs the * The @tids parameter is a bitmap and tells the driver which TIDs the
* frames will be on; it will at most have two bits set. * frames will be on; it will at most have two bits set.
* This callback must be atomic. * This callback must be atomic.
...@@ -3857,14 +3857,17 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw, ...@@ -3857,14 +3857,17 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
* %IEEE80211_TX_STATUS_EOSP bit and call this function instead. * %IEEE80211_TX_STATUS_EOSP bit and call this function instead.
* This applies for PS-Poll as well as uAPSD. * This applies for PS-Poll as well as uAPSD.
* *
* Note that there is no non-_irqsafe version right now as * Note that just like with _tx_status() and _rx() drivers must
* it wasn't needed, but just like _tx_status() and _rx() * not mix calls to irqsafe/non-irqsafe versions, this function
* must not be mixed in irqsafe/non-irqsafe versions, this * must not be mixed with those either. Use the all irqsafe, or
* function must not be mixed with those either. Use the * all non-irqsafe, don't mix!
* all irqsafe, or all non-irqsafe, don't mix! If you need *
* the non-irqsafe version of this, you need to add it. * NB: the _irqsafe version of this function doesn't exist, no
* driver needs it right now. Don't call this function if
* you'd need the _irqsafe version, look at the git history
* and restore the _irqsafe version!
*/ */
void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta); void ieee80211_sta_eosp(struct ieee80211_sta *pubsta);
/** /**
* ieee80211_iter_keys - iterate keys programmed into the device * ieee80211_iter_keys - iterate keys programmed into the device
......
...@@ -800,11 +800,6 @@ enum sdata_queue_type { ...@@ -800,11 +800,6 @@ enum sdata_queue_type {
enum { enum {
IEEE80211_RX_MSG = 1, IEEE80211_RX_MSG = 1,
IEEE80211_TX_STATUS_MSG = 2, IEEE80211_TX_STATUS_MSG = 2,
IEEE80211_EOSP_MSG = 3,
};
struct skb_eosp_msg_data {
u8 sta[ETH_ALEN], iface[ETH_ALEN];
}; };
enum queue_stop_reason { enum queue_stop_reason {
......
...@@ -226,8 +226,6 @@ u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) ...@@ -226,8 +226,6 @@ u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
static void ieee80211_tasklet_handler(unsigned long data) static void ieee80211_tasklet_handler(unsigned long data)
{ {
struct ieee80211_local *local = (struct ieee80211_local *) data; struct ieee80211_local *local = (struct ieee80211_local *) data;
struct sta_info *sta, *tmp;
struct skb_eosp_msg_data *eosp_data;
struct sk_buff *skb; struct sk_buff *skb;
while ((skb = skb_dequeue(&local->skb_queue)) || while ((skb = skb_dequeue(&local->skb_queue)) ||
...@@ -243,18 +241,6 @@ static void ieee80211_tasklet_handler(unsigned long data) ...@@ -243,18 +241,6 @@ static void ieee80211_tasklet_handler(unsigned long data)
skb->pkt_type = 0; skb->pkt_type = 0;
ieee80211_tx_status(&local->hw, skb); ieee80211_tx_status(&local->hw, skb);
break; break;
case IEEE80211_EOSP_MSG:
eosp_data = (void *)skb->cb;
for_each_sta_info(local, eosp_data->sta, sta, tmp) {
/* skip wrong virtual interface */
if (memcmp(eosp_data->iface,
sta->sdata->vif.addr, ETH_ALEN))
continue;
clear_sta_flag(sta, WLAN_STA_SP);
break;
}
dev_kfree_skb(skb);
break;
default: default:
WARN(1, "mac80211: Packet is of unknown type %d\n", WARN(1, "mac80211: Packet is of unknown type %d\n",
skb->pkt_type); skb->pkt_type);
......
...@@ -1390,30 +1390,16 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw, ...@@ -1390,30 +1390,16 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
} }
EXPORT_SYMBOL(ieee80211_sta_block_awake); EXPORT_SYMBOL(ieee80211_sta_block_awake);
void ieee80211_sta_eosp_irqsafe(struct ieee80211_sta *pubsta) void ieee80211_sta_eosp(struct ieee80211_sta *pubsta)
{ {
struct sta_info *sta = container_of(pubsta, struct sta_info, sta); struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
struct ieee80211_local *local = sta->local; struct ieee80211_local *local = sta->local;
struct sk_buff *skb;
struct skb_eosp_msg_data *data;
trace_api_eosp(local, pubsta); trace_api_eosp(local, pubsta);
skb = alloc_skb(0, GFP_ATOMIC); clear_sta_flag(sta, WLAN_STA_SP);
if (!skb) {
/* too bad ... but race is better than loss */
clear_sta_flag(sta, WLAN_STA_SP);
return;
}
data = (void *)skb->cb;
memcpy(data->sta, pubsta->addr, ETH_ALEN);
memcpy(data->iface, sta->sdata->vif.addr, ETH_ALEN);
skb->pkt_type = IEEE80211_EOSP_MSG;
skb_queue_tail(&local->skb_queue, skb);
tasklet_schedule(&local->tasklet);
} }
EXPORT_SYMBOL(ieee80211_sta_eosp_irqsafe); EXPORT_SYMBOL(ieee80211_sta_eosp);
void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta,
u8 tid, bool buffered) u8 tid, bool buffered)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment