Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 266523
b: refs/heads/master
c: 47086fc
h: refs/heads/master
i:
  266521: 3c91176
  266519: 6a55de8
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed Sep 30, 2011
1 parent e2ffaea commit 1d4ea32
Show file tree
Hide file tree
Showing 10 changed files with 245 additions and 90 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4049e09acdf4ffd270cb8fbf1cf5b39c3d02357c
refs/heads/master: 47086fc51aa2220f58049704a8b73e4fcdf372b9
2 changes: 1 addition & 1 deletion trunk/drivers/net/wireless/iwlegacy/iwl-4965-tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ int iwl4965_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
sta_priv = (void *)sta->drv_priv;

if (sta_priv && sta_priv->asleep &&
(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)) {
(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)) {
/*
* This sends an asynchronous command to the device,
* but we can rely on it being processed before the
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
sta_priv = (void *)info->control.sta->drv_priv;

if (sta_priv && sta_priv->asleep &&
(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)) {
(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)) {
/*
* This sends an asynchronous command to the device,
* but we can rely on it being processed before the
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/wireless/p54/txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb,
if (!(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
*flags |= P54_HDR_FLAG_DATA_OUT_SEQNR;

if (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)
if (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)
*flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;

if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
Expand Down
24 changes: 17 additions & 7 deletions trunk/include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,9 @@ struct ieee80211_bss_conf {
* used to indicate that a frame was already retried due to PS
* @IEEE80211_TX_INTFL_DONT_ENCRYPT: completely internal to mac80211,
* used to indicate frame should not be encrypted
* @IEEE80211_TX_CTL_PSPOLL_RESPONSE: (internal?)
* This frame is a response to a PS-poll frame and should be sent
* although the station is in powersave mode.
* @IEEE80211_TX_CTL_POLL_RESPONSE: This frame is a response to a poll
* frame (PS-Poll or uAPSD) and should be sent although the station
* is in powersave mode.
* @IEEE80211_TX_CTL_MORE_FRAMES: More frames will be passed to the
* transmit function after the current frame, this can be used
* by drivers to kick the DMA queue only if unset or when the
Expand All @@ -367,6 +367,10 @@ struct ieee80211_bss_conf {
* @IEEE80211_TX_CTL_NO_CCK_RATE: This frame will be sent at non CCK rate.
* This flag is actually used for management frame especially for P2P
* frames not being sent at CCK rate in 2GHz band.
* @IEEE80211_TX_STATUS_EOSP: This packet marks the end of service period,
* when its status is reported the service period ends. For frames in
* an SP that mac80211 transmits, it is already set; for driver frames
* the driver may set this flag.
*
* Note: If you have to add new flags to the enumeration, then don't
* forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary.
Expand All @@ -388,7 +392,7 @@ enum mac80211_tx_control_flags {
IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14),
IEEE80211_TX_INTFL_RETRIED = BIT(15),
IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16),
IEEE80211_TX_CTL_PSPOLL_RESPONSE = BIT(17),
IEEE80211_TX_CTL_POLL_RESPONSE = BIT(17),
IEEE80211_TX_CTL_MORE_FRAMES = BIT(18),
IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19),
IEEE80211_TX_INTFL_HAS_RADIOTAP = BIT(20),
Expand All @@ -398,6 +402,7 @@ enum mac80211_tx_control_flags {
IEEE80211_TX_CTL_TX_OFFCHAN = BIT(25),
IEEE80211_TX_INTFL_TKIP_MIC_FAILURE = BIT(26),
IEEE80211_TX_CTL_NO_CCK_RATE = BIT(27),
IEEE80211_TX_STATUS_EOSP = BIT(28),
};

#define IEEE80211_TX_CTL_STBC_SHIFT 23
Expand All @@ -411,9 +416,9 @@ enum mac80211_tx_control_flags {
IEEE80211_TX_CTL_SEND_AFTER_DTIM | IEEE80211_TX_CTL_AMPDU | \
IEEE80211_TX_STAT_TX_FILTERED | IEEE80211_TX_STAT_ACK | \
IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_STAT_AMPDU_NO_BACK | \
IEEE80211_TX_CTL_RATE_CTRL_PROBE | IEEE80211_TX_CTL_PSPOLL_RESPONSE | \
IEEE80211_TX_CTL_RATE_CTRL_PROBE | IEEE80211_TX_CTL_POLL_RESPONSE | \
IEEE80211_TX_CTL_MORE_FRAMES | IEEE80211_TX_CTL_LDPC | \
IEEE80211_TX_CTL_STBC)
IEEE80211_TX_CTL_STBC | IEEE80211_TX_STATUS_EOSP)

/**
* enum mac80211_rate_control_flags - per-rate flags set by the
Expand Down Expand Up @@ -1624,9 +1629,12 @@ enum ieee80211_tx_sync_type {
/**
* enum ieee80211_frame_release_type - frame release reason
* @IEEE80211_FRAME_RELEASE_PSPOLL: frame released for PS-Poll
* @IEEE80211_FRAME_RELEASE_UAPSD: frame(s) released due to
* frame received on trigger-enabled AC
*/
enum ieee80211_frame_release_type {
IEEE80211_FRAME_RELEASE_PSPOLL,
IEEE80211_FRAME_RELEASE_UAPSD,
};

/**
Expand Down Expand Up @@ -1954,7 +1962,9 @@ enum ieee80211_frame_release_type {
* In the case this is used for uAPSD, the @num_frames parameter may be
* bigger than one, but the driver may send fewer frames (it must send
* at least one, however). In this case it is also responsible for
* setting the EOSP flag in the QoS header of the frames.
* 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
* on the last frame in the SP.
* This callback must be atomic.
*/
struct ieee80211_ops {
Expand Down
102 changes: 74 additions & 28 deletions trunk/net/mac80211/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,79 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start)
}
EXPORT_SYMBOL(ieee80211_sta_ps_transition);

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx)
{
struct ieee80211_sub_if_data *sdata = rx->sdata;
struct ieee80211_hdr *hdr = (void *)rx->skb->data;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
int tid, ac;

if (!rx->sta || !(status->rx_flags & IEEE80211_RX_RA_MATCH))
return RX_CONTINUE;

if (sdata->vif.type != NL80211_IFTYPE_AP &&
sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
return RX_CONTINUE;

/*
* The device handles station powersave, so don't do anything about
* uAPSD and PS-Poll frames (the latter shouldn't even come up from
* it to mac80211 since they're handled.)
*/
if (sdata->local->hw.flags & IEEE80211_HW_AP_LINK_PS)
return RX_CONTINUE;

/*
* Don't do anything if the station isn't already asleep. In
* the uAPSD case, the station will probably be marked asleep,
* in the PS-Poll case the station must be confused ...
*/
if (!test_sta_flags(rx->sta, WLAN_STA_PS_STA))
return RX_CONTINUE;

if (unlikely(ieee80211_is_pspoll(hdr->frame_control))) {
if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER))
ieee80211_sta_ps_deliver_poll_response(rx->sta);
else
set_sta_flags(rx->sta, WLAN_STA_PSPOLL);

/* Free PS Poll skb here instead of returning RX_DROP that would
* count as an dropped frame. */
dev_kfree_skb(rx->skb);

return RX_QUEUED;
} else if (!ieee80211_has_morefrags(hdr->frame_control) &&
!(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
ieee80211_has_pm(hdr->frame_control) &&
(ieee80211_is_data_qos(hdr->frame_control) ||
ieee80211_is_qos_nullfunc(hdr->frame_control))) {
tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
ac = ieee802_1d_to_ac[tid & 7];

/*
* If this AC is not trigger-enabled do nothing.
*
* NB: This could/should check a separate bitmap of trigger-
* enabled queues, but for now we only implement uAPSD w/o
* TSPEC changes to the ACs, so they're always the same.
*/
if (!(rx->sta->sta.uapsd_queues & BIT(ac)))
return RX_CONTINUE;

/* if we are in a service period, do nothing */
if (test_sta_flags(rx->sta, WLAN_STA_SP))
return RX_CONTINUE;

if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER))
ieee80211_sta_ps_deliver_uapsd(rx->sta);
else
set_sta_flags(rx->sta, WLAN_STA_UAPSD);
}

