Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 150812
b: refs/heads/master
c: 8f77f38
h: refs/heads/master
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed Jun 10, 2009
1 parent ab27dcb commit d2efdef
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 79 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: fc240e3fc5791c572402b0857948da7b1e68d77f
refs/heads/master: 8f77f3849cc3ae2d6df9301785a3d316ea7d7ee1
4 changes: 0 additions & 4 deletions trunk/include/linux/skbuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,6 @@ typedef unsigned char *sk_buff_data_t;
* @tc_verd: traffic control verdict
* @ndisc_nodetype: router type (from link layer)
* @do_not_encrypt: set to prevent encryption of this frame
* @requeue: set to indicate that the wireless core should attempt
* a software retry on this frame if we failed to
* receive an ACK for it
* @dma_cookie: a cookie to one of several possible DMA operations
* done by skb DMA functions
* @secmark: security marking
Expand Down Expand Up @@ -380,7 +377,6 @@ struct sk_buff {
#endif
#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
__u8 do_not_encrypt:1;
__u8 requeue:1;
#endif
/* 0/13/14 bit hole */

Expand Down
3 changes: 3 additions & 0 deletions trunk/include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ struct ieee80211_bss_conf {
* @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211,
* used to indicate that a pending frame requires TX processing before
* it can be sent out.
* @IEEE80211_TX_INTFL_RETRIED: completely internal to mac80211,
* used to indicate that a frame was already retried due to PS
*/
enum mac80211_tx_control_flags {
IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
Expand All @@ -256,6 +258,7 @@ enum mac80211_tx_control_flags {
IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12),
IEEE80211_TX_INTFL_RCALGO = BIT(13),
IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14),
IEEE80211_TX_INTFL_RETRIED = BIT(15),
};

/**
Expand Down
1 change: 0 additions & 1 deletion trunk/net/core/skbuff.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,6 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->vlan_tci = old->vlan_tci;
#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
new->do_not_encrypt = old->do_not_encrypt;
new->requeue = old->requeue;
#endif

skb_copy_secmark(new, old);
Expand Down
5 changes: 5 additions & 0 deletions trunk/net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,7 @@ enum queue_stop_reason {
IEEE80211_QUEUE_STOP_REASON_AGGREGATION,
IEEE80211_QUEUE_STOP_REASON_SUSPEND,
IEEE80211_QUEUE_STOP_REASON_PENDING,
IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
};

struct ieee80211_master_priv {
Expand Down Expand Up @@ -1121,6 +1122,10 @@ void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
enum queue_stop_reason reason);
void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
enum queue_stop_reason reason);
void ieee80211_add_pending_skb(struct ieee80211_local *local,
struct sk_buff *skb);
int ieee80211_add_pending_skbs(struct ieee80211_local *local,
struct sk_buff_head *skbs);

void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
u16 transaction, u16 auth_alg,
Expand Down
61 changes: 6 additions & 55 deletions trunk/net/mac80211/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,60 +369,12 @@ static void ieee80211_tasklet_handler(unsigned long data)
}
}

/* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to
* make a prepared TX frame (one that has been given to hw) to look like brand
* new IEEE 802.11 frame that is ready to go through TX processing again.
*/
static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
struct ieee80211_key *key,
struct sk_buff *skb)
{
unsigned int hdrlen, iv_len, mic_len;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;

hdrlen = ieee80211_hdrlen(hdr->frame_control);

if (!key)
goto no_key;

switch (key->conf.alg) {
case ALG_WEP:
iv_len = WEP_IV_LEN;
mic_len = WEP_ICV_LEN;
break;
case ALG_TKIP:
iv_len = TKIP_IV_LEN;
mic_len = TKIP_ICV_LEN;
break;
case ALG_CCMP:
iv_len = CCMP_HDR_LEN;
mic_len = CCMP_MIC_LEN;
break;
default:
goto no_key;
}

if (skb->len >= hdrlen + mic_len &&
!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
skb_trim(skb, skb->len - mic_len);
if (skb->len >= hdrlen + iv_len) {
memmove(skb->data + iv_len, skb->data, hdrlen);
hdr = (struct ieee80211_hdr *)skb_pull(skb, iv_len);
}

no_key:
if (ieee80211_is_data_qos(hdr->frame_control)) {
hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
memmove(skb->data + IEEE80211_QOS_CTL_LEN, skb->data,
hdrlen - IEEE80211_QOS_CTL_LEN);
skb_pull(skb, IEEE80211_QOS_CTL_LEN);
}
}

static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
struct sta_info *sta,
struct sk_buff *skb)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);

sta->tx_filtered_count++;

