aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/xmit.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-03-29 21:01:16 +0100
committerJohn W. Linville <linville@tuxdriver.com>2008-04-08 15:05:56 -0400
commit5100d5ac81b9330dc57e35adbe50923ba6107b8f (patch)
tree48224236b50703606c97c05ec077fde4880fc3b9 /drivers/net/wireless/b43/xmit.c
parent3109ece1114293b8201d9c140d02d7ce9a9fa387 (diff)
downloadkernel_samsung_smdk4412-5100d5ac81b9330dc57e35adbe50923ba6107b8f.zip
kernel_samsung_smdk4412-5100d5ac81b9330dc57e35adbe50923ba6107b8f.tar.gz
kernel_samsung_smdk4412-5100d5ac81b9330dc57e35adbe50923ba6107b8f.tar.bz2
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 ec10a8e..b2a3123 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -30,6 +30,7 @@
#include "xmit.h"
#include "phy.h"
#include "dma.h"
+#include "pio.h"
/* Extract the bitrate index out of a CCK PLCP header. */
@@ -668,40 +669,54 @@ void b43_handle_txstatus(struct b43_wldev *dev,
dev->wl->ieee_stats.dot11RTSSuccessCount++;
}
- b43_dma_handle_txstatus(dev, status);
+ if (b43_using_pio_transfers(dev))
+ b43_pio_handle_txstatus(dev, status);
+ else
+ b43_dma_handle_txstatus(dev, status);
}
-/* Handle TX status report as received through DMA/PIO queues */
-void b43_handle_hwtxstatus(struct b43_wldev *dev,
- const struct b43_hwtxstatus *hw)
+/* Fill out the mac80211 TXstatus report based on the b43-specific
+ * txstatus report data. This returns a boolean whether the frame was
+ * successfully transmitted. */
+bool b43_fill_txstatus_report(struct ieee80211_tx_status *report,
+ const struct b43_txstatus *status)
{
- struct b43_txstatus status;
- u8 tmp;
-
- status.cookie = le16_to_cpu(hw->cookie);
- status.seq = le16_to_cpu(hw->seq);
- status.phy_stat = hw->phy_stat;
- tmp = hw->count;
- status.frame_count = (tmp >> 4);
- status.rts_count = (tmp & 0x0F);
- tmp = hw->flags;
- status.supp_reason = ((tmp & 0x1C) >> 2);
- status.pm_indicated = !!(tmp & 0x80);
- status.intermediate = !!(tmp & 0x40);
- status.for_ampdu = !!(tmp & 0x20);
- status.acked = !!(tmp & 0x02);
-
- b43_handle_txstatus(dev, &status);
+ bool frame_success = 1;
+
+ if (status->acked) {
+ /* The frame was ACKed. */
+ report->flags |= IEEE80211_TX_STATUS_ACK;
+ } else {
+ /* The frame was not ACKed... */
+ if (!(report->control.flags & IEEE80211_TXCTL_NO_ACK)) {
+ /* ...but we expected an ACK. */
+ frame_success = 0;
+ report->excessive_retries = 1;
+ }
+ }
+ if (status->frame_count == 0) {
+ /* The frame was not transmitted at all. */
+ report->retry_count = 0;
+ } else
+ report->retry_count = status->frame_count - 1;
+
+ return frame_success;
}
/* Stop any TX operation on the device (suspend the hardware queues) */
void b43_tx_suspend(struct b43_wldev *dev)
{
- b43_dma_tx_suspend(dev);
+ if (b43_using_pio_transfers(dev))
+ b43_pio_tx_suspend(dev);
+ else
+ b43_dma_tx_suspend(dev);
}
/* Resume any TX operation on the device (resume the hardware queues) */
void b43_tx_resume(struct b43_wldev *dev)
{
- b43_dma_tx_resume(dev);
+ if (b43_using_pio_transfers(dev))
+ b43_pio_tx_resume(dev);
+ else
+ b43_dma_tx_resume(dev);
}