diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-05-15 06:55:29 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-21 21:48:11 -0400 |
commit | e039fa4a4195ac4ee895e6f3d1334beed63256fe (patch) | |
tree | cfd0762d73df96b73052378be7b157c4ac6e7035 /drivers/net/wireless/zd1211rw | |
parent | e24549485f859be6518929bb1c9c0257d79f033d (diff) |
mac80211: move TX info into skb->cb
This patch converts mac80211 and all drivers to have transmit
information and status in skb->cb rather than allocating extra
memory for it and copying all the data around. To make it fit,
a union is used where only data that is necessary for all steps
is kept outside of the union.
A number of fixes were done by Ivo, as well as the rt2x00 part
of this patch.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/zd1211rw')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 156 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.h | 16 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.c | 6 |
3 files changed, 43 insertions, 135 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 99c508c09e5..edb1aefb4ad 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -224,36 +224,6 @@ out: | |||
224 | return r; | 224 | return r; |
225 | } | 225 | } |
226 | 226 | ||
227 | /** | ||
228 | * clear_tx_skb_control_block - clears the control block of tx skbuffs | ||
229 | * @skb: a &struct sk_buff pointer | ||
230 | * | ||
231 | * This clears the control block of skbuff buffers, which were transmitted to | ||
232 | * the device. Notify that the function is not thread-safe, so prevent | ||
233 | * multiple calls. | ||
234 | */ | ||
235 | static void clear_tx_skb_control_block(struct sk_buff *skb) | ||
236 | { | ||
237 | struct zd_tx_skb_control_block *cb = | ||
238 | (struct zd_tx_skb_control_block *)skb->cb; | ||
239 | |||
240 | kfree(cb->control); | ||
241 | cb->control = NULL; | ||
242 | } | ||
243 | |||
244 | /** | ||
245 | * kfree_tx_skb - frees a tx skbuff | ||
246 | * @skb: a &struct sk_buff pointer | ||
247 | * | ||
248 | * Frees the tx skbuff. Frees also the allocated control structure in the | ||
249 | * control block if necessary. | ||
250 | */ | ||
251 | static void kfree_tx_skb(struct sk_buff *skb) | ||
252 | { | ||
253 | clear_tx_skb_control_block(skb); | ||
254 | dev_kfree_skb_any(skb); | ||
255 | } | ||
256 | |||
257 | static void zd_op_stop(struct ieee80211_hw *hw) | 227 | static void zd_op_stop(struct ieee80211_hw *hw) |
258 | { | 228 | { |
259 | struct zd_mac *mac = zd_hw_mac(hw); | 229 | struct zd_mac *mac = zd_hw_mac(hw); |
@@ -276,40 +246,15 @@ static void zd_op_stop(struct ieee80211_hw *hw) | |||
276 | 246 | ||
277 | 247 | ||
278 | while ((skb = skb_dequeue(ack_wait_queue))) | 248 | while ((skb = skb_dequeue(ack_wait_queue))) |
279 | kfree_tx_skb(skb); | 249 | dev_kfree_skb_any(skb); |
280 | } | ||
281 | |||
282 | /** | ||
283 | * init_tx_skb_control_block - initializes skb control block | ||
284 | * @skb: a &sk_buff pointer | ||
285 | * @dev: pointer to the mac80221 device | ||
286 | * @control: mac80211 tx control applying for the frame in @skb | ||
287 | * | ||
288 | * Initializes the control block of the skbuff to be transmitted. | ||
289 | */ | ||
290 | static int init_tx_skb_control_block(struct sk_buff *skb, | ||
291 | struct ieee80211_hw *hw, | ||
292 | struct ieee80211_tx_control *control) | ||
293 | { | ||
294 | struct zd_tx_skb_control_block *cb = | ||
295 | (struct zd_tx_skb_control_block *)skb->cb; | ||
296 | |||
297 | ZD_ASSERT(sizeof(*cb) <= sizeof(skb->cb)); | ||
298 | memset(cb, 0, sizeof(*cb)); | ||
299 | cb->hw= hw; | ||
300 | cb->control = kmalloc(sizeof(*control), GFP_ATOMIC); | ||
301 | if (cb->control == NULL) | ||
302 | return -ENOMEM; | ||
303 | memcpy(cb->control, control, sizeof(*control)); | ||
304 | |||
305 | return 0; | ||
306 | } | 250 | } |
307 | 251 | ||
308 | /** | 252 | /** |
309 | * tx_status - reports tx status of a packet if required | 253 | * tx_status - reports tx status of a packet if required |
310 | * @hw - a &struct ieee80211_hw pointer | 254 | * @hw - a &struct ieee80211_hw pointer |
311 | * @skb - a sk-buffer | 255 | * @skb - a sk-buffer |
312 | * @status - the tx status of the packet without control information | 256 | * @flags: extra flags to set in the TX status info |
257 | * @ackssi: ACK signal strength | ||
313 | * @success - True for successfull transmission of the frame | 258 | * @success - True for successfull transmission of the frame |
314 | * | 259 | * |
315 | * This information calls ieee80211_tx_status_irqsafe() if required by the | 260 | * This information calls ieee80211_tx_status_irqsafe() if required by the |
@@ -319,18 +264,17 @@ static int init_tx_skb_control_block(struct sk_buff *skb, | |||
319 | * If no status information has been requested, the skb is freed. | 264 | * If no status information has been requested, the skb is freed. |
320 | */ | 265 | */ |
321 | static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | 266 | static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, |
322 | struct ieee80211_tx_status *status, | 267 | u32 flags, int ackssi, bool success) |
323 | bool success) | ||
324 | { | 268 | { |
325 | struct zd_tx_skb_control_block *cb = (struct zd_tx_skb_control_block *) | 269 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
326 | skb->cb; | 270 | |
271 | memset(&info->status, 0, sizeof(info->status)); | ||
327 | 272 | ||
328 | ZD_ASSERT(cb->control != NULL); | ||
329 | memcpy(&status->control, cb->control, sizeof(status->control)); | ||
330 | if (!success) | 273 | if (!success) |
331 | status->excessive_retries = 1; | 274 | info->status.excessive_retries = 1; |
332 | clear_tx_skb_control_block(skb); | 275 | info->flags |= flags; |
333 | ieee80211_tx_status_irqsafe(hw, skb, status); | 276 | info->status.ack_signal = ackssi; |
277 | ieee80211_tx_status_irqsafe(hw, skb); | ||
334 | } | 278 | } |
335 | 279 | ||
336 | /** | 280 | /** |
@@ -345,15 +289,12 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw) | |||
345 | { | 289 | { |
346 | struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue; | 290 | struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue; |
347 | struct sk_buff *skb; | 291 | struct sk_buff *skb; |
348 | struct ieee80211_tx_status status; | ||
349 | 292 | ||
350 | skb = skb_dequeue(q); | 293 | skb = skb_dequeue(q); |
351 | if (skb == NULL) | 294 | if (skb == NULL) |
352 | return; | 295 | return; |
353 | 296 | ||
354 | memset(&status, 0, sizeof(status)); | 297 | tx_status(hw, skb, 0, 0, 0); |
355 | |||
356 | tx_status(hw, skb, &status, 0); | ||
357 | } | 298 | } |
358 | 299 | ||
359 | /** | 300 | /** |
@@ -368,28 +309,20 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw) | |||
368 | */ | 309 | */ |
369 | void zd_mac_tx_to_dev(struct sk_buff *skb, int error) | 310 | void zd_mac_tx_to_dev(struct sk_buff *skb, int error) |
370 | { | 311 | { |
371 | struct zd_tx_skb_control_block *cb = | 312 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
372 | (struct zd_tx_skb_control_block *)skb->cb; | 313 | struct ieee80211_hw *hw = info->driver_data[0]; |
373 | struct ieee80211_hw *hw = cb->hw; | ||
374 | |||
375 | if (likely(cb->control)) { | ||
376 | skb_pull(skb, sizeof(struct zd_ctrlset)); | ||
377 | if (unlikely(error || | ||
378 | (cb->control->flags & IEEE80211_TXCTL_NO_ACK))) | ||
379 | { | ||
380 | struct ieee80211_tx_status status; | ||
381 | memset(&status, 0, sizeof(status)); | ||
382 | tx_status(hw, skb, &status, !error); | ||
383 | } else { | ||
384 | struct sk_buff_head *q = | ||
385 | &zd_hw_mac(hw)->ack_wait_queue; | ||
386 | 314 | ||
387 | skb_queue_tail(q, skb); | 315 | skb_pull(skb, sizeof(struct zd_ctrlset)); |
388 | while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS) | 316 | if (unlikely(error || |
389 | zd_mac_tx_failed(hw); | 317 | (info->flags & IEEE80211_TX_CTL_NO_ACK))) { |
390 | } | 318 | tx_status(hw, skb, 0, 0, !error); |
391 | } else { | 319 | } else { |
392 | kfree_tx_skb(skb); | 320 | struct sk_buff_head *q = |
321 | &zd_hw_mac(hw)->ack_wait_queue; | ||
322 | |||
323 | skb_queue_tail(q, skb); | ||
324 | while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS) | ||
325 | zd_mac_tx_failed(hw); | ||
393 | } | 326 | } |
394 | } | 327 | } |
395 | 328 | ||
@@ -454,7 +387,7 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | |||
454 | cs->control = 0; | 387 | cs->control = 0; |
455 | 388 | ||
456 | /* First fragment */ | 389 | /* First fragment */ |
457 | if (flags & IEEE80211_TXCTL_FIRST_FRAGMENT) | 390 | if (flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) |
458 | cs->control |= ZD_CS_NEED_RANDOM_BACKOFF; | 391 | cs->control |= ZD_CS_NEED_RANDOM_BACKOFF; |
459 | 392 | ||
460 | /* Multicast */ | 393 | /* Multicast */ |
@@ -466,10 +399,10 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | |||
466 | (IEEE80211_FTYPE_CTL|IEEE80211_STYPE_PSPOLL)) | 399 | (IEEE80211_FTYPE_CTL|IEEE80211_STYPE_PSPOLL)) |
467 | cs->control |= ZD_CS_PS_POLL_FRAME; | 400 | cs->control |= ZD_CS_PS_POLL_FRAME; |
468 | 401 | ||
469 | if (flags & IEEE80211_TXCTL_USE_RTS_CTS) | 402 | if (flags & IEEE80211_TX_CTL_USE_RTS_CTS) |
470 | cs->control |= ZD_CS_RTS; | 403 | cs->control |= ZD_CS_RTS; |
471 | 404 | ||
472 | if (flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 405 | if (flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) |
473 | cs->control |= ZD_CS_SELF_CTS; | 406 | cs->control |= ZD_CS_SELF_CTS; |
474 | 407 | ||
475 | /* FIXME: Management frame? */ | 408 | /* FIXME: Management frame? */ |
@@ -516,8 +449,7 @@ void zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) | |||
516 | } | 449 | } |
517 | 450 | ||
518 | static int fill_ctrlset(struct zd_mac *mac, | 451 | static int fill_ctrlset(struct zd_mac *mac, |
519 | struct sk_buff *skb, | 452 | struct sk_buff *skb) |
520 | struct ieee80211_tx_control *control) | ||
521 | { | 453 | { |
522 | int r; | 454 | int r; |
523 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 455 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
@@ -526,18 +458,19 @@ static int fill_ctrlset(struct zd_mac *mac, | |||
526 | struct ieee80211_rate *txrate; | 458 | struct ieee80211_rate *txrate; |
527 | struct zd_ctrlset *cs = (struct zd_ctrlset *) | 459 | struct zd_ctrlset *cs = (struct zd_ctrlset *) |
528 | skb_push(skb, sizeof(struct zd_ctrlset)); | 460 | skb_push(skb, sizeof(struct zd_ctrlset)); |
461 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
529 | 462 | ||
530 | ZD_ASSERT(frag_len <= 0xffff); | 463 | ZD_ASSERT(frag_len <= 0xffff); |
531 | 464 | ||
532 | txrate = ieee80211_get_tx_rate(mac->hw, control); | 465 | txrate = ieee80211_get_tx_rate(mac->hw, info); |
533 | 466 | ||
534 | cs->modulation = txrate->hw_value; | 467 | cs->modulation = txrate->hw_value; |
535 | if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE) | 468 | if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) |
536 | cs->modulation = txrate->hw_value_short; | 469 | cs->modulation = txrate->hw_value_short; |
537 | 470 | ||
538 | cs->tx_length = cpu_to_le16(frag_len); | 471 | cs->tx_length = cpu_to_le16(frag_len); |
539 | 472 | ||
540 | cs_set_control(mac, cs, hdr, control->flags); | 473 | cs_set_control(mac, cs, hdr, info->flags); |
541 | 474 | ||
542 | packet_length = frag_len + sizeof(struct zd_ctrlset) + 10; | 475 | packet_length = frag_len + sizeof(struct zd_ctrlset) + 10; |
543 | ZD_ASSERT(packet_length <= 0xffff); | 476 | ZD_ASSERT(packet_length <= 0xffff); |
@@ -582,24 +515,21 @@ static int fill_ctrlset(struct zd_mac *mac, | |||
582 | * control block of the skbuff will be initialized. If necessary the incoming | 515 | * control block of the skbuff will be initialized. If necessary the incoming |
583 | * mac80211 queues will be stopped. | 516 | * mac80211 queues will be stopped. |
584 | */ | 517 | */ |
585 | static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | 518 | static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
586 | struct ieee80211_tx_control *control) | ||
587 | { | 519 | { |
588 | struct zd_mac *mac = zd_hw_mac(hw); | 520 | struct zd_mac *mac = zd_hw_mac(hw); |
521 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
589 | int r; | 522 | int r; |
590 | 523 | ||
591 | r = fill_ctrlset(mac, skb, control); | 524 | r = fill_ctrlset(mac, skb); |
592 | if (r) | 525 | if (r) |
593 | return r; | 526 | return r; |
594 | 527 | ||
595 | r = init_tx_skb_control_block(skb, hw, control); | 528 | info->driver_data[0] = hw; |
596 | if (r) | 529 | |
597 | return r; | ||
598 | r = zd_usb_tx(&mac->chip.usb, skb); | 530 | r = zd_usb_tx(&mac->chip.usb, skb); |
599 | if (r) { | 531 | if (r) |
600 | clear_tx_skb_control_block(skb); | ||
601 | return r; | 532 | return r; |
602 | } | ||
603 | return 0; | 533 | return 0; |
604 | } | 534 | } |
605 | 535 | ||
@@ -637,13 +567,8 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, | |||
637 | tx_hdr = (struct ieee80211_hdr *)skb->data; | 567 | tx_hdr = (struct ieee80211_hdr *)skb->data; |
638 | if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1))) | 568 | if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1))) |
639 | { | 569 | { |
640 | struct ieee80211_tx_status status; | ||
641 | |||
642 | memset(&status, 0, sizeof(status)); | ||
643 | status.flags = IEEE80211_TX_STATUS_ACK; | ||
644 | status.ack_signal = stats->signal; | ||
645 | __skb_unlink(skb, q); | 570 | __skb_unlink(skb, q); |
646 | tx_status(hw, skb, &status, 1); | 571 | tx_status(hw, skb, IEEE80211_TX_STAT_ACK, stats->signal, 1); |
647 | goto out; | 572 | goto out; |
648 | } | 573 | } |
649 | } | 574 | } |
@@ -947,8 +872,7 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, | |||
947 | } | 872 | } |
948 | 873 | ||
949 | static int zd_op_beacon_update(struct ieee80211_hw *hw, | 874 | static int zd_op_beacon_update(struct ieee80211_hw *hw, |
950 | struct sk_buff *skb, | 875 | struct sk_buff *skb) |
951 | struct ieee80211_tx_control *ctl) | ||
952 | { | 876 | { |
953 | struct zd_mac *mac = zd_hw_mac(hw); | 877 | struct zd_mac *mac = zd_hw_mac(hw); |
954 | zd_mac_config_beacon(hw, skb); | 878 | zd_mac_config_beacon(hw, skb); |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 71170244d2c..18c1d56d3dd 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h | |||
@@ -149,22 +149,6 @@ struct housekeeping { | |||
149 | struct delayed_work link_led_work; | 149 | struct delayed_work link_led_work; |
150 | }; | 150 | }; |
151 | 151 | ||
152 | /** | ||
153 | * struct zd_tx_skb_control_block - control block for tx skbuffs | ||
154 | * @control: &struct ieee80211_tx_control pointer | ||
155 | * @context: context pointer | ||
156 | * | ||
157 | * This structure is used to fill the cb field in an &sk_buff to transmit. | ||
158 | * The control field is NULL, if there is no requirement from the mac80211 | ||
159 | * stack to report about the packet ACK. This is the case if the flag | ||
160 | * IEEE80211_TXCTL_NO_ACK is not set in &struct ieee80211_tx_control. | ||
161 | */ | ||
162 | struct zd_tx_skb_control_block { | ||
163 | struct ieee80211_tx_control *control; | ||
164 | struct ieee80211_hw *hw; | ||
165 | void *context; | ||
166 | }; | ||
167 | |||
168 | #define ZD_MAC_STATS_BUFFER_SIZE 16 | 152 | #define ZD_MAC_STATS_BUFFER_SIZE 16 |
169 | 153 | ||
170 | #define ZD_MAC_MAX_ACK_WAITERS 10 | 154 | #define ZD_MAC_MAX_ACK_WAITERS 10 |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 12e24f04ddd..c8a0b34aecc 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -869,7 +869,7 @@ static void tx_urb_complete(struct urb *urb) | |||
869 | { | 869 | { |
870 | int r; | 870 | int r; |
871 | struct sk_buff *skb; | 871 | struct sk_buff *skb; |
872 | struct zd_tx_skb_control_block *cb; | 872 | struct ieee80211_tx_info *info; |
873 | struct zd_usb *usb; | 873 | struct zd_usb *usb; |
874 | 874 | ||
875 | switch (urb->status) { | 875 | switch (urb->status) { |
@@ -893,8 +893,8 @@ free_urb: | |||
893 | * grab 'usb' pointer before handing off the skb (since | 893 | * grab 'usb' pointer before handing off the skb (since |
894 | * it might be freed by zd_mac_tx_to_dev or mac80211) | 894 | * it might be freed by zd_mac_tx_to_dev or mac80211) |
895 | */ | 895 | */ |
896 | cb = (struct zd_tx_skb_control_block *)skb->cb; | 896 | info = IEEE80211_SKB_CB(skb); |
897 | usb = &zd_hw_mac(cb->hw)->chip.usb; | 897 | usb = &zd_hw_mac(info->driver_data[0])->chip.usb; |
898 | zd_mac_tx_to_dev(skb, urb->status); | 898 | zd_mac_tx_to_dev(skb, urb->status); |
899 | free_tx_urb(usb, urb); | 899 | free_tx_urb(usb, urb); |
900 | tx_dec_submitted_urbs(usb); | 900 | tx_dec_submitted_urbs(usb); |