aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/pio.h
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/pio.h
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/pio.h')
-rw-r--r--drivers/net/wireless/b43/pio.h220
1 files changed, 220 insertions, 0 deletions
diff --git a/drivers/net/wireless/b43/pio.h b/drivers/net/wireless/b43/pio.h
new file mode 100644
index 000000000000..e2ec676cc9e4
--- /dev/null
+++ b/drivers/net/wireless/b43/pio.h
@@ -0,0 +1,220 @@
1#ifndef B43_PIO_H_
2#define B43_PIO_H_
3
4#include "b43.h"
5
6#include <linux/interrupt.h>
7#include <linux/io.h>
8#include <linux/list.h>
9#include <linux/skbuff.h>
10
11
12/*** Registers for PIO queues up to revision 7. ***/
13/* TX queue. */
14#define B43_PIO_TXCTL 0x00
15#define B43_PIO_TXCTL_WRITELO 0x0001
16#define B43_PIO_TXCTL_WRITEHI 0x0002
17#define B43_PIO_TXCTL_EOF 0x0004
18#define B43_PIO_TXCTL_FREADY 0x0008
19#define B43_PIO_TXCTL_FLUSHREQ 0x0020
20#define B43_PIO_TXCTL_FLUSHPEND 0x0040
21#define B43_PIO_TXCTL_SUSPREQ 0x0080
22#define B43_PIO_TXCTL_QSUSP 0x0100
23#define B43_PIO_TXCTL_COMMCNT 0xFC00
24#define B43_PIO_TXCTL_COMMCNT_SHIFT 10
25#define B43_PIO_TXDATA 0x02
26#define B43_PIO_TXQBUFSIZE 0x04
27/* RX queue. */
28#define B43_PIO_RXCTL 0x00
29#define B43_PIO_RXCTL_FRAMERDY 0x0001
30#define B43_PIO_RXCTL_DATARDY 0x0002
31#define B43_PIO_RXDATA 0x02
32
33/*** Registers for PIO queues revision 8 and later. ***/
34/* TX queue */
35#define B43_PIO8_TXCTL 0x00
36#define B43_PIO8_TXCTL_0_7 0x00000001
37#define B43_PIO8_TXCTL_8_15 0x00000002
38#define B43_PIO8_TXCTL_16_23 0x00000004
39#define B43_PIO8_TXCTL_24_31 0x00000008
40#define B43_PIO8_TXCTL_EOF 0x00000010
41#define B43_PIO8_TXCTL_FREADY 0x00000080
42#define B43_PIO8_TXCTL_SUSPREQ 0x00000100
43#define B43_PIO8_TXCTL_QSUSP 0x00000200
44#define B43_PIO8_TXCTL_FLUSHREQ 0x00000400
45#define B43_PIO8_TXCTL_FLUSHPEND 0x00000800
46#define B43_PIO8_TXDATA 0x04
47/* RX queue */
48#define B43_PIO8_RXCTL 0x00
49#define B43_PIO8_RXCTL_FRAMERDY 0x00000001
50#define B43_PIO8_RXCTL_DATARDY 0x00000002
51#define B43_PIO8_RXDATA 0x04
52
53
54/* The maximum number of TX-packets the HW can handle. */
55#define B43_PIO_MAX_NR_TXPACKETS 32
56
57
58#ifdef CONFIG_B43_PIO
59
60struct b43_pio_txpacket {
61 /* Pointer to the TX queue we belong to. */
62 struct b43_pio_txqueue *queue;
63 /* The TX data packet. */
64 struct sk_buff *skb;
65 /* The status meta data. */
66 struct ieee80211_tx_status txstat;
67 /* Index in the (struct b43_pio_txqueue)->packets array. */
68 u8 index;
69
70 struct list_head list;
71};
72
73struct b43_pio_txqueue {
74 struct b43_wldev *dev;
75 spinlock_t lock;
76 u16 mmio_base;
77
78 /* The device queue buffer size in bytes. */
79 u16 buffer_size;
80 /* The number of used bytes in the device queue buffer. */
81 u16 buffer_used;
82 /* The number of packets that can still get queued.
83 * This is decremented on queueing a packet and incremented
84 * after receiving the transmit status. */
85 u16 free_packet_slots;
86
87 /* True, if the mac80211 queue was stopped due to overflow at TX. */
88 bool stopped;
89 /* Our b43 queue index number */
90 u8 index;
91 /* The mac80211 QoS queue priority. */
92 u8 queue_prio;
93
94 /* Buffer for TX packet meta data. */
95 struct b43_pio_txpacket packets[B43_PIO_MAX_NR_TXPACKETS];
96 struct list_head packets_list;
97
98 /* Total number of transmitted packets. */
99 unsigned int nr_tx_packets;
100
101 /* Shortcut to the 802.11 core revision. This is to
102 * avoid horrible pointer dereferencing in the fastpaths. */
103 u8 rev;
104};
105
106struct b43_pio_rxqueue {
107 struct b43_wldev *dev;
108 spinlock_t lock;
109 u16 mmio_base;
110
111 /* Work to reduce latency issues on RX. */
112 struct work_struct rx_work;
113
114 /* Shortcut to the 802.11 core revision. This is to
115 * avoid horrible pointer dereferencing in the fastpaths. */
116 u8 rev;
117};
118
119
120static inline u16 b43_piotx_read16(struct b43_pio_txqueue *q, u16 offset)
121{
122 return b43_read16(q->dev, q->mmio_base + offset);
123}
124
125static inline u32 b43_piotx_read32(struct b43_pio_txqueue *q, u16 offset)
126{
127 return b43_read32(q->dev, q->mmio_base + offset);
128}
129
130static inline void b43_piotx_write16(struct b43_pio_txqueue *q,
131 u16 offset, u16 value)
132{
133 b43_write16(q->dev, q->mmio_base + offset, value);
134}
135
136static inline void b43_piotx_write32(struct b43_pio_txqueue *q,
137 u16 offset, u32 value)
138{
139 b43_write32(q->dev, q->mmio_base + offset, value);
140}
141
142
143static inline u16 b43_piorx_read16(struct b43_pio_rxqueue *q, u16 offset)
144{
145 return b43_read16(q->dev, q->mmio_base + offset);
146}
147
148static inline u32 b43_piorx_read32(struct b43_pio_rxqueue *q, u16 offset)
149{
150 return b43_read32(q->dev, q->mmio_base + offset);
151}
152
153static inline void b43_piorx_write16(struct b43_pio_rxqueue *q,
154 u16 offset, u16 value)
155{
156 b43_write16(q->dev, q->mmio_base + offset, value);
157}
158
159static inline void b43_piorx_write32(struct b43_pio_rxqueue *q,
160 u16 offset, u32 value)
161{
162 b43_write32(q->dev, q->mmio_base + offset, value);
163}
164
165
166int b43_pio_init(struct b43_wldev *dev);
167void b43_pio_stop(struct b43_wldev *dev);
168void b43_pio_free(struct b43_wldev *dev);
169
170int b43_pio_tx(struct b43_wldev *dev,
171 struct sk_buff *skb, struct ieee80211_tx_control *ctl);
172void b43_pio_handle_txstatus(struct b43_wldev *dev,
173 const struct b43_txstatus *status);
174void b43_pio_get_tx_stats(struct b43_wldev *dev,
175 struct ieee80211_tx_queue_stats *stats);
176void b43_pio_rx(struct b43_pio_rxqueue *q);
177
178void b43_pio_tx_suspend(struct b43_wldev *dev);
179void b43_pio_tx_resume(struct b43_wldev *dev);
180
181
182#else /* CONFIG_B43_PIO */
183
184
185static inline int b43_pio_init(struct b43_wldev *dev)
186{
187 return 0;
188}
189static inline void b43_pio_free(struct b43_wldev *dev)
190{
191}
192static inline void b43_pio_stop(struct b43_wldev *dev)
193{
194}
195static inline int b43_pio_tx(struct b43_wldev *dev,
196 struct sk_buff *skb,
197 struct ieee80211_tx_control *ctl)
198{
199 return 0;
200}
201static inline void b43_pio_handle_txstatus(struct b43_wldev *dev,
202 const struct b43_txstatus *status)
203{
204}
205static inline void b43_pio_get_tx_stats(struct b43_wldev *dev,
206 struct ieee80211_tx_queue_stats *stats)
207{
208}
209static inline void b43_pio_rx(struct b43_pio_rxqueue *q)
210{
211}
212static inline void b43_pio_tx_suspend(struct b43_wldev *dev)
213{
214}
215static inline void b43_pio_tx_resume(struct b43_wldev *dev)
216{
217}
218
219#endif /* CONFIG_B43_PIO */
220#endif /* B43_PIO_H_ */