/*
Expand Down Expand Up @@ -464,16 +416,15 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
*/
if (test_sta_flags(sta, WLAN_STA_PS) &&
skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) {
ieee80211_remove_tx_extra(local, sta->key, skb);
skb_queue_tail(&sta->tx_filtered, skb);
return;
}

if (!test_sta_flags(sta, WLAN_STA_PS) && !skb->requeue) {
if (!test_sta_flags(sta, WLAN_STA_PS) &&
!(info->flags & IEEE80211_TX_INTFL_RETRIED)) {
/* Software retry the packet once */
skb->requeue = 1;
ieee80211_remove_tx_extra(local, sta->key, skb);
dev_queue_xmit(skb);
info->flags |= IEEE80211_TX_INTFL_RETRIED;
ieee80211_add_pending_skb(local, skb);
return;
}

Expand Down
25 changes: 9 additions & 16 deletions trunk/net/mac80211/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -797,8 +797,7 @@ static int ap_sta_ps_end(struct sta_info *sta)
{
struct ieee80211_sub_if_data *sdata = sta->sdata;
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
int sent = 0;
int sent, buffered;

atomic_dec(&sdata->bss->num_sta_ps);

Expand All @@ -814,22 +813,16 @@ static int ap_sta_ps_end(struct sta_info *sta)
#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */

/* Send all buffered frames to the station */
while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) {
sent++;
skb->requeue = 1;
dev_queue_xmit(skb);
}
while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) {
local->total_ps_buffered--;
sent++;
sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered);
buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf);
sent += buffered;
local->total_ps_buffered -= buffered;

#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "%s: STA %pM aid %d send PS frame "
"since STA not sleeping anymore\n", sdata->dev->name,
sta->sta.addr, sta->sta.aid);
printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames "
"since STA not sleeping anymore\n", sdata->dev->name,
sta->sta.addr, sta->sta.aid, sent - buffered, buffered);
#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
skb->requeue = 1;
dev_queue_xmit(skb);
}

return sent;
}
Expand Down
3 changes: 2 additions & 1 deletion trunk/net/mac80211/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
sta_info_set_tim_bit(sta);

info->control.jiffies = jiffies;
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
skb_queue_tail(&sta->ps_tx_buf, tx->skb);
return TX_QUEUED;
}
Expand All @@ -420,7 +421,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
* frame filtering and keeps a station blacklist on its own
* (e.g: p54), so that frames can be delivered unimpeded.
*
* Note: It should be save to disable the filter now.
* Note: It should be safe to disable the filter now.
* As, it is really unlikely that we still have any pending
* frame for this station in the hw's buffers/fifos left,
* that is not rejected with a unsuccessful tx_status yet.
Expand Down
46 changes: 46 additions & 0 deletions trunk/net/mac80211/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,52 @@ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
}
EXPORT_SYMBOL(ieee80211_stop_queue);

void ieee80211_add_pending_skb(struct ieee80211_local *local,
struct sk_buff *skb)
{
struct ieee80211_hw *hw = &local->hw;
unsigned long flags;
int queue = skb_get_queue_mapping(skb);

spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
__ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
__ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_PENDING);
skb_queue_tail(&local->pending[queue], skb);
__ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}

int ieee80211_add_pending_skbs(struct ieee80211_local *local,
struct sk_buff_head *skbs)
{
struct ieee80211_hw *hw = &local->hw;
struct sk_buff *skb;
unsigned long flags;
int queue, ret = 0, i;

spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
for (i = 0; i < hw->queues; i++)
__ieee80211_stop_queue(hw, i,
IEEE80211_QUEUE_STOP_REASON_SKB_ADD);

while ((skb = skb_dequeue(skbs))) {
ret++;
queue = skb_get_queue_mapping(skb);
skb_queue_tail(&local->pending[queue], skb);
}

for (i = 0; i < hw->queues; i++) {
if (ret)
__ieee80211_stop_queue(hw, i,
IEEE80211_QUEUE_STOP_REASON_PENDING);
__ieee80211_wake_queue(hw, i,
IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
}
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);

return ret;
}

void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
enum queue_stop_reason reason)
{
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/mac80211/wme.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
* Now we know the 1d priority, fill in the QoS header if
* there is one (and we haven't done this before).
*/
if (!skb->requeue && ieee80211_is_data_qos(hdr->frame_control)) {
if (ieee80211_is_data_qos(hdr->frame_control)) {
u8 *p = ieee80211_get_qos_ctl(hdr);
u8 ack_policy = 0;
tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
Expand Down

0 comments on commit d2efdef

Please sign in to comment.