aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@web.de>2008-04-08 15:38:00 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-08 16:44:45 -0400
commitfb26971058845868f7c45b720636180d14c058e4 (patch)
treedd1463cfdad7b837b592a888847edb4200034ebd /drivers/net/wireless/p54
parent2c8dccc77420fb7433da5674818959d3499d35be (diff)
p54: move to separate directory
Signed-off-by: Christian Lamparter <chunkeey@web.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/p54')
-rw-r--r--drivers/net/wireless/p54/Kconfig63
-rw-r--r--drivers/net/wireless/p54/Makefile3
-rw-r--r--drivers/net/wireless/p54/net2280.h452
-rw-r--r--drivers/net/wireless/p54/p54.h77
-rw-r--r--drivers/net/wireless/p54/p54common.c1051
-rw-r--r--drivers/net/wireless/p54/p54common.h254
-rw-r--r--drivers/net/wireless/p54/p54pci.c697
-rw-r--r--drivers/net/wireless/p54/p54pci.h106
-rw-r--r--drivers/net/wireless/p54/p54usb.c910
-rw-r--r--drivers/net/wireless/p54/p54usb.h133
10 files changed, 3746 insertions, 0 deletions
diff --git a/drivers/net/wireless/p54/Kconfig b/drivers/net/wireless/p54/Kconfig
new file mode 100644
index 000000000000..d3469d08f966
--- /dev/null
+++ b/drivers/net/wireless/p54/Kconfig
@@ -0,0 +1,63 @@
1config P54_COMMON
2 tristate "Softmac Prism54 support"
3 depends on MAC80211 && WLAN_80211 && FW_LOADER && EXPERIMENTAL
4 ---help---
5 This is common code for isl38xx based cards.
6 This module does nothing by itself - the USB/PCI frontends
7 also need to be enabled in order to support any devices.
8
9 These devices require softmac firmware which can be found at
10 http://prism54.org/
11
12 If you choose to build a module, it'll be called p54common.
13
14config P54_USB
15 tristate "Prism54 USB support"
16 depends on P54_COMMON && USB
17 select CRC32
18 ---help---
19 This driver is for USB isl38xx based wireless cards.
20 These are USB based adapters found in devices such as:
21
22 3COM 3CRWE254G72
23 SMC 2862W-G
24 Accton 802.11g WN4501 USB
25 Siemens Gigaset USB
26 Netgear WG121
27 Netgear WG111
28 Medion 40900, Roper Europe
29 Shuttle PN15, Airvast WM168g, IOGear GWU513
30 Linksys WUSB54G
31 Linksys WUSB54G Portable
32 DLink DWL-G120 Spinnaker
33 DLink DWL-G122
34 Belkin F5D7050 ver 1000
35 Cohiba Proto board
36 SMC 2862W-G version 2
37 U.S. Robotics U5 802.11g Adapter
38 FUJITSU E-5400 USB D1700
39 Sagem XG703A
40 DLink DWL-G120 Cohiba
41 Spinnaker Proto board
42 Linksys WUSB54AG
43 Inventel UR054G
44 Spinnaker DUT
45
46 These devices require softmac firmware which can be found at
47 http://prism54.org/
48
49 If you choose to build a module, it'll be called p54usb.
50
51config P54_PCI
52 tristate "Prism54 PCI support"
53 depends on P54_COMMON && PCI
54 ---help---
55 This driver is for PCI isl38xx based wireless cards.
56 This driver supports most devices that are supported by the
57 fullmac prism54 driver plus many devices which are not
58 supported by the fullmac driver/firmware.
59
60 This driver requires softmac firmware which can be found at
61 http://prism54.org/
62
63 If you choose to build a module, it'll be called p54pci.
diff --git a/drivers/net/wireless/p54/Makefile b/drivers/net/wireless/p54/Makefile
new file mode 100644
index 000000000000..4fa9ce717360
--- /dev/null
+++ b/drivers/net/wireless/p54/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_P54_COMMON) += p54common.o
2obj-$(CONFIG_P54_USB) += p54usb.o
3obj-$(CONFIG_P54_PCI) += p54pci.o
diff --git a/drivers/net/wireless/p54/net2280.h b/drivers/net/wireless/p54/net2280.h
new file mode 100644
index 000000000000..120eb831b287
--- /dev/null
+++ b/drivers/net/wireless/p54/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/p54.h b/drivers/net/wireless/p54/p54.h
new file mode 100644
index 000000000000..06d2c67f4c81
--- /dev/null
+++ b/drivers/net/wireless/p54/p54.h
@@ -0,0 +1,77 @@
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[ETH_ALEN];
56 u8 bssid[ETH_ALEN];
57 struct pda_iq_autocal_entry *iq_autocal;
58 unsigned int iq_autocal_len;
59 struct pda_channel_output_limit *output_limit;
60 unsigned int output_limit_len;
61 struct pda_pa_curve_data *curve_data;
62 __le16 rxhw;
63 u8 version;
64 unsigned int tx_hdr_len;
65 void *cached_vdcf;
66 unsigned int fw_var;
67 struct ieee80211_tx_queue_stats tx_stats;
68};
69
70int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb);
71void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw);
72int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len);
73void p54_fill_eeprom_readback(struct p54_control_hdr *hdr);
74struct ieee80211_hw *p54_init_common(size_t priv_data_len);
75void p54_free_common(struct ieee80211_hw *dev);
76
77#endif /* PRISM54_H */
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
new file mode 100644
index 000000000000..63f9badf3f52
--- /dev/null
+++ b/drivers/net/wireless/p54/p54common.c
@@ -0,0 +1,1051 @@
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
30static struct ieee80211_rate p54_rates[] = {
31 { .bitrate = 10, .hw_value = 0, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
32 { .bitrate = 20, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
33 { .bitrate = 55, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
34 { .bitrate = 110, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
35 { .bitrate = 60, .hw_value = 4, },
36 { .bitrate = 90, .hw_value = 5, },
37 { .bitrate = 120, .hw_value = 6, },
38 { .bitrate = 180, .hw_value = 7, },
39 { .bitrate = 240, .hw_value = 8, },
40 { .bitrate = 360, .hw_value = 9, },
41 { .bitrate = 480, .hw_value = 10, },
42 { .bitrate = 540, .hw_value = 11, },
43};
44
45static struct ieee80211_channel p54_channels[] = {
46 { .center_freq = 2412, .hw_value = 1, },
47 { .center_freq = 2417, .hw_value = 2, },
48 { .center_freq = 2422, .hw_value = 3, },
49 { .center_freq = 2427, .hw_value = 4, },
50 { .center_freq = 2432, .hw_value = 5, },
51 { .center_freq = 2437, .hw_value = 6, },
52 { .center_freq = 2442, .hw_value = 7, },
53 { .center_freq = 2447, .hw_value = 8, },
54 { .center_freq = 2452, .hw_value = 9, },
55 { .center_freq = 2457, .hw_value = 10, },
56 { .center_freq = 2462, .hw_value = 11, },
57 { .center_freq = 2467, .hw_value = 12, },
58 { .center_freq = 2472, .hw_value = 13, },
59 { .center_freq = 2484, .hw_value = 14, },
60};
61
62static struct ieee80211_supported_band band_2GHz = {
63 .channels = p54_channels,
64 .n_channels = ARRAY_SIZE(p54_channels),
65 .bitrates = p54_rates,
66 .n_bitrates = ARRAY_SIZE(p54_rates),
67};
68
69
70void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
71{
72 struct p54_common *priv = dev->priv;
73 struct bootrec_exp_if *exp_if;
74 struct bootrec *bootrec;
75 u32 *data = (u32 *)fw->data;
76 u32 *end_data = (u32 *)fw->data + (fw->size >> 2);
77 u8 *fw_version = NULL;
78 size_t len;
79 int i;
80
81 if (priv->rx_start)
82 return;
83
84 while (data < end_data && *data)
85 data++;
86
87 while (data < end_data && !*data)
88 data++;
89
90 bootrec = (struct bootrec *) data;
91
92 while (bootrec->data <= end_data &&
93 (bootrec->data + (len = le32_to_cpu(bootrec->len))) <= end_data) {
94 u32 code = le32_to_cpu(bootrec->code);
95 switch (code) {
96 case BR_CODE_COMPONENT_ID:
97 switch (be32_to_cpu(*(__be32 *)bootrec->data)) {
98 case FW_FMAC:
99 printk(KERN_INFO "p54: FreeMAC firmware\n");
100 break;
101 case FW_LM20:
102 printk(KERN_INFO "p54: LM20 firmware\n");
103 break;
104 case FW_LM86:
105 printk(KERN_INFO "p54: LM86 firmware\n");
106 break;
107 case FW_LM87:
108 printk(KERN_INFO "p54: LM87 firmware - not supported yet!\n");
109 break;
110 default:
111 printk(KERN_INFO "p54: unknown firmware\n");
112 break;
113 }
114 break;
115 case BR_CODE_COMPONENT_VERSION:
116 /* 24 bytes should be enough for all firmwares */
117 if (strnlen((unsigned char*)bootrec->data, 24) < 24)
118 fw_version = (unsigned char*)bootrec->data;
119 break;
120 case BR_CODE_DESCR:
121 priv->rx_start = le32_to_cpu(((__le32 *)bootrec->data)[1]);
122 /* FIXME add sanity checking */
123 priv->rx_end = le32_to_cpu(((__le32 *)bootrec->data)[2]) - 0x3500;
124 break;
125 case BR_CODE_EXPOSED_IF:
126 exp_if = (struct bootrec_exp_if *) bootrec->data;
127 for (i = 0; i < (len * sizeof(*exp_if) / 4); i++)
128 if (exp_if[i].if_id == cpu_to_le16(0x1a))
129 priv->fw_var = le16_to_cpu(exp_if[i].variant);
130 break;
131 case BR_CODE_DEPENDENT_IF:
132 break;
133 case BR_CODE_END_OF_BRA:
134 case LEGACY_BR_CODE_END_OF_BRA:
135 end_data = NULL;
136 break;
137 default:
138 break;
139 }
140 bootrec = (struct bootrec *)&bootrec->data[len];
141 }
142
143 if (fw_version)
144 printk(KERN_INFO "p54: FW rev %s - Softmac protocol %x.%x\n",
145 fw_version, priv->fw_var >> 8, priv->fw_var & 0xff);
146
147 if (priv->fw_var >= 0x300) {
148 /* Firmware supports QoS, use it! */
149 priv->tx_stats.data[0].limit = 3;
150 priv->tx_stats.data[1].limit = 4;
151 priv->tx_stats.data[2].limit = 3;
152 priv->tx_stats.data[3].limit = 1;
153 dev->queues = 4;
154 }
155}
156EXPORT_SYMBOL_GPL(p54_parse_firmware);
157
158static int p54_convert_rev0_to_rev1(struct ieee80211_hw *dev,
159 struct pda_pa_curve_data *curve_data)
160{
161 struct p54_common *priv = dev->priv;
162 struct pda_pa_curve_data_sample_rev1 *rev1;
163 struct pda_pa_curve_data_sample_rev0 *rev0;
164 size_t cd_len = sizeof(*curve_data) +
165 (curve_data->points_per_channel*sizeof(*rev1) + 2) *
166 curve_data->channels;
167 unsigned int i, j;
168 void *source, *target;
169
170 priv->curve_data = kmalloc(cd_len, GFP_KERNEL);
171 if (!priv->curve_data)
172 return -ENOMEM;
173
174 memcpy(priv->curve_data, curve_data, sizeof(*curve_data));
175 source = curve_data->data;
176 target = priv->curve_data->data;
177 for (i = 0; i < curve_data->channels; i++) {
178 __le16 *freq = source;
179 source += sizeof(__le16);
180 *((__le16 *)target) = *freq;
181 target += sizeof(__le16);
182 for (j = 0; j < curve_data->points_per_channel; j++) {
183 rev1 = target;
184 rev0 = source;
185
186 rev1->rf_power = rev0->rf_power;
187 rev1->pa_detector = rev0->pa_detector;
188 rev1->data_64qam = rev0->pcv;
189 /* "invent" the points for the other modulations */
190#define SUB(x,y) (u8)((x) - (y)) > (x) ? 0 : (x) - (y)
191 rev1->data_16qam = SUB(rev0->pcv, 12);
192 rev1->data_qpsk = SUB(rev1->data_16qam, 12);
193 rev1->data_bpsk = SUB(rev1->data_qpsk, 12);
194 rev1->data_barker= SUB(rev1->data_bpsk, 14);
195#undef SUB
196 target += sizeof(*rev1);
197 source += sizeof(*rev0);
198 }
199 }
200
201 return 0;
202}
203
204int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
205{
206 struct p54_common *priv = dev->priv;
207 struct eeprom_pda_wrap *wrap = NULL;
208 struct pda_entry *entry;
209 unsigned int data_len, entry_len;
210 void *tmp;
211 int err;
212 u8 *end = (u8 *)eeprom + len;
213
214 wrap = (struct eeprom_pda_wrap *) eeprom;
215 entry = (void *)wrap->data + le16_to_cpu(wrap->len);
216
217 /* verify that at least the entry length/code fits */
218 while ((u8 *)entry <= end - sizeof(*entry)) {
219 entry_len = le16_to_cpu(entry->len);
220 data_len = ((entry_len - 1) << 1);
221
222 /* abort if entry exceeds whole structure */
223 if ((u8 *)entry + sizeof(*entry) + data_len > end)
224 break;
225
226 switch (le16_to_cpu(entry->code)) {
227 case PDR_MAC_ADDRESS:
228 SET_IEEE80211_PERM_ADDR(dev, entry->data);
229 break;
230 case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS:
231 if (data_len < 2) {
232 err = -EINVAL;
233 goto err;
234 }
235
236 if (2 + entry->data[1]*sizeof(*priv->output_limit) > data_len) {
237 err = -EINVAL;
238 goto err;
239 }
240
241 priv->output_limit = kmalloc(entry->data[1] *
242 sizeof(*priv->output_limit), GFP_KERNEL);
243
244 if (!priv->output_limit) {
245 err = -ENOMEM;
246 goto err;
247 }
248
249 memcpy(priv->output_limit, &entry->data[2],
250 entry->data[1]*sizeof(*priv->output_limit));
251 priv->output_limit_len = entry->data[1];
252 break;
253 case PDR_PRISM_PA_CAL_CURVE_DATA:
254 if (data_len < sizeof(struct pda_pa_curve_data)) {
255 err = -EINVAL;
256 goto err;
257 }
258
259 if (((struct pda_pa_curve_data *)entry->data)->cal_method_rev) {
260 priv->curve_data = kmalloc(data_len, GFP_KERNEL);
261 if (!priv->curve_data) {
262 err = -ENOMEM;
263 goto err;
264 }
265
266 memcpy(priv->curve_data, entry->data, data_len);
267 } else {
268 err = p54_convert_rev0_to_rev1(dev, (struct pda_pa_curve_data *)entry->data);
269 if (err)
270 goto err;
271 }
272
273 break;
274 case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
275 priv->iq_autocal = kmalloc(data_len, GFP_KERNEL);
276 if (!priv->iq_autocal) {
277 err = -ENOMEM;
278 goto err;
279 }
280
281 memcpy(priv->iq_autocal, entry->data, data_len);
282 priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry);
283 break;
284 case PDR_INTERFACE_LIST:
285 tmp = entry->data;
286 while ((u8 *)tmp < entry->data + data_len) {
287 struct bootrec_exp_if *exp_if = tmp;
288 if (le16_to_cpu(exp_if->if_id) == 0xF)
289 priv->rxhw = exp_if->variant & cpu_to_le16(0x07);
290 tmp += sizeof(struct bootrec_exp_if);
291 }
292 break;
293 case PDR_HARDWARE_PLATFORM_COMPONENT_ID:
294 priv->version = *(u8 *)(entry->data + 1);
295 break;
296 case PDR_END:
297 /* make it overrun */
298 entry_len = len;
299 break;
300 default:
301 printk(KERN_INFO "p54: unknown eeprom code : 0x%x\n",
302 le16_to_cpu(entry->code));
303 break;
304 }
305
306 entry = (void *)entry + (entry_len + 1)*2;
307 }
308
309 if (!priv->iq_autocal || !priv->output_limit || !priv->curve_data) {
310 printk(KERN_ERR "p54: not all required entries found in eeprom!\n");
311 err = -EINVAL;
312 goto err;
313 }
314
315 return 0;
316
317 err:
318 if (priv->iq_autocal) {
319 kfree(priv->iq_autocal);
320 priv->iq_autocal = NULL;
321 }
322
323 if (priv->output_limit) {
324 kfree(priv->output_limit);
325 priv->output_limit = NULL;
326 }
327
328 if (priv->curve_data) {
329 kfree(priv->curve_data);
330 priv->curve_data = NULL;
331 }
332
333 printk(KERN_ERR "p54: eeprom parse failed!\n");
334 return err;
335}
336EXPORT_SYMBOL_GPL(p54_parse_eeprom);
337
338void p54_fill_eeprom_readback(struct p54_control_hdr *hdr)
339{
340 struct p54_eeprom_lm86 *eeprom_hdr;
341
342 hdr->magic1 = cpu_to_le16(0x8000);
343 hdr->len = cpu_to_le16(sizeof(*eeprom_hdr) + 0x2000);
344 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_EEPROM_READBACK);
345 hdr->retry1 = hdr->retry2 = 0;
346 eeprom_hdr = (struct p54_eeprom_lm86 *) hdr->data;
347 eeprom_hdr->offset = 0x0;
348 eeprom_hdr->len = cpu_to_le16(0x2000);
349}
350EXPORT_SYMBOL_GPL(p54_fill_eeprom_readback);
351
352static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
353{
354 struct p54_rx_hdr *hdr = (struct p54_rx_hdr *) skb->data;
355 struct ieee80211_rx_status rx_status = {0};
356 u16 freq = le16_to_cpu(hdr->freq);
357
358 rx_status.ssi = hdr->rssi;
359 /* XX correct? */
360 rx_status.rate_idx = hdr->rate & 0xf;
361 rx_status.freq = freq;
362 rx_status.band = IEEE80211_BAND_2GHZ;
363 rx_status.antenna = hdr->antenna;
364 rx_status.mactime = le64_to_cpu(hdr->timestamp);
365 rx_status.flag |= RX_FLAG_TSFT;
366
367 skb_pull(skb, sizeof(*hdr));
368 skb_trim(skb, le16_to_cpu(hdr->len));
369
370 ieee80211_rx_irqsafe(dev, skb, &rx_status);
371}
372
373static void inline p54_wake_free_queues(struct ieee80211_hw *dev)
374{
375 struct p54_common *priv = dev->priv;
376 int i;
377
378 /* ieee80211_start_queues is great if all queues are really empty.
379 * But, what if some are full? */
380
381 for (i = 0; i < dev->queues; i++)
382 if (priv->tx_stats.data[i].len < priv->tx_stats.data[i].limit)
383 ieee80211_wake_queue(dev, i);
384}
385
386static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
387{
388 struct p54_common *priv = dev->priv;
389 struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
390 struct p54_frame_sent_hdr *payload = (struct p54_frame_sent_hdr *) hdr->data;
391 struct sk_buff *entry = (struct sk_buff *) priv->tx_queue.next;
392 u32 addr = le32_to_cpu(hdr->req_id) - 0x70;
393 struct memrecord *range = NULL;
394 u32 freed = 0;
395 u32 last_addr = priv->rx_start;
396
397 while (entry != (struct sk_buff *)&priv->tx_queue) {
398 range = (struct memrecord *)&entry->cb;
399 if (range->start_addr == addr) {
400 struct ieee80211_tx_status status;
401 struct p54_control_hdr *entry_hdr;
402 struct p54_tx_control_allocdata *entry_data;
403 int pad = 0;
404
405 if (entry->next != (struct sk_buff *)&priv->tx_queue)
406 freed = ((struct memrecord *)&entry->next->cb)->start_addr - last_addr;
407 else
408 freed = priv->rx_end - last_addr;
409
410 last_addr = range->end_addr;
411 __skb_unlink(entry, &priv->tx_queue);
412 if (!range->control) {
413 kfree_skb(entry);
414 break;
415 }
416 memset(&status, 0, sizeof(status));
417 memcpy(&status.control, range->control,
418 sizeof(status.control));
419 kfree(range->control);
420 priv->tx_stats.data[status.control.queue].len--;
421
422 entry_hdr = (struct p54_control_hdr *) entry->data;
423 entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data;
424 if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
425 pad = entry_data->align[0];
426
427 if (!(status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
428 if (!(payload->status & 0x01))
429 status.flags |= IEEE80211_TX_STATUS_ACK;
430 else
431 status.excessive_retries = 1;
432 }
433 status.retry_count = payload->retries - 1;
434 status.ack_signal = le16_to_cpu(payload->ack_rssi);
435 skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
436 ieee80211_tx_status_irqsafe(dev, entry, &status);
437 break;
438 } else
439 last_addr = range->end_addr;
440 entry = entry->next;
441 }
442
443 if (freed >= IEEE80211_MAX_RTS_THRESHOLD + 0x170 +
444 sizeof(struct p54_control_hdr))
445 p54_wake_free_queues(dev);
446}
447
448static void p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb)
449{
450 struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
451
452 switch (le16_to_cpu(hdr->type)) {
453 case P54_CONTROL_TYPE_TXDONE:
454 p54_rx_frame_sent(dev, skb);
455 break;
456 case P54_CONTROL_TYPE_BBP:
457 break;
458 default:
459 printk(KERN_DEBUG "%s: not handling 0x%02x type control frame\n",
460 wiphy_name(dev->wiphy), le16_to_cpu(hdr->type));
461 break;
462 }
463}
464
465/* returns zero if skb can be reused */
466int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb)
467{
468 u8 type = le16_to_cpu(*((__le16 *)skb->data)) >> 8;
469 switch (type) {
470 case 0x00:
471 case 0x01:
472 p54_rx_data(dev, skb);
473 return -1;
474 case 0x4d:
475 /* TODO: do something better... but then again, I've never seen this happen */
476 printk(KERN_ERR "%s: Received fault. Probably need to restart hardware now..\n",
477 wiphy_name(dev->wiphy));
478 break;
479 case 0x80:
480 p54_rx_control(dev, skb);
481 break;
482 default:
483 printk(KERN_ERR "%s: unknown frame RXed (0x%02x)\n",
484 wiphy_name(dev->wiphy), type);
485 break;
486 }
487 return 0;
488}
489EXPORT_SYMBOL_GPL(p54_rx);
490
491/*
492 * So, the firmware is somewhat stupid and doesn't know what places in its
493 * memory incoming data should go to. By poking around in the firmware, we
494 * can find some unused memory to upload our packets to. However, data that we
495 * want the card to TX needs to stay intact until the card has told us that
496 * it is done with it. This function finds empty places we can upload to and
497 * marks allocated areas as reserved if necessary. p54_rx_frame_sent frees
498 * allocated areas.
499 */
500static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
501 struct p54_control_hdr *data, u32 len,
502 struct ieee80211_tx_control *control)
503{
504 struct p54_common *priv = dev->priv;
505 struct sk_buff *entry = priv->tx_queue.next;
506 struct sk_buff *target_skb = NULL;
507 struct memrecord *range;
508 u32 last_addr = priv->rx_start;
509 u32 largest_hole = 0;
510 u32 target_addr = priv->rx_start;
511 unsigned long flags;
512 unsigned int left;
513 len = (len + 0x170 + 3) & ~0x3; /* 0x70 headroom, 0x100 tailroom */
514
515 spin_lock_irqsave(&priv->tx_queue.lock, flags);
516 left = skb_queue_len(&priv->tx_queue);
517 while (left--) {
518 u32 hole_size;
519 range = (struct memrecord *)&entry->cb;
520 hole_size = range->start_addr - last_addr;
521 if (!target_skb && hole_size >= len) {
522 target_skb = entry->prev;
523 hole_size -= len;
524 target_addr = last_addr;
525 }
526 largest_hole = max(largest_hole, hole_size);
527 last_addr = range->end_addr;
528 entry = entry->next;
529 }
530 if (!target_skb && priv->rx_end - last_addr >= len) {
531 target_skb = priv->tx_queue.prev;
532 largest_hole = max(largest_hole, priv->rx_end - last_addr - len);
533 if (!skb_queue_empty(&priv->tx_queue)) {
534 range = (struct memrecord *)&target_skb->cb;
535 target_addr = range->end_addr;
536 }
537 } else
538 largest_hole = max(largest_hole, priv->rx_end - last_addr);
539
540 if (skb) {
541 range = (struct memrecord *)&skb->cb;
542 range->start_addr = target_addr;
543 range->end_addr = target_addr + len;
544 range->control = control;
545 __skb_queue_after(&priv->tx_queue, target_skb, skb);
546 if (largest_hole < IEEE80211_MAX_RTS_THRESHOLD + 0x170 +
547 sizeof(struct p54_control_hdr))
548 ieee80211_stop_queues(dev);
549 }
550 spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
551
552 data->req_id = cpu_to_le32(target_addr + 0x70);
553}
554
555static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
556 struct ieee80211_tx_control *control)
557{
558 struct ieee80211_tx_queue_stats_data *current_queue;
559 struct p54_common *priv = dev->priv;
560 struct p54_control_hdr *hdr;
561 struct p54_tx_control_allocdata *txhdr;
562 struct ieee80211_tx_control *control_copy;
563 size_t padding, len;
564 u8 rate;
565
566 current_queue = &priv->tx_stats.data[control->queue];
567 if (unlikely(current_queue->len > current_queue->limit))
568 return NETDEV_TX_BUSY;
569 current_queue->len++;
570 current_queue->count++;
571 if (current_queue->len == current_queue->limit)
572 ieee80211_stop_queue(dev, control->queue);
573
574 padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3;
575 len = skb->len;
576
577 control_copy = kmalloc(sizeof(*control), GFP_ATOMIC);
578 if (control_copy)
579 memcpy(control_copy, control, sizeof(*control));
580
581 txhdr = (struct p54_tx_control_allocdata *)
582 skb_push(skb, sizeof(*txhdr) + padding);
583 hdr = (struct p54_control_hdr *) skb_push(skb, sizeof(*hdr));
584
585 if (padding)
586 hdr->magic1 = cpu_to_le16(0x4010);
587 else
588 hdr->magic1 = cpu_to_le16(0x0010);
589 hdr->len = cpu_to_le16(len);
590 hdr->type = (control->flags & IEEE80211_TXCTL_NO_ACK) ? 0 : cpu_to_le16(1);
591 hdr->retry1 = hdr->retry2 = control->retry_limit;
592 p54_assign_address(dev, skb, hdr, skb->len, control_copy);
593
594 memset(txhdr->wep_key, 0x0, 16);
595 txhdr->padding = 0;
596 txhdr->padding2 = 0;
597
598 /* TODO: add support for alternate retry TX rates */
599 rate = control->tx_rate->hw_value;
600 if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
601 rate |= 0x10;
602 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
603 rate |= 0x40;
604 else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
605 rate |= 0x20;
606 memset(txhdr->rateset, rate, 8);
607 txhdr->wep_key_present = 0;
608 txhdr->wep_key_len = 0;
609 txhdr->frame_type = cpu_to_le32(control->queue + 4);
610 txhdr->magic4 = 0;
611 txhdr->antenna = (control->antenna_sel_tx == 0) ?
612 2 : control->antenna_sel_tx - 1;
613 txhdr->output_power = 0x7f; // HW Maximum
614 txhdr->magic5 = (control->flags & IEEE80211_TXCTL_NO_ACK) ?
615 0 : ((rate > 0x3) ? cpu_to_le32(0x33) : cpu_to_le32(0x23));
616 if (padding)
617 txhdr->align[0] = padding;
618
619 priv->tx(dev, hdr, skb->len, 0);
620 return 0;
621}
622
623static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
624 const u8 *dst, const u8 *src, u8 antenna,
625 u32 magic3, u32 magic8, u32 magic9)
626{
627 struct p54_common *priv = dev->priv;
628 struct p54_control_hdr *hdr;
629 struct p54_tx_control_filter *filter;
630
631 hdr = kzalloc(sizeof(*hdr) + sizeof(*filter) +
632 priv->tx_hdr_len, GFP_ATOMIC);
633 if (!hdr)
634 return -ENOMEM;
635
636 hdr = (void *)hdr + priv->tx_hdr_len;
637
638 filter = (struct p54_tx_control_filter *) hdr->data;
639 hdr->magic1 = cpu_to_le16(0x8001);
640 hdr->len = cpu_to_le16(sizeof(*filter));
641 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*filter), NULL);
642 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_FILTER_SET);
643
644 filter->filter_type = cpu_to_le16(filter_type);
645 memcpy(filter->dst, dst, ETH_ALEN);
646 if (!src)
647 memset(filter->src, ~0, ETH_ALEN);
648 else
649 memcpy(filter->src, src, ETH_ALEN);
650 filter->antenna = antenna;
651 filter->magic3 = cpu_to_le32(magic3);
652 filter->rx_addr = cpu_to_le32(priv->rx_end);
653 filter->max_rx = cpu_to_le16(0x0620); /* FIXME: for usb ver 1.. maybe */
654 filter->rxhw = priv->rxhw;
655 filter->magic8 = cpu_to_le16(magic8);
656 filter->magic9 = cpu_to_le16(magic9);
657
658 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*filter), 1);
659 return 0;
660}
661
662static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
663{
664 struct p54_common *priv = dev->priv;
665 struct p54_control_hdr *hdr;
666 struct p54_tx_control_channel *chan;
667 unsigned int i;
668 size_t payload_len = sizeof(*chan) + sizeof(u32)*2 +
669 sizeof(*chan->curve_data) *
670 priv->curve_data->points_per_channel;
671 void *entry;
672
673 hdr = kzalloc(sizeof(*hdr) + payload_len +
674 priv->tx_hdr_len, GFP_KERNEL);
675 if (!hdr)
676 return -ENOMEM;
677
678 hdr = (void *)hdr + priv->tx_hdr_len;
679
680 chan = (struct p54_tx_control_channel *) hdr->data;
681
682 hdr->magic1 = cpu_to_le16(0x8001);
683 hdr->len = cpu_to_le16(sizeof(*chan));
684 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_CHANNEL_CHANGE);
685 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + payload_len, NULL);
686
687 chan->magic1 = cpu_to_le16(0x1);
688 chan->magic2 = cpu_to_le16(0x0);
689
690 for (i = 0; i < priv->iq_autocal_len; i++) {
691 if (priv->iq_autocal[i].freq != freq)
692 continue;
693
694 memcpy(&chan->iq_autocal, &priv->iq_autocal[i],
695 sizeof(*priv->iq_autocal));
696 break;
697 }
698 if (i == priv->iq_autocal_len)
699 goto err;
700
701 for (i = 0; i < priv->output_limit_len; i++) {
702 if (priv->output_limit[i].freq != freq)
703 continue;
704
705 chan->val_barker = 0x38;
706 chan->val_bpsk = priv->output_limit[i].val_bpsk;
707 chan->val_qpsk = priv->output_limit[i].val_qpsk;
708 chan->val_16qam = priv->output_limit[i].val_16qam;
709 chan->val_64qam = priv->output_limit[i].val_64qam;
710 break;
711 }
712 if (i == priv->output_limit_len)
713 goto err;
714
715 chan->pa_points_per_curve = priv->curve_data->points_per_channel;
716
717 entry = priv->curve_data->data;
718 for (i = 0; i < priv->curve_data->channels; i++) {
719 if (*((__le16 *)entry) != freq) {
720 entry += sizeof(__le16);
721 entry += sizeof(struct pda_pa_curve_data_sample_rev1) *
722 chan->pa_points_per_curve;
723 continue;
724 }
725
726 entry += sizeof(__le16);
727 memcpy(chan->curve_data, entry, sizeof(*chan->curve_data) *
728 chan->pa_points_per_curve);
729 break;
730 }
731
732 memcpy(hdr->data + payload_len - 4, &chan->val_bpsk, 4);
733
734 priv->tx(dev, hdr, sizeof(*hdr) + payload_len, 1);
735 return 0;
736
737 err:
738 printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy));
739 kfree(hdr);
740 return -EINVAL;
741}
742
743static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act)
744{
745 struct p54_common *priv = dev->priv;
746 struct p54_control_hdr *hdr;
747 struct p54_tx_control_led *led;
748
749 hdr = kzalloc(sizeof(*hdr) + sizeof(*led) +
750 priv->tx_hdr_len, GFP_KERNEL);
751 if (!hdr)
752 return -ENOMEM;
753
754 hdr = (void *)hdr + priv->tx_hdr_len;
755 hdr->magic1 = cpu_to_le16(0x8001);
756 hdr->len = cpu_to_le16(sizeof(*led));
757 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_LED);
758 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*led), NULL);
759
760 led = (struct p54_tx_control_led *) hdr->data;
761 led->mode = cpu_to_le16(mode);
762 led->led_permanent = cpu_to_le16(link);
763 led->led_temporary = cpu_to_le16(act);
764 led->duration = cpu_to_le16(1000);
765
766 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*led), 1);
767
768 return 0;
769}
770
771#define P54_SET_QUEUE(queue, ai_fs, cw_min, cw_max, _txop) \
772do { \
773 queue.aifs = cpu_to_le16(ai_fs); \
774 queue.cwmin = cpu_to_le16(cw_min); \
775 queue.cwmax = cpu_to_le16(cw_max); \
776 queue.txop = cpu_to_le16(_txop); \
777} while(0)
778
779static void p54_init_vdcf(struct ieee80211_hw *dev)
780{
781 struct p54_common *priv = dev->priv;
782 struct p54_control_hdr *hdr;
783 struct p54_tx_control_vdcf *vdcf;
784
785 /* all USB V1 adapters need a extra headroom */
786 hdr = (void *)priv->cached_vdcf + priv->tx_hdr_len;
787 hdr->magic1 = cpu_to_le16(0x8001);
788 hdr->len = cpu_to_le16(sizeof(*vdcf));
789 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_DCFINIT);
790 hdr->req_id = cpu_to_le32(priv->rx_start);
791
792 vdcf = (struct p54_tx_control_vdcf *) hdr->data;
793
794 P54_SET_QUEUE(vdcf->queue[0], 0x0002, 0x0003, 0x0007, 47);
795 P54_SET_QUEUE(vdcf->queue[1], 0x0002, 0x0007, 0x000f, 94);
796 P54_SET_QUEUE(vdcf->queue[2], 0x0003, 0x000f, 0x03ff, 0);
797 P54_SET_QUEUE(vdcf->queue[3], 0x0007, 0x000f, 0x03ff, 0);
798}
799
800static void p54_set_vdcf(struct ieee80211_hw *dev)
801{
802 struct p54_common *priv = dev->priv;
803 struct p54_control_hdr *hdr;
804 struct p54_tx_control_vdcf *vdcf;
805
806 hdr = (void *)priv->cached_vdcf + priv->tx_hdr_len;
807
808 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*vdcf), NULL);
809
810 vdcf = (struct p54_tx_control_vdcf *) hdr->data;
811
812 if (dev->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
813 vdcf->slottime = 9;
814 vdcf->magic1 = 0x00;
815 vdcf->magic2 = 0x10;
816 } else {
817 vdcf->slottime = 20;
818 vdcf->magic1 = 0x0a;
819 vdcf->magic2 = 0x06;
820 }
821
822 /* (see prism54/isl_oid.h for further details) */
823 vdcf->frameburst = cpu_to_le16(0);
824
825 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*vdcf), 0);
826}
827
828static int p54_start(struct ieee80211_hw *dev)
829{
830 struct p54_common *priv = dev->priv;
831 int err;
832
833 err = priv->open(dev);
834 if (!err)
835 priv->mode = IEEE80211_IF_TYPE_MNTR;
836
837 return err;
838}
839
840static void p54_stop(struct ieee80211_hw *dev)
841{
842 struct p54_common *priv = dev->priv;
843 struct sk_buff *skb;
844 while ((skb = skb_dequeue(&priv->tx_queue))) {
845 struct memrecord *range = (struct memrecord *)&skb->cb;
846 if (range->control)
847 kfree(range->control);
848 kfree_skb(skb);
849 }
850 priv->stop(dev);
851 priv->mode = IEEE80211_IF_TYPE_INVALID;
852}
853
854static int p54_add_interface(struct ieee80211_hw *dev,
855 struct ieee80211_if_init_conf *conf)
856{
857 struct p54_common *priv = dev->priv;
858
859 if (priv->mode != IEEE80211_IF_TYPE_MNTR)
860 return -EOPNOTSUPP;
861
862 switch (conf->type) {
863 case IEEE80211_IF_TYPE_STA:
864 priv->mode = conf->type;
865 break;
866 default:
867 return -EOPNOTSUPP;
868 }
869
870 memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
871
872 p54_set_filter(dev, 0, priv->mac_addr, NULL, 0, 1, 0, 0xF642);
873 p54_set_filter(dev, 0, priv->mac_addr, NULL, 1, 0, 0, 0xF642);
874
875 switch (conf->type) {
876 case IEEE80211_IF_TYPE_STA:
877 p54_set_filter(dev, 1, priv->mac_addr, NULL, 0, 0x15F, 0x1F4, 0);
878 break;
879 default:
880 BUG(); /* impossible */
881 break;
882 }
883
884 p54_set_leds(dev, 1, 0, 0);
885
886 return 0;
887}
888
889static void p54_remove_interface(struct ieee80211_hw *dev,
890 struct ieee80211_if_init_conf *conf)
891{
892 struct p54_common *priv = dev->priv;
893 priv->mode = IEEE80211_IF_TYPE_MNTR;
894 memset(priv->mac_addr, 0, ETH_ALEN);
895 p54_set_filter(dev, 0, priv->mac_addr, NULL, 2, 0, 0, 0);
896}
897
898static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
899{
900 int ret;
901
902 ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq));
903 p54_set_vdcf(dev);
904 return ret;
905}
906
907static int p54_config_interface(struct ieee80211_hw *dev,
908 struct ieee80211_vif *vif,
909 struct ieee80211_if_conf *conf)
910{
911 struct p54_common *priv = dev->priv;
912
913 p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 0, 1, 0, 0xF642);
914 p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 2, 0, 0, 0);
915 p54_set_leds(dev, 1, !is_multicast_ether_addr(conf->bssid), 0);
916 memcpy(priv->bssid, conf->bssid, ETH_ALEN);
917 return 0;
918}
919
920static void p54_configure_filter(struct ieee80211_hw *dev,
921 unsigned int changed_flags,
922 unsigned int *total_flags,
923 int mc_count, struct dev_mc_list *mclist)
924{
925 struct p54_common *priv = dev->priv;
926
927 *total_flags &= FIF_BCN_PRBRESP_PROMISC;
928
929 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
930 if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
931 p54_set_filter(dev, 0, priv->mac_addr,
932 NULL, 2, 0, 0, 0);
933 else
934 p54_set_filter(dev, 0, priv->mac_addr,
935 priv->bssid, 2, 0, 0, 0);
936 }
937}
938
939static int p54_conf_tx(struct ieee80211_hw *dev, int queue,
940 const struct ieee80211_tx_queue_params *params)
941{
942 struct p54_common *priv = dev->priv;
943 struct p54_tx_control_vdcf *vdcf;
944
945 vdcf = (struct p54_tx_control_vdcf *)(((struct p54_control_hdr *)
946 ((void *)priv->cached_vdcf + priv->tx_hdr_len))->data);
947
948 if ((params) && !((queue < 0) || (queue > 4))) {
949 P54_SET_QUEUE(vdcf->queue[queue], params->aifs,
950 params->cw_min, params->cw_max, params->txop);
951 } else
952 return -EINVAL;
953
954 p54_set_vdcf(dev);
955
956 return 0;
957}
958
959static int p54_get_stats(struct ieee80211_hw *dev,
960 struct ieee80211_low_level_stats *stats)
961{
962 /* TODO */
963 return 0;
964}
965
966static int p54_get_tx_stats(struct ieee80211_hw *dev,
967 struct ieee80211_tx_queue_stats *stats)
968{
969 struct p54_common *priv = dev->priv;
970 unsigned int i;
971
972 for (i = 0; i < dev->queues; i++)
973 memcpy(&stats->data[i], &priv->tx_stats.data[i],
974 sizeof(stats->data[i]));
975
976 return 0;
977}
978
979static const struct ieee80211_ops p54_ops = {
980 .tx = p54_tx,
981 .start = p54_start,
982 .stop = p54_stop,
983 .add_interface = p54_add_interface,
984 .remove_interface = p54_remove_interface,
985 .config = p54_config,
986 .config_interface = p54_config_interface,
987 .configure_filter = p54_configure_filter,
988 .conf_tx = p54_conf_tx,
989 .get_stats = p54_get_stats,
990 .get_tx_stats = p54_get_tx_stats
991};
992
993struct ieee80211_hw *p54_init_common(size_t priv_data_len)
994{
995 struct ieee80211_hw *dev;
996 struct p54_common *priv;
997
998 dev = ieee80211_alloc_hw(priv_data_len, &p54_ops);
999 if (!dev)
1000 return NULL;
1001
1002 priv = dev->priv;
1003 priv->mode = IEEE80211_IF_TYPE_INVALID;
1004 skb_queue_head_init(&priv->tx_queue);
1005 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
1006 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */
1007 IEEE80211_HW_RX_INCLUDES_FCS;
1008 dev->channel_change_time = 1000; /* TODO: find actual value */
1009 dev->max_rssi = 127;
1010
1011 priv->tx_stats.data[0].limit = 5;
1012 dev->queues = 1;
1013
1014 dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 +
1015 sizeof(struct p54_tx_control_allocdata);
1016
1017 priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf) +
1018 priv->tx_hdr_len + sizeof(struct p54_control_hdr), GFP_KERNEL);
1019
1020 if (!priv->cached_vdcf) {
1021 ieee80211_free_hw(dev);
1022 return NULL;
1023 }
1024
1025 p54_init_vdcf(dev);
1026
1027 return dev;
1028}
1029EXPORT_SYMBOL_GPL(p54_init_common);
1030
1031void p54_free_common(struct ieee80211_hw *dev)
1032{
1033 struct p54_common *priv = dev->priv;
1034 kfree(priv->iq_autocal);
1035 kfree(priv->output_limit);
1036 kfree(priv->curve_data);
1037 kfree(priv->cached_vdcf);
1038}
1039EXPORT_SYMBOL_GPL(p54_free_common);
1040
1041static int __init p54_init(void)
1042{
1043 return 0;
1044}
1045
1046static void __exit p54_exit(void)
1047{
1048}
1049
1050module_init(p54_init);
1051module_exit(p54_exit);
diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h
new file mode 100644
index 000000000000..c15b56e1d75e
--- /dev/null
+++ b/drivers/net/wireless/p54/p54common.h
@@ -0,0 +1,254 @@
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 __le32 magic;
57 __le16 pad;
58 __le16 len;
59 __le32 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
254#endif /* PRISM54COMMON_H */
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
new file mode 100644
index 000000000000..fa527723fbe0
--- /dev/null
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -0,0 +1,697 @@
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};
42
43MODULE_DEVICE_TABLE(pci, p54p_table);
44
45static int p54p_upload_firmware(struct ieee80211_hw *dev)
46{
47 struct p54p_priv *priv = dev->priv;
48 const struct firmware *fw_entry = NULL;
49 __le32 reg;
50 int err;
51 __le32 *data;
52 u32 remains, left, device_addr;
53
54 P54P_WRITE(int_enable, cpu_to_le32(0));
55 P54P_READ(int_enable);
56 udelay(10);
57
58 reg = P54P_READ(ctrl_stat);
59 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
60 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
61 P54P_WRITE(ctrl_stat, reg);
62 P54P_READ(ctrl_stat);
63 udelay(10);
64
65 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
66 P54P_WRITE(ctrl_stat, reg);
67 wmb();
68 udelay(10);
69
70 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
71 P54P_WRITE(ctrl_stat, reg);
72 wmb();
73
74 mdelay(50);
75
76 err = request_firmware(&fw_entry, "isl3886", &priv->pdev->dev);
77 if (err) {
78 printk(KERN_ERR "%s (prism54pci): cannot find firmware "
79 "(isl3886)\n", pci_name(priv->pdev));
80 return err;
81 }
82
83 p54_parse_firmware(dev, fw_entry);
84
85 data = (__le32 *) fw_entry->data;
86 remains = fw_entry->size;
87 device_addr = ISL38XX_DEV_FIRMWARE_ADDR;
88 while (remains) {
89 u32 i = 0;
90 left = min((u32)0x1000, remains);
91 P54P_WRITE(direct_mem_base, cpu_to_le32(device_addr));
92 P54P_READ(int_enable);
93
94 device_addr += 0x1000;
95 while (i < left) {
96 P54P_WRITE(direct_mem_win[i], *data++);
97 i += sizeof(u32);
98 }
99
100 remains -= left;
101 P54P_READ(int_enable);
102 }
103
104 release_firmware(fw_entry);
105
106 reg = P54P_READ(ctrl_stat);
107 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
108 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
109 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
110 P54P_WRITE(ctrl_stat, reg);
111 P54P_READ(ctrl_stat);
112 udelay(10);
113
114 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
115 P54P_WRITE(ctrl_stat, reg);
116 wmb();
117 udelay(10);
118
119 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
120 P54P_WRITE(ctrl_stat, reg);
121 wmb();
122 udelay(10);
123
124 return 0;
125}
126
127static irqreturn_t p54p_simple_interrupt(int irq, void *dev_id)
128{
129 struct p54p_priv *priv = (struct p54p_priv *) dev_id;
130 __le32 reg;
131
132 reg = P54P_READ(int_ident);
133 P54P_WRITE(int_ack, reg);
134
135 if (reg & P54P_READ(int_enable))
136 complete(&priv->boot_comp);
137
138 return IRQ_HANDLED;
139}
140
141static int p54p_read_eeprom(struct ieee80211_hw *dev)
142{
143 struct p54p_priv *priv = dev->priv;
144 struct p54p_ring_control *ring_control = priv->ring_control;
145 int err;
146 struct p54_control_hdr *hdr;
147 void *eeprom;
148 dma_addr_t rx_mapping, tx_mapping;
149 u16 alen;
150
151 init_completion(&priv->boot_comp);
152 err = request_irq(priv->pdev->irq, &p54p_simple_interrupt,
153 IRQF_SHARED, "prism54pci", priv);
154 if (err) {
155 printk(KERN_ERR "%s (prism54pci): failed to register IRQ handler\n",
156 pci_name(priv->pdev));
157 return err;
158 }
159
160 eeprom = kmalloc(0x2010 + EEPROM_READBACK_LEN, GFP_KERNEL);
161 if (!eeprom) {
162 printk(KERN_ERR "%s (prism54pci): no memory for eeprom!\n",
163 pci_name(priv->pdev));
164 err = -ENOMEM;
165 goto out;
166 }
167
168 memset(ring_control, 0, sizeof(*ring_control));
169 P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma));
170 P54P_READ(ring_control_base);
171 udelay(10);
172
173 P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_INIT));
174 P54P_READ(int_enable);
175 udelay(10);
176
177 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
178
179 if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) {
180 printk(KERN_ERR "%s (prism54pci): Cannot boot firmware!\n",
181 pci_name(priv->pdev));
182 err = -EINVAL;
183 goto out;
184 }
185
186 P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_UPDATE));
187 P54P_READ(int_enable);
188
189 hdr = eeprom + 0x2010;
190 p54_fill_eeprom_readback(hdr);
191 hdr->req_id = cpu_to_le32(priv->common.rx_start);
192
193 rx_mapping = pci_map_single(priv->pdev, eeprom,
194 0x2010, PCI_DMA_FROMDEVICE);
195 tx_mapping = pci_map_single(priv->pdev, (void *)hdr,
196 EEPROM_READBACK_LEN, PCI_DMA_TODEVICE);
197
198 ring_control->rx_mgmt[0].host_addr = cpu_to_le32(rx_mapping);
199 ring_control->rx_mgmt[0].len = cpu_to_le16(0x2010);
200 ring_control->tx_data[0].host_addr = cpu_to_le32(tx_mapping);
201 ring_control->tx_data[0].device_addr = hdr->req_id;
202 ring_control->tx_data[0].len = cpu_to_le16(EEPROM_READBACK_LEN);
203
204 ring_control->host_idx[2] = cpu_to_le32(1);
205 ring_control->host_idx[1] = cpu_to_le32(1);
206
207 wmb();
208 mdelay(100);
209 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
210
211 wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ);
212 wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ);
213
214 pci_unmap_single(priv->pdev, tx_mapping,
215 EEPROM_READBACK_LEN, PCI_DMA_TODEVICE);
216 pci_unmap_single(priv->pdev, rx_mapping,
217 0x2010, PCI_DMA_FROMDEVICE);
218
219 alen = le16_to_cpu(ring_control->rx_mgmt[0].len);
220 if (le32_to_cpu(ring_control->device_idx[2]) != 1 ||
221 alen < 0x10) {
222 printk(KERN_ERR "%s (prism54pci): Cannot read eeprom!\n",
223 pci_name(priv->pdev));
224 err = -EINVAL;
225 goto out;
226 }
227
228 p54_parse_eeprom(dev, (u8 *)eeprom + 0x10, alen - 0x10);
229
230 out:
231 kfree(eeprom);
232 P54P_WRITE(int_enable, cpu_to_le32(0));
233 P54P_READ(int_enable);
234 udelay(10);
235 free_irq(priv->pdev->irq, priv);
236 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
237 return err;
238}
239
240static void p54p_refill_rx_ring(struct ieee80211_hw *dev)
241{
242 struct p54p_priv *priv = dev->priv;
243 struct p54p_ring_control *ring_control = priv->ring_control;
244 u32 limit, host_idx, idx;
245
246 host_idx = le32_to_cpu(ring_control->host_idx[0]);
247 limit = host_idx;
248 limit -= le32_to_cpu(ring_control->device_idx[0]);
249 limit = ARRAY_SIZE(ring_control->rx_data) - limit;
250
251 idx = host_idx % ARRAY_SIZE(ring_control->rx_data);
252 while (limit-- > 1) {
253 struct p54p_desc *desc = &ring_control->rx_data[idx];
254
255 if (!desc->host_addr) {
256 struct sk_buff *skb;
257 dma_addr_t mapping;
258 skb = dev_alloc_skb(MAX_RX_SIZE);
259 if (!skb)
260 break;
261
262 mapping = pci_map_single(priv->pdev,
263 skb_tail_pointer(skb),
264 MAX_RX_SIZE,
265 PCI_DMA_FROMDEVICE);
266 desc->host_addr = cpu_to_le32(mapping);
267 desc->device_addr = 0; // FIXME: necessary?
268 desc->len = cpu_to_le16(MAX_RX_SIZE);
269 desc->flags = 0;
270 priv->rx_buf[idx] = skb;
271 }
272
273 idx++;
274 host_idx++;
275 idx %= ARRAY_SIZE(ring_control->rx_data);
276 }
277
278 wmb();
279 ring_control->host_idx[0] = cpu_to_le32(host_idx);
280}
281
282static irqreturn_t p54p_interrupt(int irq, void *dev_id)
283{
284 struct ieee80211_hw *dev = dev_id;
285 struct p54p_priv *priv = dev->priv;
286 struct p54p_ring_control *ring_control = priv->ring_control;
287 __le32 reg;
288
289 spin_lock(&priv->lock);
290 reg = P54P_READ(int_ident);
291 if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) {
292 spin_unlock(&priv->lock);
293 return IRQ_HANDLED;
294 }
295
296 P54P_WRITE(int_ack, reg);
297
298 reg &= P54P_READ(int_enable);
299
300 if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)) {
301 struct p54p_desc *desc;
302 u32 idx, i;
303 i = priv->tx_idx;
304 i %= ARRAY_SIZE(ring_control->tx_data);
305 priv->tx_idx = idx = le32_to_cpu(ring_control->device_idx[1]);
306 idx %= ARRAY_SIZE(ring_control->tx_data);
307
308 while (i != idx) {
309 desc = &ring_control->tx_data[i];
310 if (priv->tx_buf[i]) {
311 kfree(priv->tx_buf[i]);
312 priv->tx_buf[i] = NULL;
313 }
314
315 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
316 le16_to_cpu(desc->len), PCI_DMA_TODEVICE);
317
318 desc->host_addr = 0;
319 desc->device_addr = 0;
320 desc->len = 0;
321 desc->flags = 0;
322
323 i++;
324 i %= ARRAY_SIZE(ring_control->tx_data);
325 }
326
327 i = priv->rx_idx;
328 i %= ARRAY_SIZE(ring_control->rx_data);
329 priv->rx_idx = idx = le32_to_cpu(ring_control->device_idx[0]);
330 idx %= ARRAY_SIZE(ring_control->rx_data);
331 while (i != idx) {
332 u16 len;
333 struct sk_buff *skb;
334 desc = &ring_control->rx_data[i];
335 len = le16_to_cpu(desc->len);
336 skb = priv->rx_buf[i];
337
338 skb_put(skb, len);
339
340 if (p54_rx(dev, skb)) {
341 pci_unmap_single(priv->pdev,
342 le32_to_cpu(desc->host_addr),
343 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
344
345 priv->rx_buf[i] = NULL;
346 desc->host_addr = 0;
347 } else {
348 skb_trim(skb, 0);
349 desc->len = cpu_to_le16(MAX_RX_SIZE);
350 }
351
352 i++;
353 i %= ARRAY_SIZE(ring_control->rx_data);
354 }
355
356 p54p_refill_rx_ring(dev);
357
358 wmb();
359 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
360 } else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT))
361 complete(&priv->boot_comp);
362
363 spin_unlock(&priv->lock);
364
365 return reg ? IRQ_HANDLED : IRQ_NONE;
366}
367
368static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data,
369 size_t len, int free_on_tx)
370{
371 struct p54p_priv *priv = dev->priv;
372 struct p54p_ring_control *ring_control = priv->ring_control;
373 unsigned long flags;
374 struct p54p_desc *desc;
375 dma_addr_t mapping;
376 u32 device_idx, idx, i;
377
378 spin_lock_irqsave(&priv->lock, flags);
379
380 device_idx = le32_to_cpu(ring_control->device_idx[1]);
381 idx = le32_to_cpu(ring_control->host_idx[1]);
382 i = idx % ARRAY_SIZE(ring_control->tx_data);
383
384 mapping = pci_map_single(priv->pdev, data, len, PCI_DMA_TODEVICE);
385 desc = &ring_control->tx_data[i];
386 desc->host_addr = cpu_to_le32(mapping);
387 desc->device_addr = data->req_id;
388 desc->len = cpu_to_le16(len);
389 desc->flags = 0;
390
391 wmb();
392 ring_control->host_idx[1] = cpu_to_le32(idx + 1);
393
394 if (free_on_tx)
395 priv->tx_buf[i] = data;
396
397 spin_unlock_irqrestore(&priv->lock, flags);
398
399 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
400 P54P_READ(dev_int);
401
402 /* FIXME: unlikely to happen because the device usually runs out of
403 memory before we fill the ring up, but we can make it impossible */
404 if (idx - device_idx > ARRAY_SIZE(ring_control->tx_data) - 2)
405 printk(KERN_INFO "%s: tx overflow.\n", wiphy_name(dev->wiphy));
406}
407
408static int p54p_open(struct ieee80211_hw *dev)
409{
410 struct p54p_priv *priv = dev->priv;
411 int err;
412
413 init_completion(&priv->boot_comp);
414 err = request_irq(priv->pdev->irq, &p54p_interrupt,
415 IRQF_SHARED, "prism54pci", dev);
416 if (err) {
417 printk(KERN_ERR "%s: failed to register IRQ handler\n",
418 wiphy_name(dev->wiphy));
419 return err;
420 }
421
422 memset(priv->ring_control, 0, sizeof(*priv->ring_control));
423 priv->rx_idx = priv->tx_idx = 0;
424 p54p_refill_rx_ring(dev);
425
426 p54p_upload_firmware(dev);
427
428 P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma));
429 P54P_READ(ring_control_base);
430 wmb();
431 udelay(10);
432
433 P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_INIT));
434 P54P_READ(int_enable);
435 wmb();
436 udelay(10);
437
438 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
439 P54P_READ(dev_int);
440
441 if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) {
442 printk(KERN_ERR "%s: Cannot boot firmware!\n",
443 wiphy_name(dev->wiphy));
444 free_irq(priv->pdev->irq, dev);
445 return -ETIMEDOUT;
446 }
447
448 P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_UPDATE));
449 P54P_READ(int_enable);
450 wmb();
451 udelay(10);
452
453 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE));
454 P54P_READ(dev_int);
455 wmb();
456 udelay(10);
457
458 return 0;
459}
460
461static void p54p_stop(struct ieee80211_hw *dev)
462{
463 struct p54p_priv *priv = dev->priv;
464 struct p54p_ring_control *ring_control = priv->ring_control;
465 unsigned int i;
466 struct p54p_desc *desc;
467
468 P54P_WRITE(int_enable, cpu_to_le32(0));
469 P54P_READ(int_enable);
470 udelay(10);
471
472 free_irq(priv->pdev->irq, dev);
473
474 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
475
476 for (i = 0; i < ARRAY_SIZE(priv->rx_buf); i++) {
477 desc = &ring_control->rx_data[i];
478 if (desc->host_addr)
479 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
480 MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
481 kfree_skb(priv->rx_buf[i]);
482 priv->rx_buf[i] = NULL;
483 }
484
485 for (i = 0; i < ARRAY_SIZE(priv->tx_buf); i++) {
486 desc = &ring_control->tx_data[i];
487 if (desc->host_addr)
488 pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
489 le16_to_cpu(desc->len), PCI_DMA_TODEVICE);
490
491 kfree(priv->tx_buf[i]);
492 priv->tx_buf[i] = NULL;
493 }
494
495 memset(ring_control, 0, sizeof(ring_control));
496}
497
498static int __devinit p54p_probe(struct pci_dev *pdev,
499 const struct pci_device_id *id)
500{
501 struct p54p_priv *priv;
502 struct ieee80211_hw *dev;
503 unsigned long mem_addr, mem_len;
504 int err;
505 DECLARE_MAC_BUF(mac);
506
507 err = pci_enable_device(pdev);
508 if (err) {
509 printk(KERN_ERR "%s (prism54pci): Cannot enable new PCI device\n",
510 pci_name(pdev));
511 return err;
512 }
513
514 mem_addr = pci_resource_start(pdev, 0);
515 mem_len = pci_resource_len(pdev, 0);
516 if (mem_len < sizeof(struct p54p_csr)) {
517 printk(KERN_ERR "%s (prism54pci): Too short PCI resources\n",
518 pci_name(pdev));
519 pci_disable_device(pdev);
520 return err;
521 }
522
523 err = pci_request_regions(pdev, "prism54pci");
524 if (err) {
525 printk(KERN_ERR "%s (prism54pci): Cannot obtain PCI resources\n",
526 pci_name(pdev));
527 return err;
528 }
529
530 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
531 pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
532 printk(KERN_ERR "%s (prism54pci): No suitable DMA available\n",
533 pci_name(pdev));
534 goto err_free_reg;
535 }
536
537 pci_set_master(pdev);
538 pci_try_set_mwi(pdev);
539
540 pci_write_config_byte(pdev, 0x40, 0);
541 pci_write_config_byte(pdev, 0x41, 0);
542
543 dev = p54_init_common(sizeof(*priv));
544 if (!dev) {
545 printk(KERN_ERR "%s (prism54pci): ieee80211 alloc failed\n",
546 pci_name(pdev));
547 err = -ENOMEM;
548 goto err_free_reg;
549 }
550
551 priv = dev->priv;
552 priv->pdev = pdev;
553
554 SET_IEEE80211_DEV(dev, &pdev->dev);
555 pci_set_drvdata(pdev, dev);
556
557 priv->map = ioremap(mem_addr, mem_len);
558 if (!priv->map) {
559 printk(KERN_ERR "%s (prism54pci): Cannot map device memory\n",
560 pci_name(pdev));
561 err = -EINVAL; // TODO: use a better error code?
562 goto err_free_dev;
563 }
564
565 priv->ring_control = pci_alloc_consistent(pdev, sizeof(*priv->ring_control),
566 &priv->ring_control_dma);
567 if (!priv->ring_control) {
568 printk(KERN_ERR "%s (prism54pci): Cannot allocate rings\n",
569 pci_name(pdev));
570 err = -ENOMEM;
571 goto err_iounmap;
572 }
573 memset(priv->ring_control, 0, sizeof(*priv->ring_control));
574
575 err = p54p_upload_firmware(dev);
576 if (err)
577 goto err_free_desc;
578
579 err = p54p_read_eeprom(dev);
580 if (err)
581 goto err_free_desc;
582
583 priv->common.open = p54p_open;
584 priv->common.stop = p54p_stop;
585 priv->common.tx = p54p_tx;
586
587 spin_lock_init(&priv->lock);
588
589 err = ieee80211_register_hw(dev);
590 if (err) {
591 printk(KERN_ERR "%s (prism54pci): Cannot register netdevice\n",
592 pci_name(pdev));
593 goto err_free_common;
594 }
595
596 printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n",
597 wiphy_name(dev->wiphy),
598 print_mac(mac, dev->wiphy->perm_addr),
599 priv->common.version);
600
601 return 0;
602
603 err_free_common:
604 p54_free_common(dev);
605
606 err_free_desc:
607 pci_free_consistent(pdev, sizeof(*priv->ring_control),
608 priv->ring_control, priv->ring_control_dma);
609
610 err_iounmap:
611 iounmap(priv->map);
612
613 err_free_dev:
614 pci_set_drvdata(pdev, NULL);
615 ieee80211_free_hw(dev);
616
617 err_free_reg:
618 pci_release_regions(pdev);
619 pci_disable_device(pdev);
620 return err;
621}
622
623static void __devexit p54p_remove(struct pci_dev *pdev)
624{
625 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
626 struct p54p_priv *priv;
627
628 if (!dev)
629 return;
630
631 ieee80211_unregister_hw(dev);
632 priv = dev->priv;
633 pci_free_consistent(pdev, sizeof(*priv->ring_control),
634 priv->ring_control, priv->ring_control_dma);
635 p54_free_common(dev);
636 iounmap(priv->map);
637 pci_release_regions(pdev);
638 pci_disable_device(pdev);
639 ieee80211_free_hw(dev);
640}
641
642#ifdef CONFIG_PM
643static int p54p_suspend(struct pci_dev *pdev, pm_message_t state)
644{
645 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
646 struct p54p_priv *priv = dev->priv;
647
648 if (priv->common.mode != IEEE80211_IF_TYPE_INVALID) {
649 ieee80211_stop_queues(dev);
650 p54p_stop(dev);
651 }
652
653 pci_save_state(pdev);
654 pci_set_power_state(pdev, pci_choose_state(pdev, state));
655 return 0;
656}
657
658static int p54p_resume(struct pci_dev *pdev)
659{
660 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
661 struct p54p_priv *priv = dev->priv;
662
663 pci_set_power_state(pdev, PCI_D0);
664 pci_restore_state(pdev);
665
666 if (priv->common.mode != IEEE80211_IF_TYPE_INVALID) {
667 p54p_open(dev);
668 ieee80211_start_queues(dev);
669 }
670
671 return 0;
672}
673#endif /* CONFIG_PM */
674
675static struct pci_driver p54p_driver = {
676 .name = "prism54pci",
677 .id_table = p54p_table,
678 .probe = p54p_probe,
679 .remove = __devexit_p(p54p_remove),
680#ifdef CONFIG_PM
681 .suspend = p54p_suspend,
682 .resume = p54p_resume,
683#endif /* CONFIG_PM */
684};
685
686static int __init p54p_init(void)
687{
688 return pci_register_driver(&p54p_driver);
689}
690
691static void __exit p54p_exit(void)
692{
693 pci_unregister_driver(&p54p_driver);
694}
695
696module_init(p54p_init);
697module_exit(p54p_exit);
diff --git a/drivers/net/wireless/p54/p54pci.h b/drivers/net/wireless/p54/p54pci.h
new file mode 100644
index 000000000000..5bedd7af385d
--- /dev/null
+++ b/drivers/net/wireless/p54/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) (__force __le32)__raw_readl(&priv->map->r)
89#define P54P_WRITE(r, val) __raw_writel((__force u32)(__le32)(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/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
new file mode 100644
index 000000000000..98ddbb3b3273
--- /dev/null
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -0,0 +1,910 @@
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(0x083a, 0x5501)}, /* Phillips CPWUA054 */
39 {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */
40 {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
41 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
42 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
43 {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
44 {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
45 {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */
46 {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */
47 {USB_DEVICE(0x2001, 0x3703)}, /* DLink DWL-G122 */
48 {USB_DEVICE(0x5041, 0x2234)}, /* Linksys WUSB54G */
49 {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */
50
51 /* Version 2 devices (3887) */
52 {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */
53 {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */
54 {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */
55 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
56 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
57 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
58 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */
59 {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */
60 {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/
61 {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/
62 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */
63 {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
64 {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
65 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
66 {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */
67 {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */
68 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
69 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
70 {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
71 {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
72 {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */
73 {}
74};
75
76MODULE_DEVICE_TABLE(usb, p54u_table);
77
78static void p54u_rx_cb(struct urb *urb)
79{
80 struct sk_buff *skb = (struct sk_buff *) urb->context;
81 struct p54u_rx_info *info = (struct p54u_rx_info *)skb->cb;
82 struct ieee80211_hw *dev = info->dev;
83 struct p54u_priv *priv = dev->priv;
84
85 if (unlikely(urb->status)) {
86 info->urb = NULL;
87 usb_free_urb(urb);
88 return;
89 }
90
91 skb_unlink(skb, &priv->rx_queue);
92 skb_put(skb, urb->actual_length);
93 if (!priv->hw_type)
94 skb_pull(skb, sizeof(struct net2280_tx_hdr));
95
96 if (p54_rx(dev, skb)) {
97 skb = dev_alloc_skb(MAX_RX_SIZE);
98 if (unlikely(!skb)) {
99 usb_free_urb(urb);
100 /* TODO check rx queue length and refill *somewhere* */
101 return;
102 }
103
104 info = (struct p54u_rx_info *) skb->cb;
105 info->urb = urb;
106 info->dev = dev;
107 urb->transfer_buffer = skb_tail_pointer(skb);
108 urb->context = skb;
109 skb_queue_tail(&priv->rx_queue, skb);
110 } else {
111 skb_trim(skb, 0);
112 skb_queue_tail(&priv->rx_queue, skb);
113 }
114
115 usb_submit_urb(urb, GFP_ATOMIC);
116}
117
118static void p54u_tx_cb(struct urb *urb)
119{
120 usb_free_urb(urb);
121}
122
123static void p54u_tx_free_cb(struct urb *urb)
124{
125 kfree(urb->transfer_buffer);
126 usb_free_urb(urb);
127}
128
129static int p54u_init_urbs(struct ieee80211_hw *dev)
130{
131 struct p54u_priv *priv = dev->priv;
132 struct urb *entry;
133 struct sk_buff *skb;
134 struct p54u_rx_info *info;
135
136 while (skb_queue_len(&priv->rx_queue) < 32) {
137 skb = __dev_alloc_skb(MAX_RX_SIZE, GFP_KERNEL);
138 if (!skb)
139 break;
140 entry = usb_alloc_urb(0, GFP_KERNEL);
141 if (!entry) {
142 kfree_skb(skb);
143 break;
144 }
145 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);
146 info = (struct p54u_rx_info *) skb->cb;
147 info->urb = entry;
148 info->dev = dev;
149 skb_queue_tail(&priv->rx_queue, skb);
150 usb_submit_urb(entry, GFP_KERNEL);
151 }
152
153 return 0;
154}
155
156static void p54u_free_urbs(struct ieee80211_hw *dev)
157{
158 struct p54u_priv *priv = dev->priv;
159 struct p54u_rx_info *info;
160 struct sk_buff *skb;
161
162 while ((skb = skb_dequeue(&priv->rx_queue))) {
163 info = (struct p54u_rx_info *) skb->cb;
164 if (!info->urb)
165 continue;
166
167 usb_kill_urb(info->urb);
168 kfree_skb(skb);
169 }
170}
171
172static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data,
173 size_t len, int free_on_tx)
174{
175 struct p54u_priv *priv = dev->priv;
176 struct urb *addr_urb, *data_urb;
177
178 addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
179 if (!addr_urb)
180 return;
181
182 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
183 if (!data_urb) {
184 usb_free_urb(addr_urb);
185 return;
186 }
187
188 usb_fill_bulk_urb(addr_urb, priv->udev,
189 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), &data->req_id,
190 sizeof(data->req_id), p54u_tx_cb, dev);
191 usb_fill_bulk_urb(data_urb, priv->udev,
192 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), data, len,
193 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
194
195 usb_submit_urb(addr_urb, GFP_ATOMIC);
196 usb_submit_urb(data_urb, GFP_ATOMIC);
197}
198
199static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data,
200 size_t len, int free_on_tx)
201{
202 struct p54u_priv *priv = dev->priv;
203 struct urb *int_urb, *data_urb;
204 struct net2280_tx_hdr *hdr;
205 struct net2280_reg_write *reg;
206
207 reg = kmalloc(sizeof(*reg), GFP_ATOMIC);
208 if (!reg)
209 return;
210
211 int_urb = usb_alloc_urb(0, GFP_ATOMIC);
212 if (!int_urb) {
213 kfree(reg);
214 return;
215 }
216
217 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
218 if (!data_urb) {
219 kfree(reg);
220 usb_free_urb(int_urb);
221 return;
222 }
223
224 reg->port = cpu_to_le16(NET2280_DEV_U32);
225 reg->addr = cpu_to_le32(P54U_DEV_BASE);
226 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
227
228 len += sizeof(*data);
229 hdr = (void *)data - sizeof(*hdr);
230 memset(hdr, 0, sizeof(*hdr));
231 hdr->device_addr = data->req_id;
232 hdr->len = cpu_to_le16(len);
233
234 usb_fill_bulk_urb(int_urb, priv->udev,
235 usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg),
236 p54u_tx_free_cb, dev);
237 usb_submit_urb(int_urb, GFP_ATOMIC);
238
239 usb_fill_bulk_urb(data_urb, priv->udev,
240 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, len + sizeof(*hdr),
241 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev);
242 usb_submit_urb(data_urb, GFP_ATOMIC);
243}
244
245static int p54u_write(struct p54u_priv *priv,
246 struct net2280_reg_write *buf,
247 enum net2280_op_type type,
248 __le32 addr, __le32 val)
249{
250 unsigned int ep;
251 int alen;
252
253 if (type & 0x0800)
254 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV);
255 else
256 ep = usb_sndbulkpipe(priv->udev, P54U_PIPE_BRG);
257
258 buf->port = cpu_to_le16(type);
259 buf->addr = addr;
260 buf->val = val;
261
262 return usb_bulk_msg(priv->udev, ep, buf, sizeof(*buf), &alen, 1000);
263}
264
265static int p54u_read(struct p54u_priv *priv, void *buf,
266 enum net2280_op_type type,
267 __le32 addr, __le32 *val)
268{
269 struct net2280_reg_read *read = buf;
270 __le32 *reg = buf;
271 unsigned int ep;
272 int alen, err;
273
274 if (type & 0x0800)
275 ep = P54U_PIPE_DEV;
276 else
277 ep = P54U_PIPE_BRG;
278
279 read->port = cpu_to_le16(type);
280 read->addr = addr;
281
282 err = usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
283 read, sizeof(*read), &alen, 1000);
284 if (err)
285 return err;
286
287 err = usb_bulk_msg(priv->udev, usb_rcvbulkpipe(priv->udev, ep),
288 reg, sizeof(*reg), &alen, 1000);
289 if (err)
290 return err;
291
292 *val = *reg;
293 return 0;
294}
295
296static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
297 void *data, size_t len)
298{
299 int alen;
300 return usb_bulk_msg(priv->udev, usb_sndbulkpipe(priv->udev, ep),
301 data, len, &alen, 2000);
302}
303
304static int p54u_read_eeprom(struct ieee80211_hw *dev)
305{
306 struct p54u_priv *priv = dev->priv;
307 void *buf;
308 struct p54_control_hdr *hdr;
309 int err, alen;
310 size_t offset = priv->hw_type ? 0x10 : 0x20;
311
312 buf = kmalloc(0x2020, GFP_KERNEL);
313 if (!buf) {
314 printk(KERN_ERR "prism54usb: cannot allocate memory for "
315 "eeprom readback!\n");
316 return -ENOMEM;
317 }
318
319 if (priv->hw_type) {
320 *((u32 *) buf) = priv->common.rx_start;
321 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
322 if (err) {
323 printk(KERN_ERR "prism54usb: addr send failed\n");
324 goto fail;
325 }
326 } else {
327 struct net2280_reg_write *reg = buf;
328 reg->port = cpu_to_le16(NET2280_DEV_U32);
329 reg->addr = cpu_to_le32(P54U_DEV_BASE);
330 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
331 err = p54u_bulk_msg(priv, P54U_PIPE_DEV, buf, sizeof(*reg));
332 if (err) {
333 printk(KERN_ERR "prism54usb: dev_int send failed\n");
334 goto fail;
335 }
336 }
337
338 hdr = buf + priv->common.tx_hdr_len;
339 p54_fill_eeprom_readback(hdr);
340 hdr->req_id = cpu_to_le32(priv->common.rx_start);
341 if (priv->common.tx_hdr_len) {
342 struct net2280_tx_hdr *tx_hdr = buf;
343 tx_hdr->device_addr = hdr->req_id;
344 tx_hdr->len = cpu_to_le16(EEPROM_READBACK_LEN);
345 }
346
347 /* we can just pretend to send 0x2000 bytes of nothing in the headers */
348 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf,
349 EEPROM_READBACK_LEN + priv->common.tx_hdr_len);
350 if (err) {
351 printk(KERN_ERR "prism54usb: eeprom req send failed\n");
352 goto fail;
353 }
354
355 err = usb_bulk_msg(priv->udev,
356 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA),
357 buf, 0x2020, &alen, 1000);
358 if (!err && alen > offset) {
359 p54_parse_eeprom(dev, (u8 *)buf + offset, alen - offset);
360 } else {
361 printk(KERN_ERR "prism54usb: eeprom read failed!\n");
362 err = -EINVAL;
363 goto fail;
364 }
365
366 fail:
367 kfree(buf);
368 return err;
369}
370
371static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
372{
373 static char start_string[] = "~~~~<\r";
374 struct p54u_priv *priv = dev->priv;
375 const struct firmware *fw_entry = NULL;
376 int err, alen;
377 u8 carry = 0;
378 u8 *buf, *tmp, *data;
379 unsigned int left, remains, block_size;
380 struct x2_header *hdr;
381 unsigned long timeout;
382
383 tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
384 if (!buf) {
385 printk(KERN_ERR "p54usb: cannot allocate firmware upload buffer!\n");
386 err = -ENOMEM;
387 goto err_bufalloc;
388 }
389
390 memcpy(buf, start_string, 4);
391 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 4);
392 if (err) {
393 printk(KERN_ERR "p54usb: reset failed! (%d)\n", err);
394 goto err_reset;
395 }
396
397 err = request_firmware(&fw_entry, "isl3887usb_bare", &priv->udev->dev);
398 if (err) {
399 printk(KERN_ERR "p54usb: cannot find firmware (isl3887usb_bare)!\n");
400 goto err_req_fw_failed;
401 }
402
403 p54_parse_firmware(dev, fw_entry);
404
405 left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
406 strcpy(buf, start_string);
407 left -= strlen(start_string);
408 tmp += strlen(start_string);
409
410 data = fw_entry->data;
411 remains = fw_entry->size;
412
413 hdr = (struct x2_header *)(buf + strlen(start_string));
414 memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
415 hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
416 hdr->fw_length = cpu_to_le32(fw_entry->size);
417 hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
418 sizeof(u32)*2));
419 left -= sizeof(*hdr);
420 tmp += sizeof(*hdr);
421
422 while (remains) {
423 while (left--) {
424 if (carry) {
425 *tmp++ = carry;
426 carry = 0;
427 remains--;
428 continue;
429 }
430 switch (*data) {
431 case '~':
432 *tmp++ = '}';
433 carry = '^';
434 break;
435 case '}':
436 *tmp++ = '}';
437 carry = ']';
438 break;
439 default:
440 *tmp++ = *data;
441 remains--;
442 break;
443 }
444 data++;
445 }
446
447 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_size);
448 if (err) {
449 printk(KERN_ERR "prism54usb: firmware upload failed!\n");
450 goto err_upload_failed;
451 }
452
453 tmp = buf;
454 left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
455 }
456
457 *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size));
458 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
459 if (err) {
460 printk(KERN_ERR "prism54usb: firmware upload failed!\n");
461 goto err_upload_failed;
462 }
463
464 timeout = jiffies + msecs_to_jiffies(1000);
465 while (!(err = usb_bulk_msg(priv->udev,
466 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
467 if (alen > 2 && !memcmp(buf, "OK", 2))
468 break;
469
470 if (alen > 5 && !memcmp(buf, "ERROR", 5)) {
471 printk(KERN_INFO "prism54usb: firmware upload failed!\n");
472 err = -EINVAL;
473 break;
474 }
475
476 if (time_after(jiffies, timeout)) {
477 printk(KERN_ERR "prism54usb: firmware boot timed out!\n");
478 err = -ETIMEDOUT;
479 break;
480 }
481 }
482 if (err)
483 goto err_upload_failed;
484
485 buf[0] = 'g';
486 buf[1] = '\r';
487 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, 2);
488 if (err) {
489 printk(KERN_ERR "prism54usb: firmware boot failed!\n");
490 goto err_upload_failed;
491 }
492
493 timeout = jiffies + msecs_to_jiffies(1000);
494 while (!(err = usb_bulk_msg(priv->udev,
495 usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), buf, 128, &alen, 1000))) {
496 if (alen > 0 && buf[0] == 'g')
497 break;
498
499 if (time_after(jiffies, timeout)) {
500 err = -ETIMEDOUT;
501 break;
502 }
503 }
504 if (err)
505 goto err_upload_failed;
506
507 err_upload_failed:
508 release_firmware(fw_entry);
509 err_req_fw_failed:
510 err_reset:
511 kfree(buf);
512 err_bufalloc:
513 return err;
514}
515
516static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
517{
518 struct p54u_priv *priv = dev->priv;
519 const struct firmware *fw_entry = NULL;
520 const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
521 int err, alen;
522 void *buf;
523 __le32 reg;
524 unsigned int remains, offset;
525 u8 *data;
526
527 buf = kmalloc(512, GFP_KERNEL);
528 if (!buf) {
529 printk(KERN_ERR "p54usb: firmware buffer alloc failed!\n");
530 return -ENOMEM;
531 }
532
533 err = request_firmware(&fw_entry, "isl3890usb", &priv->udev->dev);
534 if (err) {
535 printk(KERN_ERR "p54usb: cannot find firmware (isl3890usb)!\n");
536 kfree(buf);
537 return err;
538 }
539
540 p54_parse_firmware(dev, fw_entry);
541
542#define P54U_WRITE(type, addr, data) \
543 do {\
544 err = p54u_write(priv, buf, type,\
545 cpu_to_le32((u32)(unsigned long)addr), data);\
546 if (err) \
547 goto fail;\
548 } while (0)
549
550#define P54U_READ(type, addr) \
551 do {\
552 err = p54u_read(priv, buf, type,\
553 cpu_to_le32((u32)(unsigned long)addr), &reg);\
554 if (err)\
555 goto fail;\
556 } while (0)
557
558 /* power down net2280 bridge */
559 P54U_READ(NET2280_BRG_U32, NET2280_GPIOCTL);
560 reg |= cpu_to_le32(P54U_BRG_POWER_DOWN);
561 reg &= cpu_to_le32(~P54U_BRG_POWER_UP);
562 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
563
564 mdelay(100);
565
566 /* power up bridge */
567 reg |= cpu_to_le32(P54U_BRG_POWER_UP);
568 reg &= cpu_to_le32(~P54U_BRG_POWER_DOWN);
569 P54U_WRITE(NET2280_BRG_U32, NET2280_GPIOCTL, reg);
570
571 mdelay(100);
572
573 P54U_WRITE(NET2280_BRG_U32, NET2280_DEVINIT,
574 cpu_to_le32(NET2280_CLK_30Mhz |
575 NET2280_PCI_ENABLE |
576 NET2280_PCI_SOFT_RESET));
577
578 mdelay(20);
579
580 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_COMMAND,
581 cpu_to_le32(PCI_COMMAND_MEMORY |
582 PCI_COMMAND_MASTER));
583
584 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_0,
585 cpu_to_le32(NET2280_BASE));
586
587 P54U_READ(NET2280_BRG_CFG_U16, PCI_STATUS);
588 reg |= cpu_to_le32(PCI_STATUS_REC_MASTER_ABORT);
589 P54U_WRITE(NET2280_BRG_CFG_U16, PCI_STATUS, reg);
590
591 // TODO: we really need this?
592 P54U_READ(NET2280_BRG_U32, NET2280_RELNUM);
593
594 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_RSP,
595 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
596 P54U_WRITE(NET2280_BRG_U32, NET2280_EPC_RSP,
597 cpu_to_le32(NET2280_CLEAR_NAK_OUT_PACKETS_MODE));
598
599 P54U_WRITE(NET2280_BRG_CFG_U32, PCI_BASE_ADDRESS_2,
600 cpu_to_le32(NET2280_BASE2));
601
602 /* finally done setting up the bridge */
603
604 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | PCI_COMMAND,
605 cpu_to_le32(PCI_COMMAND_MEMORY |
606 PCI_COMMAND_MASTER));
607
608 P54U_WRITE(NET2280_DEV_CFG_U16, 0x10000 | 0x40 /* TRDY timeout */, 0);
609 P54U_WRITE(NET2280_DEV_CFG_U32, 0x10000 | PCI_BASE_ADDRESS_0,
610 cpu_to_le32(P54U_DEV_BASE));
611
612 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
613 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
614 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
615
616 /* do romboot */
617 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable, 0);
618
619 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
620 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
621 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RAMBOOT);
622 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
623 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
624
625 mdelay(20);
626
627 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
628 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
629
630 mdelay(20);
631
632 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
633 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
634
635 mdelay(100);
636
637 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
638 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
639
640 /* finally, we can upload firmware now! */
641 remains = fw_entry->size;
642 data = fw_entry->data;
643 offset = ISL38XX_DEV_FIRMWARE_ADDR;
644
645 while (remains) {
646 unsigned int block_len = min(remains, (unsigned int)512);
647 memcpy(buf, data, block_len);
648
649 err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, block_len);
650 if (err) {
651 printk(KERN_ERR "prism54usb: firmware block upload "
652 "failed\n");
653 goto fail;
654 }
655
656 P54U_WRITE(NET2280_DEV_U32, &devreg->direct_mem_base,
657 cpu_to_le32(0xc0000f00));
658
659 P54U_WRITE(NET2280_DEV_U32,
660 0x0020 | (unsigned long)&devreg->direct_mem_win, 0);
661 P54U_WRITE(NET2280_DEV_U32,
662 0x0020 | (unsigned long)&devreg->direct_mem_win,
663 cpu_to_le32(1));
664
665 P54U_WRITE(NET2280_DEV_U32,
666 0x0024 | (unsigned long)&devreg->direct_mem_win,
667 cpu_to_le32(block_len));
668 P54U_WRITE(NET2280_DEV_U32,
669 0x0028 | (unsigned long)&devreg->direct_mem_win,
670 cpu_to_le32(offset));
671
672 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_addr,
673 cpu_to_le32(NET2280_EPA_FIFO_PCI_ADDR));
674 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_len,
675 cpu_to_le32(block_len >> 2));
676 P54U_WRITE(NET2280_DEV_U32, &devreg->dma_ctrl,
677 cpu_to_le32(ISL38XX_DMA_MASTER_CONTROL_TRIGGER));
678
679 mdelay(10);
680
681 P54U_READ(NET2280_DEV_U32,
682 0x002C | (unsigned long)&devreg->direct_mem_win);
683 if (!(reg & cpu_to_le32(ISL38XX_DMA_STATUS_DONE)) ||
684 !(reg & cpu_to_le32(ISL38XX_DMA_STATUS_READY))) {
685 printk(KERN_ERR "prism54usb: firmware DMA transfer "
686 "failed\n");
687 goto fail;
688 }
689
690 P54U_WRITE(NET2280_BRG_U32, NET2280_EPA_STAT,
691 cpu_to_le32(NET2280_FIFO_FLUSH));
692
693 remains -= block_len;
694 data += block_len;
695 offset += block_len;
696 }
697
698 /* do ramboot */
699 P54U_READ(NET2280_DEV_U32, &devreg->ctrl_stat);
700 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
701 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_CLKRUN);
702 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RAMBOOT);
703 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
704
705 mdelay(20);
706
707 reg |= cpu_to_le32(ISL38XX_CTRL_STAT_RESET);
708 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
709
710 reg &= cpu_to_le32(~ISL38XX_CTRL_STAT_RESET);
711 P54U_WRITE(NET2280_DEV_U32, &devreg->ctrl_stat, reg);
712
713 mdelay(100);
714
715 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
716 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
717
718 /* start up the firmware */
719 P54U_WRITE(NET2280_DEV_U32, &devreg->int_enable,
720 cpu_to_le32(ISL38XX_INT_IDENT_INIT));
721
722 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
723 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
724
725 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1,
726 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT_ENABLE |
727 NET2280_USB_INTERRUPT_ENABLE));
728
729 P54U_WRITE(NET2280_DEV_U32, &devreg->dev_int,
730 cpu_to_le32(ISL38XX_DEV_INT_RESET));
731
732 err = usb_interrupt_msg(priv->udev,
733 usb_rcvbulkpipe(priv->udev, P54U_PIPE_INT),
734 buf, sizeof(__le32), &alen, 1000);
735 if (err || alen != sizeof(__le32))
736 goto fail;
737
738 P54U_READ(NET2280_DEV_U32, &devreg->int_ident);
739 P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
740
741 if (!(reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)))
742 err = -EINVAL;
743
744 P54U_WRITE(NET2280_BRG_U32, NET2280_USBIRQENB1, 0);
745 P54U_WRITE(NET2280_BRG_U32, NET2280_IRQSTAT1,
746 cpu_to_le32(NET2280_PCI_INTA_INTERRUPT));
747
748#undef P54U_WRITE
749#undef P54U_READ
750
751 fail:
752 release_firmware(fw_entry);
753 kfree(buf);
754 return err;
755}
756
757static int p54u_open(struct ieee80211_hw *dev)
758{
759 struct p54u_priv *priv = dev->priv;
760 int err;
761
762 err = p54u_init_urbs(dev);
763 if (err) {
764 return err;
765 }
766
767 priv->common.open = p54u_init_urbs;
768
769 return 0;
770}
771
772static void p54u_stop(struct ieee80211_hw *dev)
773{
774 /* TODO: figure out how to reliably stop the 3887 and net2280 so
775 the hardware is still usable next time we want to start it.
776 until then, we just stop listening to the hardware.. */
777 p54u_free_urbs(dev);
778 return;
779}
780
781static int __devinit p54u_probe(struct usb_interface *intf,
782 const struct usb_device_id *id)
783{
784 struct usb_device *udev = interface_to_usbdev(intf);
785 struct ieee80211_hw *dev;
786 struct p54u_priv *priv;
787 int err;
788 unsigned int i, recognized_pipes;
789 DECLARE_MAC_BUF(mac);
790
791 dev = p54_init_common(sizeof(*priv));
792 if (!dev) {
793 printk(KERN_ERR "prism54usb: ieee80211 alloc failed\n");
794 return -ENOMEM;
795 }
796
797 priv = dev->priv;
798
799 SET_IEEE80211_DEV(dev, &intf->dev);
800 usb_set_intfdata(intf, dev);
801 priv->udev = udev;
802
803 usb_get_dev(udev);
804
805 /* really lazy and simple way of figuring out if we're a 3887 */
806 /* TODO: should just stick the identification in the device table */
807 i = intf->altsetting->desc.bNumEndpoints;
808 recognized_pipes = 0;
809 while (i--) {
810 switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {
811 case P54U_PIPE_DATA:
812 case P54U_PIPE_MGMT:
813 case P54U_PIPE_BRG:
814 case P54U_PIPE_DEV:
815 case P54U_PIPE_DATA | USB_DIR_IN:
816 case P54U_PIPE_MGMT | USB_DIR_IN:
817 case P54U_PIPE_BRG | USB_DIR_IN:
818 case P54U_PIPE_DEV | USB_DIR_IN:
819 case P54U_PIPE_INT | USB_DIR_IN:
820 recognized_pipes++;
821 }
822 }
823 priv->common.open = p54u_open;
824
825 if (recognized_pipes < P54U_PIPE_NUMBER) {
826 priv->hw_type = P54U_3887;
827 priv->common.tx = p54u_tx_3887;
828 } else {
829 dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
830 priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
831 priv->common.tx = p54u_tx_net2280;
832 }
833 priv->common.stop = p54u_stop;
834
835 if (priv->hw_type)
836 err = p54u_upload_firmware_3887(dev);
837 else
838 err = p54u_upload_firmware_net2280(dev);
839 if (err)
840 goto err_free_dev;
841
842 err = p54u_read_eeprom(dev);
843 if (err)
844 goto err_free_dev;
845
846 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
847 u8 perm_addr[ETH_ALEN];
848
849 printk(KERN_WARNING "prism54usb: Invalid hwaddr! Using randomly generated MAC addr\n");
850 random_ether_addr(perm_addr);
851 SET_IEEE80211_PERM_ADDR(dev, perm_addr);
852 }
853
854 skb_queue_head_init(&priv->rx_queue);
855
856 err = ieee80211_register_hw(dev);
857 if (err) {
858 printk(KERN_ERR "prism54usb: Cannot register netdevice\n");
859 goto err_free_dev;
860 }
861
862 printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n",
863 wiphy_name(dev->wiphy),
864 print_mac(mac, dev->wiphy->perm_addr),
865 priv->common.version);
866
867 return 0;
868
869 err_free_dev:
870 ieee80211_free_hw(dev);
871 usb_set_intfdata(intf, NULL);
872 usb_put_dev(udev);
873 return err;
874}
875
876static void __devexit p54u_disconnect(struct usb_interface *intf)
877{
878 struct ieee80211_hw *dev = usb_get_intfdata(intf);
879 struct p54u_priv *priv;
880
881 if (!dev)
882 return;
883
884 ieee80211_unregister_hw(dev);
885
886 priv = dev->priv;
887 usb_put_dev(interface_to_usbdev(intf));
888 p54_free_common(dev);
889 ieee80211_free_hw(dev);
890}
891
892static struct usb_driver p54u_driver = {
893 .name = "prism54usb",
894 .id_table = p54u_table,
895 .probe = p54u_probe,
896 .disconnect = p54u_disconnect,
897};
898
899static int __init p54u_init(void)
900{
901 return usb_register(&p54u_driver);
902}
903
904static void __exit p54u_exit(void)
905{
906 usb_deregister(&p54u_driver);
907}
908
909module_init(p54u_init);
910module_exit(p54u_exit);
diff --git a/drivers/net/wireless/p54/p54usb.h b/drivers/net/wireless/p54/p54usb.h
new file mode 100644
index 000000000000..d1896b396c1c
--- /dev/null
+++ b/drivers/net/wireless/p54/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 */