aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Wu <flamingice@sourmilk.net>2007-09-25 21:11:01 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:51:42 -0400
commiteff1a59c48e3c6a006eb4fe5f2e405a996f2259d (patch)
tree8d80376fa3bd0c60fd607be5eebef49ec2b1d733 /drivers
parent0795af5729b18218767fab27c44b1384f72dc9ad (diff)
[P54]: add mac80211-based driver for prism54 softmac hardware
Signed-off-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/Kconfig13
-rw-r--r--drivers/net/wireless/Makefile4
-rw-r--r--drivers/net/wireless/net2280.h452
-rw-r--r--drivers/net/wireless/p54.h80
-rw-r--r--drivers/net/wireless/p54common.c983
-rw-r--r--drivers/net/wireless/p54common.h329
-rw-r--r--drivers/net/wireless/p54pci.c691
-rw-r--r--drivers/net/wireless/p54pci.h106
-rw-r--r--drivers/net/wireless/p54usb.c906
-rw-r--r--drivers/net/wireless/p54usb.h133
10 files changed, 3697 insertions, 0 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index f481c757e22b..5a6fdfd0f140 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -577,6 +577,19 @@ config ADM8211
577 577
578 Thanks to Infineon-ADMtek for their support of this driver. 578 Thanks to Infineon-ADMtek for their support of this driver.
579 579
580config P54_COMMON
581 tristate "Softmac Prism54 support"
582 depends on MAC80211 && WLAN_80211 && FW_LOADER && EXPERIMENTAL
583
584config P54_USB
585 tristate "Prism54 USB support"
586 depends on P54_COMMON && USB
587 select CRC32
588
589config P54_PCI
590 tristate "Prism54 PCI support"
591 depends on P54_COMMON && PCI
592
580source "drivers/net/wireless/iwlwifi/Kconfig" 593source "drivers/net/wireless/iwlwifi/Kconfig"
581source "drivers/net/wireless/hostap/Kconfig" 594source "drivers/net/wireless/hostap/Kconfig"
582source "drivers/net/wireless/bcm43xx/Kconfig" 595source "drivers/net/wireless/bcm43xx/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index a7a15e3509e8..6f32b53ee128 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -54,3 +54,7 @@ obj-$(CONFIG_ADM8211) += adm8211.o
54 54
55obj-$(CONFIG_IWLWIFI) += iwlwifi/ 55obj-$(CONFIG_IWLWIFI) += iwlwifi/
56obj-$(CONFIG_RT2X00) += rt2x00/ 56obj-$(CONFIG_RT2X00) += rt2x00/
57
58obj-$(CONFIG_P54_COMMON) += p54common.o
59obj-$(CONFIG_P54_USB) += p54usb.o
60obj-$(CONFIG_P54_PCI) += p54pci.o
diff --git a/drivers/net/wireless/net2280.h b/drivers/net/wireless/net2280.h
new file mode 100644
index 000000000000..120eb831b287
--- /dev/null
+++ b/drivers/net/wireless/net2280.h
@@ -0,0 +1,452 @@
1#ifndef NET2280_H
2#define NET2280_H
3/*
4 * NetChip 2280 high/full speed USB device controller.
5 * Unlike many such controllers, this one talks PCI.
6 */
7
8/*
9 * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com)
10 * Copyright (C) 2003 David Brownell
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27/*-------------------------------------------------------------------------*/
28
29/* NET2280 MEMORY MAPPED REGISTERS
30 *
31 * The register layout came from the chip documentation, and the bit
32 * number definitions were extracted from chip specification.
33 *
34 * Use the shift operator ('<<') to build bit masks, with readl/writel
35 * to access the registers through PCI.
36 */
37
38/* main registers, BAR0 + 0x0000 */
39struct net2280_regs {
40 // offset 0x0000
41 __le32 devinit;
42#define LOCAL_CLOCK_FREQUENCY 8
43#define FORCE_PCI_RESET 7
44#define PCI_ID 6
45#define PCI_ENABLE 5
46#define FIFO_SOFT_RESET 4
47#define CFG_SOFT_RESET 3
48#define PCI_SOFT_RESET 2
49#define USB_SOFT_RESET 1
50#define M8051_RESET 0
51 __le32 eectl;
52#define EEPROM_ADDRESS_WIDTH 23
53#define EEPROM_CHIP_SELECT_ACTIVE 22
54#define EEPROM_PRESENT 21
55#define EEPROM_VALID 20
56#define EEPROM_BUSY 19
57#define EEPROM_CHIP_SELECT_ENABLE 18
58#define EEPROM_BYTE_READ_START 17
59#define EEPROM_BYTE_WRITE_START 16
60#define EEPROM_READ_DATA 8
61#define EEPROM_WRITE_DATA 0
62 __le32 eeclkfreq;
63 u32 _unused0;
64 // offset 0x0010
65
66 __le32 pciirqenb0; /* interrupt PCI master ... */
67#define SETUP_PACKET_INTERRUPT_ENABLE 7
68#define ENDPOINT_F_INTERRUPT_ENABLE 6
69#define ENDPOINT_E_INTERRUPT_ENABLE 5
70#define ENDPOINT_D_INTERRUPT_ENABLE 4
71#define ENDPOINT_C_INTERRUPT_ENABLE 3
72#define ENDPOINT_B_INTERRUPT_ENABLE 2
73#define ENDPOINT_A_INTERRUPT_ENABLE 1
74#define ENDPOINT_0_INTERRUPT_ENABLE 0
75 __le32 pciirqenb1;
76#define PCI_INTERRUPT_ENABLE 31
77#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27
78#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26
79#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25
80#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20
81#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19
82#define PCI_TARGET_ABORT_ASSERTED_INTERRUPT_ENABLE 18
83#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17
84#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16
85#define GPIO_INTERRUPT_ENABLE 13
86#define DMA_D_INTERRUPT_ENABLE 12
87#define DMA_C_INTERRUPT_ENABLE 11
88#define DMA_B_INTERRUPT_ENABLE 10
89#define DMA_A_INTERRUPT_ENABLE 9
90#define EEPROM_DONE_INTERRUPT_ENABLE 8
91#define VBUS_INTERRUPT_ENABLE 7
92#define CONTROL_STATUS_INTERRUPT_ENABLE 6
93#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4
94#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3
95#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2
96#define RESUME_INTERRUPT_ENABLE 1
97#define SOF_INTERRUPT_ENABLE 0
98 __le32 cpu_irqenb0; /* ... or onboard 8051 */
99#define SETUP_PACKET_INTERRUPT_ENABLE 7
100#define ENDPOINT_F_INTERRUPT_ENABLE 6
101#define ENDPOINT_E_INTERRUPT_ENABLE 5
102#define ENDPOINT_D_INTERRUPT_ENABLE 4
103#define ENDPOINT_C_INTERRUPT_ENABLE 3
104#define ENDPOINT_B_INTERRUPT_ENABLE 2
105#define ENDPOINT_A_INTERRUPT_ENABLE 1
106#define ENDPOINT_0_INTERRUPT_ENABLE 0
107 __le32 cpu_irqenb1;
108#define CPU_INTERRUPT_ENABLE 31
109#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27
110#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26
111#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25
112#define PCI_INTA_INTERRUPT_ENABLE 24
113#define PCI_PME_INTERRUPT_ENABLE 23
114#define PCI_SERR_INTERRUPT_ENABLE 22
115#define PCI_PERR_INTERRUPT_ENABLE 21
116#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20
117#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19
118#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17
119#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16
120#define GPIO_INTERRUPT_ENABLE 13
121#define DMA_D_INTERRUPT_ENABLE 12
122#define DMA_C_INTERRUPT_ENABLE 11
123#define DMA_B_INTERRUPT_ENABLE 10
124#define DMA_A_INTERRUPT_ENABLE 9
125#define EEPROM_DONE_INTERRUPT_ENABLE 8
126#define VBUS_INTERRUPT_ENABLE 7
127#define CONTROL_STATUS_INTERRUPT_ENABLE 6
128#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4
129#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3
130#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2
131#define RESUME_INTERRUPT_ENABLE 1
132#define SOF_INTERRUPT_ENABLE 0
133
134 // offset 0x0020
135 u32 _unused1;
136 __le32 usbirqenb1;
137#define USB_INTERRUPT_ENABLE 31
138#define POWER_STATE_CHANGE_INTERRUPT_ENABLE 27
139#define PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE 26
140#define PCI_PARITY_ERROR_INTERRUPT_ENABLE 25
141#define PCI_INTA_INTERRUPT_ENABLE 24
142#define PCI_PME_INTERRUPT_ENABLE 23
143#define PCI_SERR_INTERRUPT_ENABLE 22
144#define PCI_PERR_INTERRUPT_ENABLE 21
145#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE 20
146#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE 19
147#define PCI_RETRY_ABORT_INTERRUPT_ENABLE 17
148#define PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE 16
149#define GPIO_INTERRUPT_ENABLE 13
150#define DMA_D_INTERRUPT_ENABLE 12
151#define DMA_C_INTERRUPT_ENABLE 11
152#define DMA_B_INTERRUPT_ENABLE 10
153#define DMA_A_INTERRUPT_ENABLE 9
154#define EEPROM_DONE_INTERRUPT_ENABLE 8
155#define VBUS_INTERRUPT_ENABLE 7
156#define CONTROL_STATUS_INTERRUPT_ENABLE 6
157#define ROOT_PORT_RESET_INTERRUPT_ENABLE 4
158#define SUSPEND_REQUEST_INTERRUPT_ENABLE 3
159#define SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE 2
160#define RESUME_INTERRUPT_ENABLE 1
161#define SOF_INTERRUPT_ENABLE 0
162 __le32 irqstat0;
163#define INTA_ASSERTED 12
164#define SETUP_PACKET_INTERRUPT 7
165#define ENDPOINT_F_INTERRUPT 6
166#define ENDPOINT_E_INTERRUPT 5
167#define ENDPOINT_D_INTERRUPT 4
168#define ENDPOINT_C_INTERRUPT 3
169#define ENDPOINT_B_INTERRUPT 2
170#define ENDPOINT_A_INTERRUPT 1
171#define ENDPOINT_0_INTERRUPT 0
172 __le32 irqstat1;
173#define POWER_STATE_CHANGE_INTERRUPT 27
174#define PCI_ARBITER_TIMEOUT_INTERRUPT 26
175#define PCI_PARITY_ERROR_INTERRUPT 25
176#define PCI_INTA_INTERRUPT 24
177#define PCI_PME_INTERRUPT 23
178#define PCI_SERR_INTERRUPT 22
179#define PCI_PERR_INTERRUPT 21
180#define PCI_MASTER_ABORT_RECEIVED_INTERRUPT 20
181#define PCI_TARGET_ABORT_RECEIVED_INTERRUPT 19
182#define PCI_RETRY_ABORT_INTERRUPT 17
183#define PCI_MASTER_CYCLE_DONE_INTERRUPT 16
184#define GPIO_INTERRUPT 13
185#define DMA_D_INTERRUPT 12
186#define DMA_C_INTERRUPT 11
187#define DMA_B_INTERRUPT 10
188#define DMA_A_INTERRUPT 9
189#define EEPROM_DONE_INTERRUPT 8
190#define VBUS_INTERRUPT 7
191#define CONTROL_STATUS_INTERRUPT 6
192#define ROOT_PORT_RESET_INTERRUPT 4
193#define SUSPEND_REQUEST_INTERRUPT 3
194#define SUSPEND_REQUEST_CHANGE_INTERRUPT 2
195#define RESUME_INTERRUPT 1
196#define SOF_INTERRUPT 0
197 // offset 0x0030
198 __le32 idxaddr;
199 __le32 idxdata;
200 __le32 fifoctl;
201#define PCI_BASE2_RANGE 16
202#define IGNORE_FIFO_AVAILABILITY 3
203#define PCI_BASE2_SELECT 2
204#define FIFO_CONFIGURATION_SELECT 0
205 u32 _unused2;
206 // offset 0x0040
207 __le32 memaddr;
208#define START 28
209#define DIRECTION 27
210#define FIFO_DIAGNOSTIC_SELECT 24
211#define MEMORY_ADDRESS 0
212 __le32 memdata0;
213 __le32 memdata1;
214 u32 _unused3;
215 // offset 0x0050
216 __le32 gpioctl;
217#define GPIO3_LED_SELECT 12
218#define GPIO3_INTERRUPT_ENABLE 11
219#define GPIO2_INTERRUPT_ENABLE 10
220#define GPIO1_INTERRUPT_ENABLE 9
221#define GPIO0_INTERRUPT_ENABLE 8
222#define GPIO3_OUTPUT_ENABLE 7
223#define GPIO2_OUTPUT_ENABLE 6
224#define GPIO1_OUTPUT_ENABLE 5
225#define GPIO0_OUTPUT_ENABLE 4
226#define GPIO3_DATA 3
227#define GPIO2_DATA 2
228#define GPIO1_DATA 1
229#define GPIO0_DATA 0
230 __le32 gpiostat;
231#define GPIO3_INTERRUPT 3
232#define GPIO2_INTERRUPT 2
233#define GPIO1_INTERRUPT 1
234#define GPIO0_INTERRUPT 0
235} __attribute__ ((packed));
236
237/* usb control, BAR0 + 0x0080 */
238struct net2280_usb_regs {
239 // offset 0x0080
240 __le32 stdrsp;
241#define STALL_UNSUPPORTED_REQUESTS 31
242#define SET_TEST_MODE 16
243#define GET_OTHER_SPEED_CONFIGURATION 15
244#define GET_DEVICE_QUALIFIER 14
245#define SET_ADDRESS 13
246#define ENDPOINT_SET_CLEAR_HALT 12
247#define DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP 11
248#define GET_STRING_DESCRIPTOR_2 10
249#define GET_STRING_DESCRIPTOR_1 9
250#define GET_STRING_DESCRIPTOR_0 8
251#define GET_SET_INTERFACE 6
252#define GET_SET_CONFIGURATION 5
253#define GET_CONFIGURATION_DESCRIPTOR 4
254#define GET_DEVICE_DESCRIPTOR 3
255#define GET_ENDPOINT_STATUS 2
256#define GET_INTERFACE_STATUS 1
257#define GET_DEVICE_STATUS 0
258 __le32 prodvendid;
259#define PRODUCT_ID 16
260#define VENDOR_ID 0
261 __le32 relnum;
262 __le32 usbctl;
263#define SERIAL_NUMBER_INDEX 16
264#define PRODUCT_ID_STRING_ENABLE 13
265#define VENDOR_ID_STRING_ENABLE 12
266#define USB_ROOT_PORT_WAKEUP_ENABLE 11
267#define VBUS_PIN 10
268#define TIMED_DISCONNECT 9
269#define SUSPEND_IMMEDIATELY 7
270#define SELF_POWERED_USB_DEVICE 6
271#define REMOTE_WAKEUP_SUPPORT 5
272#define PME_POLARITY 4
273#define USB_DETECT_ENABLE 3
274#define PME_WAKEUP_ENABLE 2
275#define DEVICE_REMOTE_WAKEUP_ENABLE 1
276#define SELF_POWERED_STATUS 0
277 // offset 0x0090
278 __le32 usbstat;
279#define HIGH_SPEED 7
280#define FULL_SPEED 6
281#define GENERATE_RESUME 5
282#define GENERATE_DEVICE_REMOTE_WAKEUP 4
283 __le32 xcvrdiag;
284#define FORCE_HIGH_SPEED_MODE 31
285#define FORCE_FULL_SPEED_MODE 30
286#define USB_TEST_MODE 24
287#define LINE_STATE 16
288#define TRANSCEIVER_OPERATION_MODE 2
289#define TRANSCEIVER_SELECT 1
290#define TERMINATION_SELECT 0
291 __le32 setup0123;
292 __le32 setup4567;
293 // offset 0x0090
294 u32 _unused0;
295 __le32 ouraddr;
296#define FORCE_IMMEDIATE 7
297#define OUR_USB_ADDRESS 0
298 __le32 ourconfig;
299} __attribute__ ((packed));
300
301/* pci control, BAR0 + 0x0100 */
302struct net2280_pci_regs {
303 // offset 0x0100
304 __le32 pcimstctl;
305#define PCI_ARBITER_PARK_SELECT 13
306#define PCI_MULTI LEVEL_ARBITER 12
307#define PCI_RETRY_ABORT_ENABLE 11
308#define DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE 10
309#define DMA_READ_MULTIPLE_ENABLE 9
310#define DMA_READ_LINE_ENABLE 8
311#define PCI_MASTER_COMMAND_SELECT 6
312#define MEM_READ_OR_WRITE 0
313#define IO_READ_OR_WRITE 1
314#define CFG_READ_OR_WRITE 2
315#define PCI_MASTER_START 5
316#define PCI_MASTER_READ_WRITE 4
317#define PCI_MASTER_WRITE 0
318#define PCI_MASTER_READ 1
319#define PCI_MASTER_BYTE_WRITE_ENABLES 0
320 __le32 pcimstaddr;
321 __le32 pcimstdata;
322 __le32 pcimststat;
323#define PCI_ARBITER_CLEAR 2
324#define PCI_EXTERNAL_ARBITER 1
325#define PCI_HOST_MODE 0
326} __attribute__ ((packed));
327
328/* dma control, BAR0 + 0x0180 ... array of four structs like this,
329 * for channels 0..3. see also struct net2280_dma: descriptor
330 * that can be loaded into some of these registers.
331 */
332struct net2280_dma_regs { /* [11.7] */
333 // offset 0x0180, 0x01a0, 0x01c0, 0x01e0,
334 __le32 dmactl;
335#define DMA_SCATTER_GATHER_DONE_INTERRUPT_ENABLE 25
336#define DMA_CLEAR_COUNT_ENABLE 21
337#define DESCRIPTOR_POLLING_RATE 19
338#define POLL_CONTINUOUS 0
339#define POLL_1_USEC 1
340#define POLL_100_USEC 2
341#define POLL_1_MSEC 3
342#define DMA_VALID_BIT_POLLING_ENABLE 18
343#define DMA_VALID_BIT_ENABLE 17
344#define DMA_SCATTER_GATHER_ENABLE 16
345#define DMA_OUT_AUTO_START_ENABLE 4
346#define DMA_PREEMPT_ENABLE 3
347#define DMA_FIFO_VALIDATE 2
348#define DMA_ENABLE 1
349#define DMA_ADDRESS_HOLD 0
350 __le32 dmastat;
351#define DMA_SCATTER_GATHER_DONE_INTERRUPT 25
352#define DMA_TRANSACTION_DONE_INTERRUPT 24
353#define DMA_ABORT 1
354#define DMA_START 0
355 u32 _unused0[2];
356 // offset 0x0190, 0x01b0, 0x01d0, 0x01f0,
357 __le32 dmacount;
358#define VALID_BIT 31
359#define DMA_DIRECTION 30
360#define DMA_DONE_INTERRUPT_ENABLE 29
361#define END_OF_CHAIN 28
362#define DMA_BYTE_COUNT_MASK ((1<<24)-1)
363#define DMA_BYTE_COUNT 0
364 __le32 dmaaddr;
365 __le32 dmadesc;
366 u32 _unused1;
367} __attribute__ ((packed));
368
369/* dedicated endpoint registers, BAR0 + 0x0200 */
370
371struct net2280_dep_regs { /* [11.8] */
372 // offset 0x0200, 0x0210, 0x220, 0x230, 0x240
373 __le32 dep_cfg;
374 // offset 0x0204, 0x0214, 0x224, 0x234, 0x244
375 __le32 dep_rsp;
376 u32 _unused[2];
377} __attribute__ ((packed));
378
379/* configurable endpoint registers, BAR0 + 0x0300 ... array of seven structs
380 * like this, for ep0 then the configurable endpoints A..F
381 * ep0 reserved for control; E and F have only 64 bytes of fifo
382 */
383struct net2280_ep_regs { /* [11.9] */
384 // offset 0x0300, 0x0320, 0x0340, 0x0360, 0x0380, 0x03a0, 0x03c0
385 __le32 ep_cfg;
386#define ENDPOINT_BYTE_COUNT 16
387#define ENDPOINT_ENABLE 10
388#define ENDPOINT_TYPE 8
389#define ENDPOINT_DIRECTION 7
390#define ENDPOINT_NUMBER 0
391 __le32 ep_rsp;
392#define SET_NAK_OUT_PACKETS 15
393#define SET_EP_HIDE_STATUS_PHASE 14
394#define SET_EP_FORCE_CRC_ERROR 13
395#define SET_INTERRUPT_MODE 12
396#define SET_CONTROL_STATUS_PHASE_HANDSHAKE 11
397#define SET_NAK_OUT_PACKETS_MODE 10
398#define SET_ENDPOINT_TOGGLE 9
399#define SET_ENDPOINT_HALT 8
400#define CLEAR_NAK_OUT_PACKETS 7
401#define CLEAR_EP_HIDE_STATUS_PHASE 6
402#define CLEAR_EP_FORCE_CRC_ERROR 5
403#define CLEAR_INTERRUPT_MODE 4
404#define CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE 3
405#define CLEAR_NAK_OUT_PACKETS_MODE 2
406#define CLEAR_ENDPOINT_TOGGLE 1
407#define CLEAR_ENDPOINT_HALT 0
408 __le32 ep_irqenb;
409#define SHORT_PACKET_OUT_DONE_INTERRUPT_ENABLE 6
410#define SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE 5
411#define DATA_PACKET_RECEIVED_INTERRUPT_ENABLE 3
412#define DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE 2
413#define DATA_OUT_PING_TOKEN_INTERRUPT_ENABLE 1
414#define DATA_IN_TOKEN_INTERRUPT_ENABLE 0
415 __le32 ep_stat;
416#define FIFO_VALID_COUNT 24
417#define HIGH_BANDWIDTH_OUT_TRANSACTION_PID 22
418#define TIMEOUT 21
419#define USB_STALL_SENT 20
420#define USB_IN_NAK_SENT 19
421#define USB_IN_ACK_RCVD 18
422#define USB_OUT_PING_NAK_SENT 17
423#define USB_OUT_ACK_SENT 16
424#define FIFO_OVERFLOW 13
425#define FIFO_UNDERFLOW 12
426#define FIFO_FULL 11
427#define FIFO_EMPTY 10
428#define FIFO_FLUSH 9
429#define SHORT_PACKET_OUT_DONE_INTERRUPT 6
430#define SHORT_PACKET_TRANSFERRED_INTERRUPT 5
431#define NAK_OUT_PACKETS 4
432#define DATA_PACKET_RECEIVED_INTERRUPT 3
433#define DATA_PACKET_TRANSMITTED_INTERRUPT 2
434#define DATA_OUT_PING_TOKEN_INTERRUPT 1
435#define DATA_IN_TOKEN_INTERRUPT 0
436 // offset 0x0310, 0x0330, 0x0350, 0x0370, 0x0390, 0x03b0, 0x03d0
437 __le32 ep_avail;
438 __le32 ep_data;
439 u32 _unused0[2];
440} __attribute__ ((packed));
441
442struct net2280_reg_write {
443 __le16 port;
444 __le32 addr;
445 __le32 val;
446} __attribute__ ((packed));
447
448struct net2280_reg_read {
449 __le16 port;
450 __le32 addr;
451} __attribute__ ((packed));
452#endif /* NET2280_H */
diff --git a/drivers/net/wireless/p54.h b/drivers/net/wireless/p54.h
new file mode 100644
index 000000000000..e558d697d9e5
--- /dev/null
+++ b/drivers/net/wireless/p54.h
@@ -0,0 +1,80 @@
1#ifndef PRISM54_H
2#define PRISM54_H
3
4/*
5 * Shared defines for all mac80211 Prism54 code
6 *
7 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
8 *
9 * Based on the islsm (softmac prism54) driver, which is:
10 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17enum control_frame_types {
18 P54_CONTROL_TYPE_FILTER_SET = 0,
19 P54_CONTROL_TYPE_CHANNEL_CHANGE,
20 P54_CONTROL_TYPE_FREQDONE,
21 P54_CONTROL_TYPE_DCFINIT,
22 P54_CONTROL_TYPE_FREEQUEUE = 7,
23 P54_CONTROL_TYPE_TXDONE,
24 P54_CONTROL_TYPE_PING,
25 P54_CONTROL_TYPE_STAT_READBACK,
26 P54_CONTROL_TYPE_BBP,
27 P54_CONTROL_TYPE_EEPROM_READBACK,
28 P54_CONTROL_TYPE_LED
29};
30
31struct p54_control_hdr {
32 __le16 magic1;
33 __le16 len;
34 __le32 req_id;
35 __le16 type; /* enum control_frame_types */
36 u8 retry1;
37 u8 retry2;
38 u8 data[0];
39} __attribute__ ((packed));
40
41#define EEPROM_READBACK_LEN (sizeof(struct p54_control_hdr) + 4 /* p54_eeprom_lm86 */)
42#define MAX_RX_SIZE (IEEE80211_MAX_RTS_THRESHOLD + sizeof(struct p54_control_hdr) + 20 /* length of struct p54_rx_hdr */ + 16 )
43
44#define ISL38XX_DEV_FIRMWARE_ADDR 0x20000
45
46struct p54_common {
47 u32 rx_start;
48 u32 rx_end;
49 struct sk_buff_head tx_queue;
50 void (*tx)(struct ieee80211_hw *dev, struct p54_control_hdr *data,
51 size_t len, int free_on_tx);
52 int (*open)(struct ieee80211_hw *dev);
53 void (*stop)(struct ieee80211_hw *dev);
54 int mode;
55 u8 *mac_addr;
56 struct pda_iq_autocal_entry *iq_autocal;
57 unsigned int iq_autocal_len;
58 struct pda_channel_output_limit *output_limit;
59 unsigned int output_limit_len;
60 struct pda_pa_curve_data *curve_data;
61 __le16 rxhw;
62 u8 version;
63 unsigned int tx_hdr_len;
64 void *cached_vdcf;
65 unsigned int fw_var;
66 /* FIXME: this channels/modes/rates stuff sucks */
67 struct ieee80211_channel channels[14];
68 struct ieee80211_rate rates[12];
69 struct ieee80211_hw_mode modes[2];
70 struct ieee80211_tx_queue_stats tx_stats;
71};
72
73int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb);
74void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw);
75int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len);
76void p54_fill_eeprom_readback(struct p54_control_hdr *hdr);
77struct ieee80211_hw *p54_init_common(size_t priv_data_len);
78void p54_free_common(struct ieee80211_hw *dev);
79
80#endif /* PRISM54_H */
diff --git a/drivers/net/wireless/p54common.c b/drivers/net/wireless/p54common.c
new file mode 100644
index 000000000000..b05b5c5b4c04
--- /dev/null
+++ b/drivers/net/wireless/p54common.c
@@ -0,0 +1,983 @@
1
2/*
3 * Common code for mac80211 Prism54 drivers
4 *
5 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
6 * Copyright (c) 2007, Christian Lamparter <chunkeey@web.de>
7 *
8 * Based on the islsm (softmac prism54) driver, which is:
9 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/init.h>
17#include <linux/firmware.h>
18#include <linux/etherdevice.h>
19
20#include <net/mac80211.h>
21
22#include "p54.h"
23#include "p54common.h"
24
25MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
26MODULE_DESCRIPTION("Softmac Prism54 common code");
27MODULE_LICENSE("GPL");
28MODULE_ALIAS("prism54common");
29
30void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
31{
32 struct p54_common *priv = dev->priv;
33 struct bootrec_exp_if *exp_if;
34 struct bootrec *bootrec;
35 u32 *data = (u32 *)fw->data;
36 u32 *end_data = (u32 *)fw->data + (fw->size >> 2);
37 u8 *fw_version = NULL;
38 size_t len;
39 int i;
40
41 if (priv->rx_start)
42 return;
43
44 while (data < end_data && *data)
45 data++;
46
47 while (data < end_data && !*data)
48 data++;
49
50 bootrec = (struct bootrec *) data;
51
52 while (bootrec->data <= end_data &&
53 (bootrec->data + (len = le32_to_cpu(bootrec->len))) <= end_data) {
54 u32 code = le32_to_cpu(bootrec->code);
55 switch (code) {
56 case BR_CODE_COMPONENT_ID:
57 switch (be32_to_cpu(*bootrec->data)) {
58 case FW_FMAC:
59 printk(KERN_INFO "p54: FreeMAC firmware\n");
60 break;
61 case FW_LM20:
62 printk(KERN_INFO "p54: LM20 firmware\n");
63 break;
64 case FW_LM86:
65 printk(KERN_INFO "p54: LM86 firmware\n");
66 break;
67 case FW_LM87:
68 printk(KERN_INFO "p54: LM87 firmware - not supported yet!\n");
69 break;
70 default:
71 printk(KERN_INFO "p54: unknown firmware\n");
72 break;
73 }
74 break;
75 case BR_CODE_COMPONENT_VERSION:
76 /* 24 bytes should be enough for all firmwares */
77 if (strnlen((unsigned char*)bootrec->data, 24) < 24)
78 fw_version = (unsigned char*)bootrec->data;
79 break;
80 case BR_CODE_DESCR:
81 priv->rx_start = le32_to_cpu(bootrec->data[1]);
82 /* FIXME add sanity checking */
83 priv->rx_end = le32_to_cpu(bootrec->data[2]) - 0x3500;
84 break;
85 case BR_CODE_EXPOSED_IF:
86 exp_if = (struct bootrec_exp_if *) bootrec->data;
87 for (i = 0; i < (len * sizeof(*exp_if) / 4); i++)
88 if (exp_if[i].if_id == 0x1a)
89 priv->fw_var = le16_to_cpu(exp_if[i].variant);
90 break;
91 case BR_CODE_DEPENDENT_IF:
92 break;
93 case BR_CODE_END_OF_BRA:
94 case LEGACY_BR_CODE_END_OF_BRA:
95 end_data = NULL;
96 break;
97 default:
98 break;
99 }
100 bootrec = (struct bootrec *)&bootrec->data[len];
101 }
102
103 if (fw_version)
104 printk(KERN_INFO "p54: FW rev %s - Softmac protocol %x.%x\n",
105 fw_version, priv->fw_var >> 8, priv->fw_var & 0xff);
106
107 if (priv->fw_var >= 0x300) {
108 /* Firmware supports QoS, use it! */
109 priv->tx_stats.data[0].limit = 3;
110 priv->tx_stats.data[1].limit = 4;
111 priv->tx_stats.data[2].limit = 3;
112 priv->tx_stats.data[3].limit = 1;
113 dev->queues = 4;
114 }
115}
116EXPORT_SYMBOL_GPL(p54_parse_firmware);
117
118static int p54_convert_rev0_to_rev1(struct ieee80211_hw *dev,
119 struct pda_pa_curve_data *curve_data)
120{
121 struct p54_common *priv = dev->priv;
122 struct pda_pa_curve_data_sample_rev1 *rev1;
123 struct pda_pa_curve_data_sample_rev0 *rev0;
124 size_t cd_len = sizeof(*curve_data) +
125 (curve_data->points_per_channel*sizeof(*rev1) + 2) *
126 curve_data->channels;
127 unsigned int i, j;
128 void *source, *target;
129
130 priv->curve_data = kmalloc(cd_len, GFP_KERNEL);
131 if (!priv->curve_data)
132 return -ENOMEM;
133
134 memcpy(priv->curve_data, curve_data, sizeof(*curve_data));
135 source = curve_data->data;
136 target = priv->curve_data->data;
137 for (i = 0; i < curve_data->channels; i++) {
138 __le16 *freq = source;
139 source += sizeof(__le16);
140 *((__le16 *)target) = *freq;
141 target += sizeof(__le16);
142 for (j = 0; j < curve_data->points_per_channel; j++) {
143 rev1 = target;
144 rev0 = source;
145
146 rev1->rf_power = rev0->rf_power;
147 rev1->pa_detector = rev0->pa_detector;
148 rev1->data_64qam = rev0->pcv;
149 /* "invent" the points for the other modulations */
150#define SUB(x,y) (u8)((x) - (y)) > (x) ? 0 : (x) - (y)
151 rev1->data_16qam = SUB(rev0->pcv, 12);
152 rev1->data_qpsk = SUB(rev1->data_16qam, 12);
153 rev1->data_bpsk = SUB(rev1->data_qpsk, 12);
154 rev1->data_barker= SUB(rev1->data_bpsk, 14);
155#undef SUB
156 target += sizeof(*rev1);
157 source += sizeof(*rev0);
158 }
159 }
160
161 return 0;
162}
163
164int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
165{
166 struct p54_common *priv = dev->priv;
167 struct eeprom_pda_wrap *wrap = NULL;
168 struct pda_entry *entry;
169 int i = 0;
170 unsigned int data_len, entry_len;
171 void *tmp;
172 int err;
173
174 wrap = (struct eeprom_pda_wrap *) eeprom;
175 entry = (void *)wrap->data + wrap->len;
176 i += 2;
177 i += le16_to_cpu(entry->len)*2;
178 while (i < len) {
179 entry_len = le16_to_cpu(entry->len);
180 data_len = ((entry_len - 1) << 1);
181 switch (le16_to_cpu(entry->code)) {
182 case PDR_MAC_ADDRESS:
183 SET_IEEE80211_PERM_ADDR(dev, entry->data);
184 break;
185 case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS:
186 if (data_len < 2) {
187 err = -EINVAL;
188 goto err;
189 }
190
191 if (2 + entry->data[1]*sizeof(*priv->output_limit) > data_len) {
192 err = -EINVAL;
193 goto err;
194 }
195
196 priv->output_limit = kmalloc(entry->data[1] *
197 sizeof(*priv->output_limit), GFP_KERNEL);
198
199 if (!priv->output_limit) {
200 err = -ENOMEM;
201 goto err;
202 }
203
204 memcpy(priv->output_limit, &entry->data[2],
205 entry->data[1]*sizeof(*priv->output_limit));
206 priv->output_limit_len = entry->data[1];
207 break;
208 case PDR_PRISM_PA_CAL_CURVE_DATA:
209 if (data_len < sizeof(struct pda_pa_curve_data)) {
210 err = -EINVAL;
211 goto err;
212 }
213
214 if (((struct pda_pa_curve_data *)entry->data)->cal_method_rev) {
215 priv->curve_data = kmalloc(data_len, GFP_KERNEL);
216 if (!priv->curve_data) {
217 err = -ENOMEM;
218 goto err;
219 }
220
221 memcpy(priv->curve_data, entry->data, data_len);
222 } else {
223 err = p54_convert_rev0_to_rev1(dev, (struct pda_pa_curve_data *)entry->data);
224 if (err)
225 goto err;
226 }
227
228 break;
229 case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
230 priv->iq_autocal = kmalloc(data_len, GFP_KERNEL);
231 if (!priv->iq_autocal) {
232 err = -ENOMEM;
233 goto err;
234 }
235
236 memcpy(priv->iq_autocal, entry->data, data_len);
237 priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry);
238 break;
239 case PDR_INTERFACE_LIST:
240 tmp = entry->data;
241 while ((u8 *)tmp < entry->data + data_len) {
242 struct bootrec_exp_if *exp_if = tmp;
243 if (le16_to_cpu(exp_if->if_id) == 0xF)
244 priv->rxhw = exp_if->variant & cpu_to_le16(0x07);
245 tmp += sizeof(struct bootrec_exp_if);
246 }
247 break;
248 case PDR_HARDWARE_PLATFORM_COMPONENT_ID:
249 priv->version = *(u8 *)(entry->data + 1);
250 break;
251 case PDR_END:
252 i = len;
253 break;
254 }
255
256 entry = (void *)entry + (entry_len + 1)*2;
257 i += 2;
258 i += entry_len*2;
259 }
260
261 if (!priv->iq_autocal || !priv->output_limit || !priv->curve_data) {
262 printk(KERN_ERR "p54: not all required entries found in eeprom!\n");
263 err = -EINVAL;
264 goto err;
265 }
266
267 return 0;
268
269 err:
270 if (priv->iq_autocal) {
271 kfree(priv->iq_autocal);
272 priv->iq_autocal = NULL;
273 }
274
275 if (priv->output_limit) {
276 kfree(priv->output_limit);
277 priv->output_limit = NULL;
278 }
279
280 if (priv->curve_data) {
281 kfree(priv->curve_data);
282 priv->curve_data = NULL;
283 }
284
285 printk(KERN_ERR "p54: eeprom parse failed!\n");
286 return err;
287}
288EXPORT_SYMBOL_GPL(p54_parse_eeprom);
289
290void p54_fill_eeprom_readback(struct p54_control_hdr *hdr)
291{
292 struct p54_eeprom_lm86 *eeprom_hdr;
293
294 hdr->magic1 = cpu_to_le16(0x8000);
295 hdr->len = cpu_to_le16(sizeof(*eeprom_hdr) + 0x2000);
296 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_EEPROM_READBACK);
297 hdr->retry1 = hdr->retry2 = 0;
298 eeprom_hdr = (struct p54_eeprom_lm86 *) hdr->data;
299 eeprom_hdr->offset = 0x0;
300 eeprom_hdr->len = cpu_to_le16(0x2000);
301}
302EXPORT_SYMBOL_GPL(p54_fill_eeprom_readback);
303
304static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
305{
306 struct p54_rx_hdr *hdr = (struct p54_rx_hdr *) skb->data;
307 struct ieee80211_rx_status rx_status = {0};
308 u16 freq = le16_to_cpu(hdr->freq);
309
310 rx_status.ssi = hdr->rssi;
311 rx_status.rate = hdr->rate & 0x1f; /* report short preambles & CCK too */
312 rx_status.channel = freq == 2484 ? 14 : (freq - 2407)/5;
313 rx_status.freq = freq;
314 rx_status.phymode = MODE_IEEE80211G;
315 rx_status.antenna = hdr->antenna;
316 rx_status.mactime = le64_to_cpu(hdr->timestamp);
317
318 skb_pull(skb, sizeof(*hdr));
319 skb_trim(skb, le16_to_cpu(hdr->len));
320
321 ieee80211_rx_irqsafe(dev, skb, &rx_status);
322}
323
324static void inline p54_wake_free_queues(struct ieee80211_hw *dev)
325{
326 struct p54_common *priv = dev->priv;
327 int i;
328
329 /* ieee80211_start_queues is great if all queues are really empty.
330 * But, what if some are full? */
331
332 for (i = 0; i < dev->queues; i++)
333 if (priv->tx_stats.data[i].len < priv->tx_stats.data[i].limit)
334 ieee80211_wake_queue(dev, i);
335}
336
337static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
338{
339 struct p54_common *priv = dev->priv;
340 struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
341 struct p54_frame_sent_hdr *payload = (struct p54_frame_sent_hdr *) hdr->data;
342 struct sk_buff *entry = (struct sk_buff *) priv->tx_queue.next;
343 u32 addr = le32_to_cpu(hdr->req_id) - 0x70;
344 struct memrecord *range = NULL;
345 u32 freed = 0;
346 u32 last_addr = priv->rx_start;
347
348 while (entry != (struct sk_buff *)&priv->tx_queue) {
349 range = (struct memrecord *)&entry->cb;
350 if (range->start_addr == addr) {
351 struct ieee80211_tx_status status = {{0}};
352 struct p54_control_hdr *entry_hdr;
353 struct p54_tx_control_allocdata *entry_data;
354 int pad = 0;
355
356 if (entry->next != (struct sk_buff *)&priv->tx_queue)
357 freed = ((struct memrecord *)&entry->next->cb)->start_addr - last_addr;
358 else
359 freed = priv->rx_end - last_addr;
360
361 last_addr = range->end_addr;
362 __skb_unlink(entry, &priv->tx_queue);
363 if (!range->control) {
364 kfree_skb(entry);
365 break;
366 }
367 memcpy(&status.control, range->control,
368 sizeof(status.control));
369 kfree(range->control);
370 priv->tx_stats.data[status.control.queue].len--;
371
372 entry_hdr = (struct p54_control_hdr *) entry->data;
373 entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data;
374 if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
375 pad = entry_data->align[0];
376
377 if (!status.control.flags & IEEE80211_TXCTL_NO_ACK) {
378 if (!(payload->status & 0x01))
379 status.flags |= IEEE80211_TX_STATUS_ACK;
380 else
381 status.excessive_retries = 1;
382 }
383 status.retry_count = payload->retries - 1;
384 status.ack_signal = le16_to_cpu(payload->ack_rssi);
385 skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
386 ieee80211_tx_status_irqsafe(dev, entry, &status);
387 break;
388 } else
389 last_addr = range->end_addr;
390 entry = entry->next;
391 }
392
393 if (freed >= IEEE80211_MAX_RTS_THRESHOLD + 0x170 +
394 sizeof(struct p54_control_hdr))
395 p54_wake_free_queues(dev);
396}
397
398static void p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb)
399{
400 struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
401
402 switch (le16_to_cpu(hdr->type)) {
403 case P54_CONTROL_TYPE_TXDONE:
404 p54_rx_frame_sent(dev, skb);
405 break;
406 case P54_CONTROL_TYPE_BBP:
407 break;
408 default:
409 printk(KERN_DEBUG "%s: not handling 0x%02x type control frame\n",
410 wiphy_name(dev->wiphy), le16_to_cpu(hdr->type));
411 break;
412 }
413}
414
415/* returns zero if skb can be reused */
416int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb)
417{
418 u8 type = le16_to_cpu(*((__le16 *)skb->data)) >> 8;
419 switch (type) {
420 case 0x00:
421 case 0x01:
422 p54_rx_data(dev, skb);
423 return -1;
424 case 0x4d:
425 /* TODO: do something better... but then again, I've never seen this happen */
426 printk(KERN_ERR "%s: Received fault. Probably need to restart hardware now..\n",
427 wiphy_name(dev->wiphy));
428 break;
429 case 0x80:
430 p54_rx_control(dev, skb);
431 break;
432 default:
433 printk(KERN_ERR "%s: unknown frame RXed (0x%02x)\n",
434 wiphy_name(dev->wiphy), type);
435 break;
436 }
437 return 0;
438}
439EXPORT_SYMBOL_GPL(p54_rx);
440
441/*
442 * So, the firmware is somewhat stupid and doesn't know what places in its
443 * memory incoming data should go to. By poking around in the firmware, we
444 * can find some unused memory to upload our packets to. However, data that we
445 * want the card to TX needs to stay intact until the card has told us that
446 * it is done with it. This function finds empty places we can upload to and
447 * marks allocated areas as reserved if necessary. p54_rx_frame_sent frees
448 * allocated areas.
449 */
450static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
451 struct p54_control_hdr *data, u32 len,
452 struct ieee80211_tx_control *control)
453{
454 struct p54_common *priv = dev->priv;
455 struct sk_buff *entry = priv->tx_queue.next;
456 struct sk_buff *target_skb = NULL;
457 struct memrecord *range;
458 u32 last_addr = priv->rx_start;
459 u32 largest_hole = 0;
460 u32 target_addr = priv->rx_start;
461 unsigned long flags;
462 unsigned int left;
463 len = (len + 0x170 + 3) & ~0x3; /* 0x70 headroom, 0x100 tailroom */
464
465 spin_lock_irqsave(&priv->tx_queue.lock, flags);
466 left = skb_queue_len(&priv->tx_queue);
467 while (left--) {
468 u32 hole_size;
469 range = (struct memrecord *)&entry->cb;
470 hole_size = range->start_addr - last_addr;
471 if (!target_skb && hole_size >= len) {
472 target_skb = entry->prev;
473 hole_size -= len;
474 target_addr = last_addr;
475 }
476 largest_hole = max(largest_hole, hole_size);
477 last_addr = range->end_addr;
478 entry = entry->next;
479 }
480 if (!target_skb && priv->rx_end - last_addr >= len) {
481 target_skb = priv->tx_queue.prev;
482 largest_hole = max(largest_hole, priv->rx_end - last_addr - len);
483 if (!skb_queue_empty(&priv->tx_queue)) {
484 range = (struct memrecord *)&target_skb->cb;
485 target_addr = range->end_addr;
486 }
487 } else
488 largest_hole = max(largest_hole, priv->rx_end - last_addr);
489
490 if (skb) {
491 range = (struct memrecord *)&skb->cb;
492 range->start_addr = target_addr;
493 range->end_addr = target_addr + len;
494 range->control = control;
495 __skb_queue_after(&priv->tx_queue, target_skb, skb);
496 if (largest_hole < IEEE80211_MAX_RTS_THRESHOLD + 0x170 +
497 sizeof(struct p54_control_hdr))
498 ieee80211_stop_queues(dev);
499 }
500 spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
501
502 data->req_id = cpu_to_le32(target_addr + 0x70);
503}
504
505static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
506 struct ieee80211_tx_control *control)
507{
508 struct ieee80211_tx_queue_stats_data *current_queue;
509 struct p54_common *priv = dev->priv;
510 struct p54_control_hdr *hdr;
511 struct p54_tx_control_allocdata *txhdr;
512 struct ieee80211_tx_control *control_copy;
513 size_t padding, len;
514 u8 rate;
515
516 current_queue = &priv->tx_stats.data[control->queue];
517 if (unlikely(current_queue->len > current_queue->limit))
518 return NETDEV_TX_BUSY;
519 current_queue->len++;
520 current_queue->count++;
521 if (current_queue->len == current_queue->limit)
522 ieee80211_stop_queue(dev, control->queue);
523
524 padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3;
525 len = skb->len;
526
527 control_copy = kmalloc(sizeof(*control), GFP_ATOMIC);
528 if (control_copy)
529 memcpy(control_copy, control, sizeof(*control));
530
531 txhdr = (struct p54_tx_control_allocdata *)
532 skb_push(skb, sizeof(*txhdr) + padding);
533 hdr = (struct p54_control_hdr *) skb_push(skb, sizeof(*hdr));
534
535 if (padding)
536 hdr->magic1 = cpu_to_le16(0x4010);
537 else
538 hdr->magic1 = cpu_to_le16(0x0010);
539 hdr->len = cpu_to_le16(len);
540 hdr->type = (control->flags & IEEE80211_TXCTL_NO_ACK) ? 0 : cpu_to_le16(1);
541 hdr->retry1 = hdr->retry2 = control->retry_limit;
542 p54_assign_address(dev, skb, hdr, skb->len, control_copy);
543
544 memset(txhdr->wep_key, 0x0, 16);
545 txhdr->padding = 0;
546 txhdr->padding2 = 0;
547
548 /* TODO: add support for alternate retry TX rates */
549 rate = control->tx_rate;
550 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
551 rate |= 0x40;
552 else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
553 rate |= 0x20;
554 memset(txhdr->rateset, rate, 8);
555 txhdr->wep_key_present = 0;
556 txhdr->wep_key_len = 0;
557 txhdr->frame_type = cpu_to_le32(control->queue + 4);
558 txhdr->magic4 = 0;
559 txhdr->antenna = (control->antenna_sel_tx == 0) ?
560 2 : control->antenna_sel_tx - 1;
561 txhdr->output_power = 0x7f; // HW Maximum
562 txhdr->magic5 = (control->flags & IEEE80211_TXCTL_NO_ACK) ?
563 0 : ((rate > 0x3) ? cpu_to_le32(0x33) : cpu_to_le32(0x23));
564 if (padding)
565 txhdr->align[0] = padding;
566
567 priv->tx(dev, hdr, skb->len, 0);
568 return 0;
569}
570
571static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
572 const u8 *dst, const u8 *src, u8 antenna,
573 u32 magic3, u32 magic8, u32 magic9)
574{
575 struct p54_common *priv = dev->priv;
576 struct p54_control_hdr *hdr;
577 struct p54_tx_control_filter *filter;
578
579 hdr = kzalloc(sizeof(*hdr) + sizeof(*filter) +
580 priv->tx_hdr_len, GFP_KERNEL);
581 if (!hdr)
582 return -ENOMEM;
583
584 hdr = (void *)hdr + priv->tx_hdr_len;
585
586 filter = (struct p54_tx_control_filter *) hdr->data;
587 hdr->magic1 = cpu_to_le16(0x8001);
588 hdr->len = cpu_to_le16(sizeof(*filter));
589 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*filter), NULL);
590 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_FILTER_SET);
591
592 filter->filter_type = cpu_to_le16(filter_type);
593 memcpy(filter->dst, dst, ETH_ALEN);
594 if (!src)
595 memset(filter->src, ~0, ETH_ALEN);
596 else
597 memcpy(filter->src, src, ETH_ALEN);
598 filter->antenna = antenna;
599 filter->magic3 = cpu_to_le32(magic3);
600 filter->rx_addr = cpu_to_le32(priv->rx_end);
601 filter->max_rx = cpu_to_le16(0x0620); /* FIXME: for usb ver 1.. maybe */
602 filter->rxhw = priv->rxhw;
603 filter->magic8 = cpu_to_le16(magic8);
604 filter->magic9 = cpu_to_le16(magic9);
605
606 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*filter), 1);
607 return 0;
608}
609
610static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
611{
612 struct p54_common *priv = dev->priv;
613 struct p54_control_hdr *hdr;
614 struct p54_tx_control_channel *chan;
615 unsigned int i;
616 size_t payload_len = sizeof(*chan) + sizeof(u32)*2 +
617 sizeof(*chan->curve_data) *
618 priv->curve_data->points_per_channel;
619 void *entry;
620
621 hdr = kzalloc(sizeof(*hdr) + payload_len +
622 priv->tx_hdr_len, GFP_KERNEL);
623 if (!hdr)
624 return -ENOMEM;
625
626 hdr = (void *)hdr + priv->tx_hdr_len;
627
628 chan = (struct p54_tx_control_channel *) hdr->data;
629
630 hdr->magic1 = cpu_to_le16(0x8001);
631 hdr->len = cpu_to_le16(sizeof(*chan));
632 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_CHANNEL_CHANGE);
633 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + payload_len, NULL);
634
635 chan->magic1 = cpu_to_le16(0x1);
636 chan->magic2 = cpu_to_le16(0x0);
637
638 for (i = 0; i < priv->iq_autocal_len; i++) {
639 if (priv->iq_autocal[i].freq != freq)
640 continue;
641
642 memcpy(&chan->iq_autocal, &priv->iq_autocal[i],
643 sizeof(*priv->iq_autocal));
644 break;
645 }
646 if (i == priv->iq_autocal_len)
647 goto err;
648
649 for (i = 0; i < priv->output_limit_len; i++) {
650 if (priv->output_limit[i].freq != freq)
651 continue;
652
653 chan->val_barker = 0x38;
654 chan->val_bpsk = priv->output_limit[i].val_bpsk;
655 chan->val_qpsk = priv->output_limit[i].val_qpsk;
656 chan->val_16qam = priv->output_limit[i].val_16qam;
657 chan->val_64qam = priv->output_limit[i].val_64qam;
658 break;
659 }
660 if (i == priv->output_limit_len)
661 goto err;
662
663 chan->pa_points_per_curve = priv->curve_data->points_per_channel;
664
665 entry = priv->curve_data->data;
666 for (i = 0; i < priv->curve_data->channels; i++) {
667 if (*((__le16 *)entry) != freq) {
668 entry += sizeof(__le16);
669 entry += sizeof(struct pda_pa_curve_data_sample_rev1) *
670 chan->pa_points_per_curve;
671 continue;
672 }
673
674 entry += sizeof(__le16);
675 memcpy(chan->curve_data, entry, sizeof(*chan->curve_data) *
676 chan->pa_points_per_curve);
677 break;
678 }
679
680 memcpy(hdr->data + payload_len - 4, &chan->val_bpsk, 4);
681
682 priv->tx(dev, hdr, sizeof(*hdr) + payload_len, 1);
683 return 0;
684
685 err:
686 printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy));
687 kfree(hdr);
688 return -EINVAL;
689}
690
691static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act)
692{
693 struct p54_common *priv = dev->priv;
694 struct p54_control_hdr *hdr;
695 struct p54_tx_control_led *led;
696
697 hdr = kzalloc(sizeof(*hdr) + sizeof(*led) +
698 priv->tx_hdr_len, GFP_KERNEL);
699 if (!hdr)
700 return -ENOMEM;
701
702 hdr = (void *)hdr + priv->tx_hdr_len;
703 hdr->magic1 = cpu_to_le16(0x8001);
704 hdr->len = cpu_to_le16(sizeof(*led));
705 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_LED);
706 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*led), NULL);
707
708 led = (struct p54_tx_control_led *) hdr->data;
709 led->mode = cpu_to_le16(mode);
710 led->led_permanent = cpu_to_le16(link);
711 led->led_temporary = cpu_to_le16(act);
712 led->duration = cpu_to_le16(1000);
713
714 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*led), 1);
715
716 return 0;
717}
718
719#define P54_SET_QUEUE(queue, ai_fs, cw_min, cw_max, burst) \
720do { \
721 queue.aifs = cpu_to_le16(ai_fs); \
722 queue.cwmin = cpu_to_le16(cw_min); \
723 queue.cwmax = cpu_to_le16(cw_max); \
724 queue.txop = (burst == 0) ? \
725 0 : cpu_to_le16((burst * 100) / 32 + 1); \
726} while(0)
727
728static void p54_init_vdcf(struct ieee80211_hw *dev)
729{
730 struct p54_common *priv = dev->priv;
731 struct p54_control_hdr *hdr;
732 struct p54_tx_control_vdcf *vdcf;
733
734 /* all USB V1 adapters need a extra headroom */
735 hdr = (void *)priv->cached_vdcf + priv->tx_hdr_len;
736 hdr->magic1 = cpu_to_le16(0x8001);
737 hdr->len = cpu_to_le16(sizeof(*vdcf));
738 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_DCFINIT);
739 hdr->req_id = cpu_to_le32(priv->rx_start);
740
741 vdcf = (struct p54_tx_control_vdcf *) hdr->data;
742
743 P54_SET_QUEUE(vdcf->queue[0], 0x0002, 0x0003, 0x0007, 0x000f);
744 P54_SET_QUEUE(vdcf->queue[1], 0x0002, 0x0007, 0x000f, 0x001e);
745 P54_SET_QUEUE(vdcf->queue[2], 0x0002, 0x000f, 0x03ff, 0x0014);
746 P54_SET_QUEUE(vdcf->queue[3], 0x0007, 0x000f, 0x03ff, 0x0000);
747}
748
749static void p54_set_vdcf(struct ieee80211_hw *dev)
750{
751 struct p54_common *priv = dev->priv;
752 struct p54_control_hdr *hdr;
753 struct p54_tx_control_vdcf *vdcf;
754
755 hdr = (void *)priv->cached_vdcf + priv->tx_hdr_len;
756
757 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*vdcf), NULL);
758
759 vdcf = (struct p54_tx_control_vdcf *) hdr->data;
760
761 if (dev->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
762 vdcf->slottime = 9;
763 vdcf->magic1 = 0x00;
764 vdcf->magic2 = 0x10;
765 } else {
766 vdcf->slottime = 20;
767 vdcf->magic1 = 0x0a;
768 vdcf->magic2 = 0x06;
769 }
770
771 /* (see prism54/isl_oid.h for further details) */
772 vdcf->frameburst = cpu_to_le16(0);
773
774 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*vdcf), 0);
775}
776
777static int p54_add_interface(struct ieee80211_hw *dev,
778 struct ieee80211_if_init_conf *conf)
779{
780 struct p54_common *priv = dev->priv;
781 int err;
782
783 /* NOTE: using IEEE80211_IF_TYPE_MGMT to indicate no mode selected */
784 if (priv->mode != IEEE80211_IF_TYPE_MGMT)
785 return -1;
786
787 switch (conf->type) {
788 case IEEE80211_IF_TYPE_STA:
789 priv->mode = conf->type;
790 break;
791 default:
792 return -EOPNOTSUPP;
793 }
794
795 priv->mac_addr = conf->mac_addr;
796
797 err = priv->open(dev);
798 if (err) {
799 priv->mode = IEEE80211_IF_TYPE_MGMT;
800 skb_queue_purge(&priv->tx_queue);
801 return err;
802 }
803
804 p54_set_filter(dev, 0, priv->mac_addr, NULL, 0, 1, 0, 0xF642);
805 p54_set_filter(dev, 0, priv->mac_addr, NULL, 1, 0, 0, 0xF642);
806 p54_set_vdcf(dev);
807
808 switch (conf->type) {
809 case IEEE80211_IF_TYPE_STA:
810 p54_set_filter(dev, 1, priv->mac_addr, NULL, 0, 0x15F, 0x1F4, 0);
811 break;
812 }
813
814 p54_set_leds(dev, 1, 0, 0);
815
816 return 0;
817}
818
819static void p54_remove_interface(struct ieee80211_hw *dev,
820 struct ieee80211_if_init_conf *conf)
821{
822 struct p54_common *priv = dev->priv;
823 struct sk_buff *skb;
824 while ((skb = skb_dequeue(&priv->tx_queue))) {
825 struct memrecord *range = (struct memrecord *)&skb->cb;
826 if (range->control)
827 kfree(range->control);
828 kfree_skb(skb);
829 }
830 priv->mode = IEEE80211_IF_TYPE_MGMT;
831 priv->stop(dev);
832}
833
834static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
835{
836 int ret;
837
838 ret = p54_set_freq(dev, cpu_to_le16(conf->freq));
839 p54_set_vdcf(dev);
840 return ret;
841}
842
843static int p54_config_interface(struct ieee80211_hw *dev, int if_id,
844 struct ieee80211_if_conf *conf)
845{
846 struct p54_common *priv = dev->priv;
847
848 p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 0, 1, 0, 0xF642);
849 p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 2, 0, 0, 0);
850 p54_set_leds(dev, 1, !is_multicast_ether_addr(conf->bssid), 0);
851 return 0;
852}
853
854static int p54_conf_tx(struct ieee80211_hw *dev, int queue,
855 const struct ieee80211_tx_queue_params *params)
856{
857 struct p54_common *priv = dev->priv;
858 struct p54_tx_control_vdcf *vdcf;
859
860 vdcf = (struct p54_tx_control_vdcf *)(((struct p54_control_hdr *)
861 ((void *)priv->cached_vdcf + priv->tx_hdr_len))->data);
862
863 if ((params) && !((queue < 0) || (queue > 4))) {
864 P54_SET_QUEUE(vdcf->queue[queue], params->aifs,
865 params->cw_min, params->cw_max, params->burst_time);
866 } else
867 return -EINVAL;
868
869 p54_set_vdcf(dev);
870
871 return 0;
872}
873
874static int p54_get_stats(struct ieee80211_hw *dev,
875 struct ieee80211_low_level_stats *stats)
876{
877 /* TODO */
878 return 0;
879}
880
881static int p54_get_tx_stats(struct ieee80211_hw *dev,
882 struct ieee80211_tx_queue_stats *stats)
883{
884 struct p54_common *priv = dev->priv;
885 unsigned int i;
886
887 for (i = 0; i < dev->queues; i++)
888 memcpy(&stats->data[i], &priv->tx_stats.data[i],
889 sizeof(stats->data[i]));
890
891 return 0;
892}
893
894static const struct ieee80211_ops p54_ops = {
895 .tx = p54_tx,
896 .add_interface = p54_add_interface,
897 .remove_interface = p54_remove_interface,
898 .config = p54_config,
899 .config_interface = p54_config_interface,
900 .conf_tx = p54_conf_tx,
901 .get_stats = p54_get_stats,
902 .get_tx_stats = p54_get_tx_stats
903};
904
905struct ieee80211_hw *p54_init_common(size_t priv_data_len)
906{
907 struct ieee80211_hw *dev;
908 struct p54_common *priv;
909 int i;
910
911 dev = ieee80211_alloc_hw(priv_data_len, &p54_ops);
912 if (!dev)
913 return NULL;
914
915 priv = dev->priv;
916 priv->mode = IEEE80211_IF_TYPE_MGMT;
917 skb_queue_head_init(&priv->tx_queue);
918 memcpy(priv->channels, p54_channels, sizeof(p54_channels));
919 memcpy(priv->rates, p54_rates, sizeof(p54_rates));
920 priv->modes[1].mode = MODE_IEEE80211B;
921 priv->modes[1].num_rates = 4;
922 priv->modes[1].rates = priv->rates;
923 priv->modes[1].num_channels = ARRAY_SIZE(p54_channels);
924 priv->modes[1].channels = priv->channels;
925 priv->modes[0].mode = MODE_IEEE80211G;
926 priv->modes[0].num_rates = ARRAY_SIZE(p54_rates);
927 priv->modes[0].rates = priv->rates;
928 priv->modes[0].num_channels = ARRAY_SIZE(p54_channels);
929 priv->modes[0].channels = priv->channels;
930 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */
931 IEEE80211_HW_RX_INCLUDES_FCS;
932 dev->channel_change_time = 1000; /* TODO: find actual value */
933 dev->max_rssi = 127;
934
935 priv->tx_stats.data[0].limit = 5;
936 dev->queues = 1;
937
938 dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 +
939 sizeof(struct p54_tx_control_allocdata);
940
941 priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf) +
942 priv->tx_hdr_len + sizeof(struct p54_control_hdr), GFP_KERNEL);
943
944 if (!priv->cached_vdcf) {
945 ieee80211_free_hw(dev);
946 return NULL;
947 }
948
949 p54_init_vdcf(dev);
950
951 for (i = 0; i < 2; i++) {
952 if (ieee80211_register_hwmode(dev, &priv->modes[i])) {
953 kfree(priv->cached_vdcf);
954 ieee80211_free_hw(dev);
955 return NULL;
956 }
957 }
958
959 return dev;
960}
961EXPORT_SYMBOL_GPL(p54_init_common);
962
963void p54_free_common(struct ieee80211_hw *dev)
964{
965 struct p54_common *priv = dev->priv;
966 kfree(priv->iq_autocal);
967 kfree(priv->output_limit);
968 kfree(priv->curve_data);
969 kfree(priv->cached_vdcf);
970}
971EXPORT_SYMBOL_GPL(p54_free_common);
972
973static int __init p54_init(void)
974{
975 return 0;
976}
977
978static void __exit p54_exit(void)
979{
980}
981
982module_init(p54_init);
983module_exit(p54_exit);
diff --git a/drivers/net/wireless/p54common.h b/drivers/net/wireless/p54common.h
new file mode 100644
index 000000000000..a721334e20d9
--- /dev/null
+++ b/drivers/net/wireless/p54common.h
@@ -0,0 +1,329 @@
1#ifndef PRISM54COMMON_H
2#define PRISM54COMMON_H
3
4/*
5 * Common code specific definitions for mac80211 Prism54 drivers
6 *
7 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
8 * Copyright (c) 2007, Christian Lamparter <chunkeey@web.de>
9 *
10 * Based on the islsm (softmac prism54) driver, which is:
11 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18struct bootrec {
19 __le32 code;
20 __le32 len;
21 u32 data[0];
22} __attribute__((packed));
23
24struct bootrec_exp_if {
25 __le16 role;
26 __le16 if_id;
27 __le16 variant;
28 __le16 btm_compat;
29 __le16 top_compat;
30} __attribute__((packed));
31
32#define BR_CODE_MIN 0x80000000
33#define BR_CODE_COMPONENT_ID 0x80000001
34#define BR_CODE_COMPONENT_VERSION 0x80000002
35#define BR_CODE_DEPENDENT_IF 0x80000003
36#define BR_CODE_EXPOSED_IF 0x80000004
37#define BR_CODE_DESCR 0x80000101
38#define BR_CODE_MAX 0x8FFFFFFF
39#define BR_CODE_END_OF_BRA 0xFF0000FF
40#define LEGACY_BR_CODE_END_OF_BRA 0xFFFFFFFF
41
42#define FW_FMAC 0x464d4143
43#define FW_LM86 0x4c4d3836
44#define FW_LM87 0x4c4d3837
45#define FW_LM20 0x4c4d3230
46
47/* PDA defines are Copyright (C) 2005 Nokia Corporation (taken from islsm_pda.h) */
48
49struct pda_entry {
50 __le16 len; /* includes both code and data */
51 __le16 code;
52 u8 data[0];
53} __attribute__ ((packed));
54
55struct eeprom_pda_wrap {
56 u32 magic;
57 u16 pad;
58 u16 len;
59 u32 arm_opcode;
60 u8 data[0];
61} __attribute__ ((packed));
62
63struct pda_iq_autocal_entry {
64 __le16 freq;
65 __le16 iq_param[4];
66} __attribute__ ((packed));
67
68struct pda_channel_output_limit {
69 __le16 freq;
70 u8 val_bpsk;
71 u8 val_qpsk;
72 u8 val_16qam;
73 u8 val_64qam;
74 u8 rate_set_mask;
75 u8 rate_set_size;
76} __attribute__ ((packed));
77
78struct pda_pa_curve_data_sample_rev0 {
79 u8 rf_power;
80 u8 pa_detector;
81 u8 pcv;
82} __attribute__ ((packed));
83
84struct pda_pa_curve_data_sample_rev1 {
85 u8 rf_power;
86 u8 pa_detector;
87 u8 data_barker;
88 u8 data_bpsk;
89 u8 data_qpsk;
90 u8 data_16qam;
91 u8 data_64qam;
92 u8 padding;
93} __attribute__ ((packed));
94
95struct pda_pa_curve_data {
96 u8 cal_method_rev;
97 u8 channels;
98 u8 points_per_channel;
99 u8 padding;
100 u8 data[0];
101} __attribute__ ((packed));
102
103/*
104 * this defines the PDR codes used to build PDAs as defined in document
105 * number 553155. The current implementation mirrors version 1.1 of the
106 * document and lists only PDRs supported by the ARM platform.
107 */
108
109/* common and choice range (0x0000 - 0x0fff) */
110#define PDR_END 0x0000
111#define PDR_MANUFACTURING_PART_NUMBER 0x0001
112#define PDR_PDA_VERSION 0x0002
113#define PDR_NIC_SERIAL_NUMBER 0x0003
114
115#define PDR_MAC_ADDRESS 0x0101
116#define PDR_REGULATORY_DOMAIN_LIST 0x0103
117#define PDR_TEMPERATURE_TYPE 0x0107
118
119#define PDR_PRISM_PCI_IDENTIFIER 0x0402
120
121/* ARM range (0x1000 - 0x1fff) */
122#define PDR_COUNTRY_INFORMATION 0x1000
123#define PDR_INTERFACE_LIST 0x1001
124#define PDR_HARDWARE_PLATFORM_COMPONENT_ID 0x1002
125#define PDR_OEM_NAME 0x1003
126#define PDR_PRODUCT_NAME 0x1004
127#define PDR_UTF8_OEM_NAME 0x1005
128#define PDR_UTF8_PRODUCT_NAME 0x1006
129#define PDR_COUNTRY_LIST 0x1007
130#define PDR_DEFAULT_COUNTRY 0x1008
131
132#define PDR_ANTENNA_GAIN 0x1100
133
134#define PDR_PRISM_INDIGO_PA_CALIBRATION_DATA 0x1901
135#define PDR_RSSI_LINEAR_APPROXIMATION 0x1902
136#define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS 0x1903
137#define PDR_PRISM_PA_CAL_CURVE_DATA 0x1904
138#define PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND 0x1905
139#define PDR_PRISM_ZIF_TX_IQ_CALIBRATION 0x1906
140#define PDR_REGULATORY_POWER_LIMITS 0x1907
141#define PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED 0x1908
142#define PDR_RADIATED_TRANSMISSION_CORRECTION 0x1909
143#define PDR_PRISM_TX_IQ_CALIBRATION 0x190a
144
145/* reserved range (0x2000 - 0x7fff) */
146
147/* customer range (0x8000 - 0xffff) */
148#define PDR_BASEBAND_REGISTERS 0x8000
149#define PDR_PER_CHANNEL_BASEBAND_REGISTERS 0x8001
150
151/* stored in skb->cb */
152struct memrecord {
153 u32 start_addr;
154 u32 end_addr;
155 struct ieee80211_tx_control *control;
156};
157
158struct p54_eeprom_lm86 {
159 __le16 offset;
160 __le16 len;
161 u8 data[0];
162} __attribute__ ((packed));
163
164struct p54_rx_hdr {
165 __le16 magic;
166 __le16 len;
167 __le16 freq;
168 u8 antenna;
169 u8 rate;
170 u8 rssi;
171 u8 quality;
172 u16 unknown2;
173 __le64 timestamp;
174 u8 data[0];
175} __attribute__ ((packed));
176
177struct p54_frame_sent_hdr {
178 u8 status;
179 u8 retries;
180 __le16 ack_rssi;
181 __le16 seq;
182 u16 rate;
183} __attribute__ ((packed));
184
185struct p54_tx_control_allocdata {
186 u8 rateset[8];
187 u16 padding;
188 u8 wep_key_present;
189 u8 wep_key_len;
190 u8 wep_key[16];
191 __le32 frame_type;
192 u32 padding2;
193 __le16 magic4;
194 u8 antenna;
195 u8 output_power;
196 __le32 magic5;
197 u8 align[0];
198} __attribute__ ((packed));
199
200struct p54_tx_control_filter {
201 __le16 filter_type;
202 u8 dst[ETH_ALEN];
203 u8 src[ETH_ALEN];
204 u8 antenna;
205 u8 debug;
206 __le32 magic3;
207 u8 rates[8]; // FIXME: what's this for?
208 __le32 rx_addr;
209 __le16 max_rx;
210 __le16 rxhw;
211 __le16 magic8;
212 __le16 magic9;
213} __attribute__ ((packed));
214
215struct p54_tx_control_channel {
216 __le16 magic1;
217 __le16 magic2;
218 u8 padding1[20];
219 struct pda_iq_autocal_entry iq_autocal;
220 u8 pa_points_per_curve;
221 u8 val_barker;
222 u8 val_bpsk;
223 u8 val_qpsk;
224 u8 val_16qam;
225 u8 val_64qam;
226 struct pda_pa_curve_data_sample_rev1 curve_data[0];
227 /* additional padding/data after curve_data */
228} __attribute__ ((packed));
229
230struct p54_tx_control_led {
231 __le16 mode;
232 __le16 led_temporary;
233 __le16 led_permanent;
234 __le16 duration;
235} __attribute__ ((packed));
236
237struct p54_tx_vdcf_queues {
238 __le16 aifs;
239 __le16 cwmin;
240 __le16 cwmax;
241 __le16 txop;
242} __attribute__ ((packed));
243
244struct p54_tx_control_vdcf {
245 u8 padding;
246 u8 slottime;
247 u8 magic1;
248 u8 magic2;
249 struct p54_tx_vdcf_queues queue[8];
250 u8 pad2[4];
251 __le16 frameburst;
252} __attribute__ ((packed));
253
254static const struct ieee80211_rate p54_rates[] = {
255 { .rate = 10,
256 .val = 0,
257 .val2 = 0x10,
258 .flags = IEEE80211_RATE_CCK_2 },
259 { .rate = 20,
260 .val = 1,
261 .val2 = 0x11,
262 .flags = IEEE80211_RATE_CCK_2 },
263 { .rate = 55,
264 .val = 2,
265 .val2 = 0x12,
266 .flags = IEEE80211_RATE_CCK_2 },
267 { .rate = 110,
268 .val = 3,
269 .val2 = 0x13,
270 .flags = IEEE80211_RATE_CCK_2 },
271 { .rate = 60,
272 .val = 4,
273 .flags = IEEE80211_RATE_OFDM },
274 { .rate = 90,
275 .val = 5,
276 .flags = IEEE80211_RATE_OFDM },
277 { .rate = 120,
278 .val = 6,
279 .flags = IEEE80211_RATE_OFDM },
280 { .rate = 180,
281 .val = 7,
282 .flags = IEEE80211_RATE_OFDM },
283 { .rate = 240,
284 .val = 8,
285 .flags = IEEE80211_RATE_OFDM },
286 { .rate = 360,
287 .val = 9,
288 .flags = IEEE80211_RATE_OFDM },
289 { .rate = 480,
290 .val = 10,
291 .flags = IEEE80211_RATE_OFDM },
292 { .rate = 540,
293 .val = 11,
294 .flags = IEEE80211_RATE_OFDM },
295};
296
297// TODO: just generate this..
298static const struct ieee80211_channel p54_channels[] = {
299 { .chan = 1,
300 .freq = 2412},
301 { .chan = 2,
302 .freq = 2417},
303 { .chan = 3,
304 .freq = 2422},
305 { .chan = 4,
306 .freq = 2427},
307 { .chan = 5,
308 .freq = 2432},
309 { .chan = 6,
310 .freq = 2437},
311 { .chan = 7,
312 .freq = 2442},
313 { .chan = 8,
314 .freq = 2447},
315 { .chan = 9,
316 .freq = 2452},
317 { .chan = 10,
318 .freq = 2457},
319 { .chan = 11,
320 .freq = 2462},
321 { .chan = 12,
322 .freq = 2467},
323 { .chan = 13,
324 .freq = 2472},
325 { .chan = 14,
326 .freq = 2484}
327};
328
329#endif /* PRISM54COMMON_H */
diff --git a/drivers/net/wireless/p54pci.c b/drivers/net/wireless/p54pci.c
new file mode 100644
index 000000000000..e9ecc663dc70
--- /dev/null
+++ b/drivers/net/wireless/p54pci.c
@@ -0,0 +1,691 @@
1
2/*
3 * Linux device driver for PCI based Prism54
4 *
5 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
6 *
7 * Based on the islsm (softmac prism54) driver, which is:
8 * Copyright 2004-2006 Jean-Baptiste Note <jean-baptiste.note@m4x.org>, et al.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/init.h>
16#include <linux/pci.h>
17#include <linux/firmware.h>
18#include <linux/etherdevice.h>
19#include <linux/delay.h>
20#include <linux/completion.h>
21#include <net/mac80211.h>
22
23#include "p54.h"
24#include "p54pci.h"
25
26MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
27MODULE_DESCRIPTION("Prism54 PCI wireless driver");
28MODULE_LICENSE("GPL");
29MODULE_ALIAS("prism54pci");
30
31static struct pci_device_id p54p_table[] __devinitdata = {
32 /* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
33 { PCI_DEVICE(0x1260, 0x3890) },
34 /* 3COM 3CRWE154G72 Wireless LAN adapter */
35 { PCI_DEVICE(0x10b7, 0x6001) },
36 /* Intersil PRISM Indigo Wireless LAN adapter */
37 { PCI_DEVICE(0x1260, 0x3877) },
38 /* Intersil PRISM Javelin/Xbow Wireless LAN adapter */
39 { PCI_DEVICE(0x1260, 0x3886) },
40};
41
42MODULE_DEVICE_TABLE(pci, p54p_table);
43
44static int p54p_upload_firmware(struct ieee80211_hw *dev)
45{
46 struct p54p_priv *priv = dev->priv;
47 const struct firmware *fw_entry = NULL;
48 __le32 reg;
49 int err;
50 u32 *data;
51 u32 remains, left, device_addr;
52
53 P54P_WRITE(int_enable, 0);
54 P54P_READ(int_enable);
55 udelay(10);
56
57 reg = P54P_READ(ctrl_stat);
58 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
59 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
60 P54P_WRITE(ctrl_stat, reg);
61 P54P_READ(ctrl_stat);
62 udelay(10);
63
64 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
65 P54P_WRITE(ctrl_stat, reg);
66 wmb();
67 udelay(10);
68
69 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
70 P54P_WRITE(ctrl_stat, reg);
71 wmb();
72
73 mdelay(50);
74
75 err = request_firmware(&fw_entry, "isl3886", &priv->pdev->dev);
76 if (err) {
77 printk(KERN_ERR "%s (prism54pci): cannot find firmware "
78 "(isl3886)\n", pci_name(priv->pdev));
79 return err;
80 }
81
82 p54_parse_firmware(dev, fw_entry);
83
84 data = (u32 *) fw_entry->data;
85 remains = fw_entry->size;
86 device_addr = ISL38XX_DEV_FIRMWARE_ADDR;
87 while (remains) {
88 u32 i = 0;
89 left = min((u32)0x1000, remains);
90 P54P_WRITE(direct_mem_base, cpu_to_le32(device_addr));
91 P54P_READ(int_enable);
92
93 device_addr += 0x1000;
94 while (i < left) {
95 P54P_WRITE(direct_mem_win[i], *data++);
96 i += sizeof(u32);
97 }
98
99 remains -= left;
100 P54P_READ(int_enable);
101 }
102
103 release_firmware(fw_entry);
104
105 reg = P54P_READ(ctrl_stat);
106 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
107 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
108 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
109 P54P_WRITE(ctrl_stat, reg);
110 P54P_READ(ctrl_stat);
111 udelay(10);
112
113 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
114 P54P_WRITE(ctrl_stat, reg);
115 wmb();
116 udelay(10);
117
118 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
119 P54P_WRITE(ctrl_stat, reg);
120 wmb();
121 udelay(10);
122
123 return 0;
124}
125
126static irqreturn_t p54p_simple_interrupt(int irq, void *dev_id)
127{
128 struct p54p_priv *priv = (struct p54p_priv *) dev_id;
129 __le32 reg;
130
131 reg = P54P_READ(int_ident);
132 P54P_WRITE(int_ack, reg);
133
134 if (reg & P54P_READ(int_enable))
135 complete(&priv->boot_comp);
136
137 return IRQ_HANDLED;
138}
139
140static int p54p_read_eeprom(struct ieee80211_hw *dev)
141{
142 struct p54p_priv *priv = dev->priv;
143 int err;
144 struct p54_control_hdr *hdr;
145 void *eeprom;
146 dma_addr_t rx_mapping, tx_mapping;
147 u16 alen;
148
149 init_completion(&priv->boot_comp);
150 err = request_irq(priv->pdev->irq, &p54p_simple_interrupt,
151 IRQF_SHARED, "prism54pci", priv);
152 if (err) {
153 printk(KERN_ERR "%s (prism54pci): failed to register IRQ handler\n",
154 pci_name(priv->pdev));
155 return err;
156 }
157
158 eeprom = kmalloc(0x2010 + EEPROM_READBACK_LEN, GFP_KERNEL);
159 if (!eeprom) {
160 printk(KERN_ERR "%s (prism54pci): no memory for eeprom!\n",
161 pci_name(priv->pdev));
162 err = -ENOMEM;
163 goto out;
164 }
165
166 memset(priv->ring_control, 0, sizeof(*priv->ring_control));
167 P54P_WRITE(ring_control_base, priv->ring_control_dma);
168 P54P_READ(ring_control_base);
169 udelay(10);
170
171 P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_INIT));
172 P54P_READ(int_enable);
173 udelay(10);
174
175 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
176
177 if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) {
178 printk(KERN_ERR "%s (prism54pci): Cannot boot firmware!\n",
179 pci_name(priv->pdev));
180 err = -EINVAL;
181 goto out;
182 }
183
184 P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_UPDATE));
185 P54P_READ(int_enable);
186
187 hdr = eeprom + 0x2010;
188 p54_fill_eeprom_readback(hdr);
189 hdr->req_id = cpu_to_le32(priv->common.rx_start);
190
191 rx_mapping = pci_map_single(priv->pdev, eeprom,
192 0x2010, PCI_DMA_FROMDEVICE);
193 tx_mapping = pci_map_single(priv->pdev, (void *)hdr,
194 EEPROM_READBACK_LEN, PCI_DMA_TODEVICE);
195
196 priv->ring_control->rx_mgmt[0].host_addr = cpu_to_le32(rx_mapping);
197 priv->ring_control->rx_mgmt[0].len = cpu_to_le16(0x2010);
198 priv->ring_control->tx_data[0].host_addr = cpu_to_le32(tx_mapping);
199 priv->ring_control->tx_data[0].device_addr = hdr->req_id;
200 priv->ring_control->tx_data[0].len = cpu_to_le16(EEPROM_READBACK_LEN);
201
202 priv->ring_control->host_idx[2] = cpu_to_le32(1);
203 priv->ring_control->host_idx[1] = cpu_to_le32(1);
204
205 wmb();
206 mdelay(100);
207 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
208
209 wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ);
210 wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ);
211
212 pci_unmap_single(priv->pdev, tx_mapping,
213 EEPROM_READBACK_LEN, PCI_DMA_TODEVICE);
214 pci_unmap_single(priv->pdev, rx_mapping,
215 0x2010, PCI_DMA_FROMDEVICE);
216
217 alen = le16_to_cpu(priv->ring_control->rx_mgmt[0].len);
218 if (le32_to_cpu(priv->ring_control->device_idx[2]) != 1 ||
219 alen < 0x10) {
220 printk(KERN_ERR "%s (prism54pci): Cannot read eeprom!\n",
221 pci_name(priv->pdev));
222 err = -EINVAL;
223 goto out;
224 }
225
226 p54_parse_eeprom(dev, (u8 *)eeprom + 0x10, alen - 0x10);
227
228 out:
229 kfree(eeprom);
230 P54P_WRITE(int_enable, 0);
231 P54P_READ(int_enable);
232 udelay(10);
233 free_irq(priv->pdev->irq, priv);
234 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
235 return err;
236}
237
238static void p54p_refill_rx_ring(struct ieee80211_hw *dev)
239{
240 struct p54p_priv *priv = dev->priv;
241 u32 limit, host_idx, idx;
242
243 host_idx = le32_to_cpu(priv->ring_control->host_idx[0]);
244 limit = host_idx;
245 limit -= le32_to_cpu(priv->ring_control->device_idx[0]);
246 limit = ARRAY_SIZE(priv->ring_control->rx_data) - limit;
247
248 idx = host_idx % ARRAY_SIZE(priv->ring_control->rx_data);
249 while (limit-- > 1) {
250 struct p54p_desc *desc = &priv->ring_control->rx_data[idx];
251
252 if (!desc->host_addr) {
253 struct sk_buff *skb;
254 dma_addr_t mapping;
255 skb = dev_alloc_skb(MAX_RX_SIZE);
256 if (!skb)
257 break;
258
259 mapping = pci_map_single(priv->pdev,
260 skb_tail_pointer(skb),
261 MAX_RX_SIZE,
262 PCI_DMA_FROMDEVICE);
263 desc->host_addr = cpu_to_le32(mapping);
264 desc->device_addr = 0; // FIXME: necessary?
265 desc->len = cpu_to_le16(MAX_RX_SIZE);
266 desc->flags = 0;
267 priv->rx_buf[idx] = skb;
268 }
269
270 idx++;
271 host_idx++;
272 idx %= ARRAY_SIZE(priv->ring_control->rx_data);
273 }
274
275 wmb();
276 priv->ring_control->host_idx[0] = cpu_to_le32(host_idx);
277}
278
279static irqreturn_t p54p_interrupt(int irq, void *dev_id)
280{
281 struct ieee80211_hw *dev = dev_id;
282 struct p54p_priv *priv = dev->priv;
283 __le32 reg;
284
285 spin_lock(&priv->lock);
286 reg = P54P_READ(int_ident);
287 if (unlikely(reg == 0xFFFFFFFF)) {
288 spin_unlock(&priv->lock);
289 return IRQ_HANDLED;
290 }
291
292 P54P_WRITE(int_ack, reg);
293
294 reg &= P54P_READ(int_enable);
295
296 if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)) {
297 struct p54p_desc *desc;
298 u32 idx, i;
299 i = priv->tx_idx;
300 i %= ARRAY_SIZE(priv->ring_control->tx_data);
301 priv->tx_idx = idx = le32_to_cpu(priv->ring_control->device_idx[1]);
302 idx %= ARRAY_SIZE(priv->ring_control->tx_data);
303
304 while (i != idx) {
305 desc = &priv->ring_control->tx_data[i];
306 if (priv->tx_buf[i]) {
307 kfree(priv->tx_buf[i]);
308 priv->tx_buf[i] = NULL;
309 }
310
311 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
312 le16_to_cpu(desc->len), PCI_DMA_TODEVICE);
313
314 desc->host_addr = 0;
315 desc->device_addr = 0;
316 desc->len = 0;
317 desc->flags = 0;
318
319 i++;
320 i %= ARRAY_SIZE(priv->ring_control->tx_data);
321 }
322
323 i = priv->rx_idx;
324 i %= ARRAY_SIZE(priv->ring_control->rx_data);
325 priv->rx_idx = idx = le32_to_cpu(priv->ring_control->device_idx[0]);
326 idx %= ARRAY_SIZE(priv->ring_control->rx_data);
327 while (i != idx) {
328 u16 len;
329 struct sk_buff *skb;
330 desc = &priv->ring_control->rx_data[i];
331 len = le16_to_cpu(desc->len);
332 skb = priv->rx_buf[i];
333
334 skb_put(skb, len);
335
336 if (p54_rx(dev, skb)) {
337 pci_unmap_single(priv->pdev,
338 le32_to_cpu(desc->host_addr),
339 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
340
341 priv->rx_buf[i] = NULL;
342 desc->host_addr = 0;
343 } else {
344 skb_trim(skb, 0);
345 desc->len = cpu_to_le16(MAX_RX_SIZE);
346 }
347
348 i++;
349 i %= ARRAY_SIZE(priv->ring_control->rx_data);
350 }
351
352 p54p_refill_rx_ring(dev);
353
354 wmb();
355 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
356 } else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT))
357 complete(&priv->boot_comp);
358
359 spin_unlock(&priv->lock);
360
361 return reg ? IRQ_HANDLED : IRQ_NONE;
362}
363
364static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data,
365 size_t len, int free_on_tx)
366{
367 struct p54p_priv *priv = dev->priv;
368 unsigned long flags;
369 struct p54p_desc *desc;
370 dma_addr_t mapping;
371 u32 device_idx, idx, i;
372
373 spin_lock_irqsave(&priv->lock, flags);
374
375 device_idx = le32_to_cpu(priv->ring_control->device_idx[1]);
376 idx = le32_to_cpu(priv->ring_control->host_idx[1]);
377 i = idx % ARRAY_SIZE(priv->ring_control->tx_data);
378
379 mapping = pci_map_single(priv->pdev, data, len, PCI_DMA_TODEVICE);
380 desc = &priv->ring_control->tx_data[i];
381 desc->host_addr = cpu_to_le32(mapping);
382 desc->device_addr = data->req_id;
383 desc->len = cpu_to_le16(len);
384 desc->flags = 0;
385
386 wmb();
387 priv->ring_control->host_idx[1] = cpu_to_le32(idx + 1);
388
389 if (free_on_tx)
390 priv->tx_buf[i] = data;
391
392 spin_unlock_irqrestore(&priv->lock, flags);
393
394 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
395 P54P_READ(dev_int);
396
397 /* FIXME: unlikely to happen because the device usually runs out of
398 memory before we fill the ring up, but we can make it impossible */
399 if (idx - device_idx > ARRAY_SIZE(priv->ring_control->tx_data) - 2)
400 printk(KERN_INFO "%s: tx overflow.\n", wiphy_name(dev->wiphy));
401}
402
403static int p54p_open(struct ieee80211_hw *dev)
404{
405 struct p54p_priv *priv = dev->priv;
406 int err;
407
408 init_completion(&priv->boot_comp);
409 err = request_irq(priv->pdev->irq, &p54p_interrupt,
410 IRQF_SHARED, "prism54pci", dev);
411 if (err) {
412 printk(KERN_ERR "%s: failed to register IRQ handler\n",
413 wiphy_name(dev->wiphy));
414 return err;
415 }
416
417 memset(priv->ring_control, 0, sizeof(*priv->ring_control));
418 priv->rx_idx = priv->tx_idx = 0;
419 p54p_refill_rx_ring(dev);
420
421 p54p_upload_firmware(dev);
422
423 P54P_WRITE(ring_control_base, priv->ring_control_dma);
424 P54P_READ(ring_control_base);
425 wmb();
426 udelay(10);
427
428 P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_INIT));
429 P54P_READ(int_enable);
430 wmb();
431 udelay(10);
432
433 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
434 P54P_READ(dev_int);
435
436 if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) {
437 printk(KERN_ERR "%s: Cannot boot firmware!\n",
438 wiphy_name(dev->wiphy));
439 free_irq(priv->pdev->irq, dev);
440 return -ETIMEDOUT;
441 }
442
443 P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_UPDATE));
444 P54P_READ(int_enable);
445 wmb();
446 udelay(10);
447
448 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
449 P54P_READ(dev_int);
450 wmb();
451 udelay(10);
452
453 return 0;
454}
455
456static void p54p_stop(struct ieee80211_hw *dev)
457{
458 struct p54p_priv *priv = dev->priv;
459 unsigned int i;
460 struct p54p_desc *desc;
461
462 P54P_WRITE(int_enable, 0);
463 P54P_READ(int_enable);
464 udelay(10);
465
466 free_irq(priv->pdev->irq, dev);
467
468 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
469
470 for (i = 0; i < ARRAY_SIZE(priv->rx_buf); i++) {
471 desc = &priv->ring_control->rx_data[i];
472 if (desc->host_addr)
473 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
474 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
475 kfree_skb(priv->rx_buf[i]);
476 priv->rx_buf[i] = NULL;
477 }
478
479 for (i = 0; i < ARRAY_SIZE(priv->tx_buf); i++) {
480 desc = &priv->ring_control->tx_data[i];
481 if (desc->host_addr)
482 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
483 le16_to_cpu(desc->len), PCI_DMA_TODEVICE);
484
485 kfree(priv->tx_buf[i]);
486 priv->tx_buf[i] = NULL;
487 }
488
489 memset(priv->ring_control, 0, sizeof(*priv->ring_control));
490}
491
492static int __devinit p54p_probe(struct pci_dev *pdev,
493 const struct pci_device_id *id)
494{
495 struct p54p_priv *priv;
496 struct ieee80211_hw *dev;
497 unsigned long mem_addr, mem_len;
498 int err;
499 DECLARE_MAC_BUF(mac);
500
501 err = pci_enable_device(pdev);
502 if (err) {
503 printk(KERN_ERR "%s (prism54pci): Cannot enable new PCI device\n",
504 pci_name(pdev));
505 return err;
506 }
507
508 mem_addr = pci_resource_start(pdev, 0);
509 mem_len = pci_resource_len(pdev, 0);
510 if (mem_len < sizeof(struct p54p_csr)) {
511 printk(KERN_ERR "%s (prism54pci): Too short PCI resources\n",
512 pci_name(pdev));
513 pci_disable_device(pdev);
514 return err;
515 }
516
517 err = pci_request_regions(pdev, "prism54pci");
518 if (err) {
519 printk(KERN_ERR "%s (prism54pci): Cannot obtain PCI resources\n",
520 pci_name(pdev));
521 return err;
522 }
523
524 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
525 pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
526 printk(KERN_ERR "%s (prism54pci): No suitable DMA available\n",
527 pci_name(pdev));
528 goto err_free_reg;
529 }
530
531 pci_set_master(pdev);
532 pci_try_set_mwi(pdev);
533
534 pci_write_config_byte(pdev, 0x40, 0);
535 pci_write_config_byte(pdev, 0x41, 0);
536
537 dev = p54_init_common(sizeof(*priv));
538 if (!dev) {
539 printk(KERN_ERR "%s (prism54pci): ieee80211 alloc failed\n",
540 pci_name(pdev));
541 err = -ENOMEM;
542 goto err_free_reg;
543 }
544
545 priv = dev->priv;
546 priv->pdev = pdev;
547
548 SET_IEEE80211_DEV(dev, &pdev->dev);
549 pci_set_drvdata(pdev, dev);
550
551 priv->map = ioremap(mem_addr, mem_len);
552 if (!priv->map) {
553 printk(KERN_ERR "%s (prism54pci): Cannot map device memory\n",
554 pci_name(pdev));
555 err = -EINVAL; // TODO: use a better error code?
556 goto err_free_dev;
557 }
558
559 priv->ring_control = pci_alloc_consistent(pdev, sizeof(*priv->ring_control),
560 &priv->ring_control_dma);
561 if (!priv->ring_control) {
562 printk(KERN_ERR "%s (prism54pci): Cannot allocate rings\n",
563 pci_name(pdev));
564 err = -ENOMEM;
565 goto err_iounmap;
566 }
567 memset(priv->ring_control, 0, sizeof(*priv->ring_control));
568
569 err = p54p_upload_firmware(dev);
570 if (err)
571 goto err_free_desc;
572
573 err = p54p_read_eeprom(dev);
574 if (err)
575 goto err_free_desc;
576
577 priv->common.open = p54p_open;
578 priv->common.stop = p54p_stop;
579 priv->common.tx = p54p_tx;
580
581 spin_lock_init(&priv->lock);
582
583 err = ieee80211_register_hw(dev);
584 if (err) {
585 printk(KERN_ERR "%s (prism54pci): Cannot register netdevice\n",
586 pci_name(pdev));
587 goto err_free_common;
588 }
589
590 printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n",
591 wiphy_name(dev->wiphy),
592 print_mac(mac, dev->wiphy->perm_addr),
593 priv->common.version);
594
595 return 0;
596
597 err_free_common:
598 p54_free_common(dev);
599
600 err_free_desc:
601 pci_free_consistent(pdev, sizeof(*priv->ring_control),
602 priv->ring_control, priv->ring_control_dma);
603
604 err_iounmap:
605 iounmap(priv->map);
606
607 err_free_dev:
608 pci_set_drvdata(pdev, NULL);
609 ieee80211_free_hw(dev);
610
611 err_free_reg:
612 pci_release_regions(pdev);
613 pci_disable_device(pdev);
614 return err;
615}
616
617static void __devexit p54p_remove(struct pci_dev *pdev)
618{
619 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
620 struct p54p_priv *priv;
621
622 if (!dev)
623 return;
624
625 ieee80211_unregister_hw(dev);
626 priv = dev->priv;
627 pci_free_consistent(pdev, sizeof(*priv->ring_control),
628 priv->ring_control, priv->ring_control_dma);
629 p54_free_common(dev);
630 iounmap(priv->map);
631 pci_release_regions(pdev);
632 pci_disable_device(pdev);
633 ieee80211_free_hw(dev);
634}
635
636#ifdef CONFIG_PM
637static int p54p_suspend(struct pci_dev *pdev, pm_message_t state)
638{
639 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
640 struct p54p_priv *priv = dev->priv;
641
642 if (priv->common.mode != IEEE80211_IF_TYPE_MGMT) {
643 ieee80211_stop_queues(dev);
644 p54p_stop(dev);
645 }
646
647 pci_save_state(pdev);
648 pci_set_power_state(pdev, pci_choose_state(pdev, state));
649 return 0;
650}
651
652static int p54p_resume(struct pci_dev *pdev)
653{
654 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
655 struct p54p_priv *priv = dev->priv;
656
657 pci_set_power_state(pdev, PCI_D0);
658 pci_restore_state(pdev);
659
660 if (priv->common.mode != IEEE80211_IF_TYPE_MGMT) {
661 p54p_open(dev);
662 ieee80211_start_queues(dev);
663 }
664
665 return 0;
666}
667#endif /* CONFIG_PM */
668
669static struct pci_driver p54p_driver = {
670 .name = "prism54pci",
671 .id_table = p54p_table,
672 .probe = p54p_probe,
673 .remove = __devexit_p(p54p_remove),
674#ifdef CONFIG_PM
675 .suspend = p54p_suspend,
676 .resume = p54p_resume,
677#endif /* CONFIG_PM */
678};
679
680static int __init p54p_init(void)
681{
682 return pci_register_driver(&p54p_driver);
683}
684
685static void __exit p54p_exit(void)
686{
687 pci_unregister_driver(&p54p_driver);
688}
689
690module_init(p54p_init);
691module_exit(p54p_exit);
diff --git a/drivers/net/wireless/p54pci.h b/drivers/net/wireless/p54pci.h
new file mode 100644
index 000000000000..52feb597dc4a
--- /dev/null
+++ b/drivers/net/wireless/p54pci.h
@@ -0,0 +1,106 @@
1#ifndef PRISM54PCI_H
2#define PRISM54PCI_H
3
4/*
5 * Defines for PCI based mac80211 Prism54 driver
6 *
7 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
8 *
9 * Based on the islsm (softmac prism54) driver, which is:
10 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17/* Device Interrupt register bits */
18#define ISL38XX_DEV_INT_RESET 0x0001
19#define ISL38XX_DEV_INT_UPDATE 0x0002
20#define ISL38XX_DEV_INT_WAKEUP 0x0008
21#define ISL38XX_DEV_INT_SLEEP 0x0010
22#define ISL38XX_DEV_INT_ABORT 0x0020
23/* these two only used in USB */
24#define ISL38XX_DEV_INT_DATA 0x0040
25#define ISL38XX_DEV_INT_MGMT 0x0080
26
27#define ISL38XX_DEV_INT_PCIUART_CTS 0x4000
28#define ISL38XX_DEV_INT_PCIUART_DR 0x8000
29
30/* Interrupt Identification/Acknowledge/Enable register bits */
31#define ISL38XX_INT_IDENT_UPDATE 0x0002
32#define ISL38XX_INT_IDENT_INIT 0x0004
33#define ISL38XX_INT_IDENT_WAKEUP 0x0008
34#define ISL38XX_INT_IDENT_SLEEP 0x0010
35#define ISL38XX_INT_IDENT_PCIUART_CTS 0x4000
36#define ISL38XX_INT_IDENT_PCIUART_DR 0x8000
37
38/* Control/Status register bits */
39#define ISL38XX_CTRL_STAT_SLEEPMODE 0x00000200
40#define ISL38XX_CTRL_STAT_CLKRUN 0x00800000
41#define ISL38XX_CTRL_STAT_RESET 0x10000000
42#define ISL38XX_CTRL_STAT_RAMBOOT 0x20000000
43#define ISL38XX_CTRL_STAT_STARTHALTED 0x40000000
44#define ISL38XX_CTRL_STAT_HOST_OVERRIDE 0x80000000
45
46struct p54p_csr {
47 __le32 dev_int;
48 u8 unused_1[12];
49 __le32 int_ident;
50 __le32 int_ack;
51 __le32 int_enable;
52 u8 unused_2[4];
53 union {
54 __le32 ring_control_base;
55 __le32 gen_purp_com[2];
56 };
57 u8 unused_3[8];
58 __le32 direct_mem_base;
59 u8 unused_4[44];
60 __le32 dma_addr;
61 __le32 dma_len;
62 __le32 dma_ctrl;
63 u8 unused_5[12];
64 __le32 ctrl_stat;
65 u8 unused_6[1924];
66 u8 cardbus_cis[0x800];
67 u8 direct_mem_win[0x1000];
68} __attribute__ ((packed));
69
70/* usb backend only needs the register defines above */
71#ifndef PRISM54USB_H
72struct p54p_desc {
73 __le32 host_addr;
74 __le32 device_addr;
75 __le16 len;
76 __le16 flags;
77} __attribute__ ((packed));
78
79struct p54p_ring_control {
80 __le32 host_idx[4];
81 __le32 device_idx[4];
82 struct p54p_desc rx_data[8];
83 struct p54p_desc tx_data[32];
84 struct p54p_desc rx_mgmt[4];
85 struct p54p_desc tx_mgmt[4];
86} __attribute__ ((packed));
87
88#define P54P_READ(r) __raw_readl(&priv->map->r)
89#define P54P_WRITE(r, val) __raw_writel((__force u32)(val), &priv->map->r)
90
91struct p54p_priv {
92 struct p54_common common;
93 struct pci_dev *pdev;
94 struct p54p_csr __iomem *map;
95
96 spinlock_t lock;
97 struct p54p_ring_control *ring_control;
98 dma_addr_t ring_control_dma;
99 u32 rx_idx, tx_idx;
100 struct sk_buff *rx_buf[8];
101 void *tx_buf[32];
102 struct completion boot_comp;
103};
104
105#endif /* PRISM54USB_H */
106#endif /* PRISM54PCI_H */
diff --git a/drivers/net/wireless/p54usb.c b/drivers/net/wireless/p54usb.c
new file mode 100644
index 000000000000..7446c39ce5d0
--- /dev/null
+++ b/drivers/net/wireless/p54usb.c
@@ -0,0 +1,906 @@
1
2/*
3 * Linux device driver for USB based Prism54
4 *
5 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
6 *
7 * Based on the islsm (softmac prism54) driver, which is:
8 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/init.h>
16#include <linux/usb.h>
17#include <linux/pci.h>
18#include <linux/firmware.h>
19#include <linux/etherdevice.h>
20#include <linux/delay.h>
21#include <linux/crc32.h>
22#include <net/mac80211.h>
23
24#include "p54.h"
25#include "p54usb.h"
26
27MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
28MODULE_DESCRIPTION("Prism54 USB wireless driver");
29MODULE_LICENSE("GPL");
30MODULE_ALIAS("prism54usb");
31
32static struct usb_device_id p54u_table[] __devinitdata = {
33 /* Version 1 devices (pci chip + net2280) */
34 {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
35 {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
36 {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */
37 {USB_DEVICE(0x083a, 0x4502)}, /* Siemens Gigaset USB Adapter */
38 {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */
39 {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
40 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
41 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
42 {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
43 {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
44 {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */
45 {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */
46 {USB_DEVICE(0x2001, 0x3703)}, /* DLink DWL-G122 */
47 {USB_DEVICE(0x5041, 0x2234)}, /* Linksys WUSB54G */
48 {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */
49
50 /* Version 2 devices (3887) */
51 {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */
52 {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */
53 {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */
54 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
55 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
56 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
57 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */
58 {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */
59 {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/
60 {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/
61 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */
62 {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
63 {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
64 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
65 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
66 {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
67 {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
68 {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */
69 {}
70};
71
72MODULE_DEVICE_TABLE(usb, p54u_table);
73
74static void p54u_rx_cb(struct urb *urb)
75{
76 struct sk_buff *skb = (struct sk_buff *) urb->context;
77 struct p54u_rx_info *info = (struct p54u_rx_info *)skb->cb;
78 struct ieee80211_hw *dev = info->dev;
79 struct p54u_priv *priv = dev->priv;
80
81 if (unlikely(urb->status)) {
82 info->urb = NULL;
83 usb_free_urb(urb);
84 return;
85 }
86
87 skb_unlink(skb, &priv->rx_queue);
88 skb_put(skb, urb->actual_length);
89 if (!priv->hw_type)
90 skb_pull(skb, sizeof(struct net2280_tx_hdr));
91
92 if (p54_rx(dev, skb)) {
93 skb = dev_alloc_skb(MAX_RX_SIZE);
94 if (unlikely(!skb)) {
95 usb_free_urb(urb);
96 /* TODO check rx queue length and refill *somewhere* */
97 return;
98 }
99
100 info = (struct p54u_rx_info *) skb->cb;
101 info->urb = urb;
102 info->dev = dev;
103 urb->transfer_buffer = skb_tail_pointer(skb);
104 urb->context = skb;
105 skb_queue_tail(&priv->rx_queue, skb);
106 } else {
107 skb_trim(skb, 0);
108 skb_queue_tail(&priv->rx_queue, skb);
109 }
110
111 usb_submit_urb(urb, GFP_ATOMIC);
112}
113
114static void p54u_tx_cb(struct urb *urb)
115{
116 usb_free_urb(urb);
117}
118
119static void p54u_tx_free_cb(struct urb *urb)
120{
121 kfree(urb->transfer_buffer);
122 usb_free_urb(urb);
123}
124
125static int p54u_init_urbs(struct ieee80211_hw *dev)
126{
127 struct p54u_priv *priv = dev->priv;
128 struct urb *entry;
129 struct sk_buff *skb;
130 struct p54u_rx_info *info;
131
132 while (skb_queue_len(&priv->rx_queue) < 32) {
133 skb = __dev_alloc_skb(MAX_RX_SIZE, GFP_KERNEL);
134 if (!skb)
135 break;
136 entry = usb_alloc_urb(0, GFP_KERNEL);
137 if (!entry) {
138 kfree_skb(skb);
139 break;
140 }
141 usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), skb_tail_pointer(skb), MAX_RX_SIZE, p54u_rx_cb, skb);
142 info = (struct p54u_rx_info *) skb->cb;
143 info->urb = entry;
144 info->dev = dev;
145 skb_queue_tail(&priv->rx_queue, skb);
146 usb_submit_urb(entry, GFP_KERNEL);
147 }
148
149 return 0;
150}
151
152static void p54u_free_urbs(struct ieee80211_hw *dev)
153{
154 struct p54u_priv *priv = dev->priv;
155 struct p54u_rx_info *info;
156 struct sk_buff *skb;
157
158 while ((skb = skb_dequeue(&priv->rx_queue))) {
159 info = (struct p54u_rx_info *) skb->cb;
160 if (!info->urb)
161 continue;
162
163 usb_kill_urb(info->urb);
164 kfree_skb(skb);
165 }
166}
167
168static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data,
169 size_t len, int free_on_tx)
170{
171 struct p54u_priv *priv = dev->priv;
172 struct urb *addr_urb, *data_urb;
173
174 addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
175 if (!addr_urb)
176 return;
177
178 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
179 if (!data_urb) {
180 usb_free_urb(addr_urb);
181 return;
182 }
183
184 usb_fill_bulk_urb(addr_urb, priv->udev,
185 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), &data->req_id,
186 sizeof(data->req_id), p54u_tx_cb, dev);
187 usb_fill_bulk_urb(data_urb, priv->udev,
188 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), data, len,
189 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
190
191 usb_submit_urb(addr_urb, GFP_ATOMIC);
192 usb_submit_urb(data_urb, GFP_ATOMIC);
193}
194
195static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data,
196 size_t len, int free_on_tx)
197{
198 struct p54u_priv *priv = dev->priv;
199 struct urb *int_urb, *data_urb;
200 struct net2280_tx_hdr *hdr;
201 struct net2280_reg_write *reg;
202
203 reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
204 if (!reg)
205 return;
206
207 int_urb = usb_alloc_urb(0, GFP_ATOMIC);
208 if (!int_urb) {
209 kfree(reg);
210 return;
211 }
212
213 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
214 if (!data_urb) {
215 kfree(reg);
216 usb_free_urb(int_urb);
217 return;
218 }
219
220 reg->port = cpu_to_le16(NET2280_DEV_U32);
221 reg->addr = cpu_to_le32(P54U_DEV_BASE);
222 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
223
224 len += sizeof(*data);
225 hdr = (void *)data - sizeof(*hdr);
226 memset(hdr, 0, sizeof(*hdr));
227 hdr->device_addr = data->req_id;
228 hdr->len = cpu_to_le16(len);
229
230 usb_fill_bulk_urb(int_urb, priv->udev,
231 usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
232 p54u_tx_free_cb, dev);
233 usb_submit_urb(int_urb, GFP_ATOMIC);
234
235 usb_fill_bulk_urb(data_urb, priv->udev,
236 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, len + sizeof(*hdr),
237 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
238 usb_submit_urb(data_urb, GFP_ATOMIC);
239}
240
241static int p54u_write(struct p54u_priv *priv,
242 struct net2280_reg_write *buf,
243 enum net2280_op_type type,
244 __le32 addr, __le32 val)
245{
246 unsigned int ep;
247 int alen;
248
249 if (type & 0x0800)
250 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);
251 else
252 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);
253
254 buf->port = cpu_to_le16(type);
255 buf->addr = addr;
256 buf->val = val;
257
258 return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);
259}
260
261static int p54u_read(struct p54u_priv *priv, void *buf,
262 enum net2280_op_type type,
263 __le32 addr, __le32 *val)
264{
265 struct net2280_reg_read *read = buf;
266 __le32 *reg = buf;
267 unsigned int ep;
268 int alen, err;
269
270 if (type & 0x0800)
271 ep = P54U_PIPE_DEV;
272 else
273 ep = P54U_PIPE_BRG;
274
275 read->port = cpu_to_le16(type);
276 read->addr = addr;
277
278 err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
279 read, sizeof(*read), &alen, 1000);
280 if (err)
281 return err;
282
283 err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),
284 reg, sizeof(*reg), &alen, 1000);
285 if (err)
286 return err;
287
288 *val = *reg;
289 return 0;
290}
291
292static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
293 void *data, size_t len)
294{
295 int alen;
296 return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
297 data, len, &alen, 2000);
298}
299
300static int p54u_read_eeprom(struct ieee80211_hw *dev)
301{
302 struct p54u_priv *priv = dev->priv;
303 void *buf;
304 struct p54_control_hdr *hdr;
305 int err, alen;
306 size_t offset = priv->hw_type ? 0x10 : 0x20;
307
308 buf = kmalloc(0x2020, GFP_KERNEL);
309 if (!buf) {
310 printk(KERN_ERR "prism54usb: cannot allocate memory for"
311 "eeprom readback!\n");
312 return -ENOMEM;
313 }
314
315 if (priv->hw_type) {
316 *((u32 *) buf) = priv->common.rx_start;
317 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
318 if (err) {
319 printk(KERN_ERR "prism54usb: addr send failed\n");
320 goto fail;
321 }
322 } else {
323 struct net2280_reg_write *reg = buf;
324 reg->port = cpu_to_le16(NET2280_DEV_U32);
325 reg->addr = cpu_to_le32(P54U_DEV_BASE);
326 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
327 err = p54u_bulk_msg(priv, P54U_PIPE_DEV, buf, sizeof(*reg));
328 if (err) {
329 printk(KERN_ERR "prism54usb: dev_int send failed\n");
330 goto fail;
331 }
332 }
333
334 hdr = buf + priv->common.tx_hdr_len;
335 p54_fill_eeprom_readback(hdr);
336 hdr->req_id = cpu_to_le32(priv->common.rx_start);
337 if (priv->common.tx_hdr_len) {
338 struct net2280_tx_hdr *tx_hdr = buf;
339 tx_hdr->device_addr = hdr->req_id;
340 tx_hdr->len = cpu_to_le16(EEPROM_READBACK_LEN);
341 }
342
343 /* we can just pretend to send 0x2000 bytes of nothing in the headers */
344 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf,
345 EEPROM_READBACK_LEN + priv->common.tx_hdr_len);
346 if (err) {
347 printk(KERN_ERR "prism54usb: eeprom req send failed\n");
348 goto fail;
349 }
350
351 err = usb_bulk_msg(priv->udev,
352 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
353 buf, 0x2020, &alen, 1000);
354 if (!err && alen > offset) {
355 p54_parse_eeprom(dev, (u8 *)buf + offset, alen - offset);
356 } else {
357 printk(KERN_ERR "prism54usb: eeprom read failed!\n");
358 err = -EINVAL;
359 goto fail;
360 }
361
362 fail:
363 kfree(buf);
364 return err;
365}
366
367static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
368{
369 static char start_string[] = "~~~~<\r";
370 struct p54u_priv *priv = dev->priv;
371 const struct firmware *fw_entry = NULL;
372 int err, alen;
373 u8 carry = 0;
374 u8 *buf, *tmp, *data;
375 unsigned int left, remains, block_size;
376 struct x2_header *hdr;
377 unsigned long timeout;
378
379 tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
380 if (!buf) {
381 printk(KERN_ERR "p54usb: cannot allocate firmware upload buffer!\n");
382 err = -ENOMEM;
383 goto err_bufalloc;
384 }
385
386 memcpy(buf, start_string, 4);
387 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4);
388 if (err) {
389 printk(KERN_ERR "p54usb: reset failed! (%d)\n", err);
390 goto err_reset;
391 }
392
393 err = request_firmware(&fw_entry, "isl3887usb_bare", &priv->udev->dev);
394 if (err) {
395 printk(KERN_ERR "p54usb: cannot find firmware (isl3887usb_bare)!\n");
396 goto err_req_fw_failed;
397 }
398
399 p54_parse_firmware(dev, fw_entry);
400
401 left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
402 strcpy(buf, start_string);
403 left -= strlen(start_string);
404 tmp += strlen(start_string);
405
406 data = fw_entry->data;
407 remains = fw_entry->size;
408
409 hdr = (struct x2_header *)(buf + strlen(start_string));
410 memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
411 hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
412 hdr->fw_length = cpu_to_le32(fw_entry->size);
413 hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
414 sizeof(u32)*2));
415 left -= sizeof(*hdr);
416 tmp += sizeof(*hdr);
417
418 while (remains) {
419 while (left--) {
420 if (carry) {
421 *tmp++ = carry;
422 carry = 0;
423 remains--;
424 continue;
425 }
426 switch (*data) {
427 case '~':
428 *tmp++ = '}';
429 carry = '^';
430 break;
431 case '}':
432 *tmp++ = '}';
433 carry = ']';
434 break;
435 default:
436 *tmp++ = *data;
437 remains--;
438 break;
439 }
440 data++;
441 }
442
443 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size);
444 if (err) {
445 printk(KERN_ERR "prism54usb: firmware upload failed!\n");
446 goto err_upload_failed;
447 }
448
449 tmp = buf;
450 left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
451 }
452
453 *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size));
454 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
455 if (err) {
456 printk(KERN_ERR "prism54usb: firmware upload failed!\n");
457 goto err_upload_failed;
458 }
459
460 timeout = jiffies + msecs_to_jiffies(1000);
461 while (!(err = usb_bulk_msg(priv->udev,
462 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
463 if (alen > 2 && !memcmp(buf, "OK", 2))
464 break;
465
466 if (alen > 5 && !memcmp(buf, "ERROR", 5)) {
467 printk(KERN_INFO "prism54usb: firmware upload failed!\n");
468 err = -EINVAL;
469 break;
470 }
471
472 if (time_after(jiffies, timeout)) {
473 printk(KERN_ERR "prism54usb: firmware boot timed out!\n");
474 err = -ETIMEDOUT;
475 break;
476 }
477 }
478 if (err)
479 goto err_upload_failed;
480
481 buf[0] = 'g';
482 buf[1] = '\r';
483 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2);
484 if (err) {
485 printk(KERN_ERR "prism54usb: firmware boot failed!\n");
486 goto err_upload_failed;
487 }
488
489 timeout = jiffies + msecs_to_jiffies(1000);
490 while (!(err = usb_bulk_msg(priv->udev,
491 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
492 if (alen > 0 && buf[0] == 'g')
493 break;
494
495 if (time_after(jiffies, timeout)) {
496 err = -ETIMEDOUT;
497 break;
498 }
499 }
500 if (err)
501 goto err_upload_failed;
502
503 err_upload_failed:
504 release_firmware(fw_entry);
505 err_req_fw_failed:
506 err_reset:
507 kfree(buf);
508 err_bufalloc:
509 return err;
510}
511
512static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
513{
514 struct p54u_priv *priv = dev->priv;
515 const struct firmware *fw_entry = NULL;
516 const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
517 int err, alen;
518 void *buf;
519 __le32 reg;
520 unsigned int remains, offset;
521 u8 *data;
522
523 buf = kmalloc(512, GFP_KERNEL);
524 if (!buf) {
525 printk(KERN_ERR "p54usb: firmware buffer alloc failed!\n");
526 return -ENOMEM;
527 }
528
529 err = request_firmware(&fw_entry, "isl3890usb", &priv->udev->dev);
530 if (err) {
531 printk(KERN_ERR "p54usb: cannot find firmware (isl3890usb)!\n");
532 kfree(buf);
533 return err;
534 }
535
536 p54_parse_firmware(dev, fw_entry);
537
538#define P54U_WRITE(type, addr, data) \
539 do {\
540 err = p54u_write(priv, buf, type,\
541 cpu_to_le32((u32)(unsigned long)addr), data);\
542 if (err) \
543 goto fail;\
544 } while (0)
545
546#define P54U_READ(type, addr) \
547 do {\
548 err = p54u_read(priv, buf, type,\
549 cpu_to_le32((u32)(unsigned long)addr), &reg);\
550 if (err)\
551 goto fail;\
552 } while (0)
553
554 /* power down net2280 bridge */
555 P54U_READ(NET2280_BRG_U32, NET2280_GPIOCTL);
556 reg |= cpu_to_le32(P54U_BRG_POWER_DOWN);
557 reg &= cpu_to_le32(~P54U_BRG_POWER_UP);
558 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
559
560 mdelay(100);
561
562 /* power up bridge */
563 reg |= cpu_to_le32(P54U_BRG_POWER_UP);
564 reg &= cpu_to_le32(~P54U_BRG_POWER_DOWN);
565 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
566
567 mdelay(100);
568
569 P54U_WRITE(NET2280_BRG_U32, NET2280_DEVINIT,
570 cpu_to_le32(NET2280_CLK_30Mhz |
571 NET2280_PCI_ENABLE |
572 NET2280_PCI_SOFT_RESET));
573
574 mdelay(20);
575
576 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_COMMAND,
577 cpu_to_le32(PCI_COMMAND_MEMORY |
578 PCI_COMMAND_MASTER));
579
580 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_0,
581 cpu_to_le32(NET2280_BASE));
582
583 P54U_READ(NET2280_BRG_CFG_U16, PCI_STATUS);
584 reg |= cpu_to_le32(PCI_STATUS_REC_MASTER_ABORT);
585 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_STATUS, reg);
586
587 // TODO: we really need this?
588 P54U_READ(NET2280_BRG_U32, NET2280_RELNUM);
589
590 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_RSP,
591 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
592 P54U_WRITE(NET2280_BRG_U32, NET2280_EPC_RSP,
593 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
594
595 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_2,
596 cpu_to_le32(NET2280_BASE2));
597
598 /* finally done setting up the bridge */
599
600 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | PCI_COMMAND,
601 cpu_to_le32(PCI_COMMAND_MEMORY |
602 PCI_COMMAND_MASTER));
603
604 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | 0x40 /* TRDY timeout */, 0);
605 P54U_WRITE(NET2280_DEV_CFG_U32, 0x10000 | PCI_BASE_ADDRESS_0,
606 cpu_to_le32(P54U_DEV_BASE));
607
608 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
609 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
610 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
611
612 /* do romboot */
613 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable, 0);
614
615 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
616 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
617 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
618 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
619 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
620
621 mdelay(20);
622
623 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
624 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
625
626 mdelay(20);
627
628 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
629 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
630
631 mdelay(100);
632
633 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
634 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
635
636 /* finally, we can upload firmware now! */
637 remains = fw_entry->size;
638 data = fw_entry->data;
639 offset = ISL38XX_DEV_FIRMWARE_ADDR;
640
641 while (remains) {
642 unsigned int block_len = min(remains, (unsigned int)512);
643 memcpy(buf, data, block_len);
644
645 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len);
646 if (err) {
647 printk(KERN_ERR "prism54usb: firmware block upload "
648 "failed\n");
649 goto fail;
650 }
651
652 P54U_WRITE(NET2280_DEV_U32, &devreg->direct_mem_base,
653 cpu_to_le32(0xc0000f00));
654
655 P54U_WRITE(NET2280_DEV_U32,
656 0x0020 | (unsigned long)&devreg->direct_mem_win, 0);
657 P54U_WRITE(NET2280_DEV_U32,
658 0x0020 | (unsigned long)&devreg->direct_mem_win,
659 cpu_to_le32(1));
660
661 P54U_WRITE(NET2280_DEV_U32,
662 0x0024 | (unsigned long)&devreg->direct_mem_win,
663 cpu_to_le32(block_len));
664 P54U_WRITE(NET2280_DEV_U32,
665 0x0028 | (unsigned long)&devreg->direct_mem_win,
666 cpu_to_le32(offset));
667
668 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_addr,
669 cpu_to_le32(NET2280_EPA_FIFO_PCI_ADDR));
670 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_len,
671 cpu_to_le32(block_len >> 2));
672 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_ctrl,
673 cpu_to_le32(ISL38XX_DMA_MASTER_CONTROL_TRIGGER));
674
675 mdelay(10);
676
677 P54U_READ(NET2280_DEV_U32,
678 0x002C | (unsigned long)&devreg->direct_mem_win);
679 if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) ||
680 !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) {
681 printk(KERN_ERR "prism54usb: firmware DMA transfer "
682 "failed\n");
683 goto fail;
684 }
685
686 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_STAT,
687 cpu_to_le32(NET2280_FIFO_FLUSH));
688
689 remains -= block_len;
690 data += block_len;
691 offset += block_len;
692 }
693
694 /* do ramboot */
695 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
696 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
697 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
698 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
699 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
700
701 mdelay(20);
702
703 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
704 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
705
706 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
707 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
708
709 mdelay(100);
710
711 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
712 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
713
714 /* start up the firmware */
715 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable,
716 cpu_to_le32(ISL38XX_INT_IDENT_INIT));
717
718 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
719 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
720
721 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1,
722 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT_ENABLE |
723 NET2280_USB_INTERRUPT_ENABLE));
724
725 P54U_WRITE(NET2280_DEV_U32, &devreg->dev_int,
726 cpu_to_le32(ISL38XX_DEV_INT_RESET));
727
728 err = usb_interrupt_msg(priv->udev,
729 usb_rcvbulkpipe(priv->udev, P54U_PIPE_INT),
730 buf, sizeof(__le32), &alen, 1000);
731 if (err || alen != sizeof(__le32))
732 goto fail;
733
734 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
735 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
736
737 if (!(reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)))
738 err = -EINVAL;
739
740 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
741 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
742 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
743
744#undef P54U_WRITE
745#undef P54U_READ
746
747 fail:
748 release_firmware(fw_entry);
749 kfree(buf);
750 return err;
751}
752
753static int p54u_open(struct ieee80211_hw *dev)
754{
755 struct p54u_priv *priv = dev->priv;
756 int err;
757
758 err = p54u_init_urbs(dev);
759 if (err) {
760 return err;
761 }
762
763 priv->common.open = p54u_init_urbs;
764
765 return 0;
766}
767
768static void p54u_stop(struct ieee80211_hw *dev)
769{
770 /* TODO: figure out how to reliably stop the 3887 and net2280 so
771 the hardware is still usable next time we want to start it.
772 until then, we just stop listening to the hardware.. */
773 p54u_free_urbs(dev);
774 return;
775}
776
777static int __devinit p54u_probe(struct usb_interface *intf,
778 const struct usb_device_id *id)
779{
780 struct usb_device *udev = interface_to_usbdev(intf);
781 struct ieee80211_hw *dev;
782 struct p54u_priv *priv;
783 int err;
784 unsigned int i, recognized_pipes;
785 DECLARE_MAC_BUF(mac);
786
787 dev = p54_init_common(sizeof(*priv));
788 if (!dev) {
789 printk(KERN_ERR "prism54usb: ieee80211 alloc failed\n");
790 return -ENOMEM;
791 }
792
793 priv = dev->priv;
794
795 SET_IEEE80211_DEV(dev, &intf->dev);
796 usb_set_intfdata(intf, dev);
797 priv->udev = udev;
798
799 usb_get_dev(udev);
800
801 /* really lazy and simple way of figuring out if we're a 3887 */
802 /* TODO: should just stick the identification in the device table */
803 i = intf->altsetting->desc.bNumEndpoints;
804 recognized_pipes = 0;
805 while (i--) {
806 switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {
807 case P54U_PIPE_DATA:
808 case P54U_PIPE_MGMT:
809 case P54U_PIPE_BRG:
810 case P54U_PIPE_DEV:
811 case P54U_PIPE_DATA | USB_DIR_IN:
812 case P54U_PIPE_MGMT | USB_DIR_IN:
813 case P54U_PIPE_BRG | USB_DIR_IN:
814 case P54U_PIPE_DEV | USB_DIR_IN:
815 case P54U_PIPE_INT | USB_DIR_IN:
816 recognized_pipes++;
817 }
818 }
819 priv->common.open = p54u_open;
820
821 if (recognized_pipes < P54U_PIPE_NUMBER) {
822 priv->hw_type = P54U_3887;
823 priv->common.tx = p54u_tx_3887;
824 } else {
825 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
826 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
827 priv->common.tx = p54u_tx_net2280;
828 }
829 priv->common.stop = p54u_stop;
830
831 if (priv->hw_type)
832 err = p54u_upload_firmware_3887(dev);
833 else
834 err = p54u_upload_firmware_net2280(dev);
835 if (err)
836 goto err_free_dev;
837
838 err = p54u_read_eeprom(dev);
839 if (err)
840 goto err_free_dev;
841
842 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
843 u8 perm_addr[ETH_ALEN];
844
845 printk(KERN_WARNING "prism54usb: Invalid hwaddr! Using randomly generated MAC addr\n");
846 random_ether_addr(perm_addr);
847 SET_IEEE80211_PERM_ADDR(dev, perm_addr);
848 }
849
850 skb_queue_head_init(&priv->rx_queue);
851
852 err = ieee80211_register_hw(dev);
853 if (err) {
854 printk(KERN_ERR "prism54usb: Cannot register netdevice\n");
855 goto err_free_dev;
856 }
857
858 printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n",
859 wiphy_name(dev->wiphy),
860 print_mac(mac, dev->wiphy->perm_addr),
861 priv->common.version);
862
863 return 0;
864
865 err_free_dev:
866 ieee80211_free_hw(dev);
867 usb_set_intfdata(intf, NULL);
868 usb_put_dev(udev);
869 return err;
870}
871
872static void __devexit p54u_disconnect(struct usb_interface *intf)
873{
874 struct ieee80211_hw *dev = usb_get_intfdata(intf);
875 struct p54u_priv *priv;
876
877 if (!dev)
878 return;
879
880 ieee80211_unregister_hw(dev);
881
882 priv = dev->priv;
883 usb_put_dev(interface_to_usbdev(intf));
884 p54_free_common(dev);
885 ieee80211_free_hw(dev);
886}
887
888static struct usb_driver p54u_driver = {
889 .name = "prism54usb",
890 .id_table = p54u_table,
891 .probe = p54u_probe,
892 .disconnect = p54u_disconnect,
893};
894
895static int __init p54u_init(void)
896{
897 return usb_register(&p54u_driver);
898}
899
900static void __exit p54u_exit(void)
901{
902 usb_deregister(&p54u_driver);
903}
904
905module_init(p54u_init);
906module_exit(p54u_exit);
diff --git a/drivers/net/wireless/p54usb.h b/drivers/net/wireless/p54usb.h
new file mode 100644
index 000000000000..d1896b396c1c
--- /dev/null
+++ b/drivers/net/wireless/p54usb.h
@@ -0,0 +1,133 @@
1#ifndef PRISM54USB_H
2#define PRISM54USB_H
3
4/*
5 * Defines for USB based mac80211 Prism54 driver
6 *
7 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
8 *
9 * Based on the islsm (softmac prism54) driver, which is:
10 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17/* for isl3886 register definitions used on ver 1 devices */
18#include "p54pci.h"
19#include "net2280.h"
20
21/* pci */
22#define NET2280_BASE 0x10000000
23#define NET2280_BASE2 0x20000000
24
25/* gpio */
26#define P54U_BRG_POWER_UP (1 << GPIO0_DATA)
27#define P54U_BRG_POWER_DOWN (1 << GPIO1_DATA)
28
29/* devinit */
30#define NET2280_CLK_4Mhz (15 << LOCAL_CLOCK_FREQUENCY)
31#define NET2280_CLK_30Mhz (2 << LOCAL_CLOCK_FREQUENCY)
32#define NET2280_CLK_60Mhz (1 << LOCAL_CLOCK_FREQUENCY)
33#define NET2280_CLK_STOP (0 << LOCAL_CLOCK_FREQUENCY)
34#define NET2280_PCI_ENABLE (1 << PCI_ENABLE)
35#define NET2280_PCI_SOFT_RESET (1 << PCI_SOFT_RESET)
36
37/* endpoints */
38#define NET2280_CLEAR_NAK_OUT_PACKETS_MODE (1 << CLEAR_NAK_OUT_PACKETS_MODE)
39#define NET2280_FIFO_FLUSH (1 << FIFO_FLUSH)
40
41/* irq */
42#define NET2280_USB_INTERRUPT_ENABLE (1 << USB_INTERRUPT_ENABLE)
43#define NET2280_PCI_INTA_INTERRUPT (1 << PCI_INTA_INTERRUPT)
44#define NET2280_PCI_INTA_INTERRUPT_ENABLE (1 << PCI_INTA_INTERRUPT_ENABLE)
45
46/* registers */
47#define NET2280_DEVINIT 0x00
48#define NET2280_USBIRQENB1 0x24
49#define NET2280_IRQSTAT1 0x2c
50#define NET2280_FIFOCTL 0x38
51#define NET2280_GPIOCTL 0x50
52#define NET2280_RELNUM 0x88
53#define NET2280_EPA_RSP 0x324
54#define NET2280_EPA_STAT 0x32c
55#define NET2280_EPB_STAT 0x34c
56#define NET2280_EPC_RSP 0x364
57#define NET2280_EPC_STAT 0x36c
58#define NET2280_EPD_STAT 0x38c
59
60#define NET2280_EPA_CFG 0x320
61#define NET2280_EPB_CFG 0x340
62#define NET2280_EPC_CFG 0x360
63#define NET2280_EPD_CFG 0x380
64#define NET2280_EPE_CFG 0x3A0
65#define NET2280_EPF_CFG 0x3C0
66#define P54U_DEV_BASE 0x40000000
67
68struct net2280_tx_hdr {
69 __le32 device_addr;
70 __le16 len;
71 __le16 follower; /* ? */
72 u8 padding[8];
73} __attribute__((packed));
74
75/* Some flags for the isl hardware registers controlling DMA inside the
76 * chip */
77#define ISL38XX_DMA_STATUS_DONE 0x00000001
78#define ISL38XX_DMA_STATUS_READY 0x00000002
79#define NET2280_EPA_FIFO_PCI_ADDR 0x20000000
80#define ISL38XX_DMA_MASTER_CONTROL_TRIGGER 0x00000004
81
82enum net2280_op_type {
83 NET2280_BRG_U32 = 0x001F,
84 NET2280_BRG_CFG_U32 = 0x000F,
85 NET2280_BRG_CFG_U16 = 0x0003,
86 NET2280_DEV_U32 = 0x080F,
87 NET2280_DEV_CFG_U32 = 0x088F,
88 NET2280_DEV_CFG_U16 = 0x0883
89};
90
91#define P54U_FW_BLOCK 2048
92
93#define X2_SIGNATURE "x2 "
94#define X2_SIGNATURE_SIZE 4
95
96struct x2_header {
97 u8 signature[X2_SIGNATURE_SIZE];
98 __le32 fw_load_addr;
99 __le32 fw_length;
100 __le32 crc;
101} __attribute__((packed));
102
103/* pipes 3 and 4 are not used by the driver */
104#define P54U_PIPE_NUMBER 9
105
106enum p54u_pipe_addr {
107 P54U_PIPE_DATA = 0x01,
108 P54U_PIPE_MGMT = 0x02,
109 P54U_PIPE_3 = 0x03,
110 P54U_PIPE_4 = 0x04,
111 P54U_PIPE_BRG = 0x0d,
112 P54U_PIPE_DEV = 0x0e,
113 P54U_PIPE_INT = 0x0f
114};
115
116struct p54u_rx_info {
117 struct urb *urb;
118 struct ieee80211_hw *dev;
119};
120
121struct p54u_priv {
122 struct p54_common common;
123 struct usb_device *udev;
124 enum {
125 P54U_NET2280 = 0,
126 P54U_3887
127 } hw_type;
128
129 spinlock_t lock;
130 struct sk_buff_head rx_queue;
131};
132
133#endif /* PRISM54USB_H */