aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-11-18 19:08:30 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-19 11:08:56 -0500
commit7351c6bd482712e5e3ec9dffc547de0e0863efb0 (patch)
tree1847c0470af79727b58611a69fa82384bd904d60
parentad4bb6f8883a13bb0f65b194dae36c62a02ac779 (diff)
mac80211: request TX status where needed
Right now all frames mac80211 hands to the driver have the IEEE80211_TX_CTL_REQ_TX_STATUS flag set to request TX status. This isn't really necessary, only the injected frames need TX status (the latter for hostapd) so move setting this flag. The rate control algorithms also need TX status, but they don't require it. Also, rt2x00 uses that bit for its own purposes and seems to require it being set for all frames, but that can be fixed in rt2x00. This doesn't really change anything for any drivers but in the future drivers using hw-rate control may opt to not report TX status for frames that don't have the IEEE80211_TX_CTL_REQ_TX_STATUS flag set. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Ivo van Doorn <IvDoorn@gmail.com> [rt2x00 bits] Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h5
-rw-r--r--include/net/mac80211.h2
-rw-r--r--net/mac80211/tx.c4
7 files changed, 23 insertions, 14 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 6c6d0ac35549..4a4b7e42fe6e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -205,6 +205,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
205 enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); 205 enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
206 unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb); 206 unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
207 u8 rate_idx, rate_flags, retry_rates; 207 u8 rate_idx, rate_flags, retry_rates;
208 u8 skbdesc_flags = skbdesc->flags;
208 unsigned int i; 209 unsigned int i;
209 bool success; 210 bool success;
210 211
@@ -287,12 +288,12 @@ void rt2x00lib_txdone(struct queue_entry *entry,
287 } 288 }
288 289
289 /* 290 /*
290 * Only send the status report to mac80211 when TX status was 291 * Only send the status report to mac80211 when it's a frame
291 * requested by it. If this was a extra frame coming through 292 * that originated in mac80211. If this was a extra frame coming
292 * a mac80211 library call (RTS/CTS) then we should not send the 293 * through a mac80211 library call (RTS/CTS) then we should not
293 * status report back. 294 * send the status report back.
294 */ 295 */
295 if (tx_info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) 296 if (!(skbdesc_flags & SKBDESC_NOT_MAC80211))
296 ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); 297 ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb);
297 else 298 else
298 dev_kfree_skb_irq(entry->skb); 299 dev_kfree_skb_irq(entry->skb);
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index c1f48acaee41..be2e37fb4071 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -162,8 +162,10 @@ void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length);
162 * rt2x00queue_write_tx_frame - Write TX frame to hardware 162 * rt2x00queue_write_tx_frame - Write TX frame to hardware
163 * @queue: Queue over which the frame should be send 163 * @queue: Queue over which the frame should be send
164 * @skb: The skb to send 164 * @skb: The skb to send
165 * @local: frame is not from mac80211
165 */ 166 */
166int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb); 167int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
168 bool local);
167 169
168/** 170/**
169 * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware 171 * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index eed093d34532..9c90ceb0ffcc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -66,7 +66,6 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
66 rts_info = IEEE80211_SKB_CB(skb); 66 rts_info = IEEE80211_SKB_CB(skb);
67 rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_RTS_CTS; 67 rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_RTS_CTS;
68 rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_CTS_PROTECT; 68 rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_CTS_PROTECT;
69 rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS;
70 69
71 if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) 70 if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
72 rts_info->flags |= IEEE80211_TX_CTL_NO_ACK; 71 rts_info->flags |= IEEE80211_TX_CTL_NO_ACK;
@@ -91,7 +90,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
91 frag_skb->data, data_length, tx_info, 90 frag_skb->data, data_length, tx_info,
92 (struct ieee80211_rts *)(skb->data)); 91 (struct ieee80211_rts *)(skb->data));
93 92
94 retval = rt2x00queue_write_tx_frame(queue, skb); 93 retval = rt2x00queue_write_tx_frame(queue, skb, true);
95 if (retval) { 94 if (retval) {
96 dev_kfree_skb_any(skb); 95 dev_kfree_skb_any(skb);
97 WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); 96 WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
@@ -153,7 +152,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
153 goto exit_fail; 152 goto exit_fail;
154 } 153 }
155 154
156 if (rt2x00queue_write_tx_frame(queue, skb)) 155 if (rt2x00queue_write_tx_frame(queue, skb, false))
157 goto exit_fail; 156 goto exit_fail;
158 157
159 if (rt2x00queue_threshold(queue)) 158 if (rt2x00queue_threshold(queue))
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 02972a036bce..eaedee8c05c8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -454,7 +454,8 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry,
454 rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); 454 rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid);
455} 455}
456 456
457int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) 457int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
458 bool local)
458{ 459{
459 struct ieee80211_tx_info *tx_info; 460 struct ieee80211_tx_info *tx_info;
460 struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); 461 struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
@@ -495,6 +496,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
495 skbdesc->tx_rate_idx = rate_idx; 496 skbdesc->tx_rate_idx = rate_idx;
496 skbdesc->tx_rate_flags = rate_flags; 497 skbdesc->tx_rate_flags = rate_flags;
497 498
499 if (local)
500 skbdesc->flags |= SKBDESC_NOT_MAC80211;
501
498 /* 502 /*
499 * When hardware encryption is supported, and this frame 503 * When hardware encryption is supported, and this frame
500 * is to be encrypted, we should strip the IV/EIV data from 504 * is to be encrypted, we should strip the IV/EIV data from
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 97c7895c0ece..70775e5ba1ac 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -94,12 +94,15 @@ enum data_queue_qid {
94 * mac80211 but was stripped for processing by the driver. 94 * mac80211 but was stripped for processing by the driver.
95 * @SKBDESC_L2_PADDED: Payload has been padded for 4-byte alignment, 95 * @SKBDESC_L2_PADDED: Payload has been padded for 4-byte alignment,
96 * the padded bytes are located between header and payload. 96 * the padded bytes are located between header and payload.
97 * @SKBDESC_NOT_MAC80211: Frame didn't originate from mac80211,
98 * don't try to pass it back.
97 */ 99 */
98enum skb_frame_desc_flags { 100enum skb_frame_desc_flags {
99 SKBDESC_DMA_MAPPED_RX = 1 << 0, 101 SKBDESC_DMA_MAPPED_RX = 1 << 0,
100 SKBDESC_DMA_MAPPED_TX = 1 << 1, 102 SKBDESC_DMA_MAPPED_TX = 1 << 1,
101 SKBDESC_IV_STRIPPED = 1 << 2, 103 SKBDESC_IV_STRIPPED = 1 << 2,
102 SKBDESC_L2_PADDED = 1 << 3 104 SKBDESC_L2_PADDED = 1 << 3,
105 SKBDESC_NOT_MAC80211 = 1 << 4,
103}; 106};
104 107
105/** 108/**
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index f34f4ca7016c..3754ea405c88 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -219,7 +219,7 @@ struct ieee80211_bss_conf {
219 * 219 *
220 * These flags are used with the @flags member of &ieee80211_tx_info. 220 * These flags are used with the @flags member of &ieee80211_tx_info.
221 * 221 *
222 * @IEEE80211_TX_CTL_REQ_TX_STATUS: request TX status callback for this frame. 222 * @IEEE80211_TX_CTL_REQ_TX_STATUS: require TX status callback for this frame.
223 * @IEEE80211_TX_CTL_ASSIGN_SEQ: The driver has to assign a sequence 223 * @IEEE80211_TX_CTL_ASSIGN_SEQ: The driver has to assign a sequence
224 * number to this frame, taking care of not overwriting the fragment 224 * number to this frame, taking care of not overwriting the fragment
225 * number and increasing the sequence number only when the 225 * number and increasing the sequence number only when the
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 5af2f40ea4db..943def2b07df 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1443,8 +1443,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1443 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); 1443 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
1444 } 1444 }
1445 1445
1446 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
1447
1448 rcu_read_lock(); 1446 rcu_read_lock();
1449 1447
1450 if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) { 1448 if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) {
@@ -1575,6 +1573,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1575 1573
1576 memset(info, 0, sizeof(*info)); 1574 memset(info, 0, sizeof(*info));
1577 1575
1576 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
1577
1578 /* pass the radiotap header up to xmit */ 1578 /* pass the radiotap header up to xmit */
1579 ieee80211_xmit(IEEE80211_DEV_TO_SUB_IF(dev), skb); 1579 ieee80211_xmit(IEEE80211_DEV_TO_SUB_IF(dev), skb);
1580 return NETDEV_TX_OK; 1580 return NETDEV_TX_OK;