return RX_CONTINUE;
}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
{
Expand Down Expand Up @@ -1472,33 +1545,6 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
return RX_CONTINUE;
}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
{
struct ieee80211_sub_if_data *sdata = rx->sdata;
__le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);

if (likely(!rx->sta || !ieee80211_is_pspoll(fc) ||
!(status->rx_flags & IEEE80211_RX_RA_MATCH)))
return RX_CONTINUE;

if ((sdata->vif.type != NL80211_IFTYPE_AP) &&
(sdata->vif.type != NL80211_IFTYPE_AP_VLAN))
return RX_DROP_UNUSABLE;

if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER))
ieee80211_sta_ps_deliver_poll_response(rx->sta);
else
set_sta_flags(rx->sta, WLAN_STA_PSPOLL);

/* Free PS Poll skb here instead of returning RX_DROP that would
* count as an dropped frame. */
dev_kfree_skb(rx->skb);

return RX_QUEUED;
}

static ieee80211_rx_result debug_noinline
ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx)
{
Expand Down Expand Up @@ -2567,9 +2613,9 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx)

CALL_RXH(ieee80211_rx_h_decrypt)
CALL_RXH(ieee80211_rx_h_check_more_data)
CALL_RXH(ieee80211_rx_h_uapsd_and_pspoll)
CALL_RXH(ieee80211_rx_h_sta_process)
CALL_RXH(ieee80211_rx_h_defragment)
CALL_RXH(ieee80211_rx_h_ps_poll)
CALL_RXH(ieee80211_rx_h_michael_mic_verify)
/* must be after MMIC verify so header is counted in MPDU mic */
#ifdef CONFIG_MAC80211_MESH
Expand Down
Loading

0 comments on commit 1d4ea32

Please sign in to comment.