aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/xmit.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-03-29 16:01:16 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-08 15:05:56 -0400
commit5100d5ac81b9330dc57e35adbe50923ba6107b8f (patch)
tree48224236b50703606c97c05ec077fde4880fc3b9 /drivers/net/wireless/b43/xmit.c
parent3109ece1114293b8201d9c140d02d7ce9a9fa387 (diff)
b43: Add PIO support for PCMCIA devices
This adds PIO support back (D'oh!) for PCMCIA devices. This is a complete rewrite of the old PIO code. It does actually work and we get reasonable performance out of it on a modern machine. On a PowerBook G4 I get a few MBit for TX and a few more for RX. So it doesn't work as well as DMA (of course), but it's a _lot_ faster than the old PIO code (only got a few kBit with that). The limiting factor is the host CPU speed. So it will generate 100% CPU usage when the network interface is heavily loaded. A voluntary preemption point in the RX path makes sure Desktop Latency isn't hurt. PIO is needed for 16bit PCMCIA devices, as we really don't want to poke with the braindead DMA mechanisms on PCMCIA sockets. Additionally, not all PCMCIA sockets do actually support DMA in 16bit mode (mine doesn't). Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/xmit.c')
-rw-r--r--drivers/net/wireless/b43/xmit.c61
1 files changed, 38 insertions, 23 deletions
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index ec10a8e182f9..b2a3123f42db 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -30,6 +30,7 @@
30#include "xmit.h" 30#include "xmit.h"
31#include "phy.h" 31#include "phy.h"
32#include "dma.h" 32#include "dma.h"
33#include "pio.h"
33 34
34 35
35/* Extract the bitrate index out of a CCK PLCP header. */ 36/* Extract the bitrate index out of a CCK PLCP header. */
@@ -668,40 +669,54 @@ void b43_handle_txstatus(struct b43_wldev *dev,
668 dev->wl->ieee_stats.dot11RTSSuccessCount++; 669 dev->wl->ieee_stats.dot11RTSSuccessCount++;
669 } 670 }
670 671
671 b43_dma_handle_txstatus(dev, status); 672 if (b43_using_pio_transfers(dev))
673 b43_pio_handle_txstatus(dev, status);
674 else
675 b43_dma_handle_txstatus(dev, status);
672} 676}
673 677
674/* Handle TX status report as received through DMA/PIO queues */ 678/* Fill out the mac80211 TXstatus report based on the b43-specific
675void b43_handle_hwtxstatus(struct b43_wldev *dev, 679 * txstatus report data. This returns a boolean whether the frame was
676 const struct b43_hwtxstatus *hw) 680 * successfully transmitted. */
681bool b43_fill_txstatus_report(struct ieee80211_tx_status *report,
682 const struct b43_txstatus *status)
677{ 683{
678 struct b43_txstatus status; 684 bool frame_success = 1;
679 u8 tmp; 685
680 686 if (status->acked) {
681 status.cookie = le16_to_cpu(hw->cookie); 687 /* The frame was ACKed. */
682 status.seq = le16_to_cpu(hw->seq); 688 report->flags |= IEEE80211_TX_STATUS_ACK;
683 status.phy_stat = hw->phy_stat; 689 } else {
684 tmp = hw->count; 690 /* The frame was not ACKed... */
685 status.frame_count = (tmp >> 4); 691 if (!(report->control.flags & IEEE80211_TXCTL_NO_ACK)) {
686 status.rts_count = (tmp & 0x0F); 692 /* ...but we expected an ACK. */
687 tmp = hw->flags; 693 frame_success = 0;
688 status.supp_reason = ((tmp & 0x1C) >> 2); 694 report->excessive_retries = 1;
689 status.pm_indicated = !!(tmp & 0x80); 695 }
690 status.intermediate = !!(tmp & 0x40); 696 }
691 status.for_ampdu = !!(tmp & 0x20); 697 if (status->frame_count == 0) {
692 status.acked = !!(tmp & 0x02); 698 /* The frame was not transmitted at all. */
693 699 report->retry_count = 0;
694 b43_handle_txstatus(dev, &status); 700 } else
701 report->retry_count = status->frame_count - 1;
702
703 return frame_success;
695} 704}
696 705
697/* Stop any TX operation on the device (suspend the hardware queues) */ 706/* Stop any TX operation on the device (suspend the hardware queues) */
698void b43_tx_suspend(struct b43_wldev *dev) 707void b43_tx_suspend(struct b43_wldev *dev)
699{ 708{
700 b43_dma_tx_suspend(dev); 709 if (b43_using_pio_transfers(dev))
710 b43_pio_tx_suspend(dev);
711 else
712 b43_dma_tx_suspend(dev);
701} 713}
702 714
703/* Resume any TX operation on the device (resume the hardware queues) */ 715/* Resume any TX operation on the device (resume the hardware queues) */
704void b43_tx_resume(struct b43_wldev *dev) 716void b43_tx_resume(struct b43_wldev *dev)
705{ 717{
706 b43_dma_tx_resume(dev); 718 if (b43_using_pio_transfers(dev))
719 b43_pio_tx_resume(dev);
720 else
721 b43_dma_tx_resume(dev);
707} 722}