aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2009-10-09 14:33:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-27 16:48:20 -0400
commit88499ab3d8dbbf9c080416952603742666c71262 (patch)
treec44aac76081a87af616f98dc8a9eb89b4610eab3 /drivers
parent2c759e03b3b7639fff23ec3b7bab64a35ca0914f (diff)
b43: Optimize PIO scratchbuffer usage
This optimizes the PIO scratchbuffer usage. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/b43/b43.h16
-rw-r--r--drivers/net/wireless/b43/pio.c79
-rw-r--r--drivers/net/wireless/b43/xmit.c2
3 files changed, 51 insertions, 46 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 660716214d49..65b23f725a04 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -749,12 +749,6 @@ struct b43_wldev {
749#endif 749#endif
750}; 750};
751 751
752/*
753 * Include goes here to avoid a dependency problem.
754 * A better fix would be to integrate xmit.h into b43.h.
755 */
756#include "xmit.h"
757
758/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */ 752/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
759struct b43_wl { 753struct b43_wl {
760 /* Pointer to the active wireless device on this chip */ 754 /* Pointer to the active wireless device on this chip */
@@ -830,13 +824,9 @@ struct b43_wl {
830 struct b43_leds leds; 824 struct b43_leds leds;
831 825
832#ifdef CONFIG_B43_PIO 826#ifdef CONFIG_B43_PIO
833 /* 827 /* Kmalloc'ed scratch space for PIO TX/RX. Protected by wl->mutex. */
834 * RX/TX header/tail buffers used by the frame transmit functions. 828 u8 pio_scratchspace[110] __attribute__((__aligned__(8)));
835 */ 829 u8 pio_tailspace[4] __attribute__((__aligned__(8)));
836 struct b43_rxhdr_fw4 rxhdr;
837 struct b43_txhdr txhdr;
838 u8 rx_tail[4];
839 u8 tx_tail[4];
840#endif /* CONFIG_B43_PIO */ 830#endif /* CONFIG_B43_PIO */
841}; 831};
842 832
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index dbbf0d11e18e..3105f235303a 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -341,12 +341,15 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
341 q->mmio_base + B43_PIO_TXDATA, 341 q->mmio_base + B43_PIO_TXDATA,
342 sizeof(u16)); 342 sizeof(u16));
343 if (data_len & 1) { 343 if (data_len & 1) {
344 u8 *tail = wl->pio_tailspace;
345 BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2);
346
344 /* Write the last byte. */ 347 /* Write the last byte. */
345 ctl &= ~B43_PIO_TXCTL_WRITEHI; 348 ctl &= ~B43_PIO_TXCTL_WRITEHI;
346 b43_piotx_write16(q, B43_PIO_TXCTL, ctl); 349 b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
347 wl->tx_tail[0] = data[data_len - 1]; 350 tail[0] = data[data_len - 1];
348 wl->tx_tail[1] = 0; 351 tail[1] = 0;
349 ssb_block_write(dev->dev, wl->tx_tail, 2, 352 ssb_block_write(dev->dev, tail, 2,
350 q->mmio_base + B43_PIO_TXDATA, 353 q->mmio_base + B43_PIO_TXDATA,
351 sizeof(u16)); 354 sizeof(u16));
352 } 355 }
@@ -392,31 +395,31 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
392 q->mmio_base + B43_PIO8_TXDATA, 395 q->mmio_base + B43_PIO8_TXDATA,
393 sizeof(u32)); 396 sizeof(u32));
394 if (data_len & 3) { 397 if (data_len & 3) {
395 wl->tx_tail[3] = 0; 398 u8 *tail = wl->pio_tailspace;
399 BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4);
400
401 memset(tail, 0, 4);
396 /* Write the last few bytes. */ 402 /* Write the last few bytes. */
397 ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 | 403 ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 |
398 B43_PIO8_TXCTL_24_31); 404 B43_PIO8_TXCTL_24_31);
399 switch (data_len & 3) { 405 switch (data_len & 3) {
400 case 3: 406 case 3:
401 ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15; 407 ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15;
402 wl->tx_tail[0] = data[data_len - 3]; 408 tail[0] = data[data_len - 3];
403 wl->tx_tail[1] = data[data_len - 2]; 409 tail[1] = data[data_len - 2];
404 wl->tx_tail[2] = data[data_len - 1]; 410 tail[2] = data[data_len - 1];
405 break; 411 break;
406 case 2: 412 case 2:
407 ctl |= B43_PIO8_TXCTL_8_15; 413 ctl |= B43_PIO8_TXCTL_8_15;
408 wl->tx_tail[0] = data[data_len - 2]; 414 tail[0] = data[data_len - 2];
409 wl->tx_tail[1] = data[data_len - 1]; 415 tail[1] = data[data_len - 1];
410 wl->tx_tail[2] = 0;
411 break; 416 break;
412 case 1: 417 case 1:
413 wl->tx_tail[0] = data[data_len - 1]; 418 tail[0] = data[data_len - 1];
414 wl->tx_tail[1] = 0;
415 wl->tx_tail[2] = 0;
416 break; 419 break;
417 } 420 }
418 b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); 421 b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
419 ssb_block_write(dev->dev, wl->tx_tail, 4, 422 ssb_block_write(dev->dev, tail, 4,
420 q->mmio_base + B43_PIO8_TXDATA, 423 q->mmio_base + B43_PIO8_TXDATA,
421 sizeof(u32)); 424 sizeof(u32));
422 } 425 }
@@ -455,6 +458,7 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
455 int err; 458 int err;
456 unsigned int hdrlen; 459 unsigned int hdrlen;
457 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 460 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
461 struct b43_txhdr *txhdr = (struct b43_txhdr *)wl->pio_scratchspace;
458 462
459 B43_WARN_ON(list_empty(&q->packets_list)); 463 B43_WARN_ON(list_empty(&q->packets_list));
460 pack = list_entry(q->packets_list.next, 464 pack = list_entry(q->packets_list.next,
@@ -462,7 +466,9 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
462 466
463 cookie = generate_cookie(q, pack); 467 cookie = generate_cookie(q, pack);
464 hdrlen = b43_txhdr_size(dev); 468 hdrlen = b43_txhdr_size(dev);
465 err = b43_generate_txhdr(dev, (u8 *)&wl->txhdr, skb, 469 BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(struct b43_txhdr));
470 B43_WARN_ON(sizeof(wl->pio_scratchspace) < hdrlen);
471 err = b43_generate_txhdr(dev, (u8 *)txhdr, skb,
466 info, cookie); 472 info, cookie);
467 if (err) 473 if (err)
468 return err; 474 return err;
@@ -476,9 +482,9 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
476 482
477 pack->skb = skb; 483 pack->skb = skb;
478 if (q->rev >= 8) 484 if (q->rev >= 8)
479 pio_tx_frame_4byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen); 485 pio_tx_frame_4byte_queue(pack, (const u8 *)txhdr, hdrlen);
480 else 486 else
481 pio_tx_frame_2byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen); 487 pio_tx_frame_2byte_queue(pack, (const u8 *)txhdr, hdrlen);
482 488
483 /* Remove it from the list of available packet slots. 489 /* Remove it from the list of available packet slots.
484 * It will be put back when we receive the status report. */ 490 * It will be put back when we receive the status report. */
@@ -624,8 +630,11 @@ static bool pio_rx_frame(struct b43_pio_rxqueue *q)
624 unsigned int i, padding; 630 unsigned int i, padding;
625 struct sk_buff *skb; 631 struct sk_buff *skb;
626 const char *err_msg = NULL; 632 const char *err_msg = NULL;
633 struct b43_rxhdr_fw4 *rxhdr =
634 (struct b43_rxhdr_fw4 *)wl->pio_scratchspace;
627 635
628 memset(&wl->rxhdr, 0, sizeof(wl->rxhdr)); 636 BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(*rxhdr));
637 memset(rxhdr, 0, sizeof(*rxhdr));
629 638
630 /* Check if we have data and wait for it to get ready. */ 639 /* Check if we have data and wait for it to get ready. */
631 if (q->rev >= 8) { 640 if (q->rev >= 8) {
@@ -663,16 +672,16 @@ data_ready:
663 672
664 /* Get the preamble (RX header) */ 673 /* Get the preamble (RX header) */
665 if (q->rev >= 8) { 674 if (q->rev >= 8) {
666 ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr), 675 ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr),
667 q->mmio_base + B43_PIO8_RXDATA, 676 q->mmio_base + B43_PIO8_RXDATA,
668 sizeof(u32)); 677 sizeof(u32));
669 } else { 678 } else {
670 ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr), 679 ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr),
671 q->mmio_base + B43_PIO_RXDATA, 680 q->mmio_base + B43_PIO_RXDATA,
672 sizeof(u16)); 681 sizeof(u16));
673 } 682 }
674 /* Sanity checks. */ 683 /* Sanity checks. */
675 len = le16_to_cpu(wl->rxhdr.frame_len); 684 len = le16_to_cpu(rxhdr->frame_len);
676 if (unlikely(len > 0x700)) { 685 if (unlikely(len > 0x700)) {
677 err_msg = "len > 0x700"; 686 err_msg = "len > 0x700";
678 goto rx_error; 687 goto rx_error;
@@ -682,7 +691,7 @@ data_ready:
682 goto rx_error; 691 goto rx_error;
683 } 692 }
684 693
685 macstat = le32_to_cpu(wl->rxhdr.mac_status); 694 macstat = le32_to_cpu(rxhdr->mac_status);
686 if (macstat & B43_RX_MAC_FCSERR) { 695 if (macstat & B43_RX_MAC_FCSERR) {
687 if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) { 696 if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) {
688 /* Drop frames with failed FCS. */ 697 /* Drop frames with failed FCS. */
@@ -707,22 +716,25 @@ data_ready:
707 q->mmio_base + B43_PIO8_RXDATA, 716 q->mmio_base + B43_PIO8_RXDATA,
708 sizeof(u32)); 717 sizeof(u32));
709 if (len & 3) { 718 if (len & 3) {
719 u8 *tail = wl->pio_tailspace;
720 BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4);
721
710 /* Read the last few bytes. */ 722 /* Read the last few bytes. */
711 ssb_block_read(dev->dev, wl->rx_tail, 4, 723 ssb_block_read(dev->dev, tail, 4,
712 q->mmio_base + B43_PIO8_RXDATA, 724 q->mmio_base + B43_PIO8_RXDATA,
713 sizeof(u32)); 725 sizeof(u32));
714 switch (len & 3) { 726 switch (len & 3) {
715 case 3: 727 case 3:
716 skb->data[len + padding - 3] = wl->rx_tail[0]; 728 skb->data[len + padding - 3] = tail[0];
717 skb->data[len + padding - 2] = wl->rx_tail[1]; 729 skb->data[len + padding - 2] = tail[1];
718 skb->data[len + padding - 1] = wl->rx_tail[2]; 730 skb->data[len + padding - 1] = tail[2];
719 break; 731 break;
720 case 2: 732 case 2:
721 skb->data[len + padding - 2] = wl->rx_tail[0]; 733 skb->data[len + padding - 2] = tail[0];
722 skb->data[len + padding - 1] = wl->rx_tail[1]; 734 skb->data[len + padding - 1] = tail[1];
723 break; 735 break;
724 case 1: 736 case 1:
725 skb->data[len + padding - 1] = wl->rx_tail[0]; 737 skb->data[len + padding - 1] = tail[0];
726 break; 738 break;
727 } 739 }
728 } 740 }
@@ -731,15 +743,18 @@ data_ready:
731 q->mmio_base + B43_PIO_RXDATA, 743 q->mmio_base + B43_PIO_RXDATA,
732 sizeof(u16)); 744 sizeof(u16));
733 if (len & 1) { 745 if (len & 1) {
746 u8 *tail = wl->pio_tailspace;
747 BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2);
748
734 /* Read the last byte. */ 749 /* Read the last byte. */
735 ssb_block_read(dev->dev, wl->rx_tail, 2, 750 ssb_block_read(dev->dev, tail, 2,
736 q->mmio_base + B43_PIO_RXDATA, 751 q->mmio_base + B43_PIO_RXDATA,
737 sizeof(u16)); 752 sizeof(u16));
738 skb->data[len + padding - 1] = wl->rx_tail[0]; 753 skb->data[len + padding - 1] = tail[0];
739 } 754 }
740 } 755 }
741 756
742 b43_rx(q->dev, skb, &wl->rxhdr); 757 b43_rx(q->dev, skb, rxhdr);
743 758
744 return 1; 759 return 1;
745 760
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index f4e9695ec186..51d68971f6fa 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -27,7 +27,7 @@
27 27
28*/ 28*/
29 29
30#include "b43.h" 30#include "xmit.h"
31#include "phy_common.h" 31#include "phy_common.h"
32#include "dma.h" 32#include "dma.h"
33#include "pio.h" 33#include "pio.h"