aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/wireless
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/Kconfig365
-rw-r--r--drivers/net/wireless/Makefile33
-rw-r--r--drivers/net/wireless/README25
-rw-r--r--drivers/net/wireless/airo.c7667
-rw-r--r--drivers/net/wireless/airo_cs.c622
-rw-r--r--drivers/net/wireless/airport.c304
-rw-r--r--drivers/net/wireless/arlan-main.c1896
-rw-r--r--drivers/net/wireless/arlan-proc.c1262
-rw-r--r--drivers/net/wireless/arlan.h541
-rw-r--r--drivers/net/wireless/atmel.c4272
-rw-r--r--drivers/net/wireless/atmel.h43
-rw-r--r--drivers/net/wireless/atmel_cs.c708
-rw-r--r--drivers/net/wireless/atmel_pci.c89
-rw-r--r--drivers/net/wireless/hermes.c554
-rw-r--r--drivers/net/wireless/hermes.h481
-rw-r--r--drivers/net/wireless/hermes_rid.h148
-rw-r--r--drivers/net/wireless/i82586.h413
-rw-r--r--drivers/net/wireless/i82593.h224
-rw-r--r--drivers/net/wireless/ieee802_11.h78
-rw-r--r--drivers/net/wireless/netwave_cs.c1736
-rw-r--r--drivers/net/wireless/orinoco.c4243
-rw-r--r--drivers/net/wireless/orinoco.h153
-rw-r--r--drivers/net/wireless/orinoco_cs.c636
-rw-r--r--drivers/net/wireless/orinoco_pci.c417
-rw-r--r--drivers/net/wireless/orinoco_plx.c419
-rw-r--r--drivers/net/wireless/orinoco_tmd.c276
-rw-r--r--drivers/net/wireless/prism54/Makefile8
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.c260
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.h173
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c2750
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.h51
-rw-r--r--drivers/net/wireless/prism54/isl_oid.h507
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c956
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.h216
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c519
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.h73
-rw-r--r--drivers/net/wireless/prism54/islpci_hotplug.c339
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.c513
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.h145
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.c907
-rw-r--r--drivers/net/wireless/prism54/oid_mgt.h59
-rw-r--r--drivers/net/wireless/prism54/prismcompat.h44
-rw-r--r--drivers/net/wireless/ray_cs.c2957
-rw-r--r--drivers/net/wireless/ray_cs.h78
-rw-r--r--drivers/net/wireless/rayctl.h732
-rw-r--r--drivers/net/wireless/strip.c2843
-rw-r--r--drivers/net/wireless/todo.txt15
-rw-r--r--drivers/net/wireless/wavelan.c4452
-rw-r--r--drivers/net/wireless/wavelan.h370
-rw-r--r--drivers/net/wireless/wavelan.p.h716
-rw-r--r--drivers/net/wireless/wavelan_cs.c4914
-rw-r--r--drivers/net/wireless/wavelan_cs.h386
-rw-r--r--drivers/net/wireless/wavelan_cs.p.h813
-rw-r--r--drivers/net/wireless/wl3501.h614
-rw-r--r--drivers/net/wireless/wl3501_cs.c2270
55 files changed, 56285 insertions, 0 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
new file mode 100644
index 000000000000..0aaa12c0c098
--- /dev/null
+++ b/drivers/net/wireless/Kconfig
@@ -0,0 +1,365 @@
1#
2# Wireless LAN device configuration
3#
4
5menu "Wireless LAN (non-hamradio)"
6 depends on NETDEVICES
7
8config NET_RADIO
9 bool "Wireless LAN drivers (non-hamradio) & Wireless Extensions"
10 ---help---
11 Support for wireless LANs and everything having to do with radio,
12 but not with amateur radio or FM broadcasting.
13
14 Saying Y here also enables the Wireless Extensions (creates
15 /proc/net/wireless and enables iwconfig access). The Wireless
16 Extension is a generic API allowing a driver to expose to the user
17 space configuration and statistics specific to common Wireless LANs.
18 The beauty of it is that a single set of tool can support all the
19 variations of Wireless LANs, regardless of their type (as long as
20 the driver supports Wireless Extension). Another advantage is that
21 these parameters may be changed on the fly without restarting the
22 driver (or Linux). If you wish to use Wireless Extensions with
23 wireless PCMCIA (PC-) cards, you need to say Y here; you can fetch
24 the tools from
25 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
26
27 Some user-level drivers for scarab devices which don't require
28 special kernel support are available from
29 <ftp://shadow.cabi.net/pub/Linux/>.
30
31# Note : the cards are obsolete (can't buy them anymore), but the drivers
32# are not, as people are still using them...
33comment "Obsolete Wireless cards support (pre-802.11)"
34 depends on NET_RADIO && (INET || ISA || PCMCIA)
35
36config STRIP
37 tristate "STRIP (Metricom starmode radio IP)"
38 depends on NET_RADIO && INET
39 ---help---
40 Say Y if you have a Metricom radio and intend to use Starmode Radio
41 IP. STRIP is a radio protocol developed for the MosquitoNet project
42 (on the WWW at <http://mosquitonet.stanford.edu/>) to send Internet
43 traffic using Metricom radios. Metricom radios are small, battery
44 powered, 100kbit/sec packet radio transceivers, about the size and
45 weight of a cellular telephone. (You may also have heard them called
46 "Metricom modems" but we avoid the term "modem" because it misleads
47 many people into thinking that you can plug a Metricom modem into a
48 phone line and use it as a modem.)
49
50 You can use STRIP on any Linux machine with a serial port, although
51 it is obviously most useful for people with laptop computers. If you
52 think you might get a Metricom radio in the future, there is no harm
53 in saying Y to STRIP now, except that it makes the kernel a bit
54 bigger.
55
56 To compile this as a module, choose M here: the module will be
57 called strip.
58
59config ARLAN
60 tristate "Aironet Arlan 655 & IC2200 DS support"
61 depends on NET_RADIO && ISA && !64BIT
62 ---help---
63 Aironet makes Arlan, a class of wireless LAN adapters. These use the
64 www.Telxon.com chip, which is also used on several similar cards.
65 This driver is tested on the 655 and IC2200 series cards. Look at
66 <http://www.ylenurme.ee/~elmer/655/> for the latest information.
67
68 The driver is built as two modules, arlan and arlan-proc. The latter
69 is the /proc interface and is not needed most of time.
70
71 On some computers the card ends up in non-valid state after some
72 time. Use a ping-reset script to clear it.
73
74config WAVELAN
75 tristate "AT&T/Lucent old WaveLAN & DEC RoamAbout DS ISA support"
76 depends on NET_RADIO && ISA
77 ---help---
78 The Lucent WaveLAN (formerly NCR and AT&T; or DEC RoamAbout DS) is
79 a Radio LAN (wireless Ethernet-like Local Area Network) using the
80 radio frequencies 900 MHz and 2.4 GHz.
81
82 This driver support the ISA version of the WaveLAN card. A separate
83 driver for the PCMCIA (PC-card) hardware is available in David
84 Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
85 for location).
86
87 If you want to use an ISA WaveLAN card under Linux, say Y and read
88 the Ethernet-HOWTO, available from
89 <http://www.tldp.org/docs.html#howto>. Some more specific
90 information is contained in
91 <file:Documentation/networking/wavelan.txt> and in the source code
92 <file:drivers/net/wavelan.p.h>.
93
94 You will also need the wireless tools package available from
95 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
96 Please read the man pages contained therein.
97
98 To compile this driver as a module, choose M here: the module will be
99 called wavelan.
100
101config PCMCIA_WAVELAN
102 tristate "AT&T/Lucent old WaveLAN Pcmcia wireless support"
103 depends on NET_RADIO && PCMCIA
104 help
105 Say Y here if you intend to attach an AT&T/Lucent Wavelan PCMCIA
106 (PC-card) wireless Ethernet networking card to your computer. This
107 driver is for the non-IEEE-802.11 Wavelan cards.
108
109 To compile this driver as a module, choose M here: the module will be
110 called wavelan_cs. If unsure, say N.
111
112config PCMCIA_NETWAVE
113 tristate "Xircom Netwave AirSurfer Pcmcia wireless support"
114 depends on NET_RADIO && PCMCIA
115 help
116 Say Y here if you intend to attach this type of PCMCIA (PC-card)
117 wireless Ethernet networking card to your computer.
118
119 To compile this driver as a module, choose M here: the module will be
120 called netwave_cs. If unsure, say N.
121
122comment "Wireless 802.11 Frequency Hopping cards support"
123 depends on NET_RADIO && PCMCIA
124
125config PCMCIA_RAYCS
126 tristate "Aviator/Raytheon 2.4MHz wireless support"
127 depends on NET_RADIO && PCMCIA
128 ---help---
129 Say Y here if you intend to attach an Aviator/Raytheon PCMCIA
130 (PC-card) wireless Ethernet networking card to your computer.
131 Please read the file <file:Documentation/networking/ray_cs.txt> for
132 details.
133
134 To compile this driver as a module, choose M here: the module will be
135 called ray_cs. If unsure, say N.
136
137comment "Wireless 802.11b ISA/PCI cards support"
138 depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA)
139
140config AIRO
141 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
142 depends on NET_RADIO && ISA && (PCI || BROKEN)
143 ---help---
144 This is the standard Linux driver to support Cisco/Aironet ISA and
145 PCI 802.11 wireless cards.
146 It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X
147 - with or without encryption) as well as card before the Cisco
148 aquisition (Aironet 4500, Aironet 4800, Aironet 4800B).
149
150 This driver support both the standard Linux Wireless Extensions
151 and Cisco proprietary API, so both the Linux Wireless Tools and the
152 Cisco Linux utilities can be used to configure the card.
153
154 The driver can be compiled as a module and will be named "airo".
155
156config HERMES
157 tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
158 depends on NET_RADIO && (PPC_PMAC || PCI || PCMCIA)
159 ---help---
160 A driver for 802.11b wireless cards based based on the "Hermes" or
161 Intersil HFA384x (Prism 2) MAC controller. This includes the vast
162 majority of the PCMCIA 802.11b cards (which are nearly all rebadges)
163 - except for the Cisco/Aironet cards. Cards supported include the
164 Apple Airport (not a PCMCIA card), WavelanIEEE/Orinoco,
165 Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya,
166 IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear
167 MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel
168 PRO/Wireless, and Symbol Spectrum24 High Rate amongst others.
169
170 This option includes the guts of the driver, but in order to
171 actually use a card you will also need to enable support for PCMCIA
172 Hermes cards, PLX9052 based PCI adaptors or the Apple Airport below.
173
174 You will also very likely also need the Wireless Tools in order to
175 configure your card and that /etc/pcmcia/wireless.opts works :
176 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
177
178config APPLE_AIRPORT
179 tristate "Apple Airport support (built-in)"
180 depends on PPC_PMAC && HERMES
181 help
182 Say Y here to support the Airport 802.11b wireless Ethernet hardware
183 built into the Macintosh iBook and other recent PowerPC-based
184 Macintosh machines. This is essentially a Lucent Orinoco card with
185 a non-standard interface
186
187config PLX_HERMES
188 tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)"
189 depends on PCI && HERMES && EXPERIMENTAL
190 help
191 Enable support for PCMCIA cards supported by the "Hermes" (aka
192 orinoco) driver when used in PLX9052 based PCI adaptors. These
193 adaptors are not a full PCMCIA controller but act as a more limited
194 PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that
195 802.11b PCMCIA cards can be used in desktop machines. The Netgear
196 MA301 is such an adaptor.
197
198 Support for these adaptors is so far still incomplete and buggy.
199 You have been warned.
200
201config TMD_HERMES
202 tristate "Hermes in TMD7160 based PCI adaptor support (EXPERIMENTAL)"
203 depends on PCI && HERMES && EXPERIMENTAL
204 help
205 Enable support for PCMCIA cards supported by the "Hermes" (aka
206 orinoco) driver when used in TMD7160 based PCI adaptors. These
207 adaptors are not a full PCMCIA controller but act as a more limited
208 PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that
209 802.11b PCMCIA cards can be used in desktop machines.
210
211 Support for these adaptors is so far still incomplete and buggy.
212 You have been warned.
213
214config PCI_HERMES
215 tristate "Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)"
216 depends on PCI && HERMES && EXPERIMENTAL
217 help
218 Enable support for PCI and mini-PCI 802.11b wireless NICs based on
219 the Prism 2.5 chipset. These are true PCI cards, not the 802.11b
220 PCMCIA cards bundled with PCI<->PCMCIA adaptors which are also
221 common. Some of the built-in wireless adaptors in laptops are of
222 this variety.
223
224config ATMEL
225 tristate "Atmel at76c50x chipset 802.11b support"
226 depends on NET_RADIO && EXPERIMENTAL
227 select FW_LOADER
228 select CRC32
229 ---help---
230 A driver 802.11b wireless cards based on the Atmel fast-vnet
231 chips. This driver supports standard Linux wireless extensions.
232
233 Many cards based on this chipset do not have flash memory
234 and need their firmware loaded at start-up. If yours is
235 one of these, you will need to provide a firmware image
236 to be loaded into the card by the driver. The Atmel
237 firmware package can be downloaded from
238 <http://www.thekelleys.org.uk/atmel>
239
240config PCI_ATMEL
241 tristate "Atmel at76c506 PCI cards"
242 depends on ATMEL && PCI
243 ---help---
244 Enable support for PCI and mini-PCI cards containing the
245 Atmel at76c506 chip.
246
247# If Pcmcia is compiled in, offer Pcmcia cards...
248comment "Wireless 802.11b Pcmcia/Cardbus cards support"
249 depends on NET_RADIO && PCMCIA
250
251config PCMCIA_HERMES
252 tristate "Hermes PCMCIA card support"
253 depends on NET_RADIO && PCMCIA && HERMES
254 ---help---
255 A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
256 as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
257 EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and
258 others). It should also be usable on various Prism II based cards
259 such as the Linksys, D-Link and Farallon Skyline. It should also
260 work on Symbol cards such as the 3Com AirConnect and Ericsson WLAN.
261
262 To use your PC-cards, you will need supporting software from David
263 Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
264 for location). You also want to check out the PCMCIA-HOWTO,
265 available from <http://www.tldp.org/docs.html#howto>.
266
267 You will also very likely also need the Wireless Tools in order to
268 configure your card and that /etc/pcmcia/wireless.opts works:
269 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
270
271config AIRO_CS
272 tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
273 depends on NET_RADIO && PCMCIA
274 ---help---
275 This is the standard Linux driver to support Cisco/Aironet PCMCIA
276 802.11 wireless cards. This driver is the same as the Aironet
277 driver part of the Linux Pcmcia package.
278 It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X
279 - with or without encryption) as well as card before the Cisco
280 aquisition (Aironet 4500, Aironet 4800, Aironet 4800B). It also
281 supports OEM of Cisco such as the DELL TrueMobile 4800 and Xircom
282 802.11b cards.
283
284 This driver support both the standard Linux Wireless Extensions
285 and Cisco proprietary API, so both the Linux Wireless Tools and the
286 Cisco Linux utilities can be used to configure the card.
287
288 To use your PC-cards, you will need supporting software from David
289 Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
290 for location). You also want to check out the PCMCIA-HOWTO,
291 available from <http://www.tldp.org/docs.html#howto>.
292
293config PCMCIA_ATMEL
294 tristate "Atmel at76c502/at76c504 PCMCIA cards"
295 depends on NET_RADIO && ATMEL && PCMCIA
296 select FW_LOADER
297 select CRC32
298 ---help---
299 Enable support for PCMCIA cards containing the
300 Atmel at76c502 and at76c504 chips.
301
302config PCMCIA_WL3501
303 tristate "Planet WL3501 PCMCIA cards"
304 depends on NET_RADIO && EXPERIMENTAL && PCMCIA
305 ---help---
306 A driver for WL3501 PCMCIA 802.11 wireless cards made by Planet.
307 It has basic support for Linux wireless extensions and initial
308 micro support for ethtool.
309
310comment "Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support"
311 depends on NET_RADIO && PCI
312config PRISM54
313 tristate 'Intersil Prism GT/Duette/Indigo PCI/Cardbus'
314 depends on PCI && NET_RADIO && EXPERIMENTAL
315 select FW_LOADER
316 ---help---
317 Enable PCI and Cardbus support for the following chipset based cards:
318
319 ISL3880 - Prism GT 802.11 b/g
320 ISL3877 - Prism Indigo 802.11 a
321 ISL3890 - Prism Duette 802.11 a/b/g
322
323 For a complete list of supported cards visit <http://prism54.org>.
324 Here is the latest confirmed list of supported cards:
325
326 3com OfficeConnect 11g Cardbus Card aka 3CRWE154G72
327 Allnet ALL0271 PCI Card
328 Compex WL54G Cardbus Card
329 Corega CG-WLCB54GT Cardbus Card
330 D-Link Air Plus Xtreme G A1 Cardbus Card aka DWL-g650
331 I-O Data WN-G54/CB Cardbus Card
332 Kobishi XG-300 aka Z-Com Cardbus Card
333 Netgear WG511 Cardbus Card
334 Ovislink WL-5400PCI PCI Card
335 Peabird WLG-PCI PCI Card
336 Sitecom WL-100i Cardbus Card
337 Sitecom WL-110i PCI Card
338 SMC2802W - EZ Connect g 2.4GHz 54 Mbps Wireless PCI Card
339 SMC2835W - EZ Connect g 2.4GHz 54 Mbps Wireless Cardbus Card
340 SMC2835W-V2 - EZ Connect g 2.4GHz 54 Mbps Wireless Cardbus Card
341 Z-Com XG-900 PCI Card
342 Zyxel G-100 Cardbus Card
343
344 If you enable this you will need a firmware file as well.
345 You will need to copy this to /usr/lib/hotplug/firmware/isl3890.
346 You can get this non-GPL'd firmware file from the Prism54 project page:
347 <http://prism54.org>
348 You will also need the /etc/hotplug/firmware.agent script from
349 a current hotplug package.
350
351 Note: You need a motherboard with DMA support to use any of these cards
352
353 If you want to compile the driver as a module ( = code which can be
354 inserted in and removed from the running kernel whenever you want),
355 say M here and read <file:Documentation/modules.txt>. The module
356 will be called prism54.ko.
357
358# yes, this works even when no drivers are selected
359config NET_WIRELESS
360 bool
361 depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA)
362 default y
363
364endmenu
365
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
new file mode 100644
index 000000000000..2b87841322cc
--- /dev/null
+++ b/drivers/net/wireless/Makefile
@@ -0,0 +1,33 @@
1#
2# Makefile for the Linux Wireless network device drivers.
3#
4
5obj-$(CONFIG_STRIP) += strip.o
6obj-$(CONFIG_ARLAN) += arlan.o
7
8arlan-objs := arlan-main.o arlan-proc.o
9
10# Obsolete cards
11obj-$(CONFIG_WAVELAN) += wavelan.o
12obj-$(CONFIG_PCMCIA_NETWAVE) += netwave_cs.o
13obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan_cs.o
14
15obj-$(CONFIG_HERMES) += orinoco.o hermes.o
16obj-$(CONFIG_PCMCIA_HERMES) += orinoco_cs.o
17obj-$(CONFIG_APPLE_AIRPORT) += airport.o
18obj-$(CONFIG_PLX_HERMES) += orinoco_plx.o
19obj-$(CONFIG_PCI_HERMES) += orinoco_pci.o
20obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o
21
22obj-$(CONFIG_AIRO) += airo.o
23obj-$(CONFIG_AIRO_CS) += airo_cs.o airo.o
24
25obj-$(CONFIG_ATMEL) += atmel.o
26obj-$(CONFIG_PCI_ATMEL) += atmel_pci.o
27obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o
28
29obj-$(CONFIG_PRISM54) += prism54/
30
31# 16-bit wireless PCMCIA client drivers
32obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
33obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o
diff --git a/drivers/net/wireless/README b/drivers/net/wireless/README
new file mode 100644
index 000000000000..0c274bf6d45e
--- /dev/null
+++ b/drivers/net/wireless/README
@@ -0,0 +1,25 @@
1 README
2 ------
3
4 This directory is mostly for Wireless LAN drivers, in their
5various incarnations (ISA, PCI, Pcmcia...).
6 This separate directory is needed because a lot of driver work
7on different bus (typically PCI + Pcmcia) and share 95% of the
8code. This allow the code and the config options to be in one single
9place instead of scattered all over the driver tree, which is never
10100% satisfactory.
11
12 Note : if you want more info on the topic of Wireless LANs,
13you are kindly invited to have a look at the Wireless Howto :
14 http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
15 Some Wireless LAN drivers, like orinoco_cs, require the use of
16Wireless Tools to be configured :
17 http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html
18
19 Special notes for distribution maintainers :
20 1) wvlan_cs will be discontinued soon in favor of orinoco_cs
21 2) Please add Wireless Tools support in your scripts
22
23 Have fun...
24
25 Jean
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
new file mode 100644
index 000000000000..2899144f2153
--- /dev/null
+++ b/drivers/net/wireless/airo.c
@@ -0,0 +1,7667 @@
1/*======================================================================
2
3 Aironet driver for 4500 and 4800 series cards
4
5 This code is released under both the GPL version 2 and BSD licenses.
6 Either license may be used. The respective licenses are found at
7 the end of this file.
8
9 This code was developed by Benjamin Reed <breed@users.sourceforge.net>
10 including portions of which come from the Aironet PC4500
11 Developer's Reference Manual and used with permission. Copyright
12 (C) 1999 Benjamin Reed. All Rights Reserved. Permission to use
13 code in the Developer's manual was granted for this driver by
14 Aironet. Major code contributions were received from Javier Achirica
15 <achirica@users.sourceforge.net> and Jean Tourrilhes <jt@hpl.hp.com>.
16 Code was also integrated from the Cisco Aironet driver for Linux.
17 Support for MPI350 cards was added by Fabrice Bellet
18 <fabrice@bellet.info>.
19
20======================================================================*/
21
22#include <linux/config.h>
23#include <linux/init.h>
24
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/proc_fs.h>
28#include <linux/smp_lock.h>
29
30#include <linux/sched.h>
31#include <linux/ptrace.h>
32#include <linux/slab.h>
33#include <linux/string.h>
34#include <linux/timer.h>
35#include <linux/interrupt.h>
36#include <linux/in.h>
37#include <linux/bitops.h>
38#include <asm/io.h>
39#include <asm/system.h>
40
41#include <linux/netdevice.h>
42#include <linux/etherdevice.h>
43#include <linux/skbuff.h>
44#include <linux/if_arp.h>
45#include <linux/ioport.h>
46#include <linux/pci.h>
47#include <asm/uaccess.h>
48
49#ifdef CONFIG_PCI
50static struct pci_device_id card_ids[] = {
51 { 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
52 { 0x14b9, 0x4500, PCI_ANY_ID, PCI_ANY_ID },
53 { 0x14b9, 0x4800, PCI_ANY_ID, PCI_ANY_ID, },
54 { 0x14b9, 0x0340, PCI_ANY_ID, PCI_ANY_ID, },
55 { 0x14b9, 0x0350, PCI_ANY_ID, PCI_ANY_ID, },
56 { 0x14b9, 0x5000, PCI_ANY_ID, PCI_ANY_ID, },
57 { 0x14b9, 0xa504, PCI_ANY_ID, PCI_ANY_ID, },
58 { 0, }
59};
60MODULE_DEVICE_TABLE(pci, card_ids);
61
62static int airo_pci_probe(struct pci_dev *, const struct pci_device_id *);
63static void airo_pci_remove(struct pci_dev *);
64static int airo_pci_suspend(struct pci_dev *pdev, u32 state);
65static int airo_pci_resume(struct pci_dev *pdev);
66
67static struct pci_driver airo_driver = {
68 .name = "airo",
69 .id_table = card_ids,
70 .probe = airo_pci_probe,
71 .remove = __devexit_p(airo_pci_remove),
72 .suspend = airo_pci_suspend,
73 .resume = airo_pci_resume,
74};
75#endif /* CONFIG_PCI */
76
77/* Include Wireless Extension definition and check version - Jean II */
78#include <linux/wireless.h>
79#define WIRELESS_SPY // enable iwspy support
80#include <net/iw_handler.h> // New driver API
81
82#define CISCO_EXT // enable Cisco extensions
83#ifdef CISCO_EXT
84#include <linux/delay.h>
85#endif
86
87/* Support Cisco MIC feature */
88#define MICSUPPORT
89
90#if defined(MICSUPPORT) && !defined(CONFIG_CRYPTO)
91#warning MIC support requires Crypto API
92#undef MICSUPPORT
93#endif
94
95/* Hack to do some power saving */
96#define POWER_ON_DOWN
97
98/* As you can see this list is HUGH!
99 I really don't know what a lot of these counts are about, but they
100 are all here for completeness. If the IGNLABEL macro is put in
101 infront of the label, that statistic will not be included in the list
102 of statistics in the /proc filesystem */
103
104#define IGNLABEL(comment) NULL
105static char *statsLabels[] = {
106 "RxOverrun",
107 IGNLABEL("RxPlcpCrcErr"),
108 IGNLABEL("RxPlcpFormatErr"),
109 IGNLABEL("RxPlcpLengthErr"),
110 "RxMacCrcErr",
111 "RxMacCrcOk",
112 "RxWepErr",
113 "RxWepOk",
114 "RetryLong",
115 "RetryShort",
116 "MaxRetries",
117 "NoAck",
118 "NoCts",
119 "RxAck",
120 "RxCts",
121 "TxAck",
122 "TxRts",
123 "TxCts",
124 "TxMc",
125 "TxBc",
126 "TxUcFrags",
127 "TxUcPackets",
128 "TxBeacon",
129 "RxBeacon",
130 "TxSinColl",
131 "TxMulColl",
132 "DefersNo",
133 "DefersProt",
134 "DefersEngy",
135 "DupFram",
136 "RxFragDisc",
137 "TxAged",
138 "RxAged",
139 "LostSync-MaxRetry",
140 "LostSync-MissedBeacons",
141 "LostSync-ArlExceeded",
142 "LostSync-Deauth",
143 "LostSync-Disassoced",
144 "LostSync-TsfTiming",
145 "HostTxMc",
146 "HostTxBc",
147 "HostTxUc",
148 "HostTxFail",
149 "HostRxMc",
150 "HostRxBc",
151 "HostRxUc",
152 "HostRxDiscard",
153 IGNLABEL("HmacTxMc"),
154 IGNLABEL("HmacTxBc"),
155 IGNLABEL("HmacTxUc"),
156 IGNLABEL("HmacTxFail"),
157 IGNLABEL("HmacRxMc"),
158 IGNLABEL("HmacRxBc"),
159 IGNLABEL("HmacRxUc"),
160 IGNLABEL("HmacRxDiscard"),
161 IGNLABEL("HmacRxAccepted"),
162 "SsidMismatch",
163 "ApMismatch",
164 "RatesMismatch",
165 "AuthReject",
166 "AuthTimeout",
167 "AssocReject",
168 "AssocTimeout",
169 IGNLABEL("ReasonOutsideTable"),
170 IGNLABEL("ReasonStatus1"),
171 IGNLABEL("ReasonStatus2"),
172 IGNLABEL("ReasonStatus3"),
173 IGNLABEL("ReasonStatus4"),
174 IGNLABEL("ReasonStatus5"),
175 IGNLABEL("ReasonStatus6"),
176 IGNLABEL("ReasonStatus7"),
177 IGNLABEL("ReasonStatus8"),
178 IGNLABEL("ReasonStatus9"),
179 IGNLABEL("ReasonStatus10"),
180 IGNLABEL("ReasonStatus11"),
181 IGNLABEL("ReasonStatus12"),
182 IGNLABEL("ReasonStatus13"),
183 IGNLABEL("ReasonStatus14"),
184 IGNLABEL("ReasonStatus15"),
185 IGNLABEL("ReasonStatus16"),
186 IGNLABEL("ReasonStatus17"),
187 IGNLABEL("ReasonStatus18"),
188 IGNLABEL("ReasonStatus19"),
189 "RxMan",
190 "TxMan",
191 "RxRefresh",
192 "TxRefresh",
193 "RxPoll",
194 "TxPoll",
195 "HostRetries",
196 "LostSync-HostReq",
197 "HostTxBytes",
198 "HostRxBytes",
199 "ElapsedUsec",
200 "ElapsedSec",
201 "LostSyncBetterAP",
202 "PrivacyMismatch",
203 "Jammed",
204 "DiscRxNotWepped",
205 "PhyEleMismatch",
206 (char*)-1 };
207#ifndef RUN_AT
208#define RUN_AT(x) (jiffies+(x))
209#endif
210
211
212/* These variables are for insmod, since it seems that the rates
213 can only be set in setup_card. Rates should be a comma separated
214 (no spaces) list of rates (up to 8). */
215
216static int rates[8];
217static int basic_rate;
218static char *ssids[3];
219
220static int io[4];
221static int irq[4];
222
223static
224int maxencrypt /* = 0 */; /* The highest rate that the card can encrypt at.
225 0 means no limit. For old cards this was 4 */
226
227static int auto_wep /* = 0 */; /* If set, it tries to figure out the wep mode */
228static int aux_bap /* = 0 */; /* Checks to see if the aux ports are needed to read
229 the bap, needed on some older cards and buses. */
230static int adhoc;
231
232static int probe = 1;
233
234static int proc_uid /* = 0 */;
235
236static int proc_gid /* = 0 */;
237
238static int airo_perm = 0555;
239
240static int proc_perm = 0644;
241
242MODULE_AUTHOR("Benjamin Reed");
243MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
244 cards. Direct support for ISA/PCI/MPI cards and support \
245 for PCMCIA when used with airo_cs.");
246MODULE_LICENSE("Dual BSD/GPL");
247MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350");
248module_param_array(io, int, NULL, 0);
249module_param_array(irq, int, NULL, 0);
250module_param(basic_rate, int, 0);
251module_param_array(rates, int, NULL, 0);
252module_param_array(ssids, charp, NULL, 0);
253module_param(auto_wep, int, 0);
254MODULE_PARM_DESC(auto_wep, "If non-zero, the driver will keep looping through \
255the authentication options until an association is made. The value of \
256auto_wep is number of the wep keys to check. A value of 2 will try using \
257the key at index 0 and index 1.");
258module_param(aux_bap, int, 0);
259MODULE_PARM_DESC(aux_bap, "If non-zero, the driver will switch into a mode \
260than seems to work better for older cards with some older buses. Before \
261switching it checks that the switch is needed.");
262module_param(maxencrypt, int, 0);
263MODULE_PARM_DESC(maxencrypt, "The maximum speed that the card can do \
264encryption. Units are in 512kbs. Zero (default) means there is no limit. \
265Older cards used to be limited to 2mbs (4).");
266module_param(adhoc, int, 0);
267MODULE_PARM_DESC(adhoc, "If non-zero, the card will start in adhoc mode.");
268module_param(probe, int, 0);
269MODULE_PARM_DESC(probe, "If zero, the driver won't start the card.");
270
271module_param(proc_uid, int, 0);
272MODULE_PARM_DESC(proc_uid, "The uid that the /proc files will belong to.");
273module_param(proc_gid, int, 0);
274MODULE_PARM_DESC(proc_gid, "The gid that the /proc files will belong to.");
275module_param(airo_perm, int, 0);
276MODULE_PARM_DESC(airo_perm, "The permission bits of /proc/[driver/]aironet.");
277module_param(proc_perm, int, 0);
278MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc");
279
280/* This is a kind of sloppy hack to get this information to OUT4500 and
281 IN4500. I would be extremely interested in the situation where this
282 doesn't work though!!! */
283static int do8bitIO = 0;
284
285/* Return codes */
286#define SUCCESS 0
287#define ERROR -1
288#define NO_PACKET -2
289
290/* Commands */
291#define NOP2 0x0000
292#define MAC_ENABLE 0x0001
293#define MAC_DISABLE 0x0002
294#define CMD_LOSE_SYNC 0x0003 /* Not sure what this does... */
295#define CMD_SOFTRESET 0x0004
296#define HOSTSLEEP 0x0005
297#define CMD_MAGIC_PKT 0x0006
298#define CMD_SETWAKEMASK 0x0007
299#define CMD_READCFG 0x0008
300#define CMD_SETMODE 0x0009
301#define CMD_ALLOCATETX 0x000a
302#define CMD_TRANSMIT 0x000b
303#define CMD_DEALLOCATETX 0x000c
304#define NOP 0x0010
305#define CMD_WORKAROUND 0x0011
306#define CMD_ALLOCATEAUX 0x0020
307#define CMD_ACCESS 0x0021
308#define CMD_PCIBAP 0x0022
309#define CMD_PCIAUX 0x0023
310#define CMD_ALLOCBUF 0x0028
311#define CMD_GETTLV 0x0029
312#define CMD_PUTTLV 0x002a
313#define CMD_DELTLV 0x002b
314#define CMD_FINDNEXTTLV 0x002c
315#define CMD_PSPNODES 0x0030
316#define CMD_SETCW 0x0031
317#define CMD_SETPCF 0x0032
318#define CMD_SETPHYREG 0x003e
319#define CMD_TXTEST 0x003f
320#define MAC_ENABLETX 0x0101
321#define CMD_LISTBSS 0x0103
322#define CMD_SAVECFG 0x0108
323#define CMD_ENABLEAUX 0x0111
324#define CMD_WRITERID 0x0121
325#define CMD_USEPSPNODES 0x0130
326#define MAC_ENABLERX 0x0201
327
328/* Command errors */
329#define ERROR_QUALIF 0x00
330#define ERROR_ILLCMD 0x01
331#define ERROR_ILLFMT 0x02
332#define ERROR_INVFID 0x03
333#define ERROR_INVRID 0x04
334#define ERROR_LARGE 0x05
335#define ERROR_NDISABL 0x06
336#define ERROR_ALLOCBSY 0x07
337#define ERROR_NORD 0x0B
338#define ERROR_NOWR 0x0C
339#define ERROR_INVFIDTX 0x0D
340#define ERROR_TESTACT 0x0E
341#define ERROR_TAGNFND 0x12
342#define ERROR_DECODE 0x20
343#define ERROR_DESCUNAV 0x21
344#define ERROR_BADLEN 0x22
345#define ERROR_MODE 0x80
346#define ERROR_HOP 0x81
347#define ERROR_BINTER 0x82
348#define ERROR_RXMODE 0x83
349#define ERROR_MACADDR 0x84
350#define ERROR_RATES 0x85
351#define ERROR_ORDER 0x86
352#define ERROR_SCAN 0x87
353#define ERROR_AUTH 0x88
354#define ERROR_PSMODE 0x89
355#define ERROR_RTYPE 0x8A
356#define ERROR_DIVER 0x8B
357#define ERROR_SSID 0x8C
358#define ERROR_APLIST 0x8D
359#define ERROR_AUTOWAKE 0x8E
360#define ERROR_LEAP 0x8F
361
362/* Registers */
363#define COMMAND 0x00
364#define PARAM0 0x02
365#define PARAM1 0x04
366#define PARAM2 0x06
367#define STATUS 0x08
368#define RESP0 0x0a
369#define RESP1 0x0c
370#define RESP2 0x0e
371#define LINKSTAT 0x10
372#define SELECT0 0x18
373#define OFFSET0 0x1c
374#define RXFID 0x20
375#define TXALLOCFID 0x22
376#define TXCOMPLFID 0x24
377#define DATA0 0x36
378#define EVSTAT 0x30
379#define EVINTEN 0x32
380#define EVACK 0x34
381#define SWS0 0x28
382#define SWS1 0x2a
383#define SWS2 0x2c
384#define SWS3 0x2e
385#define AUXPAGE 0x3A
386#define AUXOFF 0x3C
387#define AUXDATA 0x3E
388
389#define FID_TX 1
390#define FID_RX 2
391/* Offset into aux memory for descriptors */
392#define AUX_OFFSET 0x800
393/* Size of allocated packets */
394#define PKTSIZE 1840
395#define RIDSIZE 2048
396/* Size of the transmit queue */
397#define MAXTXQ 64
398
399/* BAP selectors */
400#define BAP0 0 // Used for receiving packets
401#define BAP1 2 // Used for xmiting packets and working with RIDS
402
403/* Flags */
404#define COMMAND_BUSY 0x8000
405
406#define BAP_BUSY 0x8000
407#define BAP_ERR 0x4000
408#define BAP_DONE 0x2000
409
410#define PROMISC 0xffff
411#define NOPROMISC 0x0000
412
413#define EV_CMD 0x10
414#define EV_CLEARCOMMANDBUSY 0x4000
415#define EV_RX 0x01
416#define EV_TX 0x02
417#define EV_TXEXC 0x04
418#define EV_ALLOC 0x08
419#define EV_LINK 0x80
420#define EV_AWAKE 0x100
421#define EV_TXCPY 0x400
422#define EV_UNKNOWN 0x800
423#define EV_MIC 0x1000 /* Message Integrity Check Interrupt */
424#define EV_AWAKEN 0x2000
425#define STATUS_INTS (EV_AWAKE|EV_LINK|EV_TXEXC|EV_TX|EV_TXCPY|EV_RX|EV_MIC)
426
427#ifdef CHECK_UNKNOWN_INTS
428#define IGNORE_INTS ( EV_CMD | EV_UNKNOWN)
429#else
430#define IGNORE_INTS (~STATUS_INTS)
431#endif
432
433/* RID TYPES */
434#define RID_RW 0x20
435
436/* The RIDs */
437#define RID_CAPABILITIES 0xFF00
438#define RID_APINFO 0xFF01
439#define RID_RADIOINFO 0xFF02
440#define RID_UNKNOWN3 0xFF03
441#define RID_RSSI 0xFF04
442#define RID_CONFIG 0xFF10
443#define RID_SSID 0xFF11
444#define RID_APLIST 0xFF12
445#define RID_DRVNAME 0xFF13
446#define RID_ETHERENCAP 0xFF14
447#define RID_WEP_TEMP 0xFF15
448#define RID_WEP_PERM 0xFF16
449#define RID_MODULATION 0xFF17
450#define RID_OPTIONS 0xFF18
451#define RID_ACTUALCONFIG 0xFF20 /*readonly*/
452#define RID_FACTORYCONFIG 0xFF21
453#define RID_UNKNOWN22 0xFF22
454#define RID_LEAPUSERNAME 0xFF23
455#define RID_LEAPPASSWORD 0xFF24
456#define RID_STATUS 0xFF50
457#define RID_BEACON_HST 0xFF51
458#define RID_BUSY_HST 0xFF52
459#define RID_RETRIES_HST 0xFF53
460#define RID_UNKNOWN54 0xFF54
461#define RID_UNKNOWN55 0xFF55
462#define RID_UNKNOWN56 0xFF56
463#define RID_MIC 0xFF57
464#define RID_STATS16 0xFF60
465#define RID_STATS16DELTA 0xFF61
466#define RID_STATS16DELTACLEAR 0xFF62
467#define RID_STATS 0xFF68
468#define RID_STATSDELTA 0xFF69
469#define RID_STATSDELTACLEAR 0xFF6A
470#define RID_ECHOTEST_RID 0xFF70
471#define RID_ECHOTEST_RESULTS 0xFF71
472#define RID_BSSLISTFIRST 0xFF72
473#define RID_BSSLISTNEXT 0xFF73
474
475typedef struct {
476 u16 cmd;
477 u16 parm0;
478 u16 parm1;
479 u16 parm2;
480} Cmd;
481
482typedef struct {
483 u16 status;
484 u16 rsp0;
485 u16 rsp1;
486 u16 rsp2;
487} Resp;
488
489/*
490 * Rids and endian-ness: The Rids will always be in cpu endian, since
491 * this all the patches from the big-endian guys end up doing that.
492 * so all rid access should use the read/writeXXXRid routines.
493 */
494
495/* This is redundant for x86 archs, but it seems necessary for ARM */
496#pragma pack(1)
497
498/* This structure came from an email sent to me from an engineer at
499 aironet for inclusion into this driver */
500typedef struct {
501 u16 len;
502 u16 kindex;
503 u8 mac[ETH_ALEN];
504 u16 klen;
505 u8 key[16];
506} WepKeyRid;
507
508/* These structures are from the Aironet's PC4500 Developers Manual */
509typedef struct {
510 u16 len;
511 u8 ssid[32];
512} Ssid;
513
514typedef struct {
515 u16 len;
516 Ssid ssids[3];
517} SsidRid;
518
519typedef struct {
520 u16 len;
521 u16 modulation;
522#define MOD_DEFAULT 0
523#define MOD_CCK 1
524#define MOD_MOK 2
525} ModulationRid;
526
527typedef struct {
528 u16 len; /* sizeof(ConfigRid) */
529 u16 opmode; /* operating mode */
530#define MODE_STA_IBSS 0
531#define MODE_STA_ESS 1
532#define MODE_AP 2
533#define MODE_AP_RPTR 3
534#define MODE_ETHERNET_HOST (0<<8) /* rx payloads converted */
535#define MODE_LLC_HOST (1<<8) /* rx payloads left as is */
536#define MODE_AIRONET_EXTEND (1<<9) /* enable Aironet extenstions */
537#define MODE_AP_INTERFACE (1<<10) /* enable ap interface extensions */
538#define MODE_ANTENNA_ALIGN (1<<11) /* enable antenna alignment */
539#define MODE_ETHER_LLC (1<<12) /* enable ethernet LLC */
540#define MODE_LEAF_NODE (1<<13) /* enable leaf node bridge */
541#define MODE_CF_POLLABLE (1<<14) /* enable CF pollable */
542#define MODE_MIC (1<<15) /* enable MIC */
543 u16 rmode; /* receive mode */
544#define RXMODE_BC_MC_ADDR 0
545#define RXMODE_BC_ADDR 1 /* ignore multicasts */
546#define RXMODE_ADDR 2 /* ignore multicast and broadcast */
547#define RXMODE_RFMON 3 /* wireless monitor mode */
548#define RXMODE_RFMON_ANYBSS 4
549#define RXMODE_LANMON 5 /* lan style monitor -- data packets only */
550#define RXMODE_DISABLE_802_3_HEADER (1<<8) /* disables 802.3 header on rx */
551#define RXMODE_NORMALIZED_RSSI (1<<9) /* return normalized RSSI */
552 u16 fragThresh;
553 u16 rtsThres;
554 u8 macAddr[ETH_ALEN];
555 u8 rates[8];
556 u16 shortRetryLimit;
557 u16 longRetryLimit;
558 u16 txLifetime; /* in kusec */
559 u16 rxLifetime; /* in kusec */
560 u16 stationary;
561 u16 ordering;
562 u16 u16deviceType; /* for overriding device type */
563 u16 cfpRate;
564 u16 cfpDuration;
565 u16 _reserved1[3];
566 /*---------- Scanning/Associating ----------*/
567 u16 scanMode;
568#define SCANMODE_ACTIVE 0
569#define SCANMODE_PASSIVE 1
570#define SCANMODE_AIROSCAN 2
571 u16 probeDelay; /* in kusec */
572 u16 probeEnergyTimeout; /* in kusec */
573 u16 probeResponseTimeout;
574 u16 beaconListenTimeout;
575 u16 joinNetTimeout;
576 u16 authTimeout;
577 u16 authType;
578#define AUTH_OPEN 0x1
579#define AUTH_ENCRYPT 0x101
580#define AUTH_SHAREDKEY 0x102
581#define AUTH_ALLOW_UNENCRYPTED 0x200
582 u16 associationTimeout;
583 u16 specifiedApTimeout;
584 u16 offlineScanInterval;
585 u16 offlineScanDuration;
586 u16 linkLossDelay;
587 u16 maxBeaconLostTime;
588 u16 refreshInterval;
589#define DISABLE_REFRESH 0xFFFF
590 u16 _reserved1a[1];
591 /*---------- Power save operation ----------*/
592 u16 powerSaveMode;
593#define POWERSAVE_CAM 0
594#define POWERSAVE_PSP 1
595#define POWERSAVE_PSPCAM 2
596 u16 sleepForDtims;
597 u16 listenInterval;
598 u16 fastListenInterval;
599 u16 listenDecay;
600 u16 fastListenDelay;
601 u16 _reserved2[2];
602 /*---------- Ap/Ibss config items ----------*/
603 u16 beaconPeriod;
604 u16 atimDuration;
605 u16 hopPeriod;
606 u16 channelSet;
607 u16 channel;
608 u16 dtimPeriod;
609 u16 bridgeDistance;
610 u16 radioID;
611 /*---------- Radio configuration ----------*/
612 u16 radioType;
613#define RADIOTYPE_DEFAULT 0
614#define RADIOTYPE_802_11 1
615#define RADIOTYPE_LEGACY 2
616 u8 rxDiversity;
617 u8 txDiversity;
618 u16 txPower;
619#define TXPOWER_DEFAULT 0
620 u16 rssiThreshold;
621#define RSSI_DEFAULT 0
622 u16 modulation;
623#define PREAMBLE_AUTO 0
624#define PREAMBLE_LONG 1
625#define PREAMBLE_SHORT 2
626 u16 preamble;
627 u16 homeProduct;
628 u16 radioSpecific;
629 /*---------- Aironet Extensions ----------*/
630 u8 nodeName[16];
631 u16 arlThreshold;
632 u16 arlDecay;
633 u16 arlDelay;
634 u16 _reserved4[1];
635 /*---------- Aironet Extensions ----------*/
636 u8 magicAction;
637#define MAGIC_ACTION_STSCHG 1
638#define MAGIC_ACTION_RESUME 2
639#define MAGIC_IGNORE_MCAST (1<<8)
640#define MAGIC_IGNORE_BCAST (1<<9)
641#define MAGIC_SWITCH_TO_PSP (0<<10)
642#define MAGIC_STAY_IN_CAM (1<<10)
643 u8 magicControl;
644 u16 autoWake;
645} ConfigRid;
646
647typedef struct {
648 u16 len;
649 u8 mac[ETH_ALEN];
650 u16 mode;
651 u16 errorCode;
652 u16 sigQuality;
653 u16 SSIDlen;
654 char SSID[32];
655 char apName[16];
656 u8 bssid[4][ETH_ALEN];
657 u16 beaconPeriod;
658 u16 dimPeriod;
659 u16 atimDuration;
660 u16 hopPeriod;
661 u16 channelSet;
662 u16 channel;
663 u16 hopsToBackbone;
664 u16 apTotalLoad;
665 u16 generatedLoad;
666 u16 accumulatedArl;
667 u16 signalQuality;
668 u16 currentXmitRate;
669 u16 apDevExtensions;
670 u16 normalizedSignalStrength;
671 u16 shortPreamble;
672 u8 apIP[4];
673 u8 noisePercent; /* Noise percent in last second */
674 u8 noisedBm; /* Noise dBm in last second */
675 u8 noiseAvePercent; /* Noise percent in last minute */
676 u8 noiseAvedBm; /* Noise dBm in last minute */
677 u8 noiseMaxPercent; /* Highest noise percent in last minute */
678 u8 noiseMaxdBm; /* Highest noise dbm in last minute */
679 u16 load;
680 u8 carrier[4];
681 u16 assocStatus;
682#define STAT_NOPACKETS 0
683#define STAT_NOCARRIERSET 10
684#define STAT_GOTCARRIERSET 11
685#define STAT_WRONGSSID 20
686#define STAT_BADCHANNEL 25
687#define STAT_BADBITRATES 30
688#define STAT_BADPRIVACY 35
689#define STAT_APFOUND 40
690#define STAT_APREJECTED 50
691#define STAT_AUTHENTICATING 60
692#define STAT_DEAUTHENTICATED 61
693#define STAT_AUTHTIMEOUT 62
694#define STAT_ASSOCIATING 70
695#define STAT_DEASSOCIATED 71
696#define STAT_ASSOCTIMEOUT 72
697#define STAT_NOTAIROAP 73
698#define STAT_ASSOCIATED 80
699#define STAT_LEAPING 90
700#define STAT_LEAPFAILED 91
701#define STAT_LEAPTIMEDOUT 92
702#define STAT_LEAPCOMPLETE 93
703} StatusRid;
704
705typedef struct {
706 u16 len;
707 u16 spacer;
708 u32 vals[100];
709} StatsRid;
710
711
712typedef struct {
713 u16 len;
714 u8 ap[4][ETH_ALEN];
715} APListRid;
716
717typedef struct {
718 u16 len;
719 char oui[3];
720 char zero;
721 u16 prodNum;
722 char manName[32];
723 char prodName[16];
724 char prodVer[8];
725 char factoryAddr[ETH_ALEN];
726 char aironetAddr[ETH_ALEN];
727 u16 radioType;
728 u16 country;
729 char callid[ETH_ALEN];
730 char supportedRates[8];
731 char rxDiversity;
732 char txDiversity;
733 u16 txPowerLevels[8];
734 u16 hardVer;
735 u16 hardCap;
736 u16 tempRange;
737 u16 softVer;
738 u16 softSubVer;
739 u16 interfaceVer;
740 u16 softCap;
741 u16 bootBlockVer;
742 u16 requiredHard;
743 u16 extSoftCap;
744} CapabilityRid;
745
746typedef struct {
747 u16 len;
748 u16 index; /* First is 0 and 0xffff means end of list */
749#define RADIO_FH 1 /* Frequency hopping radio type */
750#define RADIO_DS 2 /* Direct sequence radio type */
751#define RADIO_TMA 4 /* Proprietary radio used in old cards (2500) */
752 u16 radioType;
753 u8 bssid[ETH_ALEN]; /* Mac address of the BSS */
754 u8 zero;
755 u8 ssidLen;
756 u8 ssid[32];
757 u16 rssi;
758#define CAP_ESS (1<<0)
759#define CAP_IBSS (1<<1)
760#define CAP_PRIVACY (1<<4)
761#define CAP_SHORTHDR (1<<5)
762 u16 cap;
763 u16 beaconInterval;
764 u8 rates[8]; /* Same as rates for config rid */
765 struct { /* For frequency hopping only */
766 u16 dwell;
767 u8 hopSet;
768 u8 hopPattern;
769 u8 hopIndex;
770 u8 fill;
771 } fh;
772 u16 dsChannel;
773 u16 atimWindow;
774} BSSListRid;
775
776typedef struct {
777 u8 rssipct;
778 u8 rssidBm;
779} tdsRssiEntry;
780
781typedef struct {
782 u16 len;
783 tdsRssiEntry x[256];
784} tdsRssiRid;
785
786typedef struct {
787 u16 len;
788 u16 state;
789 u16 multicastValid;
790 u8 multicast[16];
791 u16 unicastValid;
792 u8 unicast[16];
793} MICRid;
794
795typedef struct {
796 u16 typelen;
797
798 union {
799 u8 snap[8];
800 struct {
801 u8 dsap;
802 u8 ssap;
803 u8 control;
804 u8 orgcode[3];
805 u8 fieldtype[2];
806 } llc;
807 } u;
808 u32 mic;
809 u32 seq;
810} MICBuffer;
811
812typedef struct {
813 u8 da[ETH_ALEN];
814 u8 sa[ETH_ALEN];
815} etherHead;
816
817#pragma pack()
818
819#define TXCTL_TXOK (1<<1) /* report if tx is ok */
820#define TXCTL_TXEX (1<<2) /* report if tx fails */
821#define TXCTL_802_3 (0<<3) /* 802.3 packet */
822#define TXCTL_802_11 (1<<3) /* 802.11 mac packet */
823#define TXCTL_ETHERNET (0<<4) /* payload has ethertype */
824#define TXCTL_LLC (1<<4) /* payload is llc */
825#define TXCTL_RELEASE (0<<5) /* release after completion */
826#define TXCTL_NORELEASE (1<<5) /* on completion returns to host */
827
828#define BUSY_FID 0x10000
829
830#ifdef CISCO_EXT
831#define AIROMAGIC 0xa55a
832/* Warning : SIOCDEVPRIVATE may disapear during 2.5.X - Jean II */
833#ifdef SIOCIWFIRSTPRIV
834#ifdef SIOCDEVPRIVATE
835#define AIROOLDIOCTL SIOCDEVPRIVATE
836#define AIROOLDIDIFC AIROOLDIOCTL + 1
837#endif /* SIOCDEVPRIVATE */
838#else /* SIOCIWFIRSTPRIV */
839#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
840#endif /* SIOCIWFIRSTPRIV */
841/* This may be wrong. When using the new SIOCIWFIRSTPRIV range, we probably
842 * should use only "GET" ioctls (last bit set to 1). "SET" ioctls are root
843 * only and don't return the modified struct ifreq to the application which
844 * is usually a problem. - Jean II */
845#define AIROIOCTL SIOCIWFIRSTPRIV
846#define AIROIDIFC AIROIOCTL + 1
847
848/* Ioctl constants to be used in airo_ioctl.command */
849
850#define AIROGCAP 0 // Capability rid
851#define AIROGCFG 1 // USED A LOT
852#define AIROGSLIST 2 // System ID list
853#define AIROGVLIST 3 // List of specified AP's
854#define AIROGDRVNAM 4 // NOTUSED
855#define AIROGEHTENC 5 // NOTUSED
856#define AIROGWEPKTMP 6
857#define AIROGWEPKNV 7
858#define AIROGSTAT 8
859#define AIROGSTATSC32 9
860#define AIROGSTATSD32 10
861#define AIROGMICRID 11
862#define AIROGMICSTATS 12
863#define AIROGFLAGS 13
864#define AIROGID 14
865#define AIRORRID 15
866#define AIRORSWVERSION 17
867
868/* Leave gap of 40 commands after AIROGSTATSD32 for future */
869
870#define AIROPCAP AIROGSTATSD32 + 40
871#define AIROPVLIST AIROPCAP + 1
872#define AIROPSLIST AIROPVLIST + 1
873#define AIROPCFG AIROPSLIST + 1
874#define AIROPSIDS AIROPCFG + 1
875#define AIROPAPLIST AIROPSIDS + 1
876#define AIROPMACON AIROPAPLIST + 1 /* Enable mac */
877#define AIROPMACOFF AIROPMACON + 1 /* Disable mac */
878#define AIROPSTCLR AIROPMACOFF + 1
879#define AIROPWEPKEY AIROPSTCLR + 1
880#define AIROPWEPKEYNV AIROPWEPKEY + 1
881#define AIROPLEAPPWD AIROPWEPKEYNV + 1
882#define AIROPLEAPUSR AIROPLEAPPWD + 1
883
884/* Flash codes */
885
886#define AIROFLSHRST AIROPWEPKEYNV + 40
887#define AIROFLSHGCHR AIROFLSHRST + 1
888#define AIROFLSHSTFL AIROFLSHGCHR + 1
889#define AIROFLSHPCHR AIROFLSHSTFL + 1
890#define AIROFLPUTBUF AIROFLSHPCHR + 1
891#define AIRORESTART AIROFLPUTBUF + 1
892
893#define FLASHSIZE 32768
894#define AUXMEMSIZE (256 * 1024)
895
896typedef struct aironet_ioctl {
897 unsigned short command; // What to do
898 unsigned short len; // Len of data
899 unsigned short ridnum; // rid number
900 unsigned char __user *data; // d-data
901} aironet_ioctl;
902
903static char *swversion = "2.1";
904#endif /* CISCO_EXT */
905
906#define NUM_MODULES 2
907#define MIC_MSGLEN_MAX 2400
908#define EMMH32_MSGLEN_MAX MIC_MSGLEN_MAX
909
910typedef struct {
911 u32 size; // size
912 u8 enabled; // MIC enabled or not
913 u32 rxSuccess; // successful packets received
914 u32 rxIncorrectMIC; // pkts dropped due to incorrect MIC comparison
915 u32 rxNotMICed; // pkts dropped due to not being MIC'd
916 u32 rxMICPlummed; // pkts dropped due to not having a MIC plummed
917 u32 rxWrongSequence; // pkts dropped due to sequence number violation
918 u32 reserve[32];
919} mic_statistics;
920
921typedef struct {
922 u32 coeff[((EMMH32_MSGLEN_MAX)+3)>>2];
923 u64 accum; // accumulated mic, reduced to u32 in final()
924 int position; // current position (byte offset) in message
925 union {
926 u8 d8[4];
927 u32 d32;
928 } part; // saves partial message word across update() calls
929} emmh32_context;
930
931typedef struct {
932 emmh32_context seed; // Context - the seed
933 u32 rx; // Received sequence number
934 u32 tx; // Tx sequence number
935 u32 window; // Start of window
936 u8 valid; // Flag to say if context is valid or not
937 u8 key[16];
938} miccntx;
939
940typedef struct {
941 miccntx mCtx; // Multicast context
942 miccntx uCtx; // Unicast context
943} mic_module;
944
945typedef struct {
946 unsigned int rid: 16;
947 unsigned int len: 15;
948 unsigned int valid: 1;
949 dma_addr_t host_addr;
950} Rid;
951
952typedef struct {
953 unsigned int offset: 15;
954 unsigned int eoc: 1;
955 unsigned int len: 15;
956 unsigned int valid: 1;
957 dma_addr_t host_addr;
958} TxFid;
959
960typedef struct {
961 unsigned int ctl: 15;
962 unsigned int rdy: 1;
963 unsigned int len: 15;
964 unsigned int valid: 1;
965 dma_addr_t host_addr;
966} RxFid;
967
968/*
969 * Host receive descriptor
970 */
971typedef struct {
972 unsigned char __iomem *card_ram_off; /* offset into card memory of the
973 desc */
974 RxFid rx_desc; /* card receive descriptor */
975 char *virtual_host_addr; /* virtual address of host receive
976 buffer */
977 int pending;
978} HostRxDesc;
979
980/*
981 * Host transmit descriptor
982 */
983typedef struct {
984 unsigned char __iomem *card_ram_off; /* offset into card memory of the
985 desc */
986 TxFid tx_desc; /* card transmit descriptor */
987 char *virtual_host_addr; /* virtual address of host receive
988 buffer */
989 int pending;
990} HostTxDesc;
991
992/*
993 * Host RID descriptor
994 */
995typedef struct {
996 unsigned char __iomem *card_ram_off; /* offset into card memory of the
997 descriptor */
998 Rid rid_desc; /* card RID descriptor */
999 char *virtual_host_addr; /* virtual address of host receive
1000 buffer */
1001} HostRidDesc;
1002
1003typedef struct {
1004 u16 sw0;
1005 u16 sw1;
1006 u16 status;
1007 u16 len;
1008#define HOST_SET (1 << 0)
1009#define HOST_INT_TX (1 << 1) /* Interrupt on successful TX */
1010#define HOST_INT_TXERR (1 << 2) /* Interrupt on unseccessful TX */
1011#define HOST_LCC_PAYLOAD (1 << 4) /* LLC payload, 0 = Ethertype */
1012#define HOST_DONT_RLSE (1 << 5) /* Don't release buffer when done */
1013#define HOST_DONT_RETRY (1 << 6) /* Don't retry trasmit */
1014#define HOST_CLR_AID (1 << 7) /* clear AID failure */
1015#define HOST_RTS (1 << 9) /* Force RTS use */
1016#define HOST_SHORT (1 << 10) /* Do short preamble */
1017 u16 ctl;
1018 u16 aid;
1019 u16 retries;
1020 u16 fill;
1021} TxCtlHdr;
1022
1023typedef struct {
1024 u16 ctl;
1025 u16 duration;
1026 char addr1[6];
1027 char addr2[6];
1028 char addr3[6];
1029 u16 seq;
1030 char addr4[6];
1031} WifiHdr;
1032
1033
1034typedef struct {
1035 TxCtlHdr ctlhdr;
1036 u16 fill1;
1037 u16 fill2;
1038 WifiHdr wifihdr;
1039 u16 gaplen;
1040 u16 status;
1041} WifiCtlHdr;
1042
1043WifiCtlHdr wifictlhdr8023 = {
1044 .ctlhdr = {
1045 .ctl = HOST_DONT_RLSE,
1046 }
1047};
1048
1049#ifdef WIRELESS_EXT
1050// Frequency list (map channels to frequencies)
1051static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
1052 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
1053
1054// A few details needed for WEP (Wireless Equivalent Privacy)
1055#define MAX_KEY_SIZE 13 // 128 (?) bits
1056#define MIN_KEY_SIZE 5 // 40 bits RC4 - WEP
1057typedef struct wep_key_t {
1058 u16 len;
1059 u8 key[16]; /* 40-bit and 104-bit keys */
1060} wep_key_t;
1061
1062/* Backward compatibility */
1063#ifndef IW_ENCODE_NOKEY
1064#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
1065#define IW_ENCODE_MODE (IW_ENCODE_DISABLED | IW_ENCODE_RESTRICTED | IW_ENCODE_OPEN)
1066#endif /* IW_ENCODE_NOKEY */
1067
1068/* List of Wireless Handlers (new API) */
1069static const struct iw_handler_def airo_handler_def;
1070#endif /* WIRELESS_EXT */
1071
1072static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
1073
1074struct airo_info;
1075
1076static int get_dec_u16( char *buffer, int *start, int limit );
1077static void OUT4500( struct airo_info *, u16 register, u16 value );
1078static unsigned short IN4500( struct airo_info *, u16 register );
1079static u16 setup_card(struct airo_info*, u8 *mac, int lock);
1080static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock );
1081static void disable_MAC(struct airo_info *ai, int lock);
1082static void enable_interrupts(struct airo_info*);
1083static void disable_interrupts(struct airo_info*);
1084static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp);
1085static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap);
1086static int aux_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
1087 int whichbap);
1088static int fast_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
1089 int whichbap);
1090static int bap_write(struct airo_info*, const u16 *pu16Src, int bytelen,
1091 int whichbap);
1092static int PC4500_accessrid(struct airo_info*, u16 rid, u16 accmd);
1093static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len, int lock);
1094static int PC4500_writerid(struct airo_info*, u16 rid, const void
1095 *pBuf, int len, int lock);
1096static int do_writerid( struct airo_info*, u16 rid, const void *rid_data,
1097 int len, int dummy );
1098static u16 transmit_allocate(struct airo_info*, int lenPayload, int raw);
1099static int transmit_802_3_packet(struct airo_info*, int len, char *pPacket);
1100static int transmit_802_11_packet(struct airo_info*, int len, char *pPacket);
1101
1102static int mpi_send_packet (struct net_device *dev);
1103static void mpi_unmap_card(struct pci_dev *pci);
1104static void mpi_receive_802_3(struct airo_info *ai);
1105static void mpi_receive_802_11(struct airo_info *ai);
1106static int waitbusy (struct airo_info *ai);
1107
1108static irqreturn_t airo_interrupt( int irq, void* dev_id, struct pt_regs
1109 *regs);
1110static int airo_thread(void *data);
1111static void timer_func( struct net_device *dev );
1112static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
1113#ifdef WIRELESS_EXT
1114struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
1115static void airo_read_wireless_stats (struct airo_info *local);
1116#endif /* WIRELESS_EXT */
1117#ifdef CISCO_EXT
1118static int readrids(struct net_device *dev, aironet_ioctl *comp);
1119static int writerids(struct net_device *dev, aironet_ioctl *comp);
1120int flashcard(struct net_device *dev, aironet_ioctl *comp);
1121#endif /* CISCO_EXT */
1122#ifdef MICSUPPORT
1123static void micinit(struct airo_info *ai);
1124static int micsetup(struct airo_info *ai);
1125static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len);
1126static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen);
1127
1128#include <linux/crypto.h>
1129#endif
1130
1131struct airo_info {
1132 struct net_device_stats stats;
1133 struct net_device *dev;
1134 /* Note, we can have MAX_FIDS outstanding. FIDs are 16-bits, so we
1135 use the high bit to mark whether it is in use. */
1136#define MAX_FIDS 6
1137#define MPI_MAX_FIDS 1
1138 int fids[MAX_FIDS];
1139 ConfigRid config;
1140 char keyindex; // Used with auto wep
1141 char defindex; // Used with auto wep
1142 struct proc_dir_entry *proc_entry;
1143 spinlock_t aux_lock;
1144 unsigned long flags;
1145#define FLAG_PROMISC 8 /* IFF_PROMISC 0x100 - include/linux/if.h */
1146#define FLAG_RADIO_OFF 0 /* User disabling of MAC */
1147#define FLAG_RADIO_DOWN 1 /* ifup/ifdown disabling of MAC */
1148#define FLAG_RADIO_MASK 0x03
1149#define FLAG_ENABLED 2
1150#define FLAG_ADHOC 3 /* Needed by MIC */
1151#define FLAG_MIC_CAPABLE 4
1152#define FLAG_UPDATE_MULTI 5
1153#define FLAG_UPDATE_UNI 6
1154#define FLAG_802_11 7
1155#define FLAG_PENDING_XMIT 9
1156#define FLAG_PENDING_XMIT11 10
1157#define FLAG_MPI 11
1158#define FLAG_REGISTERED 12
1159#define FLAG_COMMIT 13
1160#define FLAG_RESET 14
1161#define FLAG_FLASHING 15
1162#define JOB_MASK 0x1ff0000
1163#define JOB_DIE 16
1164#define JOB_XMIT 17
1165#define JOB_XMIT11 18
1166#define JOB_STATS 19
1167#define JOB_PROMISC 20
1168#define JOB_MIC 21
1169#define JOB_EVENT 22
1170#define JOB_AUTOWEP 23
1171#define JOB_WSTATS 24
1172 int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,
1173 int whichbap);
1174 unsigned short *flash;
1175 tdsRssiEntry *rssi;
1176 struct task_struct *task;
1177 struct semaphore sem;
1178 pid_t thr_pid;
1179 wait_queue_head_t thr_wait;
1180 struct completion thr_exited;
1181 unsigned long expires;
1182 struct {
1183 struct sk_buff *skb;
1184 int fid;
1185 } xmit, xmit11;
1186 struct net_device *wifidev;
1187#ifdef WIRELESS_EXT
1188 struct iw_statistics wstats; // wireless stats
1189 unsigned long scan_timestamp; /* Time started to scan */
1190 struct iw_spy_data spy_data;
1191 struct iw_public_data wireless_data;
1192#endif /* WIRELESS_EXT */
1193#ifdef MICSUPPORT
1194 /* MIC stuff */
1195 struct crypto_tfm *tfm;
1196 mic_module mod[2];
1197 mic_statistics micstats;
1198#endif
1199 HostRxDesc rxfids[MPI_MAX_FIDS]; // rx/tx/config MPI350 descriptors
1200 HostTxDesc txfids[MPI_MAX_FIDS];
1201 HostRidDesc config_desc;
1202 unsigned long ridbus; // phys addr of config_desc
1203 struct sk_buff_head txq;// tx queue used by mpi350 code
1204 struct pci_dev *pci;
1205 unsigned char __iomem *pcimem;
1206 unsigned char __iomem *pciaux;
1207 unsigned char *shared;
1208 dma_addr_t shared_dma;
1209 int power;
1210 SsidRid *SSID;
1211 APListRid *APList;
1212#define PCI_SHARED_LEN 2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
1213 char proc_name[IFNAMSIZ];
1214};
1215
1216static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen,
1217 int whichbap) {
1218 return ai->bap_read(ai, pu16Dst, bytelen, whichbap);
1219}
1220
1221static int setup_proc_entry( struct net_device *dev,
1222 struct airo_info *apriv );
1223static int takedown_proc_entry( struct net_device *dev,
1224 struct airo_info *apriv );
1225
1226#ifdef MICSUPPORT
1227/***********************************************************************
1228 * MIC ROUTINES *
1229 ***********************************************************************
1230 */
1231
1232static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq);
1233static void MoveWindow(miccntx *context, u32 micSeq);
1234void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *);
1235void emmh32_init(emmh32_context *context);
1236void emmh32_update(emmh32_context *context, u8 *pOctets, int len);
1237void emmh32_final(emmh32_context *context, u8 digest[4]);
1238
1239/* micinit - Initialize mic seed */
1240
1241static void micinit(struct airo_info *ai)
1242{
1243 MICRid mic_rid;
1244
1245 clear_bit(JOB_MIC, &ai->flags);
1246 PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0);
1247 up(&ai->sem);
1248
1249 ai->micstats.enabled = (mic_rid.state & 0x00FF) ? 1 : 0;
1250
1251 if (ai->micstats.enabled) {
1252 /* Key must be valid and different */
1253 if (mic_rid.multicastValid && (!ai->mod[0].mCtx.valid ||
1254 (memcmp (ai->mod[0].mCtx.key, mic_rid.multicast,
1255 sizeof(ai->mod[0].mCtx.key)) != 0))) {
1256 /* Age current mic Context */
1257 memcpy(&ai->mod[1].mCtx,&ai->mod[0].mCtx,sizeof(miccntx));
1258 /* Initialize new context */
1259 memcpy(&ai->mod[0].mCtx.key,mic_rid.multicast,sizeof(mic_rid.multicast));
1260 ai->mod[0].mCtx.window = 33; //Window always points to the middle
1261 ai->mod[0].mCtx.rx = 0; //Rx Sequence numbers
1262 ai->mod[0].mCtx.tx = 0; //Tx sequence numbers
1263 ai->mod[0].mCtx.valid = 1; //Key is now valid
1264
1265 /* Give key to mic seed */
1266 emmh32_setseed(&ai->mod[0].mCtx.seed,mic_rid.multicast,sizeof(mic_rid.multicast), ai->tfm);
1267 }
1268
1269 /* Key must be valid and different */
1270 if (mic_rid.unicastValid && (!ai->mod[0].uCtx.valid ||
1271 (memcmp(ai->mod[0].uCtx.key, mic_rid.unicast,
1272 sizeof(ai->mod[0].uCtx.key)) != 0))) {
1273 /* Age current mic Context */
1274 memcpy(&ai->mod[1].uCtx,&ai->mod[0].uCtx,sizeof(miccntx));
1275 /* Initialize new context */
1276 memcpy(&ai->mod[0].uCtx.key,mic_rid.unicast,sizeof(mic_rid.unicast));
1277
1278 ai->mod[0].uCtx.window = 33; //Window always points to the middle
1279 ai->mod[0].uCtx.rx = 0; //Rx Sequence numbers
1280 ai->mod[0].uCtx.tx = 0; //Tx sequence numbers
1281 ai->mod[0].uCtx.valid = 1; //Key is now valid
1282
1283 //Give key to mic seed
1284 emmh32_setseed(&ai->mod[0].uCtx.seed, mic_rid.unicast, sizeof(mic_rid.unicast), ai->tfm);
1285 }
1286 } else {
1287 /* So next time we have a valid key and mic is enabled, we will update
1288 * the sequence number if the key is the same as before.
1289 */
1290 ai->mod[0].uCtx.valid = 0;
1291 ai->mod[0].mCtx.valid = 0;
1292 }
1293}
1294
1295/* micsetup - Get ready for business */
1296
1297static int micsetup(struct airo_info *ai) {
1298 int i;
1299
1300 if (ai->tfm == NULL)
1301 ai->tfm = crypto_alloc_tfm("aes", 0);
1302
1303 if (ai->tfm == NULL) {
1304 printk(KERN_ERR "airo: failed to load transform for AES\n");
1305 return ERROR;
1306 }
1307
1308 for (i=0; i < NUM_MODULES; i++) {
1309 memset(&ai->mod[i].mCtx,0,sizeof(miccntx));
1310 memset(&ai->mod[i].uCtx,0,sizeof(miccntx));
1311 }
1312 return SUCCESS;
1313}
1314
1315char micsnap[]= {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02};
1316
1317/*===========================================================================
1318 * Description: Mic a packet
1319 *
1320 * Inputs: etherHead * pointer to an 802.3 frame
1321 *
1322 * Returns: BOOLEAN if successful, otherwise false.
1323 * PacketTxLen will be updated with the mic'd packets size.
1324 *
1325 * Caveats: It is assumed that the frame buffer will already
1326 * be big enough to hold the largets mic message possible.
1327 * (No memory allocation is done here).
1328 *
1329 * Author: sbraneky (10/15/01)
1330 * Merciless hacks by rwilcher (1/14/02)
1331 */
1332
1333static int encapsulate(struct airo_info *ai ,etherHead *frame, MICBuffer *mic, int payLen)
1334{
1335 miccntx *context;
1336
1337 // Determine correct context
1338 // If not adhoc, always use unicast key
1339
1340 if (test_bit(FLAG_ADHOC, &ai->flags) && (frame->da[0] & 0x1))
1341 context = &ai->mod[0].mCtx;
1342 else
1343 context = &ai->mod[0].uCtx;
1344
1345 if (!context->valid)
1346 return ERROR;
1347
1348 mic->typelen = htons(payLen + 16); //Length of Mic'd packet
1349
1350 memcpy(&mic->u.snap, micsnap, sizeof(micsnap)); // Add Snap
1351
1352 // Add Tx sequence
1353 mic->seq = htonl(context->tx);
1354 context->tx += 2;
1355
1356 emmh32_init(&context->seed); // Mic the packet
1357 emmh32_update(&context->seed,frame->da,ETH_ALEN * 2); // DA,SA
1358 emmh32_update(&context->seed,(u8*)&mic->typelen,10); // Type/Length and Snap
1359 emmh32_update(&context->seed,(u8*)&mic->seq,sizeof(mic->seq)); //SEQ
1360 emmh32_update(&context->seed,frame->da + ETH_ALEN * 2,payLen); //payload
1361 emmh32_final(&context->seed, (u8*)&mic->mic);
1362
1363 /* New Type/length ?????????? */
1364 mic->typelen = 0; //Let NIC know it could be an oversized packet
1365 return SUCCESS;
1366}
1367
1368typedef enum {
1369 NONE,
1370 NOMIC,
1371 NOMICPLUMMED,
1372 SEQUENCE,
1373 INCORRECTMIC,
1374} mic_error;
1375
1376/*===========================================================================
1377 * Description: Decapsulates a MIC'd packet and returns the 802.3 packet
1378 * (removes the MIC stuff) if packet is a valid packet.
1379 *
1380 * Inputs: etherHead pointer to the 802.3 packet
1381 *
1382 * Returns: BOOLEAN - TRUE if packet should be dropped otherwise FALSE
1383 *
1384 * Author: sbraneky (10/15/01)
1385 * Merciless hacks by rwilcher (1/14/02)
1386 *---------------------------------------------------------------------------
1387 */
1388
1389static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *eth, u16 payLen)
1390{
1391 int i;
1392 u32 micSEQ;
1393 miccntx *context;
1394 u8 digest[4];
1395 mic_error micError = NONE;
1396
1397 // Check if the packet is a Mic'd packet
1398
1399 if (!ai->micstats.enabled) {
1400 //No Mic set or Mic OFF but we received a MIC'd packet.
1401 if (memcmp ((u8*)eth + 14, micsnap, sizeof(micsnap)) == 0) {
1402 ai->micstats.rxMICPlummed++;
1403 return ERROR;
1404 }
1405 return SUCCESS;
1406 }
1407
1408 if (ntohs(mic->typelen) == 0x888E)
1409 return SUCCESS;
1410
1411 if (memcmp (mic->u.snap, micsnap, sizeof(micsnap)) != 0) {
1412 // Mic enabled but packet isn't Mic'd
1413 ai->micstats.rxMICPlummed++;
1414 return ERROR;
1415 }
1416
1417 micSEQ = ntohl(mic->seq); //store SEQ as CPU order
1418
1419 //At this point we a have a mic'd packet and mic is enabled
1420 //Now do the mic error checking.
1421
1422 //Receive seq must be odd
1423 if ( (micSEQ & 1) == 0 ) {
1424 ai->micstats.rxWrongSequence++;
1425 return ERROR;
1426 }
1427
1428 for (i = 0; i < NUM_MODULES; i++) {
1429 int mcast = eth->da[0] & 1;
1430 //Determine proper context
1431 context = mcast ? &ai->mod[i].mCtx : &ai->mod[i].uCtx;
1432
1433 //Make sure context is valid
1434 if (!context->valid) {
1435 if (i == 0)
1436 micError = NOMICPLUMMED;
1437 continue;
1438 }
1439 //DeMic it
1440
1441 if (!mic->typelen)
1442 mic->typelen = htons(payLen + sizeof(MICBuffer) - 2);
1443
1444 emmh32_init(&context->seed);
1445 emmh32_update(&context->seed, eth->da, ETH_ALEN*2);
1446 emmh32_update(&context->seed, (u8 *)&mic->typelen, sizeof(mic->typelen)+sizeof(mic->u.snap));
1447 emmh32_update(&context->seed, (u8 *)&mic->seq,sizeof(mic->seq));
1448 emmh32_update(&context->seed, eth->da + ETH_ALEN*2,payLen);
1449 //Calculate MIC
1450 emmh32_final(&context->seed, digest);
1451
1452 if (memcmp(digest, &mic->mic, 4)) { //Make sure the mics match
1453 //Invalid Mic
1454 if (i == 0)
1455 micError = INCORRECTMIC;
1456 continue;
1457 }
1458
1459 //Check Sequence number if mics pass
1460 if (RxSeqValid(ai, context, mcast, micSEQ) == SUCCESS) {
1461 ai->micstats.rxSuccess++;
1462 return SUCCESS;
1463 }
1464 if (i == 0)
1465 micError = SEQUENCE;
1466 }
1467
1468 // Update statistics
1469 switch (micError) {
1470 case NOMICPLUMMED: ai->micstats.rxMICPlummed++; break;
1471 case SEQUENCE: ai->micstats.rxWrongSequence++; break;
1472 case INCORRECTMIC: ai->micstats.rxIncorrectMIC++; break;
1473 case NONE: break;
1474 case NOMIC: break;
1475 }
1476 return ERROR;
1477}
1478
1479/*===========================================================================
1480 * Description: Checks the Rx Seq number to make sure it is valid
1481 * and hasn't already been received
1482 *
1483 * Inputs: miccntx - mic context to check seq against
1484 * micSeq - the Mic seq number
1485 *
1486 * Returns: TRUE if valid otherwise FALSE.
1487 *
1488 * Author: sbraneky (10/15/01)
1489 * Merciless hacks by rwilcher (1/14/02)
1490 *---------------------------------------------------------------------------
1491 */
1492
1493static int RxSeqValid (struct airo_info *ai,miccntx *context,int mcast,u32 micSeq)
1494{
1495 u32 seq,index;
1496
1497 //Allow for the ap being rebooted - if it is then use the next
1498 //sequence number of the current sequence number - might go backwards
1499
1500 if (mcast) {
1501 if (test_bit(FLAG_UPDATE_MULTI, &ai->flags)) {
1502 clear_bit (FLAG_UPDATE_MULTI, &ai->flags);
1503 context->window = (micSeq > 33) ? micSeq : 33;
1504 context->rx = 0; // Reset rx
1505 }
1506 } else if (test_bit(FLAG_UPDATE_UNI, &ai->flags)) {
1507 clear_bit (FLAG_UPDATE_UNI, &ai->flags);
1508 context->window = (micSeq > 33) ? micSeq : 33; // Move window
1509 context->rx = 0; // Reset rx
1510 }
1511
1512 //Make sequence number relative to START of window
1513 seq = micSeq - (context->window - 33);
1514
1515 //Too old of a SEQ number to check.
1516 if ((s32)seq < 0)
1517 return ERROR;
1518
1519 if ( seq > 64 ) {
1520 //Window is infinite forward
1521 MoveWindow(context,micSeq);
1522 return SUCCESS;
1523 }
1524
1525 // We are in the window. Now check the context rx bit to see if it was already sent
1526 seq >>= 1; //divide by 2 because we only have odd numbers
1527 index = 1 << seq; //Get an index number
1528
1529 if (!(context->rx & index)) {
1530 //micSEQ falls inside the window.
1531 //Add seqence number to the list of received numbers.
1532 context->rx |= index;
1533
1534 MoveWindow(context,micSeq);
1535
1536 return SUCCESS;
1537 }
1538 return ERROR;
1539}
1540
1541static void MoveWindow(miccntx *context, u32 micSeq)
1542{
1543 u32 shift;
1544
1545 //Move window if seq greater than the middle of the window
1546 if (micSeq > context->window) {
1547 shift = (micSeq - context->window) >> 1;
1548
1549 //Shift out old
1550 if (shift < 32)
1551 context->rx >>= shift;
1552 else
1553 context->rx = 0;
1554
1555 context->window = micSeq; //Move window
1556 }
1557}
1558
1559/*==============================================*/
1560/*========== EMMH ROUTINES ====================*/
1561/*==============================================*/
1562
1563/* mic accumulate */
1564#define MIC_ACCUM(val) \
1565 context->accum += (u64)(val) * context->coeff[coeff_position++];
1566
1567static unsigned char aes_counter[16];
1568
1569/* expand the key to fill the MMH coefficient array */
1570void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen, struct crypto_tfm *tfm)
1571{
1572 /* take the keying material, expand if necessary, truncate at 16-bytes */
1573 /* run through AES counter mode to generate context->coeff[] */
1574
1575 int i,j;
1576 u32 counter;
1577 u8 *cipher, plain[16];
1578 struct scatterlist sg[1];
1579
1580 crypto_cipher_setkey(tfm, pkey, 16);
1581 counter = 0;
1582 for (i = 0; i < (sizeof(context->coeff)/sizeof(context->coeff[0])); ) {
1583 aes_counter[15] = (u8)(counter >> 0);
1584 aes_counter[14] = (u8)(counter >> 8);
1585 aes_counter[13] = (u8)(counter >> 16);
1586 aes_counter[12] = (u8)(counter >> 24);
1587 counter++;
1588 memcpy (plain, aes_counter, 16);
1589 sg[0].page = virt_to_page(plain);
1590 sg[0].offset = ((long) plain & ~PAGE_MASK);
1591 sg[0].length = 16;
1592 crypto_cipher_encrypt(tfm, sg, sg, 16);
1593 cipher = kmap(sg[0].page) + sg[0].offset;
1594 for (j=0; (j<16) && (i< (sizeof(context->coeff)/sizeof(context->coeff[0]))); ) {
1595 context->coeff[i++] = ntohl(*(u32 *)&cipher[j]);
1596 j += 4;
1597 }
1598 }
1599}
1600
1601/* prepare for calculation of a new mic */
1602void emmh32_init(emmh32_context *context)
1603{
1604 /* prepare for new mic calculation */
1605 context->accum = 0;
1606 context->position = 0;
1607}
1608
1609/* add some bytes to the mic calculation */
1610void emmh32_update(emmh32_context *context, u8 *pOctets, int len)
1611{
1612 int coeff_position, byte_position;
1613
1614 if (len == 0) return;
1615
1616 coeff_position = context->position >> 2;
1617
1618 /* deal with partial 32-bit word left over from last update */
1619 byte_position = context->position & 3;
1620 if (byte_position) {
1621 /* have a partial word in part to deal with */
1622 do {
1623 if (len == 0) return;
1624 context->part.d8[byte_position++] = *pOctets++;
1625 context->position++;
1626 len--;
1627 } while (byte_position < 4);
1628 MIC_ACCUM(htonl(context->part.d32));
1629 }
1630
1631 /* deal with full 32-bit words */
1632 while (len >= 4) {
1633 MIC_ACCUM(htonl(*(u32 *)pOctets));
1634 context->position += 4;
1635 pOctets += 4;
1636 len -= 4;
1637 }
1638
1639 /* deal with partial 32-bit word that will be left over from this update */
1640 byte_position = 0;
1641 while (len > 0) {
1642 context->part.d8[byte_position++] = *pOctets++;
1643 context->position++;
1644 len--;
1645 }
1646}
1647
1648/* mask used to zero empty bytes for final partial word */
1649static u32 mask32[4] = { 0x00000000L, 0xFF000000L, 0xFFFF0000L, 0xFFFFFF00L };
1650
1651/* calculate the mic */
1652void emmh32_final(emmh32_context *context, u8 digest[4])
1653{
1654 int coeff_position, byte_position;
1655 u32 val;
1656
1657 u64 sum, utmp;
1658 s64 stmp;
1659
1660 coeff_position = context->position >> 2;
1661
1662 /* deal with partial 32-bit word left over from last update */
1663 byte_position = context->position & 3;
1664 if (byte_position) {
1665 /* have a partial word in part to deal with */
1666 val = htonl(context->part.d32);
1667 MIC_ACCUM(val & mask32[byte_position]); /* zero empty bytes */
1668 }
1669
1670 /* reduce the accumulated u64 to a 32-bit MIC */
1671 sum = context->accum;
1672 stmp = (sum & 0xffffffffLL) - ((sum >> 32) * 15);
1673 utmp = (stmp & 0xffffffffLL) - ((stmp >> 32) * 15);
1674 sum = utmp & 0xffffffffLL;
1675 if (utmp > 0x10000000fLL)
1676 sum -= 15;
1677
1678 val = (u32)sum;
1679 digest[0] = (val>>24) & 0xFF;
1680 digest[1] = (val>>16) & 0xFF;
1681 digest[2] = (val>>8) & 0xFF;
1682 digest[3] = val & 0xFF;
1683}
1684#endif
1685
1686static int readBSSListRid(struct airo_info *ai, int first,
1687 BSSListRid *list) {
1688 int rc;
1689 Cmd cmd;
1690 Resp rsp;
1691
1692 if (first == 1) {
1693 if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
1694 memset(&cmd, 0, sizeof(cmd));
1695 cmd.cmd=CMD_LISTBSS;
1696 if (down_interruptible(&ai->sem))
1697 return -ERESTARTSYS;
1698 issuecommand(ai, &cmd, &rsp);
1699 up(&ai->sem);
1700 /* Let the command take effect */
1701 ai->task = current;
1702 ssleep(3);
1703 ai->task = NULL;
1704 }
1705 rc = PC4500_readrid(ai, first ? RID_BSSLISTFIRST : RID_BSSLISTNEXT,
1706 list, sizeof(*list), 1);
1707
1708 list->len = le16_to_cpu(list->len);
1709 list->index = le16_to_cpu(list->index);
1710 list->radioType = le16_to_cpu(list->radioType);
1711 list->cap = le16_to_cpu(list->cap);
1712 list->beaconInterval = le16_to_cpu(list->beaconInterval);
1713 list->fh.dwell = le16_to_cpu(list->fh.dwell);
1714 list->dsChannel = le16_to_cpu(list->dsChannel);
1715 list->atimWindow = le16_to_cpu(list->atimWindow);
1716 return rc;
1717}
1718
1719static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp, int lock) {
1720 int rc = PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,
1721 wkr, sizeof(*wkr), lock);
1722
1723 wkr->len = le16_to_cpu(wkr->len);
1724 wkr->kindex = le16_to_cpu(wkr->kindex);
1725 wkr->klen = le16_to_cpu(wkr->klen);
1726 return rc;
1727}
1728/* In the writeXXXRid routines we copy the rids so that we don't screwup
1729 * the originals when we endian them... */
1730static int writeWepKeyRid(struct airo_info*ai, WepKeyRid *pwkr, int perm, int lock) {
1731 int rc;
1732 WepKeyRid wkr = *pwkr;
1733
1734 wkr.len = cpu_to_le16(wkr.len);
1735 wkr.kindex = cpu_to_le16(wkr.kindex);
1736 wkr.klen = cpu_to_le16(wkr.klen);
1737 rc = PC4500_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr), lock);
1738 if (rc!=SUCCESS) printk(KERN_ERR "airo: WEP_TEMP set %x\n", rc);
1739 if (perm) {
1740 rc = PC4500_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr), lock);
1741 if (rc!=SUCCESS) {
1742 printk(KERN_ERR "airo: WEP_PERM set %x\n", rc);
1743 }
1744 }
1745 return rc;
1746}
1747
1748static int readSsidRid(struct airo_info*ai, SsidRid *ssidr) {
1749 int i;
1750 int rc = PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr), 1);
1751
1752 ssidr->len = le16_to_cpu(ssidr->len);
1753 for(i = 0; i < 3; i++) {
1754 ssidr->ssids[i].len = le16_to_cpu(ssidr->ssids[i].len);
1755 }
1756 return rc;
1757}
1758static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr, int lock) {
1759 int rc;
1760 int i;
1761 SsidRid ssidr = *pssidr;
1762
1763 ssidr.len = cpu_to_le16(ssidr.len);
1764 for(i = 0; i < 3; i++) {
1765 ssidr.ssids[i].len = cpu_to_le16(ssidr.ssids[i].len);
1766 }
1767 rc = PC4500_writerid(ai, RID_SSID, &ssidr, sizeof(ssidr), lock);
1768 return rc;
1769}
1770static int readConfigRid(struct airo_info*ai, int lock) {
1771 int rc;
1772 u16 *s;
1773 ConfigRid cfg;
1774
1775 if (ai->config.len)
1776 return SUCCESS;
1777
1778 rc = PC4500_readrid(ai, RID_ACTUALCONFIG, &cfg, sizeof(cfg), lock);
1779 if (rc != SUCCESS)
1780 return rc;
1781
1782 for(s = &cfg.len; s <= &cfg.rtsThres; s++) *s = le16_to_cpu(*s);
1783
1784 for(s = &cfg.shortRetryLimit; s <= &cfg.radioType; s++)
1785 *s = le16_to_cpu(*s);
1786
1787 for(s = &cfg.txPower; s <= &cfg.radioSpecific; s++)
1788 *s = le16_to_cpu(*s);
1789
1790 for(s = &cfg.arlThreshold; s <= &cfg._reserved4[0]; s++)
1791 *s = cpu_to_le16(*s);
1792
1793 for(s = &cfg.autoWake; s <= &cfg.autoWake; s++)
1794 *s = cpu_to_le16(*s);
1795
1796 ai->config = cfg;
1797 return SUCCESS;
1798}
1799static inline void checkThrottle(struct airo_info *ai) {
1800 int i;
1801/* Old hardware had a limit on encryption speed */
1802 if (ai->config.authType != AUTH_OPEN && maxencrypt) {
1803 for(i=0; i<8; i++) {
1804 if (ai->config.rates[i] > maxencrypt) {
1805 ai->config.rates[i] = 0;
1806 }
1807 }
1808 }
1809}
1810static int writeConfigRid(struct airo_info*ai, int lock) {
1811 u16 *s;
1812 ConfigRid cfgr;
1813
1814 if (!test_bit (FLAG_COMMIT, &ai->flags))
1815 return SUCCESS;
1816
1817 clear_bit (FLAG_COMMIT, &ai->flags);
1818 clear_bit (FLAG_RESET, &ai->flags);
1819 checkThrottle(ai);
1820 cfgr = ai->config;
1821
1822 if ((cfgr.opmode & 0xFF) == MODE_STA_IBSS)
1823 set_bit(FLAG_ADHOC, &ai->flags);
1824 else
1825 clear_bit(FLAG_ADHOC, &ai->flags);
1826
1827 for(s = &cfgr.len; s <= &cfgr.rtsThres; s++) *s = cpu_to_le16(*s);
1828
1829 for(s = &cfgr.shortRetryLimit; s <= &cfgr.radioType; s++)
1830 *s = cpu_to_le16(*s);
1831
1832 for(s = &cfgr.txPower; s <= &cfgr.radioSpecific; s++)
1833 *s = cpu_to_le16(*s);
1834
1835 for(s = &cfgr.arlThreshold; s <= &cfgr._reserved4[0]; s++)
1836 *s = cpu_to_le16(*s);
1837
1838 for(s = &cfgr.autoWake; s <= &cfgr.autoWake; s++)
1839 *s = cpu_to_le16(*s);
1840
1841 return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock);
1842}
1843static int readStatusRid(struct airo_info*ai, StatusRid *statr, int lock) {
1844 int rc = PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock);
1845 u16 *s;
1846
1847 statr->len = le16_to_cpu(statr->len);
1848 for(s = &statr->mode; s <= &statr->SSIDlen; s++) *s = le16_to_cpu(*s);
1849
1850 for(s = &statr->beaconPeriod; s <= &statr->shortPreamble; s++)
1851 *s = le16_to_cpu(*s);
1852 statr->load = le16_to_cpu(statr->load);
1853 statr->assocStatus = le16_to_cpu(statr->assocStatus);
1854 return rc;
1855}
1856static int readAPListRid(struct airo_info*ai, APListRid *aplr) {
1857 int rc = PC4500_readrid(ai, RID_APLIST, aplr, sizeof(*aplr), 1);
1858 aplr->len = le16_to_cpu(aplr->len);
1859 return rc;
1860}
1861static int writeAPListRid(struct airo_info*ai, APListRid *aplr, int lock) {
1862 int rc;
1863 aplr->len = cpu_to_le16(aplr->len);
1864 rc = PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), lock);
1865 return rc;
1866}
1867static int readCapabilityRid(struct airo_info*ai, CapabilityRid *capr, int lock) {
1868 int rc = PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), lock);
1869 u16 *s;
1870
1871 capr->len = le16_to_cpu(capr->len);
1872 capr->prodNum = le16_to_cpu(capr->prodNum);
1873 capr->radioType = le16_to_cpu(capr->radioType);
1874 capr->country = le16_to_cpu(capr->country);
1875 for(s = &capr->txPowerLevels[0]; s <= &capr->requiredHard; s++)
1876 *s = le16_to_cpu(*s);
1877 return rc;
1878}
1879static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) {
1880 int rc = PC4500_readrid(ai, rid, sr, sizeof(*sr), lock);
1881 u32 *i;
1882
1883 sr->len = le16_to_cpu(sr->len);
1884 for(i = &sr->vals[0]; i <= &sr->vals[99]; i++) *i = le32_to_cpu(*i);
1885 return rc;
1886}
1887
1888static int airo_open(struct net_device *dev) {
1889 struct airo_info *info = dev->priv;
1890 Resp rsp;
1891
1892 if (test_bit(FLAG_FLASHING, &info->flags))
1893 return -EIO;
1894
1895 /* Make sure the card is configured.
1896 * Wireless Extensions may postpone config changes until the card
1897 * is open (to pipeline changes and speed-up card setup). If
1898 * those changes are not yet commited, do it now - Jean II */
1899 if (test_bit (FLAG_COMMIT, &info->flags)) {
1900 disable_MAC(info, 1);
1901 writeConfigRid(info, 1);
1902 }
1903
1904 if (info->wifidev != dev) {
1905 /* Power on the MAC controller (which may have been disabled) */
1906 clear_bit(FLAG_RADIO_DOWN, &info->flags);
1907 enable_interrupts(info);
1908 }
1909 enable_MAC(info, &rsp, 1);
1910
1911 netif_start_queue(dev);
1912 return 0;
1913}
1914
1915static int mpi_start_xmit(struct sk_buff *skb, struct net_device *dev) {
1916 int npacks, pending;
1917 unsigned long flags;
1918 struct airo_info *ai = dev->priv;
1919
1920 if (!skb) {
1921 printk(KERN_ERR "airo: %s: skb==NULL\n",__FUNCTION__);
1922 return 0;
1923 }
1924 npacks = skb_queue_len (&ai->txq);
1925
1926 if (npacks >= MAXTXQ - 1) {
1927 netif_stop_queue (dev);
1928 if (npacks > MAXTXQ) {
1929 ai->stats.tx_fifo_errors++;
1930 return 1;
1931 }
1932 skb_queue_tail (&ai->txq, skb);
1933 return 0;
1934 }
1935
1936 spin_lock_irqsave(&ai->aux_lock, flags);
1937 skb_queue_tail (&ai->txq, skb);
1938 pending = test_bit(FLAG_PENDING_XMIT, &ai->flags);
1939 spin_unlock_irqrestore(&ai->aux_lock,flags);
1940 netif_wake_queue (dev);
1941
1942 if (pending == 0) {
1943 set_bit(FLAG_PENDING_XMIT, &ai->flags);
1944 mpi_send_packet (dev);
1945 }
1946 return 0;
1947}
1948
1949/*
1950 * @mpi_send_packet
1951 *
1952 * Attempt to transmit a packet. Can be called from interrupt
1953 * or transmit . return number of packets we tried to send
1954 */
1955
1956static int mpi_send_packet (struct net_device *dev)
1957{
1958 struct sk_buff *skb;
1959 unsigned char *buffer;
1960 s16 len, *payloadLen;
1961 struct airo_info *ai = dev->priv;
1962 u8 *sendbuf;
1963
1964 /* get a packet to send */
1965
1966 if ((skb = skb_dequeue(&ai->txq)) == 0) {
1967 printk (KERN_ERR
1968 "airo: %s: Dequeue'd zero in send_packet()\n",
1969 __FUNCTION__);
1970 return 0;
1971 }
1972
1973 /* check min length*/
1974 len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1975 buffer = skb->data;
1976
1977 ai->txfids[0].tx_desc.offset = 0;
1978 ai->txfids[0].tx_desc.valid = 1;
1979 ai->txfids[0].tx_desc.eoc = 1;
1980 ai->txfids[0].tx_desc.len =len+sizeof(WifiHdr);
1981
1982/*
1983 * Magic, the cards firmware needs a length count (2 bytes) in the host buffer
1984 * right after TXFID_HDR.The TXFID_HDR contains the status short so payloadlen
1985 * is immediatly after it. ------------------------------------------------
1986 * |TXFIDHDR+STATUS|PAYLOADLEN|802.3HDR|PACKETDATA|
1987 * ------------------------------------------------
1988 */
1989
1990 memcpy((char *)ai->txfids[0].virtual_host_addr,
1991 (char *)&wifictlhdr8023, sizeof(wifictlhdr8023));
1992
1993 payloadLen = (s16 *)(ai->txfids[0].virtual_host_addr +
1994 sizeof(wifictlhdr8023));
1995 sendbuf = ai->txfids[0].virtual_host_addr +
1996 sizeof(wifictlhdr8023) + 2 ;
1997
1998 /*
1999 * Firmware automaticly puts 802 header on so
2000 * we don't need to account for it in the length
2001 */
2002#ifdef MICSUPPORT
2003 if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
2004 (ntohs(((u16 *)buffer)[6]) != 0x888E)) {
2005 MICBuffer pMic;
2006
2007 if (encapsulate(ai, (etherHead *)buffer, &pMic, len - sizeof(etherHead)) != SUCCESS)
2008 return ERROR;
2009
2010 *payloadLen = cpu_to_le16(len-sizeof(etherHead)+sizeof(pMic));
2011 ai->txfids[0].tx_desc.len += sizeof(pMic);
2012 /* copy data into airo dma buffer */
2013 memcpy (sendbuf, buffer, sizeof(etherHead));
2014 buffer += sizeof(etherHead);
2015 sendbuf += sizeof(etherHead);
2016 memcpy (sendbuf, &pMic, sizeof(pMic));
2017 sendbuf += sizeof(pMic);
2018 memcpy (sendbuf, buffer, len - sizeof(etherHead));
2019 } else
2020#endif
2021 {
2022 *payloadLen = cpu_to_le16(len - sizeof(etherHead));
2023
2024 dev->trans_start = jiffies;
2025
2026 /* copy data into airo dma buffer */
2027 memcpy(sendbuf, buffer, len);
2028 }
2029
2030 memcpy_toio(ai->txfids[0].card_ram_off,
2031 &ai->txfids[0].tx_desc, sizeof(TxFid));
2032
2033 OUT4500(ai, EVACK, 8);
2034
2035 dev_kfree_skb_any(skb);
2036 return 1;
2037}
2038
2039static void get_tx_error(struct airo_info *ai, u32 fid)
2040{
2041 u16 status;
2042
2043 if (fid < 0)
2044 status = ((WifiCtlHdr *)ai->txfids[0].virtual_host_addr)->ctlhdr.status;
2045 else {
2046 if (bap_setup(ai, ai->fids[fid] & 0xffff, 4, BAP0) != SUCCESS)
2047 return;
2048 bap_read(ai, &status, 2, BAP0);
2049 }
2050 if (le16_to_cpu(status) & 2) /* Too many retries */
2051 ai->stats.tx_aborted_errors++;
2052 if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */
2053 ai->stats.tx_heartbeat_errors++;
2054 if (le16_to_cpu(status) & 8) /* Aid fail */
2055 { }
2056 if (le16_to_cpu(status) & 0x10) /* MAC disabled */
2057 ai->stats.tx_carrier_errors++;
2058 if (le16_to_cpu(status) & 0x20) /* Association lost */
2059 { }
2060 /* We produce a TXDROP event only for retry or lifetime
2061 * exceeded, because that's the only status that really mean
2062 * that this particular node went away.
2063 * Other errors means that *we* screwed up. - Jean II */
2064 if ((le16_to_cpu(status) & 2) ||
2065 (le16_to_cpu(status) & 4)) {
2066 union iwreq_data wrqu;
2067 char junk[0x18];
2068
2069 /* Faster to skip over useless data than to do
2070 * another bap_setup(). We are at offset 0x6 and
2071 * need to go to 0x18 and read 6 bytes - Jean II */
2072 bap_read(ai, (u16 *) junk, 0x18, BAP0);
2073
2074 /* Copy 802.11 dest address.
2075 * We use the 802.11 header because the frame may
2076 * not be 802.3 or may be mangled...
2077 * In Ad-Hoc mode, it will be the node address.
2078 * In managed mode, it will be most likely the AP addr
2079 * User space will figure out how to convert it to
2080 * whatever it needs (IP address or else).
2081 * - Jean II */
2082 memcpy(wrqu.addr.sa_data, junk + 0x12, ETH_ALEN);
2083 wrqu.addr.sa_family = ARPHRD_ETHER;
2084
2085 /* Send event to user space */
2086 wireless_send_event(ai->dev, IWEVTXDROP, &wrqu, NULL);
2087 }
2088}
2089
2090static void airo_end_xmit(struct net_device *dev) {
2091 u16 status;
2092 int i;
2093 struct airo_info *priv = dev->priv;
2094 struct sk_buff *skb = priv->xmit.skb;
2095 int fid = priv->xmit.fid;
2096 u32 *fids = priv->fids;
2097
2098 clear_bit(JOB_XMIT, &priv->flags);
2099 clear_bit(FLAG_PENDING_XMIT, &priv->flags);
2100 status = transmit_802_3_packet (priv, fids[fid], skb->data);
2101 up(&priv->sem);
2102
2103 i = 0;
2104 if ( status == SUCCESS ) {
2105 dev->trans_start = jiffies;
2106 for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++);
2107 } else {
2108 priv->fids[fid] &= 0xffff;
2109 priv->stats.tx_window_errors++;
2110 }
2111 if (i < MAX_FIDS / 2)
2112 netif_wake_queue(dev);
2113 dev_kfree_skb(skb);
2114}
2115
2116static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
2117 s16 len;
2118 int i, j;
2119 struct airo_info *priv = dev->priv;
2120 u32 *fids = priv->fids;
2121
2122 if ( skb == NULL ) {
2123 printk( KERN_ERR "airo: skb == NULL!!!\n" );
2124 return 0;
2125 }
2126
2127 /* Find a vacant FID */
2128 for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ );
2129 for( j = i + 1; j < MAX_FIDS / 2 && (fids[j] & 0xffff0000); j++ );
2130
2131 if ( j >= MAX_FIDS / 2 ) {
2132 netif_stop_queue(dev);
2133
2134 if (i == MAX_FIDS / 2) {
2135 priv->stats.tx_fifo_errors++;
2136 return 1;
2137 }
2138 }
2139 /* check min length*/
2140 len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
2141 /* Mark fid as used & save length for later */
2142 fids[i] |= (len << 16);
2143 priv->xmit.skb = skb;
2144 priv->xmit.fid = i;
2145 if (down_trylock(&priv->sem) != 0) {
2146 set_bit(FLAG_PENDING_XMIT, &priv->flags);
2147 netif_stop_queue(dev);
2148 set_bit(JOB_XMIT, &priv->flags);
2149 wake_up_interruptible(&priv->thr_wait);
2150 } else
2151 airo_end_xmit(dev);
2152 return 0;
2153}
2154
2155static void airo_end_xmit11(struct net_device *dev) {
2156 u16 status;
2157 int i;
2158 struct airo_info *priv = dev->priv;
2159 struct sk_buff *skb = priv->xmit11.skb;
2160 int fid = priv->xmit11.fid;
2161 u32 *fids = priv->fids;
2162
2163 clear_bit(JOB_XMIT11, &priv->flags);
2164 clear_bit(FLAG_PENDING_XMIT11, &priv->flags);
2165 status = transmit_802_11_packet (priv, fids[fid], skb->data);
2166 up(&priv->sem);
2167
2168 i = MAX_FIDS / 2;
2169 if ( status == SUCCESS ) {
2170 dev->trans_start = jiffies;
2171 for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++);
2172 } else {
2173 priv->fids[fid] &= 0xffff;
2174 priv->stats.tx_window_errors++;
2175 }
2176 if (i < MAX_FIDS)
2177 netif_wake_queue(dev);
2178 dev_kfree_skb(skb);
2179}
2180
2181static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
2182 s16 len;
2183 int i, j;
2184 struct airo_info *priv = dev->priv;
2185 u32 *fids = priv->fids;
2186
2187 if (test_bit(FLAG_MPI, &priv->flags)) {
2188 /* Not implemented yet for MPI350 */
2189 netif_stop_queue(dev);
2190 return -ENETDOWN;
2191 }
2192
2193 if ( skb == NULL ) {
2194 printk( KERN_ERR "airo: skb == NULL!!!\n" );
2195 return 0;
2196 }
2197
2198 /* Find a vacant FID */
2199 for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ );
2200 for( j = i + 1; j < MAX_FIDS && (fids[j] & 0xffff0000); j++ );
2201
2202 if ( j >= MAX_FIDS ) {
2203 netif_stop_queue(dev);
2204
2205 if (i == MAX_FIDS) {
2206 priv->stats.tx_fifo_errors++;
2207 return 1;
2208 }
2209 }
2210 /* check min length*/
2211 len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
2212 /* Mark fid as used & save length for later */
2213 fids[i] |= (len << 16);
2214 priv->xmit11.skb = skb;
2215 priv->xmit11.fid = i;
2216 if (down_trylock(&priv->sem) != 0) {
2217 set_bit(FLAG_PENDING_XMIT11, &priv->flags);
2218 netif_stop_queue(dev);
2219 set_bit(JOB_XMIT11, &priv->flags);
2220 wake_up_interruptible(&priv->thr_wait);
2221 } else
2222 airo_end_xmit11(dev);
2223 return 0;
2224}
2225
2226static void airo_read_stats(struct airo_info *ai) {
2227 StatsRid stats_rid;
2228 u32 *vals = stats_rid.vals;
2229
2230 clear_bit(JOB_STATS, &ai->flags);
2231 if (ai->power) {
2232 up(&ai->sem);
2233 return;
2234 }
2235 readStatsRid(ai, &stats_rid, RID_STATS, 0);
2236 up(&ai->sem);
2237
2238 ai->stats.rx_packets = vals[43] + vals[44] + vals[45];
2239 ai->stats.tx_packets = vals[39] + vals[40] + vals[41];
2240 ai->stats.rx_bytes = vals[92];
2241 ai->stats.tx_bytes = vals[91];
2242 ai->stats.rx_errors = vals[0] + vals[2] + vals[3] + vals[4];
2243 ai->stats.tx_errors = vals[42] + ai->stats.tx_fifo_errors;
2244 ai->stats.multicast = vals[43];
2245 ai->stats.collisions = vals[89];
2246
2247 /* detailed rx_errors: */
2248 ai->stats.rx_length_errors = vals[3];
2249 ai->stats.rx_crc_errors = vals[4];
2250 ai->stats.rx_frame_errors = vals[2];
2251 ai->stats.rx_fifo_errors = vals[0];
2252}
2253
2254struct net_device_stats *airo_get_stats(struct net_device *dev)
2255{
2256 struct airo_info *local = dev->priv;
2257
2258 if (!test_bit(JOB_STATS, &local->flags)) {
2259 /* Get stats out of the card if available */
2260 if (down_trylock(&local->sem) != 0) {
2261 set_bit(JOB_STATS, &local->flags);
2262 wake_up_interruptible(&local->thr_wait);
2263 } else
2264 airo_read_stats(local);
2265 }
2266
2267 return &local->stats;
2268}
2269
2270static void airo_set_promisc(struct airo_info *ai) {
2271 Cmd cmd;
2272 Resp rsp;
2273
2274 memset(&cmd, 0, sizeof(cmd));
2275 cmd.cmd=CMD_SETMODE;
2276 clear_bit(JOB_PROMISC, &ai->flags);
2277 cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC;
2278 issuecommand(ai, &cmd, &rsp);
2279 up(&ai->sem);
2280}
2281
2282static void airo_set_multicast_list(struct net_device *dev) {
2283 struct airo_info *ai = dev->priv;
2284
2285 if ((dev->flags ^ ai->flags) & IFF_PROMISC) {
2286 change_bit(FLAG_PROMISC, &ai->flags);
2287 if (down_trylock(&ai->sem) != 0) {
2288 set_bit(JOB_PROMISC, &ai->flags);
2289 wake_up_interruptible(&ai->thr_wait);
2290 } else
2291 airo_set_promisc(ai);
2292 }
2293
2294 if ((dev->flags&IFF_ALLMULTI)||dev->mc_count>0) {
2295 /* Turn on multicast. (Should be already setup...) */
2296 }
2297}
2298
2299static int airo_set_mac_address(struct net_device *dev, void *p)
2300{
2301 struct airo_info *ai = dev->priv;
2302 struct sockaddr *addr = p;
2303 Resp rsp;
2304
2305 readConfigRid(ai, 1);
2306 memcpy (ai->config.macAddr, addr->sa_data, dev->addr_len);
2307 set_bit (FLAG_COMMIT, &ai->flags);
2308 disable_MAC(ai, 1);
2309 writeConfigRid (ai, 1);
2310 enable_MAC(ai, &rsp, 1);
2311 memcpy (ai->dev->dev_addr, addr->sa_data, dev->addr_len);
2312 if (ai->wifidev)
2313 memcpy (ai->wifidev->dev_addr, addr->sa_data, dev->addr_len);
2314 return 0;
2315}
2316
2317static int airo_change_mtu(struct net_device *dev, int new_mtu)
2318{
2319 if ((new_mtu < 68) || (new_mtu > 2400))
2320 return -EINVAL;
2321 dev->mtu = new_mtu;
2322 return 0;
2323}
2324
2325
2326static int airo_close(struct net_device *dev) {
2327 struct airo_info *ai = dev->priv;
2328
2329 netif_stop_queue(dev);
2330
2331 if (ai->wifidev != dev) {
2332#ifdef POWER_ON_DOWN
2333 /* Shut power to the card. The idea is that the user can save
2334 * power when he doesn't need the card with "ifconfig down".
2335 * That's the method that is most friendly towards the network
2336 * stack (i.e. the network stack won't try to broadcast
2337 * anything on the interface and routes are gone. Jean II */
2338 set_bit(FLAG_RADIO_DOWN, &ai->flags);
2339 disable_MAC(ai, 1);
2340#endif
2341 disable_interrupts( ai );
2342 }
2343 return 0;
2344}
2345
2346static void del_airo_dev( struct net_device *dev );
2347
2348void stop_airo_card( struct net_device *dev, int freeres )
2349{
2350 struct airo_info *ai = dev->priv;
2351
2352 set_bit(FLAG_RADIO_DOWN, &ai->flags);
2353 disable_MAC(ai, 1);
2354 disable_interrupts(ai);
2355 free_irq( dev->irq, dev );
2356 takedown_proc_entry( dev, ai );
2357 if (test_bit(FLAG_REGISTERED, &ai->flags)) {
2358 unregister_netdev( dev );
2359 if (ai->wifidev) {
2360 unregister_netdev(ai->wifidev);
2361 free_netdev(ai->wifidev);
2362 ai->wifidev = NULL;
2363 }
2364 clear_bit(FLAG_REGISTERED, &ai->flags);
2365 }
2366 set_bit(JOB_DIE, &ai->flags);
2367 kill_proc(ai->thr_pid, SIGTERM, 1);
2368 wait_for_completion(&ai->thr_exited);
2369
2370 /*
2371 * Clean out tx queue
2372 */
2373 if (test_bit(FLAG_MPI, &ai->flags) && skb_queue_len (&ai->txq) > 0) {
2374 struct sk_buff *skb = NULL;
2375 for (;(skb = skb_dequeue(&ai->txq));)
2376 dev_kfree_skb(skb);
2377 }
2378
2379 if (ai->flash)
2380 kfree(ai->flash);
2381 if (ai->rssi)
2382 kfree(ai->rssi);
2383 if (ai->APList)
2384 kfree(ai->APList);
2385 if (ai->SSID)
2386 kfree(ai->SSID);
2387 if (freeres) {
2388 /* PCMCIA frees this stuff, so only for PCI and ISA */
2389 release_region( dev->base_addr, 64 );
2390 if (test_bit(FLAG_MPI, &ai->flags)) {
2391 if (ai->pci)
2392 mpi_unmap_card(ai->pci);
2393 if (ai->pcimem)
2394 iounmap(ai->pcimem);
2395 if (ai->pciaux)
2396 iounmap(ai->pciaux);
2397 pci_free_consistent(ai->pci, PCI_SHARED_LEN,
2398 ai->shared, ai->shared_dma);
2399 }
2400 }
2401#ifdef MICSUPPORT
2402 if (ai->tfm)
2403 crypto_free_tfm(ai->tfm);
2404#endif
2405 del_airo_dev( dev );
2406 free_netdev( dev );
2407}
2408
2409EXPORT_SYMBOL(stop_airo_card);
2410
2411static int add_airo_dev( struct net_device *dev );
2412
2413int wll_header_parse(struct sk_buff *skb, unsigned char *haddr)
2414{
2415 memcpy(haddr, skb->mac.raw + 10, ETH_ALEN);
2416 return ETH_ALEN;
2417}
2418
2419static void mpi_unmap_card(struct pci_dev *pci)
2420{
2421 unsigned long mem_start = pci_resource_start(pci, 1);
2422 unsigned long mem_len = pci_resource_len(pci, 1);
2423 unsigned long aux_start = pci_resource_start(pci, 2);
2424 unsigned long aux_len = AUXMEMSIZE;
2425
2426 release_mem_region(aux_start, aux_len);
2427 release_mem_region(mem_start, mem_len);
2428}
2429
2430/*************************************************************
2431 * This routine assumes that descriptors have been setup .
2432 * Run at insmod time or after reset when the decriptors
2433 * have been initialized . Returns 0 if all is well nz
2434 * otherwise . Does not allocate memory but sets up card
2435 * using previously allocated descriptors.
2436 */
2437static int mpi_init_descriptors (struct airo_info *ai)
2438{
2439 Cmd cmd;
2440 Resp rsp;
2441 int i;
2442 int rc = SUCCESS;
2443
2444 /* Alloc card RX descriptors */
2445 netif_stop_queue(ai->dev);
2446
2447 memset(&rsp,0,sizeof(rsp));
2448 memset(&cmd,0,sizeof(cmd));
2449
2450 cmd.cmd = CMD_ALLOCATEAUX;
2451 cmd.parm0 = FID_RX;
2452 cmd.parm1 = (ai->rxfids[0].card_ram_off - ai->pciaux);
2453 cmd.parm2 = MPI_MAX_FIDS;
2454 rc=issuecommand(ai, &cmd, &rsp);
2455 if (rc != SUCCESS) {
2456 printk(KERN_ERR "airo: Couldn't allocate RX FID\n");
2457 return rc;
2458 }
2459
2460 for (i=0; i<MPI_MAX_FIDS; i++) {
2461 memcpy_toio(ai->rxfids[i].card_ram_off,
2462 &ai->rxfids[i].rx_desc, sizeof(RxFid));
2463 }
2464
2465 /* Alloc card TX descriptors */
2466
2467 memset(&rsp,0,sizeof(rsp));
2468 memset(&cmd,0,sizeof(cmd));
2469
2470 cmd.cmd = CMD_ALLOCATEAUX;
2471 cmd.parm0 = FID_TX;
2472 cmd.parm1 = (ai->txfids[0].card_ram_off - ai->pciaux);
2473 cmd.parm2 = MPI_MAX_FIDS;
2474
2475 for (i=0; i<MPI_MAX_FIDS; i++) {
2476 ai->txfids[i].tx_desc.valid = 1;
2477 memcpy_toio(ai->txfids[i].card_ram_off,
2478 &ai->txfids[i].tx_desc, sizeof(TxFid));
2479 }
2480 ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
2481
2482 rc=issuecommand(ai, &cmd, &rsp);
2483 if (rc != SUCCESS) {
2484 printk(KERN_ERR "airo: Couldn't allocate TX FID\n");
2485 return rc;
2486 }
2487
2488 /* Alloc card Rid descriptor */
2489 memset(&rsp,0,sizeof(rsp));
2490 memset(&cmd,0,sizeof(cmd));
2491
2492 cmd.cmd = CMD_ALLOCATEAUX;
2493 cmd.parm0 = RID_RW;
2494 cmd.parm1 = (ai->config_desc.card_ram_off - ai->pciaux);
2495 cmd.parm2 = 1; /* Magic number... */
2496 rc=issuecommand(ai, &cmd, &rsp);
2497 if (rc != SUCCESS) {
2498 printk(KERN_ERR "airo: Couldn't allocate RID\n");
2499 return rc;
2500 }
2501
2502 memcpy_toio(ai->config_desc.card_ram_off,
2503 &ai->config_desc.rid_desc, sizeof(Rid));
2504
2505 return rc;
2506}
2507
2508/*
2509 * We are setting up three things here:
2510 * 1) Map AUX memory for descriptors: Rid, TxFid, or RxFid.
2511 * 2) Map PCI memory for issueing commands.
2512 * 3) Allocate memory (shared) to send and receive ethernet frames.
2513 */
2514static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
2515 const char *name)
2516{
2517 unsigned long mem_start, mem_len, aux_start, aux_len;
2518 int rc = -1;
2519 int i;
2520 unsigned char *busaddroff,*vpackoff;
2521 unsigned char __iomem *pciaddroff;
2522
2523 mem_start = pci_resource_start(pci, 1);
2524 mem_len = pci_resource_len(pci, 1);
2525 aux_start = pci_resource_start(pci, 2);
2526 aux_len = AUXMEMSIZE;
2527
2528 if (!request_mem_region(mem_start, mem_len, name)) {
2529 printk(KERN_ERR "airo: Couldn't get region %x[%x] for %s\n",
2530 (int)mem_start, (int)mem_len, name);
2531 goto out;
2532 }
2533 if (!request_mem_region(aux_start, aux_len, name)) {
2534 printk(KERN_ERR "airo: Couldn't get region %x[%x] for %s\n",
2535 (int)aux_start, (int)aux_len, name);
2536 goto free_region1;
2537 }
2538
2539 ai->pcimem = ioremap(mem_start, mem_len);
2540 if (!ai->pcimem) {
2541 printk(KERN_ERR "airo: Couldn't map region %x[%x] for %s\n",
2542 (int)mem_start, (int)mem_len, name);
2543 goto free_region2;
2544 }
2545 ai->pciaux = ioremap(aux_start, aux_len);
2546 if (!ai->pciaux) {
2547 printk(KERN_ERR "airo: Couldn't map region %x[%x] for %s\n",
2548 (int)aux_start, (int)aux_len, name);
2549 goto free_memmap;
2550 }
2551
2552 /* Reserve PKTSIZE for each fid and 2K for the Rids */
2553 ai->shared = pci_alloc_consistent(pci, PCI_SHARED_LEN, &ai->shared_dma);
2554 if (!ai->shared) {
2555 printk(KERN_ERR "airo: Couldn't alloc_consistent %d\n",
2556 PCI_SHARED_LEN);
2557 goto free_auxmap;
2558 }
2559
2560 /*
2561 * Setup descriptor RX, TX, CONFIG
2562 */
2563 busaddroff = (unsigned char *)ai->shared_dma;
2564 pciaddroff = ai->pciaux + AUX_OFFSET;
2565 vpackoff = ai->shared;
2566
2567 /* RX descriptor setup */
2568 for(i = 0; i < MPI_MAX_FIDS; i++) {
2569 ai->rxfids[i].pending = 0;
2570 ai->rxfids[i].card_ram_off = pciaddroff;
2571 ai->rxfids[i].virtual_host_addr = vpackoff;
2572 ai->rxfids[i].rx_desc.host_addr = (dma_addr_t) busaddroff;
2573 ai->rxfids[i].rx_desc.valid = 1;
2574 ai->rxfids[i].rx_desc.len = PKTSIZE;
2575 ai->rxfids[i].rx_desc.rdy = 0;
2576
2577 pciaddroff += sizeof(RxFid);
2578 busaddroff += PKTSIZE;
2579 vpackoff += PKTSIZE;
2580 }
2581
2582 /* TX descriptor setup */
2583 for(i = 0; i < MPI_MAX_FIDS; i++) {
2584 ai->txfids[i].card_ram_off = pciaddroff;
2585 ai->txfids[i].virtual_host_addr = vpackoff;
2586 ai->txfids[i].tx_desc.valid = 1;
2587 ai->txfids[i].tx_desc.host_addr = (dma_addr_t) busaddroff;
2588 memcpy(ai->txfids[i].virtual_host_addr,
2589 &wifictlhdr8023, sizeof(wifictlhdr8023));
2590
2591 pciaddroff += sizeof(TxFid);
2592 busaddroff += PKTSIZE;
2593 vpackoff += PKTSIZE;
2594 }
2595 ai->txfids[i-1].tx_desc.eoc = 1; /* Last descriptor has EOC set */
2596
2597 /* Rid descriptor setup */
2598 ai->config_desc.card_ram_off = pciaddroff;
2599 ai->config_desc.virtual_host_addr = vpackoff;
2600 ai->config_desc.rid_desc.host_addr = (dma_addr_t) busaddroff;
2601 ai->ridbus = (dma_addr_t)busaddroff;
2602 ai->config_desc.rid_desc.rid = 0;
2603 ai->config_desc.rid_desc.len = RIDSIZE;
2604 ai->config_desc.rid_desc.valid = 1;
2605 pciaddroff += sizeof(Rid);
2606 busaddroff += RIDSIZE;
2607 vpackoff += RIDSIZE;
2608
2609 /* Tell card about descriptors */
2610 if (mpi_init_descriptors (ai) != SUCCESS)
2611 goto free_shared;
2612
2613 return 0;
2614 free_shared:
2615 pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
2616 free_auxmap:
2617 iounmap(ai->pciaux);
2618 free_memmap:
2619 iounmap(ai->pcimem);
2620 free_region2:
2621 release_mem_region(aux_start, aux_len);
2622 free_region1:
2623 release_mem_region(mem_start, mem_len);
2624 out:
2625 return rc;
2626}
2627
2628static void wifi_setup(struct net_device *dev)
2629{
2630 dev->hard_header = NULL;
2631 dev->rebuild_header = NULL;
2632 dev->hard_header_cache = NULL;
2633 dev->header_cache_update= NULL;
2634
2635 dev->hard_header_parse = wll_header_parse;
2636 dev->hard_start_xmit = &airo_start_xmit11;
2637 dev->get_stats = &airo_get_stats;
2638 dev->set_mac_address = &airo_set_mac_address;
2639 dev->do_ioctl = &airo_ioctl;
2640#ifdef WIRELESS_EXT
2641 dev->wireless_handlers = &airo_handler_def;
2642#endif /* WIRELESS_EXT */
2643 dev->change_mtu = &airo_change_mtu;
2644 dev->open = &airo_open;
2645 dev->stop = &airo_close;
2646
2647 dev->type = ARPHRD_IEEE80211;
2648 dev->hard_header_len = ETH_HLEN;
2649 dev->mtu = 2312;
2650 dev->addr_len = ETH_ALEN;
2651 dev->tx_queue_len = 100;
2652
2653 memset(dev->broadcast,0xFF, ETH_ALEN);
2654
2655 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
2656}
2657
2658static struct net_device *init_wifidev(struct airo_info *ai,
2659 struct net_device *ethdev)
2660{
2661 int err;
2662 struct net_device *dev = alloc_netdev(0, "wifi%d", wifi_setup);
2663 if (!dev)
2664 return NULL;
2665 dev->priv = ethdev->priv;
2666 dev->irq = ethdev->irq;
2667 dev->base_addr = ethdev->base_addr;
2668#ifdef WIRELESS_EXT
2669 dev->wireless_data = ethdev->wireless_data;
2670#endif /* WIRELESS_EXT */
2671 memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len);
2672 err = register_netdev(dev);
2673 if (err<0) {
2674 free_netdev(dev);
2675 return NULL;
2676 }
2677 return dev;
2678}
2679
2680int reset_card( struct net_device *dev , int lock) {
2681 struct airo_info *ai = dev->priv;
2682
2683 if (lock && down_interruptible(&ai->sem))
2684 return -1;
2685 waitbusy (ai);
2686 OUT4500(ai,COMMAND,CMD_SOFTRESET);
2687 msleep(200);
2688 waitbusy (ai);
2689 msleep(200);
2690 if (lock)
2691 up(&ai->sem);
2692 return 0;
2693}
2694
2695struct net_device *_init_airo_card( unsigned short irq, int port,
2696 int is_pcmcia, struct pci_dev *pci,
2697 struct device *dmdev )
2698{
2699 struct net_device *dev;
2700 struct airo_info *ai;
2701 int i, rc;
2702
2703 /* Create the network device object. */
2704 dev = alloc_etherdev(sizeof(*ai));
2705 if (!dev) {
2706 printk(KERN_ERR "airo: Couldn't alloc_etherdev\n");
2707 return NULL;
2708 }
2709 if (dev_alloc_name(dev, dev->name) < 0) {
2710 printk(KERN_ERR "airo: Couldn't get name!\n");
2711 goto err_out_free;
2712 }
2713
2714 ai = dev->priv;
2715 ai->wifidev = NULL;
2716 ai->flags = 0;
2717 if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) {
2718 printk(KERN_DEBUG "airo: Found an MPI350 card\n");
2719 set_bit(FLAG_MPI, &ai->flags);
2720 }
2721 ai->dev = dev;
2722 spin_lock_init(&ai->aux_lock);
2723 sema_init(&ai->sem, 1);
2724 ai->config.len = 0;
2725 ai->pci = pci;
2726 init_waitqueue_head (&ai->thr_wait);
2727 init_completion (&ai->thr_exited);
2728 ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES);
2729 if (ai->thr_pid < 0)
2730 goto err_out_free;
2731#ifdef MICSUPPORT
2732 ai->tfm = NULL;
2733#endif
2734 rc = add_airo_dev( dev );
2735 if (rc)
2736 goto err_out_thr;
2737
2738 /* The Airo-specific entries in the device structure. */
2739 if (test_bit(FLAG_MPI,&ai->flags)) {
2740 skb_queue_head_init (&ai->txq);
2741 dev->hard_start_xmit = &mpi_start_xmit;
2742 } else
2743 dev->hard_start_xmit = &airo_start_xmit;
2744 dev->get_stats = &airo_get_stats;
2745 dev->set_multicast_list = &airo_set_multicast_list;
2746 dev->set_mac_address = &airo_set_mac_address;
2747 dev->do_ioctl = &airo_ioctl;
2748#ifdef WIRELESS_EXT
2749 dev->wireless_handlers = &airo_handler_def;
2750 ai->wireless_data.spy_data = &ai->spy_data;
2751 dev->wireless_data = &ai->wireless_data;
2752#endif /* WIRELESS_EXT */
2753 dev->change_mtu = &airo_change_mtu;
2754 dev->open = &airo_open;
2755 dev->stop = &airo_close;
2756 dev->irq = irq;
2757 dev->base_addr = port;
2758
2759 SET_NETDEV_DEV(dev, dmdev);
2760
2761
2762 if (test_bit(FLAG_MPI,&ai->flags))
2763 reset_card (dev, 1);
2764
2765 rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev );
2766 if (rc) {
2767 printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc );
2768 goto err_out_unlink;
2769 }
2770 if (!is_pcmcia) {
2771 if (!request_region( dev->base_addr, 64, dev->name )) {
2772 rc = -EBUSY;
2773 printk(KERN_ERR "airo: Couldn't request region\n");
2774 goto err_out_irq;
2775 }
2776 }
2777
2778 if (test_bit(FLAG_MPI,&ai->flags)) {
2779 if (mpi_map_card(ai, pci, dev->name)) {
2780 printk(KERN_ERR "airo: Could not map memory\n");
2781 goto err_out_res;
2782 }
2783 }
2784
2785 if (probe) {
2786 if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) {
2787 printk( KERN_ERR "airo: MAC could not be enabled\n" );
2788 rc = -EIO;
2789 goto err_out_map;
2790 }
2791 } else if (!test_bit(FLAG_MPI,&ai->flags)) {
2792 ai->bap_read = fast_bap_read;
2793 set_bit(FLAG_FLASHING, &ai->flags);
2794 }
2795
2796 rc = register_netdev(dev);
2797 if (rc) {
2798 printk(KERN_ERR "airo: Couldn't register_netdev\n");
2799 goto err_out_map;
2800 }
2801 ai->wifidev = init_wifidev(ai, dev);
2802
2803 set_bit(FLAG_REGISTERED,&ai->flags);
2804 printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n",
2805 dev->name,
2806 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
2807 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
2808
2809 /* Allocate the transmit buffers */
2810 if (probe && !test_bit(FLAG_MPI,&ai->flags))
2811 for( i = 0; i < MAX_FIDS; i++ )
2812 ai->fids[i] = transmit_allocate(ai,2312,i>=MAX_FIDS/2);
2813
2814 setup_proc_entry( dev, dev->priv ); /* XXX check for failure */
2815 netif_start_queue(dev);
2816 SET_MODULE_OWNER(dev);
2817 return dev;
2818
2819err_out_map:
2820 if (test_bit(FLAG_MPI,&ai->flags) && pci) {
2821 pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma);
2822 iounmap(ai->pciaux);
2823 iounmap(ai->pcimem);
2824 mpi_unmap_card(ai->pci);
2825 }
2826err_out_res:
2827 if (!is_pcmcia)
2828 release_region( dev->base_addr, 64 );
2829err_out_irq:
2830 free_irq(dev->irq, dev);
2831err_out_unlink:
2832 del_airo_dev(dev);
2833err_out_thr:
2834 set_bit(JOB_DIE, &ai->flags);
2835 kill_proc(ai->thr_pid, SIGTERM, 1);
2836 wait_for_completion(&ai->thr_exited);
2837err_out_free:
2838 free_netdev(dev);
2839 return NULL;
2840}
2841
2842struct net_device *init_airo_card( unsigned short irq, int port, int is_pcmcia,
2843 struct device *dmdev)
2844{
2845 return _init_airo_card ( irq, port, is_pcmcia, NULL, dmdev);
2846}
2847
2848EXPORT_SYMBOL(init_airo_card);
2849
2850static int waitbusy (struct airo_info *ai) {
2851 int delay = 0;
2852 while ((IN4500 (ai, COMMAND) & COMMAND_BUSY) & (delay < 10000)) {
2853 udelay (10);
2854 if ((++delay % 20) == 0)
2855 OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
2856 }
2857 return delay < 10000;
2858}
2859
2860int reset_airo_card( struct net_device *dev )
2861{
2862 int i;
2863 struct airo_info *ai = dev->priv;
2864
2865 if (reset_card (dev, 1))
2866 return -1;
2867
2868 if ( setup_card(ai, dev->dev_addr, 1 ) != SUCCESS ) {
2869 printk( KERN_ERR "airo: MAC could not be enabled\n" );
2870 return -1;
2871 }
2872 printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n", dev->name,
2873 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
2874 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
2875 /* Allocate the transmit buffers if needed */
2876 if (!test_bit(FLAG_MPI,&ai->flags))
2877 for( i = 0; i < MAX_FIDS; i++ )
2878 ai->fids[i] = transmit_allocate (ai,2312,i>=MAX_FIDS/2);
2879
2880 enable_interrupts( ai );
2881 netif_wake_queue(dev);
2882 return 0;
2883}
2884
2885EXPORT_SYMBOL(reset_airo_card);
2886
2887static void airo_send_event(struct net_device *dev) {
2888 struct airo_info *ai = dev->priv;
2889 union iwreq_data wrqu;
2890 StatusRid status_rid;
2891
2892 clear_bit(JOB_EVENT, &ai->flags);
2893 PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0);
2894 up(&ai->sem);
2895 wrqu.data.length = 0;
2896 wrqu.data.flags = 0;
2897 memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN);
2898 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
2899
2900 /* Send event to user space */
2901 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
2902}
2903
2904static int airo_thread(void *data) {
2905 struct net_device *dev = data;
2906 struct airo_info *ai = dev->priv;
2907 int locked;
2908
2909 daemonize("%s", dev->name);
2910 allow_signal(SIGTERM);
2911
2912 while(1) {
2913 if (signal_pending(current))
2914 flush_signals(current);
2915
2916 /* make swsusp happy with our thread */
2917 try_to_freeze(PF_FREEZE);
2918
2919 if (test_bit(JOB_DIE, &ai->flags))
2920 break;
2921
2922 if (ai->flags & JOB_MASK) {
2923 locked = down_interruptible(&ai->sem);
2924 } else {
2925 wait_queue_t wait;
2926
2927 init_waitqueue_entry(&wait, current);
2928 add_wait_queue(&ai->thr_wait, &wait);
2929 for (;;) {
2930 set_current_state(TASK_INTERRUPTIBLE);
2931 if (ai->flags & JOB_MASK)
2932 break;
2933 if (ai->expires) {
2934 if (time_after_eq(jiffies,ai->expires)){
2935 set_bit(JOB_AUTOWEP,&ai->flags);
2936 break;
2937 }
2938 if (!signal_pending(current)) {
2939 schedule_timeout(ai->expires - jiffies);
2940 continue;
2941 }
2942 } else if (!signal_pending(current)) {
2943 schedule();
2944 continue;
2945 }
2946 break;
2947 }
2948 current->state = TASK_RUNNING;
2949 remove_wait_queue(&ai->thr_wait, &wait);
2950 locked = 1;
2951 }
2952
2953 if (locked)
2954 continue;
2955
2956 if (test_bit(JOB_DIE, &ai->flags)) {
2957 up(&ai->sem);
2958 break;
2959 }
2960
2961 if (ai->power || test_bit(FLAG_FLASHING, &ai->flags)) {
2962 up(&ai->sem);
2963 continue;
2964 }
2965
2966 if (test_bit(JOB_XMIT, &ai->flags))
2967 airo_end_xmit(dev);
2968 else if (test_bit(JOB_XMIT11, &ai->flags))
2969 airo_end_xmit11(dev);
2970 else if (test_bit(JOB_STATS, &ai->flags))
2971 airo_read_stats(ai);
2972 else if (test_bit(JOB_WSTATS, &ai->flags))
2973 airo_read_wireless_stats(ai);
2974 else if (test_bit(JOB_PROMISC, &ai->flags))
2975 airo_set_promisc(ai);
2976#ifdef MICSUPPORT
2977 else if (test_bit(JOB_MIC, &ai->flags))
2978 micinit(ai);
2979#endif
2980 else if (test_bit(JOB_EVENT, &ai->flags))
2981 airo_send_event(dev);
2982 else if (test_bit(JOB_AUTOWEP, &ai->flags))
2983 timer_func(dev);
2984 }
2985 complete_and_exit (&ai->thr_exited, 0);
2986}
2987
2988static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) {
2989 struct net_device *dev = (struct net_device *)dev_id;
2990 u16 status;
2991 u16 fid;
2992 struct airo_info *apriv = dev->priv;
2993 u16 savedInterrupts = 0;
2994 int handled = 0;
2995
2996 if (!netif_device_present(dev))
2997 return IRQ_NONE;
2998
2999 for (;;) {
3000 status = IN4500( apriv, EVSTAT );
3001 if ( !(status & STATUS_INTS) || status == 0xffff ) break;
3002
3003 handled = 1;
3004
3005 if ( status & EV_AWAKE ) {
3006 OUT4500( apriv, EVACK, EV_AWAKE );
3007 OUT4500( apriv, EVACK, EV_AWAKE );
3008 }
3009
3010 if (!savedInterrupts) {
3011 savedInterrupts = IN4500( apriv, EVINTEN );
3012 OUT4500( apriv, EVINTEN, 0 );
3013 }
3014
3015 if ( status & EV_MIC ) {
3016 OUT4500( apriv, EVACK, EV_MIC );
3017#ifdef MICSUPPORT
3018 if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) {
3019 set_bit(JOB_MIC, &apriv->flags);
3020 wake_up_interruptible(&apriv->thr_wait);
3021 }
3022#endif
3023 }
3024 if ( status & EV_LINK ) {
3025 union iwreq_data wrqu;
3026 /* The link status has changed, if you want to put a
3027 monitor hook in, do it here. (Remember that
3028 interrupts are still disabled!)
3029 */
3030 u16 newStatus = IN4500(apriv, LINKSTAT);
3031 OUT4500( apriv, EVACK, EV_LINK);
3032 /* Here is what newStatus means: */
3033#define NOBEACON 0x8000 /* Loss of sync - missed beacons */
3034#define MAXRETRIES 0x8001 /* Loss of sync - max retries */
3035#define MAXARL 0x8002 /* Loss of sync - average retry level exceeded*/
3036#define FORCELOSS 0x8003 /* Loss of sync - host request */
3037#define TSFSYNC 0x8004 /* Loss of sync - TSF synchronization */
3038#define DEAUTH 0x8100 /* Deauthentication (low byte is reason code) */
3039#define DISASS 0x8200 /* Disassociation (low byte is reason code) */
3040#define ASSFAIL 0x8400 /* Association failure (low byte is reason
3041 code) */
3042#define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason
3043 code) */
3044#define ASSOCIATED 0x0400 /* Assocatied */
3045#define RC_RESERVED 0 /* Reserved return code */
3046#define RC_NOREASON 1 /* Unspecified reason */
3047#define RC_AUTHINV 2 /* Previous authentication invalid */
3048#define RC_DEAUTH 3 /* Deauthenticated because sending station is
3049 leaving */
3050#define RC_NOACT 4 /* Disassociated due to inactivity */
3051#define RC_MAXLOAD 5 /* Disassociated because AP is unable to handle
3052 all currently associated stations */
3053#define RC_BADCLASS2 6 /* Class 2 frame received from
3054 non-Authenticated station */
3055#define RC_BADCLASS3 7 /* Class 3 frame received from
3056 non-Associated station */
3057#define RC_STATLEAVE 8 /* Disassociated because sending station is
3058 leaving BSS */
3059#define RC_NOAUTH 9 /* Station requesting (Re)Association is not
3060 Authenticated with the responding station */
3061 if (newStatus != ASSOCIATED) {
3062 if (auto_wep && !apriv->expires) {
3063 apriv->expires = RUN_AT(3*HZ);
3064 wake_up_interruptible(&apriv->thr_wait);
3065 }
3066 } else {
3067 struct task_struct *task = apriv->task;
3068 if (auto_wep)
3069 apriv->expires = 0;
3070 if (task)
3071 wake_up_process (task);
3072 set_bit(FLAG_UPDATE_UNI, &apriv->flags);
3073 set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
3074 }
3075 /* Question : is ASSOCIATED the only status
3076 * that is valid ? We want to catch handover
3077 * and reassociations as valid status
3078 * Jean II */
3079 if(newStatus == ASSOCIATED) {
3080 if (apriv->scan_timestamp) {
3081 /* Send an empty event to user space.
3082 * We don't send the received data on
3083 * the event because it would require
3084 * us to do complex transcoding, and
3085 * we want to minimise the work done in
3086 * the irq handler. Use a request to
3087 * extract the data - Jean II */
3088 wrqu.data.length = 0;
3089 wrqu.data.flags = 0;
3090 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
3091 apriv->scan_timestamp = 0;
3092 }
3093 if (down_trylock(&apriv->sem) != 0) {
3094 set_bit(JOB_EVENT, &apriv->flags);
3095 wake_up_interruptible(&apriv->thr_wait);
3096 } else
3097 airo_send_event(dev);
3098 } else {
3099 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
3100 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3101
3102 /* Send event to user space */
3103 wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL);
3104 }
3105 }
3106
3107 /* Check to see if there is something to receive */
3108 if ( status & EV_RX ) {
3109 struct sk_buff *skb = NULL;
3110 u16 fc, len, hdrlen = 0;
3111#pragma pack(1)
3112 struct {
3113 u16 status, len;
3114 u8 rssi[2];
3115 u8 rate;
3116 u8 freq;
3117 u16 tmp[4];
3118 } hdr;
3119#pragma pack()
3120 u16 gap;
3121 u16 tmpbuf[4];
3122 u16 *buffer;
3123
3124 if (test_bit(FLAG_MPI,&apriv->flags)) {
3125 if (test_bit(FLAG_802_11, &apriv->flags))
3126 mpi_receive_802_11(apriv);
3127 else
3128 mpi_receive_802_3(apriv);
3129 OUT4500(apriv, EVACK, EV_RX);
3130 goto exitrx;
3131 }
3132
3133 fid = IN4500( apriv, RXFID );
3134
3135 /* Get the packet length */
3136 if (test_bit(FLAG_802_11, &apriv->flags)) {
3137 bap_setup (apriv, fid, 4, BAP0);
3138 bap_read (apriv, (u16*)&hdr, sizeof(hdr), BAP0);
3139 /* Bad CRC. Ignore packet */
3140 if (le16_to_cpu(hdr.status) & 2)
3141 hdr.len = 0;
3142 if (apriv->wifidev == NULL)
3143 hdr.len = 0;
3144 } else {
3145 bap_setup (apriv, fid, 0x36, BAP0);
3146 bap_read (apriv, (u16*)&hdr.len, 2, BAP0);
3147 }
3148 len = le16_to_cpu(hdr.len);
3149
3150 if (len > 2312) {
3151 printk( KERN_ERR "airo: Bad size %d\n", len );
3152 goto badrx;
3153 }
3154 if (len == 0)
3155 goto badrx;
3156
3157 if (test_bit(FLAG_802_11, &apriv->flags)) {
3158 bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0);
3159 fc = le16_to_cpu(fc);
3160 switch (fc & 0xc) {
3161 case 4:
3162 if ((fc & 0xe0) == 0xc0)
3163 hdrlen = 10;
3164 else
3165 hdrlen = 16;
3166 break;
3167 case 8:
3168 if ((fc&0x300)==0x300){
3169 hdrlen = 30;
3170 break;
3171 }
3172 default:
3173 hdrlen = 24;
3174 }
3175 } else
3176 hdrlen = ETH_ALEN * 2;
3177
3178 skb = dev_alloc_skb( len + hdrlen + 2 + 2 );
3179 if ( !skb ) {
3180 apriv->stats.rx_dropped++;
3181 goto badrx;
3182 }
3183 skb_reserve(skb, 2); /* This way the IP header is aligned */
3184 buffer = (u16*)skb_put (skb, len + hdrlen);
3185 if (test_bit(FLAG_802_11, &apriv->flags)) {
3186 buffer[0] = fc;
3187 bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
3188 if (hdrlen == 24)
3189 bap_read (apriv, tmpbuf, 6, BAP0);
3190
3191 bap_read (apriv, &gap, sizeof(gap), BAP0);
3192 gap = le16_to_cpu(gap);
3193 if (gap) {
3194 if (gap <= 8)
3195 bap_read (apriv, tmpbuf, gap, BAP0);
3196 else
3197 printk(KERN_ERR "airo: gaplen too big. Problems will follow...\n");
3198 }
3199 bap_read (apriv, buffer + hdrlen/2, len, BAP0);
3200 } else {
3201#ifdef MICSUPPORT
3202 MICBuffer micbuf;
3203#endif
3204 bap_read (apriv, buffer, ETH_ALEN*2, BAP0);
3205#ifdef MICSUPPORT
3206 if (apriv->micstats.enabled) {
3207 bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0);
3208 if (ntohs(micbuf.typelen) > 0x05DC)
3209 bap_setup (apriv, fid, 0x44, BAP0);
3210 else {
3211 if (len <= sizeof(micbuf))
3212 goto badmic;
3213
3214 len -= sizeof(micbuf);
3215 skb_trim (skb, len + hdrlen);
3216 }
3217 }
3218#endif
3219 bap_read(apriv,buffer+ETH_ALEN,len,BAP0);
3220#ifdef MICSUPPORT
3221 if (decapsulate(apriv,&micbuf,(etherHead*)buffer,len)) {
3222badmic:
3223 dev_kfree_skb_irq (skb);
3224#else
3225 if (0) {
3226#endif
3227badrx:
3228 OUT4500( apriv, EVACK, EV_RX);
3229 goto exitrx;
3230 }
3231 }
3232#ifdef WIRELESS_SPY
3233 if (apriv->spy_data.spy_number > 0) {
3234 char *sa;
3235 struct iw_quality wstats;
3236 /* Prepare spy data : addr + qual */
3237 if (!test_bit(FLAG_802_11, &apriv->flags)) {
3238 sa = (char*)buffer + 6;
3239 bap_setup (apriv, fid, 8, BAP0);
3240 bap_read (apriv, (u16*)hdr.rssi, 2, BAP0);
3241 } else
3242 sa = (char*)buffer + 10;
3243 wstats.qual = hdr.rssi[0];
3244 if (apriv->rssi)
3245 wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm;
3246 else
3247 wstats.level = (hdr.rssi[1] + 321) / 2;
3248 wstats.updated = 3;
3249 /* Update spy records */
3250 wireless_spy_update(dev, sa, &wstats);
3251 }
3252#endif /* WIRELESS_SPY */
3253 OUT4500( apriv, EVACK, EV_RX);
3254
3255 if (test_bit(FLAG_802_11, &apriv->flags)) {
3256 skb->mac.raw = skb->data;
3257 skb->pkt_type = PACKET_OTHERHOST;
3258 skb->dev = apriv->wifidev;
3259 skb->protocol = htons(ETH_P_802_2);
3260 } else {
3261 skb->dev = dev;
3262 skb->protocol = eth_type_trans(skb,dev);
3263 }
3264 skb->dev->last_rx = jiffies;
3265 skb->ip_summed = CHECKSUM_NONE;
3266
3267 netif_rx( skb );
3268 }
3269exitrx:
3270
3271 /* Check to see if a packet has been transmitted */
3272 if ( status & ( EV_TX|EV_TXCPY|EV_TXEXC ) ) {
3273 int i;
3274 int len = 0;
3275 int index = -1;
3276
3277 if (test_bit(FLAG_MPI,&apriv->flags)) {
3278 unsigned long flags;
3279
3280 if (status & EV_TXEXC)
3281 get_tx_error(apriv, -1);
3282 spin_lock_irqsave(&apriv->aux_lock, flags);
3283 if (skb_queue_len (&apriv->txq)) {
3284 spin_unlock_irqrestore(&apriv->aux_lock,flags);
3285 mpi_send_packet (dev);
3286 } else {
3287 clear_bit(FLAG_PENDING_XMIT, &apriv->flags);
3288 spin_unlock_irqrestore(&apriv->aux_lock,flags);
3289 netif_wake_queue (dev);
3290 }
3291 OUT4500( apriv, EVACK,
3292 status & (EV_TX|EV_TXCPY|EV_TXEXC));
3293 goto exittx;
3294 }
3295
3296 fid = IN4500(apriv, TXCOMPLFID);
3297
3298 for( i = 0; i < MAX_FIDS; i++ ) {
3299 if ( ( apriv->fids[i] & 0xffff ) == fid ) {
3300 len = apriv->fids[i] >> 16;
3301 index = i;
3302 }
3303 }
3304 if (index != -1) {
3305 if (status & EV_TXEXC)
3306 get_tx_error(apriv, index);
3307 OUT4500( apriv, EVACK, status & (EV_TX | EV_TXEXC));
3308 /* Set up to be used again */
3309 apriv->fids[index] &= 0xffff;
3310 if (index < MAX_FIDS / 2) {
3311 if (!test_bit(FLAG_PENDING_XMIT, &apriv->flags))
3312 netif_wake_queue(dev);
3313 } else {
3314 if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags))
3315 netif_wake_queue(apriv->wifidev);
3316 }
3317 } else {
3318 OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3319 printk( KERN_ERR "airo: Unallocated FID was used to xmit\n" );
3320 }
3321 }
3322exittx:
3323 if ( status & ~STATUS_INTS & ~IGNORE_INTS )
3324 printk( KERN_WARNING "airo: Got weird status %x\n",
3325 status & ~STATUS_INTS & ~IGNORE_INTS );
3326 }
3327
3328 if (savedInterrupts)
3329 OUT4500( apriv, EVINTEN, savedInterrupts );
3330
3331 /* done.. */
3332 return IRQ_RETVAL(handled);
3333}
3334
3335/*
3336 * Routines to talk to the card
3337 */
3338
3339/*
3340 * This was originally written for the 4500, hence the name
3341 * NOTE: If use with 8bit mode and SMP bad things will happen!
3342 * Why would some one do 8 bit IO in an SMP machine?!?
3343 */
3344static void OUT4500( struct airo_info *ai, u16 reg, u16 val ) {
3345 if (test_bit(FLAG_MPI,&ai->flags))
3346 reg <<= 1;
3347 if ( !do8bitIO )
3348 outw( val, ai->dev->base_addr + reg );
3349 else {
3350 outb( val & 0xff, ai->dev->base_addr + reg );
3351 outb( val >> 8, ai->dev->base_addr + reg + 1 );
3352 }
3353}
3354
3355static u16 IN4500( struct airo_info *ai, u16 reg ) {
3356 unsigned short rc;
3357
3358 if (test_bit(FLAG_MPI,&ai->flags))
3359 reg <<= 1;
3360 if ( !do8bitIO )
3361 rc = inw( ai->dev->base_addr + reg );
3362 else {
3363 rc = inb( ai->dev->base_addr + reg );
3364 rc += ((int)inb( ai->dev->base_addr + reg + 1 )) << 8;
3365 }
3366 return rc;
3367}
3368
3369static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock ) {
3370 int rc;
3371 Cmd cmd;
3372
3373 /* FLAG_RADIO_OFF : Radio disabled via /proc or Wireless Extensions
3374 * FLAG_RADIO_DOWN : Radio disabled via "ifconfig ethX down"
3375 * Note : we could try to use !netif_running(dev) in enable_MAC()
3376 * instead of this flag, but I don't trust it *within* the
3377 * open/close functions, and testing both flags together is
3378 * "cheaper" - Jean II */
3379 if (ai->flags & FLAG_RADIO_MASK) return SUCCESS;
3380
3381 if (lock && down_interruptible(&ai->sem))
3382 return -ERESTARTSYS;
3383
3384 if (!test_bit(FLAG_ENABLED, &ai->flags)) {
3385 memset(&cmd, 0, sizeof(cmd));
3386 cmd.cmd = MAC_ENABLE;
3387 rc = issuecommand(ai, &cmd, rsp);
3388 if (rc == SUCCESS)
3389 set_bit(FLAG_ENABLED, &ai->flags);
3390 } else
3391 rc = SUCCESS;
3392
3393 if (lock)
3394 up(&ai->sem);
3395
3396 if (rc)
3397 printk(KERN_ERR "%s: Cannot enable MAC, err=%d\n",
3398 __FUNCTION__,rc);
3399 return rc;
3400}
3401
3402static void disable_MAC( struct airo_info *ai, int lock ) {
3403 Cmd cmd;
3404 Resp rsp;
3405
3406 if (lock && down_interruptible(&ai->sem))
3407 return;
3408
3409 if (test_bit(FLAG_ENABLED, &ai->flags)) {
3410 memset(&cmd, 0, sizeof(cmd));
3411 cmd.cmd = MAC_DISABLE; // disable in case already enabled
3412 issuecommand(ai, &cmd, &rsp);
3413 clear_bit(FLAG_ENABLED, &ai->flags);
3414 }
3415 if (lock)
3416 up(&ai->sem);
3417}
3418
3419static void enable_interrupts( struct airo_info *ai ) {
3420 /* Enable the interrupts */
3421 OUT4500( ai, EVINTEN, STATUS_INTS );
3422}
3423
3424static void disable_interrupts( struct airo_info *ai ) {
3425 OUT4500( ai, EVINTEN, 0 );
3426}
3427
3428static void mpi_receive_802_3(struct airo_info *ai)
3429{
3430 RxFid rxd;
3431 int len = 0;
3432 struct sk_buff *skb;
3433 char *buffer;
3434#ifdef MICSUPPORT
3435 int off = 0;
3436 MICBuffer micbuf;
3437#endif
3438
3439 memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3440 /* Make sure we got something */
3441 if (rxd.rdy && rxd.valid == 0) {
3442 len = rxd.len + 12;
3443 if (len < 12 || len > 2048)
3444 goto badrx;
3445
3446 skb = dev_alloc_skb(len);
3447 if (!skb) {
3448 ai->stats.rx_dropped++;
3449 goto badrx;
3450 }
3451 buffer = skb_put(skb,len);
3452#ifdef MICSUPPORT
3453 memcpy(buffer, ai->rxfids[0].virtual_host_addr, ETH_ALEN * 2);
3454 if (ai->micstats.enabled) {
3455 memcpy(&micbuf,
3456 ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2,
3457 sizeof(micbuf));
3458 if (ntohs(micbuf.typelen) <= 0x05DC) {
3459 if (len <= sizeof(micbuf) + ETH_ALEN * 2)
3460 goto badmic;
3461
3462 off = sizeof(micbuf);
3463 skb_trim (skb, len - off);
3464 }
3465 }
3466 memcpy(buffer + ETH_ALEN * 2,
3467 ai->rxfids[0].virtual_host_addr + ETH_ALEN * 2 + off,
3468 len - ETH_ALEN * 2 - off);
3469 if (decapsulate (ai, &micbuf, (etherHead*)buffer, len - off - ETH_ALEN * 2)) {
3470badmic:
3471 dev_kfree_skb_irq (skb);
3472 goto badrx;
3473 }
3474#else
3475 memcpy(buffer, ai->rxfids[0].virtual_host_addr, len);
3476#endif
3477#ifdef WIRELESS_SPY
3478 if (ai->spy_data.spy_number > 0) {
3479 char *sa;
3480 struct iw_quality wstats;
3481 /* Prepare spy data : addr + qual */
3482 sa = buffer + ETH_ALEN;
3483 wstats.qual = 0; /* XXX Where do I get that info from ??? */
3484 wstats.level = 0;
3485 wstats.updated = 0;
3486 /* Update spy records */
3487 wireless_spy_update(ai->dev, sa, &wstats);
3488 }
3489#endif /* WIRELESS_SPY */
3490
3491 skb->dev = ai->dev;
3492 skb->ip_summed = CHECKSUM_NONE;
3493 skb->protocol = eth_type_trans(skb, ai->dev);
3494 skb->dev->last_rx = jiffies;
3495 netif_rx(skb);
3496 }
3497badrx:
3498 if (rxd.valid == 0) {
3499 rxd.valid = 1;
3500 rxd.rdy = 0;
3501 rxd.len = PKTSIZE;
3502 memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
3503 }
3504}
3505
3506void mpi_receive_802_11 (struct airo_info *ai)
3507{
3508 RxFid rxd;
3509 struct sk_buff *skb = NULL;
3510 u16 fc, len, hdrlen = 0;
3511#pragma pack(1)
3512 struct {
3513 u16 status, len;
3514 u8 rssi[2];
3515 u8 rate;
3516 u8 freq;
3517 u16 tmp[4];
3518 } hdr;
3519#pragma pack()
3520 u16 gap;
3521 u16 *buffer;
3522 char *ptr = ai->rxfids[0].virtual_host_addr+4;
3523
3524 memcpy_fromio(&rxd, ai->rxfids[0].card_ram_off, sizeof(rxd));
3525 memcpy ((char *)&hdr, ptr, sizeof(hdr));
3526 ptr += sizeof(hdr);
3527 /* Bad CRC. Ignore packet */
3528 if (le16_to_cpu(hdr.status) & 2)
3529 hdr.len = 0;
3530 if (ai->wifidev == NULL)
3531 hdr.len = 0;
3532 len = le16_to_cpu(hdr.len);
3533 if (len > 2312) {
3534 printk( KERN_ERR "airo: Bad size %d\n", len );
3535 goto badrx;
3536 }
3537 if (len == 0)
3538 goto badrx;
3539
3540 memcpy ((char *)&fc, ptr, sizeof(fc));
3541 fc = le16_to_cpu(fc);
3542 switch (fc & 0xc) {
3543 case 4:
3544 if ((fc & 0xe0) == 0xc0)
3545 hdrlen = 10;
3546 else
3547 hdrlen = 16;
3548 break;
3549 case 8:
3550 if ((fc&0x300)==0x300){
3551 hdrlen = 30;
3552 break;
3553 }
3554 default:
3555 hdrlen = 24;
3556 }
3557
3558 skb = dev_alloc_skb( len + hdrlen + 2 );
3559 if ( !skb ) {
3560 ai->stats.rx_dropped++;
3561 goto badrx;
3562 }
3563 buffer = (u16*)skb_put (skb, len + hdrlen);
3564 memcpy ((char *)buffer, ptr, hdrlen);
3565 ptr += hdrlen;
3566 if (hdrlen == 24)
3567 ptr += 6;
3568 memcpy ((char *)&gap, ptr, sizeof(gap));
3569 ptr += sizeof(gap);
3570 gap = le16_to_cpu(gap);
3571 if (gap) {
3572 if (gap <= 8)
3573 ptr += gap;
3574 else
3575 printk(KERN_ERR
3576 "airo: gaplen too big. Problems will follow...\n");
3577 }
3578 memcpy ((char *)buffer + hdrlen, ptr, len);
3579 ptr += len;
3580#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
3581 if (ai->spy_data.spy_number > 0) {
3582 char *sa;
3583 struct iw_quality wstats;
3584 /* Prepare spy data : addr + qual */
3585 sa = (char*)buffer + 10;
3586 wstats.qual = hdr.rssi[0];
3587 if (ai->rssi)
3588 wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm;
3589 else
3590 wstats.level = (hdr.rssi[1] + 321) / 2;
3591 wstats.updated = 3;
3592 /* Update spy records */
3593 wireless_spy_update(ai->dev, sa, &wstats);
3594 }
3595#endif /* IW_WIRELESS_SPY */
3596 skb->mac.raw = skb->data;
3597 skb->pkt_type = PACKET_OTHERHOST;
3598 skb->dev = ai->wifidev;
3599 skb->protocol = htons(ETH_P_802_2);
3600 skb->dev->last_rx = jiffies;
3601 skb->ip_summed = CHECKSUM_NONE;
3602 netif_rx( skb );
3603badrx:
3604 if (rxd.valid == 0) {
3605 rxd.valid = 1;
3606 rxd.rdy = 0;
3607 rxd.len = PKTSIZE;
3608 memcpy_toio(ai->rxfids[0].card_ram_off, &rxd, sizeof(rxd));
3609 }
3610}
3611
3612static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3613{
3614 Cmd cmd;
3615 Resp rsp;
3616 int status;
3617 int i;
3618 SsidRid mySsid;
3619 u16 lastindex;
3620 WepKeyRid wkr;
3621 int rc;
3622
3623 memset( &mySsid, 0, sizeof( mySsid ) );
3624 if (ai->flash) {
3625 kfree (ai->flash);
3626 ai->flash = NULL;
3627 }
3628
3629 /* The NOP is the first step in getting the card going */
3630 cmd.cmd = NOP;
3631 cmd.parm0 = cmd.parm1 = cmd.parm2 = 0;
3632 if (lock && down_interruptible(&ai->sem))
3633 return ERROR;
3634 if ( issuecommand( ai, &cmd, &rsp ) != SUCCESS ) {
3635 if (lock)
3636 up(&ai->sem);
3637 return ERROR;
3638 }
3639 disable_MAC( ai, 0);
3640
3641 // Let's figure out if we need to use the AUX port
3642 if (!test_bit(FLAG_MPI,&ai->flags)) {
3643 cmd.cmd = CMD_ENABLEAUX;
3644 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
3645 if (lock)
3646 up(&ai->sem);
3647 printk(KERN_ERR "airo: Error checking for AUX port\n");
3648 return ERROR;
3649 }
3650 if (!aux_bap || rsp.status & 0xff00) {
3651 ai->bap_read = fast_bap_read;
3652 printk(KERN_DEBUG "airo: Doing fast bap_reads\n");
3653 } else {
3654 ai->bap_read = aux_bap_read;
3655 printk(KERN_DEBUG "airo: Doing AUX bap_reads\n");
3656 }
3657 }
3658 if (lock)
3659 up(&ai->sem);
3660 if (ai->config.len == 0) {
3661 tdsRssiRid rssi_rid;
3662 CapabilityRid cap_rid;
3663
3664 if (ai->APList) {
3665 kfree(ai->APList);
3666 ai->APList = NULL;
3667 }
3668 if (ai->SSID) {
3669 kfree(ai->SSID);
3670 ai->SSID = NULL;
3671 }
3672 // general configuration (read/modify/write)
3673 status = readConfigRid(ai, lock);
3674 if ( status != SUCCESS ) return ERROR;
3675
3676 status = readCapabilityRid(ai, &cap_rid, lock);
3677 if ( status != SUCCESS ) return ERROR;
3678
3679 status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock);
3680 if ( status == SUCCESS ) {
3681 if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL)
3682 memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512);
3683 }
3684 else {
3685 if (ai->rssi) {
3686 kfree(ai->rssi);
3687 ai->rssi = NULL;
3688 }
3689 if (cap_rid.softCap & 8)
3690 ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
3691 else
3692 printk(KERN_WARNING "airo: unknown received signal level scale\n");
3693 }
3694 ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
3695 ai->config.authType = AUTH_OPEN;
3696 ai->config.modulation = MOD_CCK;
3697
3698#ifdef MICSUPPORT
3699 if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1) &&
3700 (micsetup(ai) == SUCCESS)) {
3701 ai->config.opmode |= MODE_MIC;
3702 set_bit(FLAG_MIC_CAPABLE, &ai->flags);
3703 }
3704#endif
3705
3706 /* Save off the MAC */
3707 for( i = 0; i < ETH_ALEN; i++ ) {
3708 mac[i] = ai->config.macAddr[i];
3709 }
3710
3711 /* Check to see if there are any insmod configured
3712 rates to add */
3713 if ( rates[0] ) {
3714 int i = 0;
3715 memset(ai->config.rates,0,sizeof(ai->config.rates));
3716 for( i = 0; i < 8 && rates[i]; i++ ) {
3717 ai->config.rates[i] = rates[i];
3718 }
3719 }
3720 if ( basic_rate > 0 ) {
3721 int i;
3722 for( i = 0; i < 8; i++ ) {
3723 if ( ai->config.rates[i] == basic_rate ||
3724 !ai->config.rates ) {
3725 ai->config.rates[i] = basic_rate | 0x80;
3726 break;
3727 }
3728 }
3729 }
3730 set_bit (FLAG_COMMIT, &ai->flags);
3731 }
3732
3733 /* Setup the SSIDs if present */
3734 if ( ssids[0] ) {
3735 int i;
3736 for( i = 0; i < 3 && ssids[i]; i++ ) {
3737 mySsid.ssids[i].len = strlen(ssids[i]);
3738 if ( mySsid.ssids[i].len > 32 )
3739 mySsid.ssids[i].len = 32;
3740 memcpy(mySsid.ssids[i].ssid, ssids[i],
3741 mySsid.ssids[i].len);
3742 }
3743 mySsid.len = sizeof(mySsid);
3744 }
3745
3746 status = writeConfigRid(ai, lock);
3747 if ( status != SUCCESS ) return ERROR;
3748
3749 /* Set up the SSID list */
3750 if ( ssids[0] ) {
3751 status = writeSsidRid(ai, &mySsid, lock);
3752 if ( status != SUCCESS ) return ERROR;
3753 }
3754
3755 status = enable_MAC(ai, &rsp, lock);
3756 if ( status != SUCCESS || (rsp.status & 0xFF00) != 0) {
3757 printk( KERN_ERR "airo: Bad MAC enable reason = %x, rid = %x, offset = %d\n", rsp.rsp0, rsp.rsp1, rsp.rsp2 );
3758 return ERROR;
3759 }
3760
3761 /* Grab the initial wep key, we gotta save it for auto_wep */
3762 rc = readWepKeyRid(ai, &wkr, 1, lock);
3763 if (rc == SUCCESS) do {
3764 lastindex = wkr.kindex;
3765 if (wkr.kindex == 0xffff) {
3766 ai->defindex = wkr.mac[0];
3767 }
3768 rc = readWepKeyRid(ai, &wkr, 0, lock);
3769 } while(lastindex != wkr.kindex);
3770
3771 if (auto_wep) {
3772 ai->expires = RUN_AT(3*HZ);
3773 wake_up_interruptible(&ai->thr_wait);
3774 }
3775
3776 return SUCCESS;
3777}
3778
3779static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
3780 // Im really paranoid about letting it run forever!
3781 int max_tries = 600000;
3782
3783 if (IN4500(ai, EVSTAT) & EV_CMD)
3784 OUT4500(ai, EVACK, EV_CMD);
3785
3786 OUT4500(ai, PARAM0, pCmd->parm0);
3787 OUT4500(ai, PARAM1, pCmd->parm1);
3788 OUT4500(ai, PARAM2, pCmd->parm2);
3789 OUT4500(ai, COMMAND, pCmd->cmd);
3790
3791 while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) {
3792 if ((IN4500(ai, COMMAND)) == pCmd->cmd)
3793 // PC4500 didn't notice command, try again
3794 OUT4500(ai, COMMAND, pCmd->cmd);
3795 if (!in_atomic() && (max_tries & 255) == 0)
3796 schedule();
3797 }
3798
3799 if ( max_tries == -1 ) {
3800 printk( KERN_ERR
3801 "airo: Max tries exceeded when issueing command\n" );
3802 if (IN4500(ai, COMMAND) & COMMAND_BUSY)
3803 OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
3804 return ERROR;
3805 }
3806
3807 // command completed
3808 pRsp->status = IN4500(ai, STATUS);
3809 pRsp->rsp0 = IN4500(ai, RESP0);
3810 pRsp->rsp1 = IN4500(ai, RESP1);
3811 pRsp->rsp2 = IN4500(ai, RESP2);
3812 if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET) {
3813 printk (KERN_ERR "airo: cmd= %x\n", pCmd->cmd);
3814 printk (KERN_ERR "airo: status= %x\n", pRsp->status);
3815 printk (KERN_ERR "airo: Rsp0= %x\n", pRsp->rsp0);
3816 printk (KERN_ERR "airo: Rsp1= %x\n", pRsp->rsp1);
3817 printk (KERN_ERR "airo: Rsp2= %x\n", pRsp->rsp2);
3818 }
3819
3820 // clear stuck command busy if necessary
3821 if (IN4500(ai, COMMAND) & COMMAND_BUSY) {
3822 OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
3823 }
3824 // acknowledge processing the status/response
3825 OUT4500(ai, EVACK, EV_CMD);
3826
3827 return SUCCESS;
3828}
3829
3830/* Sets up the bap to start exchange data. whichbap should
3831 * be one of the BAP0 or BAP1 defines. Locks should be held before
3832 * calling! */
3833static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap )
3834{
3835 int timeout = 50;
3836 int max_tries = 3;
3837
3838 OUT4500(ai, SELECT0+whichbap, rid);
3839 OUT4500(ai, OFFSET0+whichbap, offset);
3840 while (1) {
3841 int status = IN4500(ai, OFFSET0+whichbap);
3842 if (status & BAP_BUSY) {
3843 /* This isn't really a timeout, but its kinda
3844 close */
3845 if (timeout--) {
3846 continue;
3847 }
3848 } else if ( status & BAP_ERR ) {
3849 /* invalid rid or offset */
3850 printk( KERN_ERR "airo: BAP error %x %d\n",
3851 status, whichbap );
3852 return ERROR;
3853 } else if (status & BAP_DONE) { // success
3854 return SUCCESS;
3855 }
3856 if ( !(max_tries--) ) {
3857 printk( KERN_ERR
3858 "airo: BAP setup error too many retries\n" );
3859 return ERROR;
3860 }
3861 // -- PC4500 missed it, try again
3862 OUT4500(ai, SELECT0+whichbap, rid);
3863 OUT4500(ai, OFFSET0+whichbap, offset);
3864 timeout = 50;
3865 }
3866}
3867
3868/* should only be called by aux_bap_read. This aux function and the
3869 following use concepts not documented in the developers guide. I
3870 got them from a patch given to my by Aironet */
3871static u16 aux_setup(struct airo_info *ai, u16 page,
3872 u16 offset, u16 *len)
3873{
3874 u16 next;
3875
3876 OUT4500(ai, AUXPAGE, page);
3877 OUT4500(ai, AUXOFF, 0);
3878 next = IN4500(ai, AUXDATA);
3879 *len = IN4500(ai, AUXDATA)&0xff;
3880 if (offset != 4) OUT4500(ai, AUXOFF, offset);
3881 return next;
3882}
3883
3884/* requires call to bap_setup() first */
3885static int aux_bap_read(struct airo_info *ai, u16 *pu16Dst,
3886 int bytelen, int whichbap)
3887{
3888 u16 len;
3889 u16 page;
3890 u16 offset;
3891 u16 next;
3892 int words;
3893 int i;
3894 unsigned long flags;
3895
3896 spin_lock_irqsave(&ai->aux_lock, flags);
3897 page = IN4500(ai, SWS0+whichbap);
3898 offset = IN4500(ai, SWS2+whichbap);
3899 next = aux_setup(ai, page, offset, &len);
3900 words = (bytelen+1)>>1;
3901
3902 for (i=0; i<words;) {
3903 int count;
3904 count = (len>>1) < (words-i) ? (len>>1) : (words-i);
3905 if ( !do8bitIO )
3906 insw( ai->dev->base_addr+DATA0+whichbap,
3907 pu16Dst+i,count );
3908 else
3909 insb( ai->dev->base_addr+DATA0+whichbap,
3910 pu16Dst+i, count << 1 );
3911 i += count;
3912 if (i<words) {
3913 next = aux_setup(ai, next, 4, &len);
3914 }
3915 }
3916 spin_unlock_irqrestore(&ai->aux_lock, flags);
3917 return SUCCESS;
3918}
3919
3920
3921/* requires call to bap_setup() first */
3922static int fast_bap_read(struct airo_info *ai, u16 *pu16Dst,
3923 int bytelen, int whichbap)
3924{
3925 bytelen = (bytelen + 1) & (~1); // round up to even value
3926 if ( !do8bitIO )
3927 insw( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen>>1 );
3928 else
3929 insb( ai->dev->base_addr+DATA0+whichbap, pu16Dst, bytelen );
3930 return SUCCESS;
3931}
3932
3933/* requires call to bap_setup() first */
3934static int bap_write(struct airo_info *ai, const u16 *pu16Src,
3935 int bytelen, int whichbap)
3936{
3937 bytelen = (bytelen + 1) & (~1); // round up to even value
3938 if ( !do8bitIO )
3939 outsw( ai->dev->base_addr+DATA0+whichbap,
3940 pu16Src, bytelen>>1 );
3941 else
3942 outsb( ai->dev->base_addr+DATA0+whichbap, pu16Src, bytelen );
3943 return SUCCESS;
3944}
3945
3946static int PC4500_accessrid(struct airo_info *ai, u16 rid, u16 accmd)
3947{
3948 Cmd cmd; /* for issuing commands */
3949 Resp rsp; /* response from commands */
3950 u16 status;
3951
3952 memset(&cmd, 0, sizeof(cmd));
3953 cmd.cmd = accmd;
3954 cmd.parm0 = rid;
3955 status = issuecommand(ai, &cmd, &rsp);
3956 if (status != 0) return status;
3957 if ( (rsp.status & 0x7F00) != 0) {
3958 return (accmd << 8) + (rsp.rsp0 & 0xFF);
3959 }
3960 return 0;
3961}
3962
3963/* Note, that we are using BAP1 which is also used by transmit, so
3964 * we must get a lock. */
3965static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, int lock)
3966{
3967 u16 status;
3968 int rc = SUCCESS;
3969
3970 if (lock) {
3971 if (down_interruptible(&ai->sem))
3972 return ERROR;
3973 }
3974 if (test_bit(FLAG_MPI,&ai->flags)) {
3975 Cmd cmd;
3976 Resp rsp;
3977
3978 memset(&cmd, 0, sizeof(cmd));
3979 memset(&rsp, 0, sizeof(rsp));
3980 ai->config_desc.rid_desc.valid = 1;
3981 ai->config_desc.rid_desc.len = RIDSIZE;
3982 ai->config_desc.rid_desc.rid = 0;
3983 ai->config_desc.rid_desc.host_addr = ai->ridbus;
3984
3985 cmd.cmd = CMD_ACCESS;
3986 cmd.parm0 = rid;
3987
3988 memcpy_toio(ai->config_desc.card_ram_off,
3989 &ai->config_desc.rid_desc, sizeof(Rid));
3990
3991 rc = issuecommand(ai, &cmd, &rsp);
3992
3993 if (rsp.status & 0x7f00)
3994 rc = rsp.rsp0;
3995 if (!rc)
3996 memcpy(pBuf, ai->config_desc.virtual_host_addr, len);
3997 goto done;
3998 } else {
3999 if ((status = PC4500_accessrid(ai, rid, CMD_ACCESS))!=SUCCESS) {
4000 rc = status;
4001 goto done;
4002 }
4003 if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
4004 rc = ERROR;
4005 goto done;
4006 }
4007 // read the rid length field
4008 bap_read(ai, pBuf, 2, BAP1);
4009 // length for remaining part of rid
4010 len = min(len, (int)le16_to_cpu(*(u16*)pBuf)) - 2;
4011
4012 if ( len <= 2 ) {
4013 printk( KERN_ERR
4014 "airo: Rid %x has a length of %d which is too short\n",
4015 (int)rid, (int)len );
4016 rc = ERROR;
4017 goto done;
4018 }
4019 // read remainder of the rid
4020 rc = bap_read(ai, ((u16*)pBuf)+1, len, BAP1);
4021 }
4022done:
4023 if (lock)
4024 up(&ai->sem);
4025 return rc;
4026}
4027
4028/* Note, that we are using BAP1 which is also used by transmit, so
4029 * make sure this isnt called when a transmit is happening */
4030static int PC4500_writerid(struct airo_info *ai, u16 rid,
4031 const void *pBuf, int len, int lock)
4032{
4033 u16 status;
4034 int rc = SUCCESS;
4035
4036 *(u16*)pBuf = cpu_to_le16((u16)len);
4037
4038 if (lock) {
4039 if (down_interruptible(&ai->sem))
4040 return ERROR;
4041 }
4042 if (test_bit(FLAG_MPI,&ai->flags)) {
4043 Cmd cmd;
4044 Resp rsp;
4045
4046 if (test_bit(FLAG_ENABLED, &ai->flags))
4047 printk(KERN_ERR
4048 "%s: MAC should be disabled (rid=%04x)\n",
4049 __FUNCTION__, rid);
4050 memset(&cmd, 0, sizeof(cmd));
4051 memset(&rsp, 0, sizeof(rsp));
4052
4053 ai->config_desc.rid_desc.valid = 1;
4054 ai->config_desc.rid_desc.len = *((u16 *)pBuf);
4055 ai->config_desc.rid_desc.rid = 0;
4056
4057 cmd.cmd = CMD_WRITERID;
4058 cmd.parm0 = rid;
4059
4060 memcpy_toio(ai->config_desc.card_ram_off,
4061 &ai->config_desc.rid_desc, sizeof(Rid));
4062
4063 if (len < 4 || len > 2047) {
4064 printk(KERN_ERR "%s: len=%d\n",__FUNCTION__,len);
4065 rc = -1;
4066 } else {
4067 memcpy((char *)ai->config_desc.virtual_host_addr,
4068 pBuf, len);
4069
4070 rc = issuecommand(ai, &cmd, &rsp);
4071 if ((rc & 0xff00) != 0) {
4072 printk(KERN_ERR "%s: Write rid Error %d\n",
4073 __FUNCTION__,rc);
4074 printk(KERN_ERR "%s: Cmd=%04x\n",
4075 __FUNCTION__,cmd.cmd);
4076 }
4077
4078 if ((rsp.status & 0x7f00))
4079 rc = rsp.rsp0;
4080 }
4081 } else {
4082 // --- first access so that we can write the rid data
4083 if ( (status = PC4500_accessrid(ai, rid, CMD_ACCESS)) != 0) {
4084 rc = status;
4085 goto done;
4086 }
4087 // --- now write the rid data
4088 if (bap_setup(ai, rid, 0, BAP1) != SUCCESS) {
4089 rc = ERROR;
4090 goto done;
4091 }
4092 bap_write(ai, pBuf, len, BAP1);
4093 // ---now commit the rid data
4094 rc = PC4500_accessrid(ai, rid, 0x100|CMD_ACCESS);
4095 }
4096done:
4097 if (lock)
4098 up(&ai->sem);
4099 return rc;
4100}
4101
4102/* Allocates a FID to be used for transmitting packets. We only use
4103 one for now. */
4104static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
4105{
4106 unsigned int loop = 3000;
4107 Cmd cmd;
4108 Resp rsp;
4109 u16 txFid;
4110 u16 txControl;
4111
4112 cmd.cmd = CMD_ALLOCATETX;
4113 cmd.parm0 = lenPayload;
4114 if (down_interruptible(&ai->sem))
4115 return ERROR;
4116 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
4117 txFid = ERROR;
4118 goto done;
4119 }
4120 if ( (rsp.status & 0xFF00) != 0) {
4121 txFid = ERROR;
4122 goto done;
4123 }
4124 /* wait for the allocate event/indication
4125 * It makes me kind of nervous that this can just sit here and spin,
4126 * but in practice it only loops like four times. */
4127 while (((IN4500(ai, EVSTAT) & EV_ALLOC) == 0) && --loop);
4128 if (!loop) {
4129 txFid = ERROR;
4130 goto done;
4131 }
4132
4133 // get the allocated fid and acknowledge
4134 txFid = IN4500(ai, TXALLOCFID);
4135 OUT4500(ai, EVACK, EV_ALLOC);
4136
4137 /* The CARD is pretty cool since it converts the ethernet packet
4138 * into 802.11. Also note that we don't release the FID since we
4139 * will be using the same one over and over again. */
4140 /* We only have to setup the control once since we are not
4141 * releasing the fid. */
4142 if (raw)
4143 txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_11
4144 | TXCTL_ETHERNET | TXCTL_NORELEASE);
4145 else
4146 txControl = cpu_to_le16(TXCTL_TXOK | TXCTL_TXEX | TXCTL_802_3
4147 | TXCTL_ETHERNET | TXCTL_NORELEASE);
4148 if (bap_setup(ai, txFid, 0x0008, BAP1) != SUCCESS)
4149 txFid = ERROR;
4150 else
4151 bap_write(ai, &txControl, sizeof(txControl), BAP1);
4152
4153done:
4154 up(&ai->sem);
4155
4156 return txFid;
4157}
4158
4159/* In general BAP1 is dedicated to transmiting packets. However,
4160 since we need a BAP when accessing RIDs, we also use BAP1 for that.
4161 Make sure the BAP1 spinlock is held when this is called. */
4162static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
4163{
4164 u16 payloadLen;
4165 Cmd cmd;
4166 Resp rsp;
4167 int miclen = 0;
4168 u16 txFid = len;
4169 MICBuffer pMic;
4170
4171 len >>= 16;
4172
4173 if (len <= ETH_ALEN * 2) {
4174 printk( KERN_WARNING "Short packet %d\n", len );
4175 return ERROR;
4176 }
4177 len -= ETH_ALEN * 2;
4178
4179#ifdef MICSUPPORT
4180 if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
4181 (ntohs(((u16 *)pPacket)[6]) != 0x888E)) {
4182 if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS)
4183 return ERROR;
4184 miclen = sizeof(pMic);
4185 }
4186#endif
4187
4188 // packet is destination[6], source[6], payload[len-12]
4189 // write the payload length and dst/src/payload
4190 if (bap_setup(ai, txFid, 0x0036, BAP1) != SUCCESS) return ERROR;
4191 /* The hardware addresses aren't counted as part of the payload, so
4192 * we have to subtract the 12 bytes for the addresses off */
4193 payloadLen = cpu_to_le16(len + miclen);
4194 bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
4195 bap_write(ai, (const u16*)pPacket, sizeof(etherHead), BAP1);
4196 if (miclen)
4197 bap_write(ai, (const u16*)&pMic, miclen, BAP1);
4198 bap_write(ai, (const u16*)(pPacket + sizeof(etherHead)), len, BAP1);
4199 // issue the transmit command
4200 memset( &cmd, 0, sizeof( cmd ) );
4201 cmd.cmd = CMD_TRANSMIT;
4202 cmd.parm0 = txFid;
4203 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
4204 if ( (rsp.status & 0xFF00) != 0) return ERROR;
4205 return SUCCESS;
4206}
4207
4208static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket)
4209{
4210 u16 fc, payloadLen;
4211 Cmd cmd;
4212 Resp rsp;
4213 int hdrlen;
4214 struct {
4215 u8 addr4[ETH_ALEN];
4216 u16 gaplen;
4217 u8 gap[6];
4218 } gap;
4219 u16 txFid = len;
4220 len >>= 16;
4221 gap.gaplen = 6;
4222
4223 fc = le16_to_cpu(*(const u16*)pPacket);
4224 switch (fc & 0xc) {
4225 case 4:
4226 if ((fc & 0xe0) == 0xc0)
4227 hdrlen = 10;
4228 else
4229 hdrlen = 16;
4230 break;
4231 case 8:
4232 if ((fc&0x300)==0x300){
4233 hdrlen = 30;
4234 break;
4235 }
4236 default:
4237 hdrlen = 24;
4238 }
4239
4240 if (len < hdrlen) {
4241 printk( KERN_WARNING "Short packet %d\n", len );
4242 return ERROR;
4243 }
4244
4245 /* packet is 802.11 header + payload
4246 * write the payload length and dst/src/payload */
4247 if (bap_setup(ai, txFid, 6, BAP1) != SUCCESS) return ERROR;
4248 /* The 802.11 header aren't counted as part of the payload, so
4249 * we have to subtract the header bytes off */
4250 payloadLen = cpu_to_le16(len-hdrlen);
4251 bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
4252 if (bap_setup(ai, txFid, 0x0014, BAP1) != SUCCESS) return ERROR;
4253 bap_write(ai, (const u16*)pPacket, hdrlen, BAP1);
4254 bap_write(ai, hdrlen == 30 ?
4255 (const u16*)&gap.gaplen : (const u16*)&gap, 38 - hdrlen, BAP1);
4256
4257 bap_write(ai, (const u16*)(pPacket + hdrlen), len - hdrlen, BAP1);
4258 // issue the transmit command
4259 memset( &cmd, 0, sizeof( cmd ) );
4260 cmd.cmd = CMD_TRANSMIT;
4261 cmd.parm0 = txFid;
4262 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) return ERROR;
4263 if ( (rsp.status & 0xFF00) != 0) return ERROR;
4264 return SUCCESS;
4265}
4266
4267/*
4268 * This is the proc_fs routines. It is a bit messier than I would
4269 * like! Feel free to clean it up!
4270 */
4271
4272static ssize_t proc_read( struct file *file,
4273 char __user *buffer,
4274 size_t len,
4275 loff_t *offset);
4276
4277static ssize_t proc_write( struct file *file,
4278 const char __user *buffer,
4279 size_t len,
4280 loff_t *offset );
4281static int proc_close( struct inode *inode, struct file *file );
4282
4283static int proc_stats_open( struct inode *inode, struct file *file );
4284static int proc_statsdelta_open( struct inode *inode, struct file *file );
4285static int proc_status_open( struct inode *inode, struct file *file );
4286static int proc_SSID_open( struct inode *inode, struct file *file );
4287static int proc_APList_open( struct inode *inode, struct file *file );
4288static int proc_BSSList_open( struct inode *inode, struct file *file );
4289static int proc_config_open( struct inode *inode, struct file *file );
4290static int proc_wepkey_open( struct inode *inode, struct file *file );
4291
4292static struct file_operations proc_statsdelta_ops = {
4293 .read = proc_read,
4294 .open = proc_statsdelta_open,
4295 .release = proc_close
4296};
4297
4298static struct file_operations proc_stats_ops = {
4299 .read = proc_read,
4300 .open = proc_stats_open,
4301 .release = proc_close
4302};
4303
4304static struct file_operations proc_status_ops = {
4305 .read = proc_read,
4306 .open = proc_status_open,
4307 .release = proc_close
4308};
4309
4310static struct file_operations proc_SSID_ops = {
4311 .read = proc_read,
4312 .write = proc_write,
4313 .open = proc_SSID_open,
4314 .release = proc_close
4315};
4316
4317static struct file_operations proc_BSSList_ops = {
4318 .read = proc_read,
4319 .write = proc_write,
4320 .open = proc_BSSList_open,
4321 .release = proc_close
4322};
4323
4324static struct file_operations proc_APList_ops = {
4325 .read = proc_read,
4326 .write = proc_write,
4327 .open = proc_APList_open,
4328 .release = proc_close
4329};
4330
4331static struct file_operations proc_config_ops = {
4332 .read = proc_read,
4333 .write = proc_write,
4334 .open = proc_config_open,
4335 .release = proc_close
4336};
4337
4338static struct file_operations proc_wepkey_ops = {
4339 .read = proc_read,
4340 .write = proc_write,
4341 .open = proc_wepkey_open,
4342 .release = proc_close
4343};
4344
4345static struct proc_dir_entry *airo_entry;
4346
4347struct proc_data {
4348 int release_buffer;
4349 int readlen;
4350 char *rbuffer;
4351 int writelen;
4352 int maxwritelen;
4353 char *wbuffer;
4354 void (*on_close) (struct inode *, struct file *);
4355};
4356
4357#ifndef SETPROC_OPS
4358#define SETPROC_OPS(entry, ops) (entry)->proc_fops = &(ops)
4359#endif
4360
4361static int setup_proc_entry( struct net_device *dev,
4362 struct airo_info *apriv ) {
4363 struct proc_dir_entry *entry;
4364 /* First setup the device directory */
4365 strcpy(apriv->proc_name,dev->name);
4366 apriv->proc_entry = create_proc_entry(apriv->proc_name,
4367 S_IFDIR|airo_perm,
4368 airo_entry);
4369 apriv->proc_entry->uid = proc_uid;
4370 apriv->proc_entry->gid = proc_gid;
4371 apriv->proc_entry->owner = THIS_MODULE;
4372
4373 /* Setup the StatsDelta */
4374 entry = create_proc_entry("StatsDelta",
4375 S_IFREG | (S_IRUGO&proc_perm),
4376 apriv->proc_entry);
4377 entry->uid = proc_uid;
4378 entry->gid = proc_gid;
4379 entry->data = dev;
4380 entry->owner = THIS_MODULE;
4381 SETPROC_OPS(entry, proc_statsdelta_ops);
4382
4383 /* Setup the Stats */
4384 entry = create_proc_entry("Stats",
4385 S_IFREG | (S_IRUGO&proc_perm),
4386 apriv->proc_entry);
4387 entry->uid = proc_uid;
4388 entry->gid = proc_gid;
4389 entry->data = dev;
4390 entry->owner = THIS_MODULE;
4391 SETPROC_OPS(entry, proc_stats_ops);
4392
4393 /* Setup the Status */
4394 entry = create_proc_entry("Status",
4395 S_IFREG | (S_IRUGO&proc_perm),
4396 apriv->proc_entry);
4397 entry->uid = proc_uid;
4398 entry->gid = proc_gid;
4399 entry->data = dev;
4400 entry->owner = THIS_MODULE;
4401 SETPROC_OPS(entry, proc_status_ops);
4402
4403 /* Setup the Config */
4404 entry = create_proc_entry("Config",
4405 S_IFREG | proc_perm,
4406 apriv->proc_entry);
4407 entry->uid = proc_uid;
4408 entry->gid = proc_gid;
4409 entry->data = dev;
4410 entry->owner = THIS_MODULE;
4411 SETPROC_OPS(entry, proc_config_ops);
4412
4413 /* Setup the SSID */
4414 entry = create_proc_entry("SSID",
4415 S_IFREG | proc_perm,
4416 apriv->proc_entry);
4417 entry->uid = proc_uid;
4418 entry->gid = proc_gid;
4419 entry->data = dev;
4420 entry->owner = THIS_MODULE;
4421 SETPROC_OPS(entry, proc_SSID_ops);
4422
4423 /* Setup the APList */
4424 entry = create_proc_entry("APList",
4425 S_IFREG | proc_perm,
4426 apriv->proc_entry);
4427 entry->uid = proc_uid;
4428 entry->gid = proc_gid;
4429 entry->data = dev;
4430 entry->owner = THIS_MODULE;
4431 SETPROC_OPS(entry, proc_APList_ops);
4432
4433 /* Setup the BSSList */
4434 entry = create_proc_entry("BSSList",
4435 S_IFREG | proc_perm,
4436 apriv->proc_entry);
4437 entry->uid = proc_uid;
4438 entry->gid = proc_gid;
4439 entry->data = dev;
4440 entry->owner = THIS_MODULE;
4441 SETPROC_OPS(entry, proc_BSSList_ops);
4442
4443 /* Setup the WepKey */
4444 entry = create_proc_entry("WepKey",
4445 S_IFREG | proc_perm,
4446 apriv->proc_entry);
4447 entry->uid = proc_uid;
4448 entry->gid = proc_gid;
4449 entry->data = dev;
4450 entry->owner = THIS_MODULE;
4451 SETPROC_OPS(entry, proc_wepkey_ops);
4452
4453 return 0;
4454}
4455
4456static int takedown_proc_entry( struct net_device *dev,
4457 struct airo_info *apriv ) {
4458 if ( !apriv->proc_entry->namelen ) return 0;
4459 remove_proc_entry("Stats",apriv->proc_entry);
4460 remove_proc_entry("StatsDelta",apriv->proc_entry);
4461 remove_proc_entry("Status",apriv->proc_entry);
4462 remove_proc_entry("Config",apriv->proc_entry);
4463 remove_proc_entry("SSID",apriv->proc_entry);
4464 remove_proc_entry("APList",apriv->proc_entry);
4465 remove_proc_entry("BSSList",apriv->proc_entry);
4466 remove_proc_entry("WepKey",apriv->proc_entry);
4467 remove_proc_entry(apriv->proc_name,airo_entry);
4468 return 0;
4469}
4470
4471/*
4472 * What we want from the proc_fs is to be able to efficiently read
4473 * and write the configuration. To do this, we want to read the
4474 * configuration when the file is opened and write it when the file is
4475 * closed. So basically we allocate a read buffer at open and fill it
4476 * with data, and allocate a write buffer and read it at close.
4477 */
4478
4479/*
4480 * The read routine is generic, it relies on the preallocated rbuffer
4481 * to supply the data.
4482 */
4483static ssize_t proc_read( struct file *file,
4484 char __user *buffer,
4485 size_t len,
4486 loff_t *offset )
4487{
4488 loff_t pos = *offset;
4489 struct proc_data *priv = (struct proc_data*)file->private_data;
4490
4491 if (!priv->rbuffer)
4492 return -EINVAL;
4493
4494 if (pos < 0)
4495 return -EINVAL;
4496 if (pos >= priv->readlen)
4497 return 0;
4498 if (len > priv->readlen - pos)
4499 len = priv->readlen - pos;
4500 if (copy_to_user(buffer, priv->rbuffer + pos, len))
4501 return -EFAULT;
4502 *offset = pos + len;
4503 return len;
4504}
4505
4506/*
4507 * The write routine is generic, it fills in a preallocated rbuffer
4508 * to supply the data.
4509 */
4510static ssize_t proc_write( struct file *file,
4511 const char __user *buffer,
4512 size_t len,
4513 loff_t *offset )
4514{
4515 loff_t pos = *offset;
4516 struct proc_data *priv = (struct proc_data*)file->private_data;
4517
4518 if (!priv->wbuffer)
4519 return -EINVAL;
4520
4521 if (pos < 0)
4522 return -EINVAL;
4523 if (pos >= priv->maxwritelen)
4524 return 0;
4525 if (len > priv->maxwritelen - pos)
4526 len = priv->maxwritelen - pos;
4527 if (copy_from_user(priv->wbuffer + pos, buffer, len))
4528 return -EFAULT;
4529 if ( pos + len > priv->writelen )
4530 priv->writelen = len + file->f_pos;
4531 *offset = pos + len;
4532 return len;
4533}
4534
4535static int proc_status_open( struct inode *inode, struct file *file ) {
4536 struct proc_data *data;
4537 struct proc_dir_entry *dp = PDE(inode);
4538 struct net_device *dev = dp->data;
4539 struct airo_info *apriv = dev->priv;
4540 CapabilityRid cap_rid;
4541 StatusRid status_rid;
4542 int i;
4543
4544 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4545 return -ENOMEM;
4546 memset(file->private_data, 0, sizeof(struct proc_data));
4547 data = (struct proc_data *)file->private_data;
4548 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4549 kfree (file->private_data);
4550 return -ENOMEM;
4551 }
4552
4553 readStatusRid(apriv, &status_rid, 1);
4554 readCapabilityRid(apriv, &cap_rid, 1);
4555
4556 i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
4557 status_rid.mode & 1 ? "CFG ": "",
4558 status_rid.mode & 2 ? "ACT ": "",
4559 status_rid.mode & 0x10 ? "SYN ": "",
4560 status_rid.mode & 0x20 ? "LNK ": "",
4561 status_rid.mode & 0x40 ? "LEAP ": "",
4562 status_rid.mode & 0x80 ? "PRIV ": "",
4563 status_rid.mode & 0x100 ? "KEY ": "",
4564 status_rid.mode & 0x200 ? "WEP ": "",
4565 status_rid.mode & 0x8000 ? "ERR ": "");
4566 sprintf( data->rbuffer+i, "Mode: %x\n"
4567 "Signal Strength: %d\n"
4568 "Signal Quality: %d\n"
4569 "SSID: %-.*s\n"
4570 "AP: %-.16s\n"
4571 "Freq: %d\n"
4572 "BitRate: %dmbs\n"
4573 "Driver Version: %s\n"
4574 "Device: %s\nManufacturer: %s\nFirmware Version: %s\n"
4575 "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
4576 "Software Version: %x\nSoftware Subversion: %x\n"
4577 "Boot block version: %x\n",
4578 (int)status_rid.mode,
4579 (int)status_rid.normalizedSignalStrength,
4580 (int)status_rid.signalQuality,
4581 (int)status_rid.SSIDlen,
4582 status_rid.SSID,
4583 status_rid.apName,
4584 (int)status_rid.channel,
4585 (int)status_rid.currentXmitRate/2,
4586 version,
4587 cap_rid.prodName,
4588 cap_rid.manName,
4589 cap_rid.prodVer,
4590 cap_rid.radioType,
4591 cap_rid.country,
4592 cap_rid.hardVer,
4593 (int)cap_rid.softVer,
4594 (int)cap_rid.softSubVer,
4595 (int)cap_rid.bootBlockVer );
4596 data->readlen = strlen( data->rbuffer );
4597 return 0;
4598}
4599
4600static int proc_stats_rid_open(struct inode*, struct file*, u16);
4601static int proc_statsdelta_open( struct inode *inode,
4602 struct file *file ) {
4603 if (file->f_mode&FMODE_WRITE) {
4604 return proc_stats_rid_open(inode, file, RID_STATSDELTACLEAR);
4605 }
4606 return proc_stats_rid_open(inode, file, RID_STATSDELTA);
4607}
4608
4609static int proc_stats_open( struct inode *inode, struct file *file ) {
4610 return proc_stats_rid_open(inode, file, RID_STATS);
4611}
4612
4613static int proc_stats_rid_open( struct inode *inode,
4614 struct file *file,
4615 u16 rid ) {
4616 struct proc_data *data;
4617 struct proc_dir_entry *dp = PDE(inode);
4618 struct net_device *dev = dp->data;
4619 struct airo_info *apriv = dev->priv;
4620 StatsRid stats;
4621 int i, j;
4622 u32 *vals = stats.vals;
4623
4624 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4625 return -ENOMEM;
4626 memset(file->private_data, 0, sizeof(struct proc_data));
4627 data = (struct proc_data *)file->private_data;
4628 if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
4629 kfree (file->private_data);
4630 return -ENOMEM;
4631 }
4632
4633 readStatsRid(apriv, &stats, rid, 1);
4634
4635 j = 0;
4636 for(i=0; statsLabels[i]!=(char *)-1 &&
4637 i*4<stats.len; i++){
4638 if (!statsLabels[i]) continue;
4639 if (j+strlen(statsLabels[i])+16>4096) {
4640 printk(KERN_WARNING
4641 "airo: Potentially disasterous buffer overflow averted!\n");
4642 break;
4643 }
4644 j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i], vals[i]);
4645 }
4646 if (i*4>=stats.len){
4647 printk(KERN_WARNING
4648 "airo: Got a short rid\n");
4649 }
4650 data->readlen = j;
4651 return 0;
4652}
4653
4654static int get_dec_u16( char *buffer, int *start, int limit ) {
4655 u16 value;
4656 int valid = 0;
4657 for( value = 0; buffer[*start] >= '0' &&
4658 buffer[*start] <= '9' &&
4659 *start < limit; (*start)++ ) {
4660 valid = 1;
4661 value *= 10;
4662 value += buffer[*start] - '0';
4663 }
4664 if ( !valid ) return -1;
4665 return value;
4666}
4667
4668static int airo_config_commit(struct net_device *dev,
4669 struct iw_request_info *info, void *zwrq,
4670 char *extra);
4671
4672static void proc_config_on_close( struct inode *inode, struct file *file ) {
4673 struct proc_data *data = file->private_data;
4674 struct proc_dir_entry *dp = PDE(inode);
4675 struct net_device *dev = dp->data;
4676 struct airo_info *ai = dev->priv;
4677 char *line;
4678
4679 if ( !data->writelen ) return;
4680
4681 readConfigRid(ai, 1);
4682 set_bit (FLAG_COMMIT, &ai->flags);
4683
4684 line = data->wbuffer;
4685 while( line[0] ) {
4686/*** Mode processing */
4687 if ( !strncmp( line, "Mode: ", 6 ) ) {
4688 line += 6;
4689 if ((ai->config.rmode & 0xff) >= RXMODE_RFMON)
4690 set_bit (FLAG_RESET, &ai->flags);
4691 ai->config.rmode &= 0xfe00;
4692 clear_bit (FLAG_802_11, &ai->flags);
4693 ai->config.opmode &= 0xFF00;
4694 ai->config.scanMode = SCANMODE_ACTIVE;
4695 if ( line[0] == 'a' ) {
4696 ai->config.opmode |= 0;
4697 } else {
4698 ai->config.opmode |= 1;
4699 if ( line[0] == 'r' ) {
4700 ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
4701 ai->config.scanMode = SCANMODE_PASSIVE;
4702 set_bit (FLAG_802_11, &ai->flags);
4703 } else if ( line[0] == 'y' ) {
4704 ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER;
4705 ai->config.scanMode = SCANMODE_PASSIVE;
4706 set_bit (FLAG_802_11, &ai->flags);
4707 } else if ( line[0] == 'l' )
4708 ai->config.rmode |= RXMODE_LANMON;
4709 }
4710 set_bit (FLAG_COMMIT, &ai->flags);
4711 }
4712
4713/*** Radio status */
4714 else if (!strncmp(line,"Radio: ", 7)) {
4715 line += 7;
4716 if (!strncmp(line,"off",3)) {
4717 set_bit (FLAG_RADIO_OFF, &ai->flags);
4718 } else {
4719 clear_bit (FLAG_RADIO_OFF, &ai->flags);
4720 }
4721 }
4722/*** NodeName processing */
4723 else if ( !strncmp( line, "NodeName: ", 10 ) ) {
4724 int j;
4725
4726 line += 10;
4727 memset( ai->config.nodeName, 0, 16 );
4728/* Do the name, assume a space between the mode and node name */
4729 for( j = 0; j < 16 && line[j] != '\n'; j++ ) {
4730 ai->config.nodeName[j] = line[j];
4731 }
4732 set_bit (FLAG_COMMIT, &ai->flags);
4733 }
4734
4735/*** PowerMode processing */
4736 else if ( !strncmp( line, "PowerMode: ", 11 ) ) {
4737 line += 11;
4738 if ( !strncmp( line, "PSPCAM", 6 ) ) {
4739 ai->config.powerSaveMode = POWERSAVE_PSPCAM;
4740 set_bit (FLAG_COMMIT, &ai->flags);
4741 } else if ( !strncmp( line, "PSP", 3 ) ) {
4742 ai->config.powerSaveMode = POWERSAVE_PSP;
4743 set_bit (FLAG_COMMIT, &ai->flags);
4744 } else {
4745 ai->config.powerSaveMode = POWERSAVE_CAM;
4746 set_bit (FLAG_COMMIT, &ai->flags);
4747 }
4748 } else if ( !strncmp( line, "DataRates: ", 11 ) ) {
4749 int v, i = 0, k = 0; /* i is index into line,
4750 k is index to rates */
4751
4752 line += 11;
4753 while((v = get_dec_u16(line, &i, 3))!=-1) {
4754 ai->config.rates[k++] = (u8)v;
4755 line += i + 1;
4756 i = 0;
4757 }
4758 set_bit (FLAG_COMMIT, &ai->flags);
4759 } else if ( !strncmp( line, "Channel: ", 9 ) ) {
4760 int v, i = 0;
4761 line += 9;
4762 v = get_dec_u16(line, &i, i+3);
4763 if ( v != -1 ) {
4764 ai->config.channelSet = (u16)v;
4765 set_bit (FLAG_COMMIT, &ai->flags);
4766 }
4767 } else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
4768 int v, i = 0;
4769 line += 11;
4770 v = get_dec_u16(line, &i, i+3);
4771 if ( v != -1 ) {
4772 ai->config.txPower = (u16)v;
4773 set_bit (FLAG_COMMIT, &ai->flags);
4774 }
4775 } else if ( !strncmp( line, "WEP: ", 5 ) ) {
4776 line += 5;
4777 switch( line[0] ) {
4778 case 's':
4779 ai->config.authType = (u16)AUTH_SHAREDKEY;
4780 break;
4781 case 'e':
4782 ai->config.authType = (u16)AUTH_ENCRYPT;
4783 break;
4784 default:
4785 ai->config.authType = (u16)AUTH_OPEN;
4786 break;
4787 }
4788 set_bit (FLAG_COMMIT, &ai->flags);
4789 } else if ( !strncmp( line, "LongRetryLimit: ", 16 ) ) {
4790 int v, i = 0;
4791
4792 line += 16;
4793 v = get_dec_u16(line, &i, 3);
4794 v = (v<0) ? 0 : ((v>255) ? 255 : v);
4795 ai->config.longRetryLimit = (u16)v;
4796 set_bit (FLAG_COMMIT, &ai->flags);
4797 } else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
4798 int v, i = 0;
4799
4800 line += 17;
4801 v = get_dec_u16(line, &i, 3);
4802 v = (v<0) ? 0 : ((v>255) ? 255 : v);
4803 ai->config.shortRetryLimit = (u16)v;
4804 set_bit (FLAG_COMMIT, &ai->flags);
4805 } else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
4806 int v, i = 0;
4807
4808 line += 14;
4809 v = get_dec_u16(line, &i, 4);
4810 v = (v<0) ? 0 : ((v>2312) ? 2312 : v);
4811 ai->config.rtsThres = (u16)v;
4812 set_bit (FLAG_COMMIT, &ai->flags);
4813 } else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
4814 int v, i = 0;
4815
4816 line += 16;
4817 v = get_dec_u16(line, &i, 5);
4818 v = (v<0) ? 0 : v;
4819 ai->config.txLifetime = (u16)v;
4820 set_bit (FLAG_COMMIT, &ai->flags);
4821 } else if ( !strncmp( line, "RXMSDULifetime: ", 16 ) ) {
4822 int v, i = 0;
4823
4824 line += 16;
4825 v = get_dec_u16(line, &i, 5);
4826 v = (v<0) ? 0 : v;
4827 ai->config.rxLifetime = (u16)v;
4828 set_bit (FLAG_COMMIT, &ai->flags);
4829 } else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
4830 ai->config.txDiversity =
4831 (line[13]=='l') ? 1 :
4832 ((line[13]=='r')? 2: 3);
4833 set_bit (FLAG_COMMIT, &ai->flags);
4834 } else if ( !strncmp( line, "RXDiversity: ", 13 ) ) {
4835 ai->config.rxDiversity =
4836 (line[13]=='l') ? 1 :
4837 ((line[13]=='r')? 2: 3);
4838 set_bit (FLAG_COMMIT, &ai->flags);
4839 } else if ( !strncmp( line, "FragThreshold: ", 15 ) ) {
4840 int v, i = 0;
4841
4842 line += 15;
4843 v = get_dec_u16(line, &i, 4);
4844 v = (v<256) ? 256 : ((v>2312) ? 2312 : v);
4845 v = v & 0xfffe; /* Make sure its even */
4846 ai->config.fragThresh = (u16)v;
4847 set_bit (FLAG_COMMIT, &ai->flags);
4848 } else if (!strncmp(line, "Modulation: ", 12)) {
4849 line += 12;
4850 switch(*line) {
4851 case 'd': ai->config.modulation=MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break;
4852 case 'c': ai->config.modulation=MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break;
4853 case 'm': ai->config.modulation=MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break;
4854 default:
4855 printk( KERN_WARNING "airo: Unknown modulation\n" );
4856 }
4857 } else if (!strncmp(line, "Preamble: ", 10)) {
4858 line += 10;
4859 switch(*line) {
4860 case 'a': ai->config.preamble=PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break;
4861 case 'l': ai->config.preamble=PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break;
4862 case 's': ai->config.preamble=PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break;
4863 default: printk(KERN_WARNING "airo: Unknown preamble\n");
4864 }
4865 } else {
4866 printk( KERN_WARNING "Couldn't figure out %s\n", line );
4867 }
4868 while( line[0] && line[0] != '\n' ) line++;
4869 if ( line[0] ) line++;
4870 }
4871 airo_config_commit(dev, NULL, NULL, NULL);
4872}
4873
4874static char *get_rmode(u16 mode) {
4875 switch(mode&0xff) {
4876 case RXMODE_RFMON: return "rfmon";
4877 case RXMODE_RFMON_ANYBSS: return "yna (any) bss rfmon";
4878 case RXMODE_LANMON: return "lanmon";
4879 }
4880 return "ESS";
4881}
4882
4883static int proc_config_open( struct inode *inode, struct file *file ) {
4884 struct proc_data *data;
4885 struct proc_dir_entry *dp = PDE(inode);
4886 struct net_device *dev = dp->data;
4887 struct airo_info *ai = dev->priv;
4888 int i;
4889
4890 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4891 return -ENOMEM;
4892 memset(file->private_data, 0, sizeof(struct proc_data));
4893 data = (struct proc_data *)file->private_data;
4894 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4895 kfree (file->private_data);
4896 return -ENOMEM;
4897 }
4898 if ((data->wbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4899 kfree (data->rbuffer);
4900 kfree (file->private_data);
4901 return -ENOMEM;
4902 }
4903 memset( data->wbuffer, 0, 2048 );
4904 data->maxwritelen = 2048;
4905 data->on_close = proc_config_on_close;
4906
4907 readConfigRid(ai, 1);
4908
4909 i = sprintf( data->rbuffer,
4910 "Mode: %s\n"
4911 "Radio: %s\n"
4912 "NodeName: %-16s\n"
4913 "PowerMode: %s\n"
4914 "DataRates: %d %d %d %d %d %d %d %d\n"
4915 "Channel: %d\n"
4916 "XmitPower: %d\n",
4917 (ai->config.opmode & 0xFF) == 0 ? "adhoc" :
4918 (ai->config.opmode & 0xFF) == 1 ? get_rmode(ai->config.rmode):
4919 (ai->config.opmode & 0xFF) == 2 ? "AP" :
4920 (ai->config.opmode & 0xFF) == 3 ? "AP RPTR" : "Error",
4921 test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on",
4922 ai->config.nodeName,
4923 ai->config.powerSaveMode == 0 ? "CAM" :
4924 ai->config.powerSaveMode == 1 ? "PSP" :
4925 ai->config.powerSaveMode == 2 ? "PSPCAM" : "Error",
4926 (int)ai->config.rates[0],
4927 (int)ai->config.rates[1],
4928 (int)ai->config.rates[2],
4929 (int)ai->config.rates[3],
4930 (int)ai->config.rates[4],
4931 (int)ai->config.rates[5],
4932 (int)ai->config.rates[6],
4933 (int)ai->config.rates[7],
4934 (int)ai->config.channelSet,
4935 (int)ai->config.txPower
4936 );
4937 sprintf( data->rbuffer + i,
4938 "LongRetryLimit: %d\n"
4939 "ShortRetryLimit: %d\n"
4940 "RTSThreshold: %d\n"
4941 "TXMSDULifetime: %d\n"
4942 "RXMSDULifetime: %d\n"
4943 "TXDiversity: %s\n"
4944 "RXDiversity: %s\n"
4945 "FragThreshold: %d\n"
4946 "WEP: %s\n"
4947 "Modulation: %s\n"
4948 "Preamble: %s\n",
4949 (int)ai->config.longRetryLimit,
4950 (int)ai->config.shortRetryLimit,
4951 (int)ai->config.rtsThres,
4952 (int)ai->config.txLifetime,
4953 (int)ai->config.rxLifetime,
4954 ai->config.txDiversity == 1 ? "left" :
4955 ai->config.txDiversity == 2 ? "right" : "both",
4956 ai->config.rxDiversity == 1 ? "left" :
4957 ai->config.rxDiversity == 2 ? "right" : "both",
4958 (int)ai->config.fragThresh,
4959 ai->config.authType == AUTH_ENCRYPT ? "encrypt" :
4960 ai->config.authType == AUTH_SHAREDKEY ? "shared" : "open",
4961 ai->config.modulation == 0 ? "default" :
4962 ai->config.modulation == MOD_CCK ? "cck" :
4963 ai->config.modulation == MOD_MOK ? "mok" : "error",
4964 ai->config.preamble == PREAMBLE_AUTO ? "auto" :
4965 ai->config.preamble == PREAMBLE_LONG ? "long" :
4966 ai->config.preamble == PREAMBLE_SHORT ? "short" : "error"
4967 );
4968 data->readlen = strlen( data->rbuffer );
4969 return 0;
4970}
4971
4972static void proc_SSID_on_close( struct inode *inode, struct file *file ) {
4973 struct proc_data *data = (struct proc_data *)file->private_data;
4974 struct proc_dir_entry *dp = PDE(inode);
4975 struct net_device *dev = dp->data;
4976 struct airo_info *ai = dev->priv;
4977 SsidRid SSID_rid;
4978 Resp rsp;
4979 int i;
4980 int offset = 0;
4981
4982 if ( !data->writelen ) return;
4983
4984 memset( &SSID_rid, 0, sizeof( SSID_rid ) );
4985
4986 for( i = 0; i < 3; i++ ) {
4987 int j;
4988 for( j = 0; j+offset < data->writelen && j < 32 &&
4989 data->wbuffer[offset+j] != '\n'; j++ ) {
4990 SSID_rid.ssids[i].ssid[j] = data->wbuffer[offset+j];
4991 }
4992 if ( j == 0 ) break;
4993 SSID_rid.ssids[i].len = j;
4994 offset += j;
4995 while( data->wbuffer[offset] != '\n' &&
4996 offset < data->writelen ) offset++;
4997 offset++;
4998 }
4999 if (i)
5000 SSID_rid.len = sizeof(SSID_rid);
5001 disable_MAC(ai, 1);
5002 writeSsidRid(ai, &SSID_rid, 1);
5003 enable_MAC(ai, &rsp, 1);
5004}
5005
5006inline static u8 hexVal(char c) {
5007 if (c>='0' && c<='9') return c -= '0';
5008 if (c>='a' && c<='f') return c -= 'a'-10;
5009 if (c>='A' && c<='F') return c -= 'A'-10;
5010 return 0;
5011}
5012
5013static void proc_APList_on_close( struct inode *inode, struct file *file ) {
5014 struct proc_data *data = (struct proc_data *)file->private_data;
5015 struct proc_dir_entry *dp = PDE(inode);
5016 struct net_device *dev = dp->data;
5017 struct airo_info *ai = dev->priv;
5018 APListRid APList_rid;
5019 Resp rsp;
5020 int i;
5021
5022 if ( !data->writelen ) return;
5023
5024 memset( &APList_rid, 0, sizeof(APList_rid) );
5025 APList_rid.len = sizeof(APList_rid);
5026
5027 for( i = 0; i < 4 && data->writelen >= (i+1)*6*3; i++ ) {
5028 int j;
5029 for( j = 0; j < 6*3 && data->wbuffer[j+i*6*3]; j++ ) {
5030 switch(j%3) {
5031 case 0:
5032 APList_rid.ap[i][j/3]=
5033 hexVal(data->wbuffer[j+i*6*3])<<4;
5034 break;
5035 case 1:
5036 APList_rid.ap[i][j/3]|=
5037 hexVal(data->wbuffer[j+i*6*3]);
5038 break;
5039 }
5040 }
5041 }
5042 disable_MAC(ai, 1);
5043 writeAPListRid(ai, &APList_rid, 1);
5044 enable_MAC(ai, &rsp, 1);
5045}
5046
5047/* This function wraps PC4500_writerid with a MAC disable */
5048static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
5049 int len, int dummy ) {
5050 int rc;
5051 Resp rsp;
5052
5053 disable_MAC(ai, 1);
5054 rc = PC4500_writerid(ai, rid, rid_data, len, 1);
5055 enable_MAC(ai, &rsp, 1);
5056 return rc;
5057}
5058
5059/* Returns the length of the key at the index. If index == 0xffff
5060 * the index of the transmit key is returned. If the key doesn't exist,
5061 * -1 will be returned.
5062 */
5063static int get_wep_key(struct airo_info *ai, u16 index) {
5064 WepKeyRid wkr;
5065 int rc;
5066 u16 lastindex;
5067
5068 rc = readWepKeyRid(ai, &wkr, 1, 1);
5069 if (rc == SUCCESS) do {
5070 lastindex = wkr.kindex;
5071 if (wkr.kindex == index) {
5072 if (index == 0xffff) {
5073 return wkr.mac[0];
5074 }
5075 return wkr.klen;
5076 }
5077 readWepKeyRid(ai, &wkr, 0, 1);
5078 } while(lastindex != wkr.kindex);
5079 return -1;
5080}
5081
5082static int set_wep_key(struct airo_info *ai, u16 index,
5083 const char *key, u16 keylen, int perm, int lock ) {
5084 static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
5085 WepKeyRid wkr;
5086 Resp rsp;
5087
5088 memset(&wkr, 0, sizeof(wkr));
5089 if (keylen == 0) {
5090// We are selecting which key to use
5091 wkr.len = sizeof(wkr);
5092 wkr.kindex = 0xffff;
5093 wkr.mac[0] = (char)index;
5094 if (perm) printk(KERN_INFO "Setting transmit key to %d\n", index);
5095 if (perm) ai->defindex = (char)index;
5096 } else {
5097// We are actually setting the key
5098 wkr.len = sizeof(wkr);
5099 wkr.kindex = index;
5100 wkr.klen = keylen;
5101 memcpy( wkr.key, key, keylen );
5102 memcpy( wkr.mac, macaddr, ETH_ALEN );
5103 printk(KERN_INFO "Setting key %d\n", index);
5104 }
5105
5106 disable_MAC(ai, lock);
5107 writeWepKeyRid(ai, &wkr, perm, lock);
5108 enable_MAC(ai, &rsp, lock);
5109 return 0;
5110}
5111
5112static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
5113 struct proc_data *data;
5114 struct proc_dir_entry *dp = PDE(inode);
5115 struct net_device *dev = dp->data;
5116 struct airo_info *ai = dev->priv;
5117 int i;
5118 char key[16];
5119 u16 index = 0;
5120 int j = 0;
5121
5122 memset(key, 0, sizeof(key));
5123
5124 data = (struct proc_data *)file->private_data;
5125 if ( !data->writelen ) return;
5126
5127 if (data->wbuffer[0] >= '0' && data->wbuffer[0] <= '3' &&
5128 (data->wbuffer[1] == ' ' || data->wbuffer[1] == '\n')) {
5129 index = data->wbuffer[0] - '0';
5130 if (data->wbuffer[1] == '\n') {
5131 set_wep_key(ai, index, NULL, 0, 1, 1);
5132 return;
5133 }
5134 j = 2;
5135 } else {
5136 printk(KERN_ERR "airo: WepKey passed invalid key index\n");
5137 return;
5138 }
5139
5140 for( i = 0; i < 16*3 && data->wbuffer[i+j]; i++ ) {
5141 switch(i%3) {
5142 case 0:
5143 key[i/3] = hexVal(data->wbuffer[i+j])<<4;
5144 break;
5145 case 1:
5146 key[i/3] |= hexVal(data->wbuffer[i+j]);
5147 break;
5148 }
5149 }
5150 set_wep_key(ai, index, key, i/3, 1, 1);
5151}
5152
5153static int proc_wepkey_open( struct inode *inode, struct file *file ) {
5154 struct proc_data *data;
5155 struct proc_dir_entry *dp = PDE(inode);
5156 struct net_device *dev = dp->data;
5157 struct airo_info *ai = dev->priv;
5158 char *ptr;
5159 WepKeyRid wkr;
5160 u16 lastindex;
5161 int j=0;
5162 int rc;
5163
5164 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5165 return -ENOMEM;
5166 memset(file->private_data, 0, sizeof(struct proc_data));
5167 memset(&wkr, 0, sizeof(wkr));
5168 data = (struct proc_data *)file->private_data;
5169 if ((data->rbuffer = kmalloc( 180, GFP_KERNEL )) == NULL) {
5170 kfree (file->private_data);
5171 return -ENOMEM;
5172 }
5173 memset(data->rbuffer, 0, 180);
5174 data->writelen = 0;
5175 data->maxwritelen = 80;
5176 if ((data->wbuffer = kmalloc( 80, GFP_KERNEL )) == NULL) {
5177 kfree (data->rbuffer);
5178 kfree (file->private_data);
5179 return -ENOMEM;
5180 }
5181 memset( data->wbuffer, 0, 80 );
5182 data->on_close = proc_wepkey_on_close;
5183
5184 ptr = data->rbuffer;
5185 strcpy(ptr, "No wep keys\n");
5186 rc = readWepKeyRid(ai, &wkr, 1, 1);
5187 if (rc == SUCCESS) do {
5188 lastindex = wkr.kindex;
5189 if (wkr.kindex == 0xffff) {
5190 j += sprintf(ptr+j, "Tx key = %d\n",
5191 (int)wkr.mac[0]);
5192 } else {
5193 j += sprintf(ptr+j, "Key %d set with length = %d\n",
5194 (int)wkr.kindex, (int)wkr.klen);
5195 }
5196 readWepKeyRid(ai, &wkr, 0, 1);
5197 } while((lastindex != wkr.kindex) && (j < 180-30));
5198
5199 data->readlen = strlen( data->rbuffer );
5200 return 0;
5201}
5202
5203static int proc_SSID_open( struct inode *inode, struct file *file ) {
5204 struct proc_data *data;
5205 struct proc_dir_entry *dp = PDE(inode);
5206 struct net_device *dev = dp->data;
5207 struct airo_info *ai = dev->priv;
5208 int i;
5209 char *ptr;
5210 SsidRid SSID_rid;
5211
5212 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5213 return -ENOMEM;
5214 memset(file->private_data, 0, sizeof(struct proc_data));
5215 data = (struct proc_data *)file->private_data;
5216 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5217 kfree (file->private_data);
5218 return -ENOMEM;
5219 }
5220 data->writelen = 0;
5221 data->maxwritelen = 33*3;
5222 if ((data->wbuffer = kmalloc( 33*3, GFP_KERNEL )) == NULL) {
5223 kfree (data->rbuffer);
5224 kfree (file->private_data);
5225 return -ENOMEM;
5226 }
5227 memset( data->wbuffer, 0, 33*3 );
5228 data->on_close = proc_SSID_on_close;
5229
5230 readSsidRid(ai, &SSID_rid);
5231 ptr = data->rbuffer;
5232 for( i = 0; i < 3; i++ ) {
5233 int j;
5234 if ( !SSID_rid.ssids[i].len ) break;
5235 for( j = 0; j < 32 &&
5236 j < SSID_rid.ssids[i].len &&
5237 SSID_rid.ssids[i].ssid[j]; j++ ) {
5238 *ptr++ = SSID_rid.ssids[i].ssid[j];
5239 }
5240 *ptr++ = '\n';
5241 }
5242 *ptr = '\0';
5243 data->readlen = strlen( data->rbuffer );
5244 return 0;
5245}
5246
5247static int proc_APList_open( struct inode *inode, struct file *file ) {
5248 struct proc_data *data;
5249 struct proc_dir_entry *dp = PDE(inode);
5250 struct net_device *dev = dp->data;
5251 struct airo_info *ai = dev->priv;
5252 int i;
5253 char *ptr;
5254 APListRid APList_rid;
5255
5256 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5257 return -ENOMEM;
5258 memset(file->private_data, 0, sizeof(struct proc_data));
5259 data = (struct proc_data *)file->private_data;
5260 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5261 kfree (file->private_data);
5262 return -ENOMEM;
5263 }
5264 data->writelen = 0;
5265 data->maxwritelen = 4*6*3;
5266 if ((data->wbuffer = kmalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
5267 kfree (data->rbuffer);
5268 kfree (file->private_data);
5269 return -ENOMEM;
5270 }
5271 memset( data->wbuffer, 0, data->maxwritelen );
5272 data->on_close = proc_APList_on_close;
5273
5274 readAPListRid(ai, &APList_rid);
5275 ptr = data->rbuffer;
5276 for( i = 0; i < 4; i++ ) {
5277// We end when we find a zero MAC
5278 if ( !*(int*)APList_rid.ap[i] &&
5279 !*(int*)&APList_rid.ap[i][2]) break;
5280 ptr += sprintf(ptr, "%02x:%02x:%02x:%02x:%02x:%02x\n",
5281 (int)APList_rid.ap[i][0],
5282 (int)APList_rid.ap[i][1],
5283 (int)APList_rid.ap[i][2],
5284 (int)APList_rid.ap[i][3],
5285 (int)APList_rid.ap[i][4],
5286 (int)APList_rid.ap[i][5]);
5287 }
5288 if (i==0) ptr += sprintf(ptr, "Not using specific APs\n");
5289
5290 *ptr = '\0';
5291 data->readlen = strlen( data->rbuffer );
5292 return 0;
5293}
5294
5295static int proc_BSSList_open( struct inode *inode, struct file *file ) {
5296 struct proc_data *data;
5297 struct proc_dir_entry *dp = PDE(inode);
5298 struct net_device *dev = dp->data;
5299 struct airo_info *ai = dev->priv;
5300 char *ptr;
5301 BSSListRid BSSList_rid;
5302 int rc;
5303 /* If doLoseSync is not 1, we won't do a Lose Sync */
5304 int doLoseSync = -1;
5305
5306 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5307 return -ENOMEM;
5308 memset(file->private_data, 0, sizeof(struct proc_data));
5309 data = (struct proc_data *)file->private_data;
5310 if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
5311 kfree (file->private_data);
5312 return -ENOMEM;
5313 }
5314 data->writelen = 0;
5315 data->maxwritelen = 0;
5316 data->wbuffer = NULL;
5317 data->on_close = NULL;
5318
5319 if (file->f_mode & FMODE_WRITE) {
5320 if (!(file->f_mode & FMODE_READ)) {
5321 Cmd cmd;
5322 Resp rsp;
5323
5324 if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
5325 memset(&cmd, 0, sizeof(cmd));
5326 cmd.cmd=CMD_LISTBSS;
5327 if (down_interruptible(&ai->sem))
5328 return -ERESTARTSYS;
5329 issuecommand(ai, &cmd, &rsp);
5330 up(&ai->sem);
5331 data->readlen = 0;
5332 return 0;
5333 }
5334 doLoseSync = 1;
5335 }
5336 ptr = data->rbuffer;
5337 /* There is a race condition here if there are concurrent opens.
5338 Since it is a rare condition, we'll just live with it, otherwise
5339 we have to add a spin lock... */
5340 rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
5341 while(rc == 0 && BSSList_rid.index != 0xffff) {
5342 ptr += sprintf(ptr, "%02x:%02x:%02x:%02x:%02x:%02x %*s rssi = %d",
5343 (int)BSSList_rid.bssid[0],
5344 (int)BSSList_rid.bssid[1],
5345 (int)BSSList_rid.bssid[2],
5346 (int)BSSList_rid.bssid[3],
5347 (int)BSSList_rid.bssid[4],
5348 (int)BSSList_rid.bssid[5],
5349 (int)BSSList_rid.ssidLen,
5350 BSSList_rid.ssid,
5351 (int)BSSList_rid.rssi);
5352 ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
5353 (int)BSSList_rid.dsChannel,
5354 BSSList_rid.cap & CAP_ESS ? "ESS" : "",
5355 BSSList_rid.cap & CAP_IBSS ? "adhoc" : "",
5356 BSSList_rid.cap & CAP_PRIVACY ? "wep" : "",
5357 BSSList_rid.cap & CAP_SHORTHDR ? "shorthdr" : "");
5358 rc = readBSSListRid(ai, 0, &BSSList_rid);
5359 }
5360 *ptr = '\0';
5361 data->readlen = strlen( data->rbuffer );
5362 return 0;
5363}
5364
5365static int proc_close( struct inode *inode, struct file *file )
5366{
5367 struct proc_data *data = (struct proc_data *)file->private_data;
5368 if ( data->on_close != NULL ) data->on_close( inode, file );
5369 if ( data->rbuffer ) kfree( data->rbuffer );
5370 if ( data->wbuffer ) kfree( data->wbuffer );
5371 kfree( data );
5372 return 0;
5373}
5374
5375static struct net_device_list {
5376 struct net_device *dev;
5377 struct net_device_list *next;
5378} *airo_devices;
5379
5380/* Since the card doesn't automatically switch to the right WEP mode,
5381 we will make it do it. If the card isn't associated, every secs we
5382 will switch WEP modes to see if that will help. If the card is
5383 associated we will check every minute to see if anything has
5384 changed. */
5385static void timer_func( struct net_device *dev ) {
5386 struct airo_info *apriv = dev->priv;
5387 Resp rsp;
5388
5389/* We don't have a link so try changing the authtype */
5390 readConfigRid(apriv, 0);
5391 disable_MAC(apriv, 0);
5392 switch(apriv->config.authType) {
5393 case AUTH_ENCRYPT:
5394/* So drop to OPEN */
5395 apriv->config.authType = AUTH_OPEN;
5396 break;
5397 case AUTH_SHAREDKEY:
5398 if (apriv->keyindex < auto_wep) {
5399 set_wep_key(apriv, apriv->keyindex, NULL, 0, 0, 0);
5400 apriv->config.authType = AUTH_SHAREDKEY;
5401 apriv->keyindex++;
5402 } else {
5403 /* Drop to ENCRYPT */
5404 apriv->keyindex = 0;
5405 set_wep_key(apriv, apriv->defindex, NULL, 0, 0, 0);
5406 apriv->config.authType = AUTH_ENCRYPT;
5407 }
5408 break;
5409 default: /* We'll escalate to SHAREDKEY */
5410 apriv->config.authType = AUTH_SHAREDKEY;
5411 }
5412 set_bit (FLAG_COMMIT, &apriv->flags);
5413 writeConfigRid(apriv, 0);
5414 enable_MAC(apriv, &rsp, 0);
5415 up(&apriv->sem);
5416
5417/* Schedule check to see if the change worked */
5418 clear_bit(JOB_AUTOWEP, &apriv->flags);
5419 apriv->expires = RUN_AT(HZ*3);
5420}
5421
5422static int add_airo_dev( struct net_device *dev ) {
5423 struct net_device_list *node = kmalloc( sizeof( *node ), GFP_KERNEL );
5424 if ( !node )
5425 return -ENOMEM;
5426
5427 node->dev = dev;
5428 node->next = airo_devices;
5429 airo_devices = node;
5430
5431 return 0;
5432}
5433
5434static void del_airo_dev( struct net_device *dev ) {
5435 struct net_device_list **p = &airo_devices;
5436 while( *p && ( (*p)->dev != dev ) )
5437 p = &(*p)->next;
5438 if ( *p && (*p)->dev == dev )
5439 *p = (*p)->next;
5440}
5441
5442#ifdef CONFIG_PCI
5443static int __devinit airo_pci_probe(struct pci_dev *pdev,
5444 const struct pci_device_id *pent)
5445{
5446 struct net_device *dev;
5447
5448 if (pci_enable_device(pdev))
5449 return -ENODEV;
5450 pci_set_master(pdev);
5451
5452 if (pdev->device == 0x5000 || pdev->device == 0xa504)
5453 dev = _init_airo_card(pdev->irq, pdev->resource[0].start, 0, pdev, &pdev->dev);
5454 else
5455 dev = _init_airo_card(pdev->irq, pdev->resource[2].start, 0, pdev, &pdev->dev);
5456 if (!dev)
5457 return -ENODEV;
5458
5459 pci_set_drvdata(pdev, dev);
5460 return 0;
5461}
5462
5463static void __devexit airo_pci_remove(struct pci_dev *pdev)
5464{
5465}
5466
5467static int airo_pci_suspend(struct pci_dev *pdev, u32 state)
5468{
5469 struct net_device *dev = pci_get_drvdata(pdev);
5470 struct airo_info *ai = dev->priv;
5471 Cmd cmd;
5472 Resp rsp;
5473
5474 if ((ai->APList == NULL) &&
5475 (ai->APList = kmalloc(sizeof(APListRid), GFP_KERNEL)) == NULL)
5476 return -ENOMEM;
5477 if ((ai->SSID == NULL) &&
5478 (ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL)) == NULL)
5479 return -ENOMEM;
5480 readAPListRid(ai, ai->APList);
5481 readSsidRid(ai, ai->SSID);
5482 memset(&cmd, 0, sizeof(cmd));
5483 /* the lock will be released at the end of the resume callback */
5484 if (down_interruptible(&ai->sem))
5485 return -EAGAIN;
5486 disable_MAC(ai, 0);
5487 netif_device_detach(dev);
5488 ai->power = state;
5489 cmd.cmd=HOSTSLEEP;
5490 issuecommand(ai, &cmd, &rsp);
5491
5492 pci_enable_wake(pdev, state, 1);
5493 pci_save_state(pdev);
5494 return pci_set_power_state(pdev, state);
5495}
5496
5497static int airo_pci_resume(struct pci_dev *pdev)
5498{
5499 struct net_device *dev = pci_get_drvdata(pdev);
5500 struct airo_info *ai = dev->priv;
5501 Resp rsp;
5502
5503 pci_set_power_state(pdev, 0);
5504 pci_restore_state(pdev);
5505 pci_enable_wake(pdev, ai->power, 0);
5506
5507 if (ai->power > 1) {
5508 reset_card(dev, 0);
5509 mpi_init_descriptors(ai);
5510 setup_card(ai, dev->dev_addr, 0);
5511 clear_bit(FLAG_RADIO_OFF, &ai->flags);
5512 clear_bit(FLAG_PENDING_XMIT, &ai->flags);
5513 } else {
5514 OUT4500(ai, EVACK, EV_AWAKEN);
5515 OUT4500(ai, EVACK, EV_AWAKEN);
5516 msleep(100);
5517 }
5518
5519 set_bit (FLAG_COMMIT, &ai->flags);
5520 disable_MAC(ai, 0);
5521 msleep(200);
5522 if (ai->SSID) {
5523 writeSsidRid(ai, ai->SSID, 0);
5524 kfree(ai->SSID);
5525 ai->SSID = NULL;
5526 }
5527 if (ai->APList) {
5528 writeAPListRid(ai, ai->APList, 0);
5529 kfree(ai->APList);
5530 ai->APList = NULL;
5531 }
5532 writeConfigRid(ai, 0);
5533 enable_MAC(ai, &rsp, 0);
5534 ai->power = 0;
5535 netif_device_attach(dev);
5536 netif_wake_queue(dev);
5537 enable_interrupts(ai);
5538 up(&ai->sem);
5539 return 0;
5540}
5541#endif
5542
5543static int __init airo_init_module( void )
5544{
5545 int i, have_isa_dev = 0;
5546
5547 airo_entry = create_proc_entry("aironet",
5548 S_IFDIR | airo_perm,
5549 proc_root_driver);
5550 airo_entry->uid = proc_uid;
5551 airo_entry->gid = proc_gid;
5552
5553 for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
5554 printk( KERN_INFO
5555 "airo: Trying to configure ISA adapter at irq=%d io=0x%x\n",
5556 irq[i], io[i] );
5557 if (init_airo_card( irq[i], io[i], 0, NULL ))
5558 have_isa_dev = 1;
5559 }
5560
5561#ifdef CONFIG_PCI
5562 printk( KERN_INFO "airo: Probing for PCI adapters\n" );
5563 pci_register_driver(&airo_driver);
5564 printk( KERN_INFO "airo: Finished probing for PCI adapters\n" );
5565#endif
5566
5567 /* Always exit with success, as we are a library module
5568 * as well as a driver module
5569 */
5570 return 0;
5571}
5572
5573static void __exit airo_cleanup_module( void )
5574{
5575 while( airo_devices ) {
5576 printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name );
5577 stop_airo_card( airo_devices->dev, 1 );
5578 }
5579#ifdef CONFIG_PCI
5580 pci_unregister_driver(&airo_driver);
5581#endif
5582 remove_proc_entry("aironet", proc_root_driver);
5583}
5584
5585#ifdef WIRELESS_EXT
5586/*
5587 * Initial Wireless Extension code for Aironet driver by :
5588 * Jean Tourrilhes <jt@hpl.hp.com> - HPL - 17 November 00
5589 * Conversion to new driver API by :
5590 * Jean Tourrilhes <jt@hpl.hp.com> - HPL - 26 March 02
5591 * Javier also did a good amount of work here, adding some new extensions
5592 * and fixing my code. Let's just say that without him this code just
5593 * would not work at all... - Jean II
5594 */
5595
5596static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
5597{
5598 int quality = 0;
5599
5600 if ((status_rid->mode & 0x3f) == 0x3f && (cap_rid->hardCap & 8)) {
5601 if (memcmp(cap_rid->prodName, "350", 3))
5602 if (status_rid->signalQuality > 0x20)
5603 quality = 0;
5604 else
5605 quality = 0x20 - status_rid->signalQuality;
5606 else
5607 if (status_rid->signalQuality > 0xb0)
5608 quality = 0;
5609 else if (status_rid->signalQuality < 0x10)
5610 quality = 0xa0;
5611 else
5612 quality = 0xb0 - status_rid->signalQuality;
5613 }
5614 return quality;
5615}
5616
5617#define airo_get_max_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x20 : 0xa0)
5618#define airo_get_avg_quality(cap_rid) (memcmp((cap_rid)->prodName, "350", 3) ? 0x10 : 0x50);
5619
5620/*------------------------------------------------------------------*/
5621/*
5622 * Wireless Handler : get protocol name
5623 */
5624static int airo_get_name(struct net_device *dev,
5625 struct iw_request_info *info,
5626 char *cwrq,
5627 char *extra)
5628{
5629 strcpy(cwrq, "IEEE 802.11-DS");
5630 return 0;
5631}
5632
5633/*------------------------------------------------------------------*/
5634/*
5635 * Wireless Handler : set frequency
5636 */
5637static int airo_set_freq(struct net_device *dev,
5638 struct iw_request_info *info,
5639 struct iw_freq *fwrq,
5640 char *extra)
5641{
5642 struct airo_info *local = dev->priv;
5643 int rc = -EINPROGRESS; /* Call commit handler */
5644
5645 /* If setting by frequency, convert to a channel */
5646 if((fwrq->e == 1) &&
5647 (fwrq->m >= (int) 2.412e8) &&
5648 (fwrq->m <= (int) 2.487e8)) {
5649 int f = fwrq->m / 100000;
5650 int c = 0;
5651 while((c < 14) && (f != frequency_list[c]))
5652 c++;
5653 /* Hack to fall through... */
5654 fwrq->e = 0;
5655 fwrq->m = c + 1;
5656 }
5657 /* Setting by channel number */
5658 if((fwrq->m > 1000) || (fwrq->e > 0))
5659 rc = -EOPNOTSUPP;
5660 else {
5661 int channel = fwrq->m;
5662 /* We should do a better check than that,
5663 * based on the card capability !!! */
5664 if((channel < 1) || (channel > 16)) {
5665 printk(KERN_DEBUG "%s: New channel value of %d is invalid!\n", dev->name, fwrq->m);
5666 rc = -EINVAL;
5667 } else {
5668 readConfigRid(local, 1);
5669 /* Yes ! We can set it !!! */
5670 local->config.channelSet = (u16)(channel - 1);
5671 set_bit (FLAG_COMMIT, &local->flags);
5672 }
5673 }
5674 return rc;
5675}
5676
5677/*------------------------------------------------------------------*/
5678/*
5679 * Wireless Handler : get frequency
5680 */
5681static int airo_get_freq(struct net_device *dev,
5682 struct iw_request_info *info,
5683 struct iw_freq *fwrq,
5684 char *extra)
5685{
5686 struct airo_info *local = dev->priv;
5687 StatusRid status_rid; /* Card status info */
5688
5689 readConfigRid(local, 1);
5690 if ((local->config.opmode & 0xFF) == MODE_STA_ESS)
5691 status_rid.channel = local->config.channelSet;
5692 else
5693 readStatusRid(local, &status_rid, 1);
5694
5695#ifdef WEXT_USECHANNELS
5696 fwrq->m = ((int)status_rid.channel) + 1;
5697 fwrq->e = 0;
5698#else
5699 {
5700 int f = (int)status_rid.channel;
5701 fwrq->m = frequency_list[f] * 100000;
5702 fwrq->e = 1;
5703 }
5704#endif
5705
5706 return 0;
5707}
5708
5709/*------------------------------------------------------------------*/
5710/*
5711 * Wireless Handler : set ESSID
5712 */
5713static int airo_set_essid(struct net_device *dev,
5714 struct iw_request_info *info,
5715 struct iw_point *dwrq,
5716 char *extra)
5717{
5718 struct airo_info *local = dev->priv;
5719 Resp rsp;
5720 SsidRid SSID_rid; /* SSIDs */
5721
5722 /* Reload the list of current SSID */
5723 readSsidRid(local, &SSID_rid);
5724
5725 /* Check if we asked for `any' */
5726 if(dwrq->flags == 0) {
5727 /* Just send an empty SSID list */
5728 memset(&SSID_rid, 0, sizeof(SSID_rid));
5729 } else {
5730 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
5731
5732 /* Check the size of the string */
5733 if(dwrq->length > IW_ESSID_MAX_SIZE+1) {
5734 return -E2BIG ;
5735 }
5736 /* Check if index is valid */
5737 if((index < 0) || (index >= 4)) {
5738 return -EINVAL;
5739 }
5740
5741 /* Set the SSID */
5742 memset(SSID_rid.ssids[index].ssid, 0,
5743 sizeof(SSID_rid.ssids[index].ssid));
5744 memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
5745 SSID_rid.ssids[index].len = dwrq->length - 1;
5746 }
5747 SSID_rid.len = sizeof(SSID_rid);
5748 /* Write it to the card */
5749 disable_MAC(local, 1);
5750 writeSsidRid(local, &SSID_rid, 1);
5751 enable_MAC(local, &rsp, 1);
5752
5753 return 0;
5754}
5755
5756/*------------------------------------------------------------------*/
5757/*
5758 * Wireless Handler : get ESSID
5759 */
5760static int airo_get_essid(struct net_device *dev,
5761 struct iw_request_info *info,
5762 struct iw_point *dwrq,
5763 char *extra)
5764{
5765 struct airo_info *local = dev->priv;
5766 StatusRid status_rid; /* Card status info */
5767
5768 readStatusRid(local, &status_rid, 1);
5769
5770 /* Note : if dwrq->flags != 0, we should
5771 * get the relevant SSID from the SSID list... */
5772
5773 /* Get the current SSID */
5774 memcpy(extra, status_rid.SSID, status_rid.SSIDlen);
5775 extra[status_rid.SSIDlen] = '\0';
5776 /* If none, we may want to get the one that was set */
5777
5778 /* Push it out ! */
5779 dwrq->length = status_rid.SSIDlen + 1;
5780 dwrq->flags = 1; /* active */
5781
5782 return 0;
5783}
5784
5785/*------------------------------------------------------------------*/
5786/*
5787 * Wireless Handler : set AP address
5788 */
5789static int airo_set_wap(struct net_device *dev,
5790 struct iw_request_info *info,
5791 struct sockaddr *awrq,
5792 char *extra)
5793{
5794 struct airo_info *local = dev->priv;
5795 Cmd cmd;
5796 Resp rsp;
5797 APListRid APList_rid;
5798 static const unsigned char bcast[ETH_ALEN] = { 255, 255, 255, 255, 255, 255 };
5799
5800 if (awrq->sa_family != ARPHRD_ETHER)
5801 return -EINVAL;
5802 else if (!memcmp(bcast, awrq->sa_data, ETH_ALEN)) {
5803 memset(&cmd, 0, sizeof(cmd));
5804 cmd.cmd=CMD_LOSE_SYNC;
5805 if (down_interruptible(&local->sem))
5806 return -ERESTARTSYS;
5807 issuecommand(local, &cmd, &rsp);
5808 up(&local->sem);
5809 } else {
5810 memset(&APList_rid, 0, sizeof(APList_rid));
5811 APList_rid.len = sizeof(APList_rid);
5812 memcpy(APList_rid.ap[0], awrq->sa_data, ETH_ALEN);
5813 disable_MAC(local, 1);
5814 writeAPListRid(local, &APList_rid, 1);
5815 enable_MAC(local, &rsp, 1);
5816 }
5817 return 0;
5818}
5819
5820/*------------------------------------------------------------------*/
5821/*
5822 * Wireless Handler : get AP address
5823 */
5824static int airo_get_wap(struct net_device *dev,
5825 struct iw_request_info *info,
5826 struct sockaddr *awrq,
5827 char *extra)
5828{
5829 struct airo_info *local = dev->priv;
5830 StatusRid status_rid; /* Card status info */
5831
5832 readStatusRid(local, &status_rid, 1);
5833
5834 /* Tentative. This seems to work, wow, I'm lucky !!! */
5835 memcpy(awrq->sa_data, status_rid.bssid[0], ETH_ALEN);
5836 awrq->sa_family = ARPHRD_ETHER;
5837
5838 return 0;
5839}
5840
5841/*------------------------------------------------------------------*/
5842/*
5843 * Wireless Handler : set Nickname
5844 */
5845static int airo_set_nick(struct net_device *dev,
5846 struct iw_request_info *info,
5847 struct iw_point *dwrq,
5848 char *extra)
5849{
5850 struct airo_info *local = dev->priv;
5851
5852 /* Check the size of the string */
5853 if(dwrq->length > 16 + 1) {
5854 return -E2BIG;
5855 }
5856 readConfigRid(local, 1);
5857 memset(local->config.nodeName, 0, sizeof(local->config.nodeName));
5858 memcpy(local->config.nodeName, extra, dwrq->length);
5859 set_bit (FLAG_COMMIT, &local->flags);
5860
5861 return -EINPROGRESS; /* Call commit handler */
5862}
5863
5864/*------------------------------------------------------------------*/
5865/*
5866 * Wireless Handler : get Nickname
5867 */
5868static int airo_get_nick(struct net_device *dev,
5869 struct iw_request_info *info,
5870 struct iw_point *dwrq,
5871 char *extra)
5872{
5873 struct airo_info *local = dev->priv;
5874
5875 readConfigRid(local, 1);
5876 strncpy(extra, local->config.nodeName, 16);
5877 extra[16] = '\0';
5878 dwrq->length = strlen(extra) + 1;
5879
5880 return 0;
5881}
5882
5883/*------------------------------------------------------------------*/
5884/*
5885 * Wireless Handler : set Bit-Rate
5886 */
5887static int airo_set_rate(struct net_device *dev,
5888 struct iw_request_info *info,
5889 struct iw_param *vwrq,
5890 char *extra)
5891{
5892 struct airo_info *local = dev->priv;
5893 CapabilityRid cap_rid; /* Card capability info */
5894 u8 brate = 0;
5895 int i;
5896
5897 /* First : get a valid bit rate value */
5898 readCapabilityRid(local, &cap_rid, 1);
5899
5900 /* Which type of value ? */
5901 if((vwrq->value < 8) && (vwrq->value >= 0)) {
5902 /* Setting by rate index */
5903 /* Find value in the magic rate table */
5904 brate = cap_rid.supportedRates[vwrq->value];
5905 } else {
5906 /* Setting by frequency value */
5907 u8 normvalue = (u8) (vwrq->value/500000);
5908
5909 /* Check if rate is valid */
5910 for(i = 0 ; i < 8 ; i++) {
5911 if(normvalue == cap_rid.supportedRates[i]) {
5912 brate = normvalue;
5913 break;
5914 }
5915 }
5916 }
5917 /* -1 designed the max rate (mostly auto mode) */
5918 if(vwrq->value == -1) {
5919 /* Get the highest available rate */
5920 for(i = 0 ; i < 8 ; i++) {
5921 if(cap_rid.supportedRates[i] == 0)
5922 break;
5923 }
5924 if(i != 0)
5925 brate = cap_rid.supportedRates[i - 1];
5926 }
5927 /* Check that it is valid */
5928 if(brate == 0) {
5929 return -EINVAL;
5930 }
5931
5932 readConfigRid(local, 1);
5933 /* Now, check if we want a fixed or auto value */
5934 if(vwrq->fixed == 0) {
5935 /* Fill all the rates up to this max rate */
5936 memset(local->config.rates, 0, 8);
5937 for(i = 0 ; i < 8 ; i++) {
5938 local->config.rates[i] = cap_rid.supportedRates[i];
5939 if(local->config.rates[i] == brate)
5940 break;
5941 }
5942 } else {
5943 /* Fixed mode */
5944 /* One rate, fixed */
5945 memset(local->config.rates, 0, 8);
5946 local->config.rates[0] = brate;
5947 }
5948 set_bit (FLAG_COMMIT, &local->flags);
5949
5950 return -EINPROGRESS; /* Call commit handler */
5951}
5952
5953/*------------------------------------------------------------------*/
5954/*
5955 * Wireless Handler : get Bit-Rate
5956 */
5957static int airo_get_rate(struct net_device *dev,
5958 struct iw_request_info *info,
5959 struct iw_param *vwrq,
5960 char *extra)
5961{
5962 struct airo_info *local = dev->priv;
5963 StatusRid status_rid; /* Card status info */
5964
5965 readStatusRid(local, &status_rid, 1);
5966
5967 vwrq->value = status_rid.currentXmitRate * 500000;
5968 /* If more than one rate, set auto */
5969 readConfigRid(local, 1);
5970 vwrq->fixed = (local->config.rates[1] == 0);
5971
5972 return 0;
5973}
5974
5975/*------------------------------------------------------------------*/
5976/*
5977 * Wireless Handler : set RTS threshold
5978 */
5979static int airo_set_rts(struct net_device *dev,
5980 struct iw_request_info *info,
5981 struct iw_param *vwrq,
5982 char *extra)
5983{
5984 struct airo_info *local = dev->priv;
5985 int rthr = vwrq->value;
5986
5987 if(vwrq->disabled)
5988 rthr = 2312;
5989 if((rthr < 0) || (rthr > 2312)) {
5990 return -EINVAL;
5991 }
5992 readConfigRid(local, 1);
5993 local->config.rtsThres = rthr;
5994 set_bit (FLAG_COMMIT, &local->flags);
5995
5996 return -EINPROGRESS; /* Call commit handler */
5997}
5998
5999/*------------------------------------------------------------------*/
6000/*
6001 * Wireless Handler : get RTS threshold
6002 */
6003static int airo_get_rts(struct net_device *dev,
6004 struct iw_request_info *info,
6005 struct iw_param *vwrq,
6006 char *extra)
6007{
6008 struct airo_info *local = dev->priv;
6009
6010 readConfigRid(local, 1);
6011 vwrq->value = local->config.rtsThres;
6012 vwrq->disabled = (vwrq->value >= 2312);
6013 vwrq->fixed = 1;
6014
6015 return 0;
6016}
6017
6018/*------------------------------------------------------------------*/
6019/*
6020 * Wireless Handler : set Fragmentation threshold
6021 */
6022static int airo_set_frag(struct net_device *dev,
6023 struct iw_request_info *info,
6024 struct iw_param *vwrq,
6025 char *extra)
6026{
6027 struct airo_info *local = dev->priv;
6028 int fthr = vwrq->value;
6029
6030 if(vwrq->disabled)
6031 fthr = 2312;
6032 if((fthr < 256) || (fthr > 2312)) {
6033 return -EINVAL;
6034 }
6035 fthr &= ~0x1; /* Get an even value - is it really needed ??? */
6036 readConfigRid(local, 1);
6037 local->config.fragThresh = (u16)fthr;
6038 set_bit (FLAG_COMMIT, &local->flags);
6039
6040 return -EINPROGRESS; /* Call commit handler */
6041}
6042
6043/*------------------------------------------------------------------*/
6044/*
6045 * Wireless Handler : get Fragmentation threshold
6046 */
6047static int airo_get_frag(struct net_device *dev,
6048 struct iw_request_info *info,
6049 struct iw_param *vwrq,
6050 char *extra)
6051{
6052 struct airo_info *local = dev->priv;
6053
6054 readConfigRid(local, 1);
6055 vwrq->value = local->config.fragThresh;
6056 vwrq->disabled = (vwrq->value >= 2312);
6057 vwrq->fixed = 1;
6058
6059 return 0;
6060}
6061
6062/*------------------------------------------------------------------*/
6063/*
6064 * Wireless Handler : set Mode of Operation
6065 */
6066static int airo_set_mode(struct net_device *dev,
6067 struct iw_request_info *info,
6068 __u32 *uwrq,
6069 char *extra)
6070{
6071 struct airo_info *local = dev->priv;
6072 int reset = 0;
6073
6074 readConfigRid(local, 1);
6075 if ((local->config.rmode & 0xff) >= RXMODE_RFMON)
6076 reset = 1;
6077
6078 switch(*uwrq) {
6079 case IW_MODE_ADHOC:
6080 local->config.opmode &= 0xFF00;
6081 local->config.opmode |= MODE_STA_IBSS;
6082 local->config.rmode &= 0xfe00;
6083 local->config.scanMode = SCANMODE_ACTIVE;
6084 clear_bit (FLAG_802_11, &local->flags);
6085 break;
6086 case IW_MODE_INFRA:
6087 local->config.opmode &= 0xFF00;
6088 local->config.opmode |= MODE_STA_ESS;
6089 local->config.rmode &= 0xfe00;
6090 local->config.scanMode = SCANMODE_ACTIVE;
6091 clear_bit (FLAG_802_11, &local->flags);
6092 break;
6093 case IW_MODE_MASTER:
6094 local->config.opmode &= 0xFF00;
6095 local->config.opmode |= MODE_AP;
6096 local->config.rmode &= 0xfe00;
6097 local->config.scanMode = SCANMODE_ACTIVE;
6098 clear_bit (FLAG_802_11, &local->flags);
6099 break;
6100 case IW_MODE_REPEAT:
6101 local->config.opmode &= 0xFF00;
6102 local->config.opmode |= MODE_AP_RPTR;
6103 local->config.rmode &= 0xfe00;
6104 local->config.scanMode = SCANMODE_ACTIVE;
6105 clear_bit (FLAG_802_11, &local->flags);
6106 break;
6107 case IW_MODE_MONITOR:
6108 local->config.opmode &= 0xFF00;
6109 local->config.opmode |= MODE_STA_ESS;
6110 local->config.rmode &= 0xfe00;
6111 local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
6112 local->config.scanMode = SCANMODE_PASSIVE;
6113 set_bit (FLAG_802_11, &local->flags);
6114 break;
6115 default:
6116 return -EINVAL;
6117 }
6118 if (reset)
6119 set_bit (FLAG_RESET, &local->flags);
6120 set_bit (FLAG_COMMIT, &local->flags);
6121
6122 return -EINPROGRESS; /* Call commit handler */
6123}
6124
6125/*------------------------------------------------------------------*/
6126/*
6127 * Wireless Handler : get Mode of Operation
6128 */
6129static int airo_get_mode(struct net_device *dev,
6130 struct iw_request_info *info,
6131 __u32 *uwrq,
6132 char *extra)
6133{
6134 struct airo_info *local = dev->priv;
6135
6136 readConfigRid(local, 1);
6137 /* If not managed, assume it's ad-hoc */
6138 switch (local->config.opmode & 0xFF) {
6139 case MODE_STA_ESS:
6140 *uwrq = IW_MODE_INFRA;
6141 break;
6142 case MODE_AP:
6143 *uwrq = IW_MODE_MASTER;
6144 break;
6145 case MODE_AP_RPTR:
6146 *uwrq = IW_MODE_REPEAT;
6147 break;
6148 default:
6149 *uwrq = IW_MODE_ADHOC;
6150 }
6151
6152 return 0;
6153}
6154
6155/*------------------------------------------------------------------*/
6156/*
6157 * Wireless Handler : set Encryption Key
6158 */
6159static int airo_set_encode(struct net_device *dev,
6160 struct iw_request_info *info,
6161 struct iw_point *dwrq,
6162 char *extra)
6163{
6164 struct airo_info *local = dev->priv;
6165 CapabilityRid cap_rid; /* Card capability info */
6166
6167 /* Is WEP supported ? */
6168 readCapabilityRid(local, &cap_rid, 1);
6169 /* Older firmware doesn't support this...
6170 if(!(cap_rid.softCap & 2)) {
6171 return -EOPNOTSUPP;
6172 } */
6173 readConfigRid(local, 1);
6174
6175 /* Basic checking: do we have a key to set ?
6176 * Note : with the new API, it's impossible to get a NULL pointer.
6177 * Therefore, we need to check a key size == 0 instead.
6178 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
6179 * when no key is present (only change flags), but older versions
6180 * don't do it. - Jean II */
6181 if (dwrq->length > 0) {
6182 wep_key_t key;
6183 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6184 int current_index = get_wep_key(local, 0xffff);
6185 /* Check the size of the key */
6186 if (dwrq->length > MAX_KEY_SIZE) {
6187 return -EINVAL;
6188 }
6189 /* Check the index (none -> use current) */
6190 if ((index < 0) || (index >= ((cap_rid.softCap & 0x80) ? 4:1)))
6191 index = current_index;
6192 /* Set the length */
6193 if (dwrq->length > MIN_KEY_SIZE)
6194 key.len = MAX_KEY_SIZE;
6195 else
6196 if (dwrq->length > 0)
6197 key.len = MIN_KEY_SIZE;
6198 else
6199 /* Disable the key */
6200 key.len = 0;
6201 /* Check if the key is not marked as invalid */
6202 if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
6203 /* Cleanup */
6204 memset(key.key, 0, MAX_KEY_SIZE);
6205 /* Copy the key in the driver */
6206 memcpy(key.key, extra, dwrq->length);
6207 /* Send the key to the card */
6208 set_wep_key(local, index, key.key, key.len, 1, 1);
6209 }
6210 /* WE specify that if a valid key is set, encryption
6211 * should be enabled (user may turn it off later)
6212 * This is also how "iwconfig ethX key on" works */
6213 if((index == current_index) && (key.len > 0) &&
6214 (local->config.authType == AUTH_OPEN)) {
6215 local->config.authType = AUTH_ENCRYPT;
6216 set_bit (FLAG_COMMIT, &local->flags);
6217 }
6218 } else {
6219 /* Do we want to just set the transmit key index ? */
6220 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6221 if ((index >= 0) && (index < ((cap_rid.softCap & 0x80)?4:1))) {
6222 set_wep_key(local, index, NULL, 0, 1, 1);
6223 } else
6224 /* Don't complain if only change the mode */
6225 if(!dwrq->flags & IW_ENCODE_MODE) {
6226 return -EINVAL;
6227 }
6228 }
6229 /* Read the flags */
6230 if(dwrq->flags & IW_ENCODE_DISABLED)
6231 local->config.authType = AUTH_OPEN; // disable encryption
6232 if(dwrq->flags & IW_ENCODE_RESTRICTED)
6233 local->config.authType = AUTH_SHAREDKEY; // Only Both
6234 if(dwrq->flags & IW_ENCODE_OPEN)
6235 local->config.authType = AUTH_ENCRYPT; // Only Wep
6236 /* Commit the changes to flags if needed */
6237 if(dwrq->flags & IW_ENCODE_MODE)
6238 set_bit (FLAG_COMMIT, &local->flags);
6239 return -EINPROGRESS; /* Call commit handler */
6240}
6241
6242/*------------------------------------------------------------------*/
6243/*
6244 * Wireless Handler : get Encryption Key
6245 */
6246static int airo_get_encode(struct net_device *dev,
6247 struct iw_request_info *info,
6248 struct iw_point *dwrq,
6249 char *extra)
6250{
6251 struct airo_info *local = dev->priv;
6252 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
6253 CapabilityRid cap_rid; /* Card capability info */
6254
6255 /* Is it supported ? */
6256 readCapabilityRid(local, &cap_rid, 1);
6257 if(!(cap_rid.softCap & 2)) {
6258 return -EOPNOTSUPP;
6259 }
6260 readConfigRid(local, 1);
6261 /* Check encryption mode */
6262 switch(local->config.authType) {
6263 case AUTH_ENCRYPT:
6264 dwrq->flags = IW_ENCODE_OPEN;
6265 break;
6266 case AUTH_SHAREDKEY:
6267 dwrq->flags = IW_ENCODE_RESTRICTED;
6268 break;
6269 default:
6270 case AUTH_OPEN:
6271 dwrq->flags = IW_ENCODE_DISABLED;
6272 break;
6273 }
6274 /* We can't return the key, so set the proper flag and return zero */
6275 dwrq->flags |= IW_ENCODE_NOKEY;
6276 memset(extra, 0, 16);
6277
6278 /* Which key do we want ? -1 -> tx index */
6279 if ((index < 0) || (index >= ((cap_rid.softCap & 0x80) ? 4 : 1)))
6280 index = get_wep_key(local, 0xffff);
6281 dwrq->flags |= index + 1;
6282 /* Copy the key to the user buffer */
6283 dwrq->length = get_wep_key(local, index);
6284 if (dwrq->length > 16) {
6285 dwrq->length=0;
6286 }
6287 return 0;
6288}
6289
6290/*------------------------------------------------------------------*/
6291/*
6292 * Wireless Handler : set Tx-Power
6293 */
6294static int airo_set_txpow(struct net_device *dev,
6295 struct iw_request_info *info,
6296 struct iw_param *vwrq,
6297 char *extra)
6298{
6299 struct airo_info *local = dev->priv;
6300 CapabilityRid cap_rid; /* Card capability info */
6301 int i;
6302 int rc = -EINVAL;
6303
6304 readCapabilityRid(local, &cap_rid, 1);
6305
6306 if (vwrq->disabled) {
6307 set_bit (FLAG_RADIO_OFF, &local->flags);
6308 set_bit (FLAG_COMMIT, &local->flags);
6309 return -EINPROGRESS; /* Call commit handler */
6310 }
6311 if (vwrq->flags != IW_TXPOW_MWATT) {
6312 return -EINVAL;
6313 }
6314 clear_bit (FLAG_RADIO_OFF, &local->flags);
6315 for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++)
6316 if ((vwrq->value==cap_rid.txPowerLevels[i])) {
6317 readConfigRid(local, 1);
6318 local->config.txPower = vwrq->value;
6319 set_bit (FLAG_COMMIT, &local->flags);
6320 rc = -EINPROGRESS; /* Call commit handler */
6321 break;
6322 }
6323 return rc;
6324}
6325
6326/*------------------------------------------------------------------*/
6327/*
6328 * Wireless Handler : get Tx-Power
6329 */
6330static int airo_get_txpow(struct net_device *dev,
6331 struct iw_request_info *info,
6332 struct iw_param *vwrq,
6333 char *extra)
6334{
6335 struct airo_info *local = dev->priv;
6336
6337 readConfigRid(local, 1);
6338 vwrq->value = local->config.txPower;
6339 vwrq->fixed = 1; /* No power control */
6340 vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags);
6341 vwrq->flags = IW_TXPOW_MWATT;
6342
6343 return 0;
6344}
6345
6346/*------------------------------------------------------------------*/
6347/*
6348 * Wireless Handler : set Retry limits
6349 */
6350static int airo_set_retry(struct net_device *dev,
6351 struct iw_request_info *info,
6352 struct iw_param *vwrq,
6353 char *extra)
6354{
6355 struct airo_info *local = dev->priv;
6356 int rc = -EINVAL;
6357
6358 if(vwrq->disabled) {
6359 return -EINVAL;
6360 }
6361 readConfigRid(local, 1);
6362 if(vwrq->flags & IW_RETRY_LIMIT) {
6363 if(vwrq->flags & IW_RETRY_MAX)
6364 local->config.longRetryLimit = vwrq->value;
6365 else if (vwrq->flags & IW_RETRY_MIN)
6366 local->config.shortRetryLimit = vwrq->value;
6367 else {
6368 /* No modifier : set both */
6369 local->config.longRetryLimit = vwrq->value;
6370 local->config.shortRetryLimit = vwrq->value;
6371 }
6372 set_bit (FLAG_COMMIT, &local->flags);
6373 rc = -EINPROGRESS; /* Call commit handler */
6374 }
6375 if(vwrq->flags & IW_RETRY_LIFETIME) {
6376 local->config.txLifetime = vwrq->value / 1024;
6377 set_bit (FLAG_COMMIT, &local->flags);
6378 rc = -EINPROGRESS; /* Call commit handler */
6379 }
6380 return rc;
6381}
6382
6383/*------------------------------------------------------------------*/
6384/*
6385 * Wireless Handler : get Retry limits
6386 */
6387static int airo_get_retry(struct net_device *dev,
6388 struct iw_request_info *info,
6389 struct iw_param *vwrq,
6390 char *extra)
6391{
6392 struct airo_info *local = dev->priv;
6393
6394 vwrq->disabled = 0; /* Can't be disabled */
6395
6396 readConfigRid(local, 1);
6397 /* Note : by default, display the min retry number */
6398 if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
6399 vwrq->flags = IW_RETRY_LIFETIME;
6400 vwrq->value = (int)local->config.txLifetime * 1024;
6401 } else if((vwrq->flags & IW_RETRY_MAX)) {
6402 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
6403 vwrq->value = (int)local->config.longRetryLimit;
6404 } else {
6405 vwrq->flags = IW_RETRY_LIMIT;
6406 vwrq->value = (int)local->config.shortRetryLimit;
6407 if((int)local->config.shortRetryLimit != (int)local->config.longRetryLimit)
6408 vwrq->flags |= IW_RETRY_MIN;
6409 }
6410
6411 return 0;
6412}
6413
6414/*------------------------------------------------------------------*/
6415/*
6416 * Wireless Handler : get range info
6417 */
6418static int airo_get_range(struct net_device *dev,
6419 struct iw_request_info *info,
6420 struct iw_point *dwrq,
6421 char *extra)
6422{
6423 struct airo_info *local = dev->priv;
6424 struct iw_range *range = (struct iw_range *) extra;
6425 CapabilityRid cap_rid; /* Card capability info */
6426 int i;
6427 int k;
6428
6429 readCapabilityRid(local, &cap_rid, 1);
6430
6431 dwrq->length = sizeof(struct iw_range);
6432 memset(range, 0, sizeof(*range));
6433 range->min_nwid = 0x0000;
6434 range->max_nwid = 0x0000;
6435 range->num_channels = 14;
6436 /* Should be based on cap_rid.country to give only
6437 * what the current card support */
6438 k = 0;
6439 for(i = 0; i < 14; i++) {
6440 range->freq[k].i = i + 1; /* List index */
6441 range->freq[k].m = frequency_list[i] * 100000;
6442 range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
6443 }
6444 range->num_frequency = k;
6445
6446 /* Hum... Should put the right values there */
6447 range->max_qual.qual = airo_get_max_quality(&cap_rid);
6448 range->max_qual.level = 0x100 - 120; /* -120 dBm */
6449 range->max_qual.noise = 0;
6450 range->sensitivity = 65535;
6451
6452 for(i = 0 ; i < 8 ; i++) {
6453 range->bitrate[i] = cap_rid.supportedRates[i] * 500000;
6454 if(range->bitrate[i] == 0)
6455 break;
6456 }
6457 range->num_bitrates = i;
6458
6459 /* Set an indication of the max TCP throughput
6460 * in bit/s that we can expect using this interface.
6461 * May be use for QoS stuff... Jean II */
6462 if(i > 2)
6463 range->throughput = 5000 * 1000;
6464 else
6465 range->throughput = 1500 * 1000;
6466
6467 range->min_rts = 0;
6468 range->max_rts = 2312;
6469 range->min_frag = 256;
6470 range->max_frag = 2312;
6471
6472 if(cap_rid.softCap & 2) {
6473 // WEP: RC4 40 bits
6474 range->encoding_size[0] = 5;
6475 // RC4 ~128 bits
6476 if (cap_rid.softCap & 0x100) {
6477 range->encoding_size[1] = 13;
6478 range->num_encoding_sizes = 2;
6479 } else
6480 range->num_encoding_sizes = 1;
6481 range->max_encoding_tokens = (cap_rid.softCap & 0x80) ? 4 : 1;
6482 } else {
6483 range->num_encoding_sizes = 0;
6484 range->max_encoding_tokens = 0;
6485 }
6486 range->min_pmp = 0;
6487 range->max_pmp = 5000000; /* 5 secs */
6488 range->min_pmt = 0;
6489 range->max_pmt = 65535 * 1024; /* ??? */
6490 range->pmp_flags = IW_POWER_PERIOD;
6491 range->pmt_flags = IW_POWER_TIMEOUT;
6492 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R;
6493
6494 /* Transmit Power - values are in mW */
6495 for(i = 0 ; i < 8 ; i++) {
6496 range->txpower[i] = cap_rid.txPowerLevels[i];
6497 if(range->txpower[i] == 0)
6498 break;
6499 }
6500 range->num_txpower = i;
6501 range->txpower_capa = IW_TXPOW_MWATT;
6502 range->we_version_source = 12;
6503 range->we_version_compiled = WIRELESS_EXT;
6504 range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
6505 range->retry_flags = IW_RETRY_LIMIT;
6506 range->r_time_flags = IW_RETRY_LIFETIME;
6507 range->min_retry = 1;
6508 range->max_retry = 65535;
6509 range->min_r_time = 1024;
6510 range->max_r_time = 65535 * 1024;
6511 /* Experimental measurements - boundary 11/5.5 Mb/s */
6512 /* Note : with or without the (local->rssi), results
6513 * are somewhat different. - Jean II */
6514 range->avg_qual.qual = airo_get_avg_quality(&cap_rid);
6515 if (local->rssi)
6516 range->avg_qual.level = 186; /* -70 dBm */
6517 else
6518 range->avg_qual.level = 176; /* -80 dBm */
6519 range->avg_qual.noise = 0;
6520
6521 /* Event capability (kernel + driver) */
6522 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
6523 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
6524 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
6525 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
6526 range->event_capa[1] = IW_EVENT_CAPA_K_1;
6527 range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVTXDROP);
6528 return 0;
6529}
6530
6531/*------------------------------------------------------------------*/
6532/*
6533 * Wireless Handler : set Power Management
6534 */
6535static int airo_set_power(struct net_device *dev,
6536 struct iw_request_info *info,
6537 struct iw_param *vwrq,
6538 char *extra)
6539{
6540 struct airo_info *local = dev->priv;
6541
6542 readConfigRid(local, 1);
6543 if (vwrq->disabled) {
6544 if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
6545 return -EINVAL;
6546 }
6547 local->config.powerSaveMode = POWERSAVE_CAM;
6548 local->config.rmode &= 0xFF00;
6549 local->config.rmode |= RXMODE_BC_MC_ADDR;
6550 set_bit (FLAG_COMMIT, &local->flags);
6551 return -EINPROGRESS; /* Call commit handler */
6552 }
6553 if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
6554 local->config.fastListenDelay = (vwrq->value + 500) / 1024;
6555 local->config.powerSaveMode = POWERSAVE_PSPCAM;
6556 set_bit (FLAG_COMMIT, &local->flags);
6557 } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
6558 local->config.fastListenInterval = local->config.listenInterval = (vwrq->value + 500) / 1024;
6559 local->config.powerSaveMode = POWERSAVE_PSPCAM;
6560 set_bit (FLAG_COMMIT, &local->flags);
6561 }
6562 switch (vwrq->flags & IW_POWER_MODE) {
6563 case IW_POWER_UNICAST_R:
6564 if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
6565 return -EINVAL;
6566 }
6567 local->config.rmode &= 0xFF00;
6568 local->config.rmode |= RXMODE_ADDR;
6569 set_bit (FLAG_COMMIT, &local->flags);
6570 break;
6571 case IW_POWER_ALL_R:
6572 if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
6573 return -EINVAL;
6574 }
6575 local->config.rmode &= 0xFF00;
6576 local->config.rmode |= RXMODE_BC_MC_ADDR;
6577 set_bit (FLAG_COMMIT, &local->flags);
6578 case IW_POWER_ON:
6579 break;
6580 default:
6581 return -EINVAL;
6582 }
6583 // Note : we may want to factor local->need_commit here
6584 // Note2 : may also want to factor RXMODE_RFMON test
6585 return -EINPROGRESS; /* Call commit handler */
6586}
6587
6588/*------------------------------------------------------------------*/
6589/*
6590 * Wireless Handler : get Power Management
6591 */
6592static int airo_get_power(struct net_device *dev,
6593 struct iw_request_info *info,
6594 struct iw_param *vwrq,
6595 char *extra)
6596{
6597 struct airo_info *local = dev->priv;
6598 int mode;
6599
6600 readConfigRid(local, 1);
6601 mode = local->config.powerSaveMode;
6602 if ((vwrq->disabled = (mode == POWERSAVE_CAM)))
6603 return 0;
6604 if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
6605 vwrq->value = (int)local->config.fastListenDelay * 1024;
6606 vwrq->flags = IW_POWER_TIMEOUT;
6607 } else {
6608 vwrq->value = (int)local->config.fastListenInterval * 1024;
6609 vwrq->flags = IW_POWER_PERIOD;
6610 }
6611 if ((local->config.rmode & 0xFF) == RXMODE_ADDR)
6612 vwrq->flags |= IW_POWER_UNICAST_R;
6613 else
6614 vwrq->flags |= IW_POWER_ALL_R;
6615
6616 return 0;
6617}
6618
6619/*------------------------------------------------------------------*/
6620/*
6621 * Wireless Handler : set Sensitivity
6622 */
6623static int airo_set_sens(struct net_device *dev,
6624 struct iw_request_info *info,
6625 struct iw_param *vwrq,
6626 char *extra)
6627{
6628 struct airo_info *local = dev->priv;
6629
6630 readConfigRid(local, 1);
6631 local->config.rssiThreshold = vwrq->disabled ? RSSI_DEFAULT : vwrq->value;
6632 set_bit (FLAG_COMMIT, &local->flags);
6633
6634 return -EINPROGRESS; /* Call commit handler */
6635}
6636
6637/*------------------------------------------------------------------*/
6638/*
6639 * Wireless Handler : get Sensitivity
6640 */
6641static int airo_get_sens(struct net_device *dev,
6642 struct iw_request_info *info,
6643 struct iw_param *vwrq,
6644 char *extra)
6645{
6646 struct airo_info *local = dev->priv;
6647
6648 readConfigRid(local, 1);
6649 vwrq->value = local->config.rssiThreshold;
6650 vwrq->disabled = (vwrq->value == 0);
6651 vwrq->fixed = 1;
6652
6653 return 0;
6654}
6655
6656/*------------------------------------------------------------------*/
6657/*
6658 * Wireless Handler : get AP List
6659 * Note : this is deprecated in favor of IWSCAN
6660 */
6661static int airo_get_aplist(struct net_device *dev,
6662 struct iw_request_info *info,
6663 struct iw_point *dwrq,
6664 char *extra)
6665{
6666 struct airo_info *local = dev->priv;
6667 struct sockaddr *address = (struct sockaddr *) extra;
6668 struct iw_quality qual[IW_MAX_AP];
6669 BSSListRid BSSList;
6670 int i;
6671 int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
6672
6673 for (i = 0; i < IW_MAX_AP; i++) {
6674 if (readBSSListRid(local, loseSync, &BSSList))
6675 break;
6676 loseSync = 0;
6677 memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
6678 address[i].sa_family = ARPHRD_ETHER;
6679 if (local->rssi)
6680 qual[i].level = 0x100 - local->rssi[BSSList.rssi].rssidBm;
6681 else
6682 qual[i].level = (BSSList.rssi + 321) / 2;
6683 qual[i].qual = qual[i].noise = 0;
6684 qual[i].updated = 2;
6685 if (BSSList.index == 0xffff)
6686 break;
6687 }
6688 if (!i) {
6689 StatusRid status_rid; /* Card status info */
6690 readStatusRid(local, &status_rid, 1);
6691 for (i = 0;
6692 i < min(IW_MAX_AP, 4) &&
6693 (status_rid.bssid[i][0]
6694 & status_rid.bssid[i][1]
6695 & status_rid.bssid[i][2]
6696 & status_rid.bssid[i][3]
6697 & status_rid.bssid[i][4]
6698 & status_rid.bssid[i][5])!=0xff &&
6699 (status_rid.bssid[i][0]
6700 | status_rid.bssid[i][1]
6701 | status_rid.bssid[i][2]
6702 | status_rid.bssid[i][3]
6703 | status_rid.bssid[i][4]
6704 | status_rid.bssid[i][5]);
6705 i++) {
6706 memcpy(address[i].sa_data,
6707 status_rid.bssid[i], ETH_ALEN);
6708 address[i].sa_family = ARPHRD_ETHER;
6709 }
6710 } else {
6711 dwrq->flags = 1; /* Should be define'd */
6712 memcpy(extra + sizeof(struct sockaddr)*i,
6713 &qual, sizeof(struct iw_quality)*i);
6714 }
6715 dwrq->length = i;
6716
6717 return 0;
6718}
6719
6720/*------------------------------------------------------------------*/
6721/*
6722 * Wireless Handler : Initiate Scan
6723 */
6724static int airo_set_scan(struct net_device *dev,
6725 struct iw_request_info *info,
6726 struct iw_param *vwrq,
6727 char *extra)
6728{
6729 struct airo_info *ai = dev->priv;
6730 Cmd cmd;
6731 Resp rsp;
6732
6733 /* Note : you may have realised that, as this is a SET operation,
6734 * this is privileged and therefore a normal user can't
6735 * perform scanning.
6736 * This is not an error, while the device perform scanning,
6737 * traffic doesn't flow, so it's a perfect DoS...
6738 * Jean II */
6739 if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
6740
6741 /* Initiate a scan command */
6742 memset(&cmd, 0, sizeof(cmd));
6743 cmd.cmd=CMD_LISTBSS;
6744 if (down_interruptible(&ai->sem))
6745 return -ERESTARTSYS;
6746 issuecommand(ai, &cmd, &rsp);
6747 ai->scan_timestamp = jiffies;
6748 up(&ai->sem);
6749
6750 /* At this point, just return to the user. */
6751
6752 return 0;
6753}
6754
6755/*------------------------------------------------------------------*/
6756/*
6757 * Translate scan data returned from the card to a card independent
6758 * format that the Wireless Tools will understand - Jean II
6759 */
6760static inline char *airo_translate_scan(struct net_device *dev,
6761 char *current_ev,
6762 char *end_buf,
6763 BSSListRid *list)
6764{
6765 struct airo_info *ai = dev->priv;
6766 struct iw_event iwe; /* Temporary buffer */
6767 u16 capabilities;
6768 char * current_val; /* For rates */
6769 int i;
6770
6771 /* First entry *MUST* be the AP MAC address */
6772 iwe.cmd = SIOCGIWAP;
6773 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
6774 memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN);
6775 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
6776
6777 /* Other entries will be displayed in the order we give them */
6778
6779 /* Add the ESSID */
6780 iwe.u.data.length = list->ssidLen;
6781 if(iwe.u.data.length > 32)
6782 iwe.u.data.length = 32;
6783 iwe.cmd = SIOCGIWESSID;
6784 iwe.u.data.flags = 1;
6785 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid);
6786
6787 /* Add mode */
6788 iwe.cmd = SIOCGIWMODE;
6789 capabilities = le16_to_cpu(list->cap);
6790 if(capabilities & (CAP_ESS | CAP_IBSS)) {
6791 if(capabilities & CAP_ESS)
6792 iwe.u.mode = IW_MODE_MASTER;
6793 else
6794 iwe.u.mode = IW_MODE_ADHOC;
6795 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
6796 }
6797
6798 /* Add frequency */
6799 iwe.cmd = SIOCGIWFREQ;
6800 iwe.u.freq.m = le16_to_cpu(list->dsChannel);
6801 iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000;
6802 iwe.u.freq.e = 1;
6803 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
6804
6805 /* Add quality statistics */
6806 iwe.cmd = IWEVQUAL;
6807 if (ai->rssi)
6808 iwe.u.qual.level = 0x100 - ai->rssi[list->rssi].rssidBm;
6809 else
6810 iwe.u.qual.level = (list->rssi + 321) / 2;
6811 iwe.u.qual.noise = 0;
6812 iwe.u.qual.qual = 0;
6813 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
6814
6815 /* Add encryption capability */
6816 iwe.cmd = SIOCGIWENCODE;
6817 if(capabilities & CAP_PRIVACY)
6818 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
6819 else
6820 iwe.u.data.flags = IW_ENCODE_DISABLED;
6821 iwe.u.data.length = 0;
6822 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid);
6823
6824 /* Rate : stuffing multiple values in a single event require a bit
6825 * more of magic - Jean II */
6826 current_val = current_ev + IW_EV_LCP_LEN;
6827
6828 iwe.cmd = SIOCGIWRATE;
6829 /* Those two flags are ignored... */
6830 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
6831 /* Max 8 values */
6832 for(i = 0 ; i < 8 ; i++) {
6833 /* NULL terminated */
6834 if(list->rates[i] == 0)
6835 break;
6836 /* Bit rate given in 500 kb/s units (+ 0x80) */
6837 iwe.u.bitrate.value = ((list->rates[i] & 0x7f) * 500000);
6838 /* Add new value to event */
6839 current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
6840 }
6841 /* Check if we added any event */
6842 if((current_val - current_ev) > IW_EV_LCP_LEN)
6843 current_ev = current_val;
6844
6845 /* The other data in the scan result are not really
6846 * interesting, so for now drop it - Jean II */
6847 return current_ev;
6848}
6849
6850/*------------------------------------------------------------------*/
6851/*
6852 * Wireless Handler : Read Scan Results
6853 */
6854static int airo_get_scan(struct net_device *dev,
6855 struct iw_request_info *info,
6856 struct iw_point *dwrq,
6857 char *extra)
6858{
6859 struct airo_info *ai = dev->priv;
6860 BSSListRid BSSList;
6861 int rc;
6862 char *current_ev = extra;
6863
6864 /* When we are associated again, the scan has surely finished.
6865 * Just in case, let's make sure enough time has elapsed since
6866 * we started the scan. - Javier */
6867 if(ai->scan_timestamp && time_before(jiffies,ai->scan_timestamp+3*HZ)) {
6868 /* Important note : we don't want to block the caller
6869 * until results are ready for various reasons.
6870 * First, managing wait queues is complex and racy
6871 * (there may be multiple simultaneous callers).
6872 * Second, we grab some rtnetlink lock before comming
6873 * here (in dev_ioctl()).
6874 * Third, the caller can wait on the Wireless Event
6875 * - Jean II */
6876 return -EAGAIN;
6877 }
6878 ai->scan_timestamp = 0;
6879
6880 /* There's only a race with proc_BSSList_open(), but its
6881 * consequences are begnign. So I don't bother fixing it - Javier */
6882
6883 /* Try to read the first entry of the scan result */
6884 rc = PC4500_readrid(ai, RID_BSSLISTFIRST, &BSSList, sizeof(BSSList), 1);
6885 if((rc) || (BSSList.index == 0xffff)) {
6886 /* Client error, no scan results...
6887 * The caller need to restart the scan. */
6888 return -ENODATA;
6889 }
6890
6891 /* Read and parse all entries */
6892 while((!rc) && (BSSList.index != 0xffff)) {
6893 /* Translate to WE format this entry */
6894 current_ev = airo_translate_scan(dev, current_ev,
6895 extra + dwrq->length,
6896 &BSSList);
6897
6898 /* Check if there is space for one more entry */
6899 if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
6900 /* Ask user space to try again with a bigger buffer */
6901 return -E2BIG;
6902 }
6903
6904 /* Read next entry */
6905 rc = PC4500_readrid(ai, RID_BSSLISTNEXT,
6906 &BSSList, sizeof(BSSList), 1);
6907 }
6908 /* Length of data */
6909 dwrq->length = (current_ev - extra);
6910 dwrq->flags = 0; /* todo */
6911
6912 return 0;
6913}
6914
6915/*------------------------------------------------------------------*/
6916/*
6917 * Commit handler : called after a bunch of SET operations
6918 */
6919static int airo_config_commit(struct net_device *dev,
6920 struct iw_request_info *info, /* NULL */
6921 void *zwrq, /* NULL */
6922 char *extra) /* NULL */
6923{
6924 struct airo_info *local = dev->priv;
6925 Resp rsp;
6926
6927 if (!test_bit (FLAG_COMMIT, &local->flags))
6928 return 0;
6929
6930 /* Some of the "SET" function may have modified some of the
6931 * parameters. It's now time to commit them in the card */
6932 disable_MAC(local, 1);
6933 if (test_bit (FLAG_RESET, &local->flags)) {
6934 APListRid APList_rid;
6935 SsidRid SSID_rid;
6936
6937 readAPListRid(local, &APList_rid);
6938 readSsidRid(local, &SSID_rid);
6939 if (test_bit(FLAG_MPI,&local->flags))
6940 setup_card(local, dev->dev_addr, 1 );
6941 else
6942 reset_airo_card(dev);
6943 disable_MAC(local, 1);
6944 writeSsidRid(local, &SSID_rid, 1);
6945 writeAPListRid(local, &APList_rid, 1);
6946 }
6947 if (down_interruptible(&local->sem))
6948 return -ERESTARTSYS;
6949 writeConfigRid(local, 0);
6950 enable_MAC(local, &rsp, 0);
6951 if (test_bit (FLAG_RESET, &local->flags))
6952 airo_set_promisc(local);
6953 else
6954 up(&local->sem);
6955
6956 return 0;
6957}
6958
6959/*------------------------------------------------------------------*/
6960/*
6961 * Structures to export the Wireless Handlers
6962 */
6963
6964static const struct iw_priv_args airo_private_args[] = {
6965/*{ cmd, set_args, get_args, name } */
6966 { AIROIOCTL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
6967 IW_PRIV_TYPE_BYTE | 2047, "airoioctl" },
6968 { AIROIDIFC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (aironet_ioctl),
6969 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "airoidifc" },
6970};
6971
6972static const iw_handler airo_handler[] =
6973{
6974 (iw_handler) airo_config_commit, /* SIOCSIWCOMMIT */
6975 (iw_handler) airo_get_name, /* SIOCGIWNAME */
6976 (iw_handler) NULL, /* SIOCSIWNWID */
6977 (iw_handler) NULL, /* SIOCGIWNWID */
6978 (iw_handler) airo_set_freq, /* SIOCSIWFREQ */
6979 (iw_handler) airo_get_freq, /* SIOCGIWFREQ */
6980 (iw_handler) airo_set_mode, /* SIOCSIWMODE */
6981 (iw_handler) airo_get_mode, /* SIOCGIWMODE */
6982 (iw_handler) airo_set_sens, /* SIOCSIWSENS */
6983 (iw_handler) airo_get_sens, /* SIOCGIWSENS */
6984 (iw_handler) NULL, /* SIOCSIWRANGE */
6985 (iw_handler) airo_get_range, /* SIOCGIWRANGE */
6986 (iw_handler) NULL, /* SIOCSIWPRIV */
6987 (iw_handler) NULL, /* SIOCGIWPRIV */
6988 (iw_handler) NULL, /* SIOCSIWSTATS */
6989 (iw_handler) NULL, /* SIOCGIWSTATS */
6990 iw_handler_set_spy, /* SIOCSIWSPY */
6991 iw_handler_get_spy, /* SIOCGIWSPY */
6992 iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
6993 iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
6994 (iw_handler) airo_set_wap, /* SIOCSIWAP */
6995 (iw_handler) airo_get_wap, /* SIOCGIWAP */
6996 (iw_handler) NULL, /* -- hole -- */
6997 (iw_handler) airo_get_aplist, /* SIOCGIWAPLIST */
6998 (iw_handler) airo_set_scan, /* SIOCSIWSCAN */
6999 (iw_handler) airo_get_scan, /* SIOCGIWSCAN */
7000 (iw_handler) airo_set_essid, /* SIOCSIWESSID */
7001 (iw_handler) airo_get_essid, /* SIOCGIWESSID */
7002 (iw_handler) airo_set_nick, /* SIOCSIWNICKN */
7003 (iw_handler) airo_get_nick, /* SIOCGIWNICKN */
7004 (iw_handler) NULL, /* -- hole -- */
7005 (iw_handler) NULL, /* -- hole -- */
7006 (iw_handler) airo_set_rate, /* SIOCSIWRATE */
7007 (iw_handler) airo_get_rate, /* SIOCGIWRATE */
7008 (iw_handler) airo_set_rts, /* SIOCSIWRTS */
7009 (iw_handler) airo_get_rts, /* SIOCGIWRTS */
7010 (iw_handler) airo_set_frag, /* SIOCSIWFRAG */
7011 (iw_handler) airo_get_frag, /* SIOCGIWFRAG */
7012 (iw_handler) airo_set_txpow, /* SIOCSIWTXPOW */
7013 (iw_handler) airo_get_txpow, /* SIOCGIWTXPOW */
7014 (iw_handler) airo_set_retry, /* SIOCSIWRETRY */
7015 (iw_handler) airo_get_retry, /* SIOCGIWRETRY */
7016 (iw_handler) airo_set_encode, /* SIOCSIWENCODE */
7017 (iw_handler) airo_get_encode, /* SIOCGIWENCODE */
7018 (iw_handler) airo_set_power, /* SIOCSIWPOWER */
7019 (iw_handler) airo_get_power, /* SIOCGIWPOWER */
7020};
7021
7022/* Note : don't describe AIROIDIFC and AIROOLDIDIFC in here.
7023 * We want to force the use of the ioctl code, because those can't be
7024 * won't work the iw_handler code (because they simultaneously read
7025 * and write data and iw_handler can't do that).
7026 * Note that it's perfectly legal to read/write on a single ioctl command,
7027 * you just can't use iwpriv and need to force it via the ioctl handler.
7028 * Jean II */
7029static const iw_handler airo_private_handler[] =
7030{
7031 NULL, /* SIOCIWFIRSTPRIV */
7032};
7033
7034static const struct iw_handler_def airo_handler_def =
7035{
7036 .num_standard = sizeof(airo_handler)/sizeof(iw_handler),
7037 .num_private = sizeof(airo_private_handler)/sizeof(iw_handler),
7038 .num_private_args = sizeof(airo_private_args)/sizeof(struct iw_priv_args),
7039 .standard = airo_handler,
7040 .private = airo_private_handler,
7041 .private_args = airo_private_args,
7042 .get_wireless_stats = airo_get_wireless_stats,
7043};
7044
7045#endif /* WIRELESS_EXT */
7046
7047/*
7048 * This defines the configuration part of the Wireless Extensions
7049 * Note : irq and spinlock protection will occur in the subroutines
7050 *
7051 * TODO :
7052 * o Check input value more carefully and fill correct values in range
7053 * o Test and shakeout the bugs (if any)
7054 *
7055 * Jean II
7056 *
7057 * Javier Achirica did a great job of merging code from the unnamed CISCO
7058 * developer that added support for flashing the card.
7059 */
7060static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
7061{
7062 int rc = 0;
7063 struct airo_info *ai = (struct airo_info *)dev->priv;
7064
7065 if (ai->power)
7066 return 0;
7067
7068 switch (cmd) {
7069#ifdef CISCO_EXT
7070 case AIROIDIFC:
7071#ifdef AIROOLDIDIFC
7072 case AIROOLDIDIFC:
7073#endif
7074 {
7075 int val = AIROMAGIC;
7076 aironet_ioctl com;
7077 if (copy_from_user(&com,rq->ifr_data,sizeof(com)))
7078 rc = -EFAULT;
7079 else if (copy_to_user(com.data,(char *)&val,sizeof(val)))
7080 rc = -EFAULT;
7081 }
7082 break;
7083
7084 case AIROIOCTL:
7085#ifdef AIROOLDIOCTL
7086 case AIROOLDIOCTL:
7087#endif
7088 /* Get the command struct and hand it off for evaluation by
7089 * the proper subfunction
7090 */
7091 {
7092 aironet_ioctl com;
7093 if (copy_from_user(&com,rq->ifr_data,sizeof(com))) {
7094 rc = -EFAULT;
7095 break;
7096 }
7097
7098 /* Separate R/W functions bracket legality here
7099 */
7100 if ( com.command == AIRORSWVERSION ) {
7101 if (copy_to_user(com.data, swversion, sizeof(swversion)))
7102 rc = -EFAULT;
7103 else
7104 rc = 0;
7105 }
7106 else if ( com.command <= AIRORRID)
7107 rc = readrids(dev,&com);
7108 else if ( com.command >= AIROPCAP && com.command <= (AIROPLEAPUSR+2) )
7109 rc = writerids(dev,&com);
7110 else if ( com.command >= AIROFLSHRST && com.command <= AIRORESTART )
7111 rc = flashcard(dev,&com);
7112 else
7113 rc = -EINVAL; /* Bad command in ioctl */
7114 }
7115 break;
7116#endif /* CISCO_EXT */
7117
7118 // All other calls are currently unsupported
7119 default:
7120 rc = -EOPNOTSUPP;
7121 }
7122 return rc;
7123}
7124
7125#ifdef WIRELESS_EXT
7126/*
7127 * Get the Wireless stats out of the driver
7128 * Note : irq and spinlock protection will occur in the subroutines
7129 *
7130 * TODO :
7131 * o Check if work in Ad-Hoc mode (otherwise, use SPY, as in wvlan_cs)
7132 *
7133 * Jean
7134 */
7135static void airo_read_wireless_stats(struct airo_info *local)
7136{
7137 StatusRid status_rid;
7138 StatsRid stats_rid;
7139 CapabilityRid cap_rid;
7140 u32 *vals = stats_rid.vals;
7141
7142 /* Get stats out of the card */
7143 clear_bit(JOB_WSTATS, &local->flags);
7144 if (local->power) {
7145 up(&local->sem);
7146 return;
7147 }
7148 readCapabilityRid(local, &cap_rid, 0);
7149 readStatusRid(local, &status_rid, 0);
7150 readStatsRid(local, &stats_rid, RID_STATS, 0);
7151 up(&local->sem);
7152
7153 /* The status */
7154 local->wstats.status = status_rid.mode;
7155
7156 /* Signal quality and co. But where is the noise level ??? */
7157 local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
7158 if (local->rssi)
7159 local->wstats.qual.level = 0x100 - local->rssi[status_rid.sigQuality].rssidBm;
7160 else
7161 local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2;
7162 if (status_rid.len >= 124) {
7163 local->wstats.qual.noise = 256 - status_rid.noisedBm;
7164 local->wstats.qual.updated = 7;
7165 } else {
7166 local->wstats.qual.noise = 0;
7167 local->wstats.qual.updated = 3;
7168 }
7169
7170 /* Packets discarded in the wireless adapter due to wireless
7171 * specific problems */
7172 local->wstats.discard.nwid = vals[56] + vals[57] + vals[58];/* SSID Mismatch */
7173 local->wstats.discard.code = vals[6];/* RxWepErr */
7174 local->wstats.discard.fragment = vals[30];
7175 local->wstats.discard.retries = vals[10];
7176 local->wstats.discard.misc = vals[1] + vals[32];
7177 local->wstats.miss.beacon = vals[34];
7178}
7179
7180struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
7181{
7182 struct airo_info *local = dev->priv;
7183
7184 if (!test_bit(JOB_WSTATS, &local->flags)) {
7185 /* Get stats out of the card if available */
7186 if (down_trylock(&local->sem) != 0) {
7187 set_bit(JOB_WSTATS, &local->flags);
7188 wake_up_interruptible(&local->thr_wait);
7189 } else
7190 airo_read_wireless_stats(local);
7191 }
7192
7193 return &local->wstats;
7194}
7195#endif /* WIRELESS_EXT */
7196
7197#ifdef CISCO_EXT
7198/*
7199 * This just translates from driver IOCTL codes to the command codes to
7200 * feed to the radio's host interface. Things can be added/deleted
7201 * as needed. This represents the READ side of control I/O to
7202 * the card
7203 */
7204static int readrids(struct net_device *dev, aironet_ioctl *comp) {
7205 unsigned short ridcode;
7206 unsigned char *iobuf;
7207 int len;
7208 struct airo_info *ai = dev->priv;
7209 Resp rsp;
7210
7211 if (test_bit(FLAG_FLASHING, &ai->flags))
7212 return -EIO;
7213
7214 switch(comp->command)
7215 {
7216 case AIROGCAP: ridcode = RID_CAPABILITIES; break;
7217 case AIROGCFG: ridcode = RID_CONFIG;
7218 if (test_bit(FLAG_COMMIT, &ai->flags)) {
7219 disable_MAC (ai, 1);
7220 writeConfigRid (ai, 1);
7221 enable_MAC (ai, &rsp, 1);
7222 }
7223 break;
7224 case AIROGSLIST: ridcode = RID_SSID; break;
7225 case AIROGVLIST: ridcode = RID_APLIST; break;
7226 case AIROGDRVNAM: ridcode = RID_DRVNAME; break;
7227 case AIROGEHTENC: ridcode = RID_ETHERENCAP; break;
7228 case AIROGWEPKTMP: ridcode = RID_WEP_TEMP;
7229 /* Only super-user can read WEP keys */
7230 if (!capable(CAP_NET_ADMIN))
7231 return -EPERM;
7232 break;
7233 case AIROGWEPKNV: ridcode = RID_WEP_PERM;
7234 /* Only super-user can read WEP keys */
7235 if (!capable(CAP_NET_ADMIN))
7236 return -EPERM;
7237 break;
7238 case AIROGSTAT: ridcode = RID_STATUS; break;
7239 case AIROGSTATSD32: ridcode = RID_STATSDELTA; break;
7240 case AIROGSTATSC32: ridcode = RID_STATS; break;
7241#ifdef MICSUPPORT
7242 case AIROGMICSTATS:
7243 if (copy_to_user(comp->data, &ai->micstats,
7244 min((int)comp->len,(int)sizeof(ai->micstats))))
7245 return -EFAULT;
7246 return 0;
7247#endif
7248 case AIRORRID: ridcode = comp->ridnum; break;
7249 default:
7250 return -EINVAL;
7251 break;
7252 }
7253
7254 if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7255 return -ENOMEM;
7256
7257 PC4500_readrid(ai,ridcode,iobuf,RIDSIZE, 1);
7258 /* get the count of bytes in the rid docs say 1st 2 bytes is it.
7259 * then return it to the user
7260 * 9/22/2000 Honor user given length
7261 */
7262 len = comp->len;
7263
7264 if (copy_to_user(comp->data, iobuf, min(len, (int)RIDSIZE))) {
7265 kfree (iobuf);
7266 return -EFAULT;
7267 }
7268 kfree (iobuf);
7269 return 0;
7270}
7271
7272/*
7273 * Danger Will Robinson write the rids here
7274 */
7275
7276static int writerids(struct net_device *dev, aironet_ioctl *comp) {
7277 struct airo_info *ai = dev->priv;
7278 int ridcode;
7279#ifdef MICSUPPORT
7280 int enabled;
7281#endif
7282 Resp rsp;
7283 static int (* writer)(struct airo_info *, u16 rid, const void *, int, int);
7284 unsigned char *iobuf;
7285
7286 /* Only super-user can write RIDs */
7287 if (!capable(CAP_NET_ADMIN))
7288 return -EPERM;
7289
7290 if (test_bit(FLAG_FLASHING, &ai->flags))
7291 return -EIO;
7292
7293 ridcode = 0;
7294 writer = do_writerid;
7295
7296 switch(comp->command)
7297 {
7298 case AIROPSIDS: ridcode = RID_SSID; break;
7299 case AIROPCAP: ridcode = RID_CAPABILITIES; break;
7300 case AIROPAPLIST: ridcode = RID_APLIST; break;
7301 case AIROPCFG: ai->config.len = 0;
7302 clear_bit(FLAG_COMMIT, &ai->flags);
7303 ridcode = RID_CONFIG; break;
7304 case AIROPWEPKEYNV: ridcode = RID_WEP_PERM; break;
7305 case AIROPLEAPUSR: ridcode = RID_LEAPUSERNAME; break;
7306 case AIROPLEAPPWD: ridcode = RID_LEAPPASSWORD; break;
7307 case AIROPWEPKEY: ridcode = RID_WEP_TEMP; writer = PC4500_writerid;
7308 break;
7309 case AIROPLEAPUSR+1: ridcode = 0xFF2A; break;
7310 case AIROPLEAPUSR+2: ridcode = 0xFF2B; break;
7311
7312 /* this is not really a rid but a command given to the card
7313 * same with MAC off
7314 */
7315 case AIROPMACON:
7316 if (enable_MAC(ai, &rsp, 1) != 0)
7317 return -EIO;
7318 return 0;
7319
7320 /*
7321 * Evidently this code in the airo driver does not get a symbol
7322 * as disable_MAC. it's probably so short the compiler does not gen one.
7323 */
7324 case AIROPMACOFF:
7325 disable_MAC(ai, 1);
7326 return 0;
7327
7328 /* This command merely clears the counts does not actually store any data
7329 * only reads rid. But as it changes the cards state, I put it in the
7330 * writerid routines.
7331 */
7332 case AIROPSTCLR:
7333 if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7334 return -ENOMEM;
7335
7336 PC4500_readrid(ai,RID_STATSDELTACLEAR,iobuf,RIDSIZE, 1);
7337
7338#ifdef MICSUPPORT
7339 enabled = ai->micstats.enabled;
7340 memset(&ai->micstats,0,sizeof(ai->micstats));
7341 ai->micstats.enabled = enabled;
7342#endif
7343
7344 if (copy_to_user(comp->data, iobuf,
7345 min((int)comp->len, (int)RIDSIZE))) {
7346 kfree (iobuf);
7347 return -EFAULT;
7348 }
7349 kfree (iobuf);
7350 return 0;
7351
7352 default:
7353 return -EOPNOTSUPP; /* Blarg! */
7354 }
7355 if(comp->len > RIDSIZE)
7356 return -EINVAL;
7357
7358 if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL)
7359 return -ENOMEM;
7360
7361 if (copy_from_user(iobuf,comp->data,comp->len)) {
7362 kfree (iobuf);
7363 return -EFAULT;
7364 }
7365
7366 if (comp->command == AIROPCFG) {
7367 ConfigRid *cfg = (ConfigRid *)iobuf;
7368
7369 if (test_bit(FLAG_MIC_CAPABLE, &ai->flags))
7370 cfg->opmode |= MODE_MIC;
7371
7372 if ((cfg->opmode & 0xFF) == MODE_STA_IBSS)
7373 set_bit (FLAG_ADHOC, &ai->flags);
7374 else
7375 clear_bit (FLAG_ADHOC, &ai->flags);
7376 }
7377
7378 if((*writer)(ai, ridcode, iobuf,comp->len,1)) {
7379 kfree (iobuf);
7380 return -EIO;
7381 }
7382 kfree (iobuf);
7383 return 0;
7384}
7385
7386/*****************************************************************************
7387 * Ancillary flash / mod functions much black magic lurkes here *
7388 *****************************************************************************
7389 */
7390
7391/*
7392 * Flash command switch table
7393 */
7394
7395int flashcard(struct net_device *dev, aironet_ioctl *comp) {
7396 int z;
7397 int cmdreset(struct airo_info *);
7398 int setflashmode(struct airo_info *);
7399 int flashgchar(struct airo_info *,int,int);
7400 int flashpchar(struct airo_info *,int,int);
7401 int flashputbuf(struct airo_info *);
7402 int flashrestart(struct airo_info *,struct net_device *);
7403
7404 /* Only super-user can modify flash */
7405 if (!capable(CAP_NET_ADMIN))
7406 return -EPERM;
7407
7408 switch(comp->command)
7409 {
7410 case AIROFLSHRST:
7411 return cmdreset((struct airo_info *)dev->priv);
7412
7413 case AIROFLSHSTFL:
7414 if (!((struct airo_info *)dev->priv)->flash &&
7415 (((struct airo_info *)dev->priv)->flash = kmalloc (FLASHSIZE, GFP_KERNEL)) == NULL)
7416 return -ENOMEM;
7417 return setflashmode((struct airo_info *)dev->priv);
7418
7419 case AIROFLSHGCHR: /* Get char from aux */
7420 if(comp->len != sizeof(int))
7421 return -EINVAL;
7422 if (copy_from_user(&z,comp->data,comp->len))
7423 return -EFAULT;
7424 return flashgchar((struct airo_info *)dev->priv,z,8000);
7425
7426 case AIROFLSHPCHR: /* Send char to card. */
7427 if(comp->len != sizeof(int))
7428 return -EINVAL;
7429 if (copy_from_user(&z,comp->data,comp->len))
7430 return -EFAULT;
7431 return flashpchar((struct airo_info *)dev->priv,z,8000);
7432
7433 case AIROFLPUTBUF: /* Send 32k to card */
7434 if (!((struct airo_info *)dev->priv)->flash)
7435 return -ENOMEM;
7436 if(comp->len > FLASHSIZE)
7437 return -EINVAL;
7438 if(copy_from_user(((struct airo_info *)dev->priv)->flash,comp->data,comp->len))
7439 return -EFAULT;
7440
7441 flashputbuf((struct airo_info *)dev->priv);
7442 return 0;
7443
7444 case AIRORESTART:
7445 if(flashrestart((struct airo_info *)dev->priv,dev))
7446 return -EIO;
7447 return 0;
7448 }
7449 return -EINVAL;
7450}
7451
7452#define FLASH_COMMAND 0x7e7e
7453
7454/*
7455 * STEP 1)
7456 * Disable MAC and do soft reset on
7457 * card.
7458 */
7459
7460int cmdreset(struct airo_info *ai) {
7461 disable_MAC(ai, 1);
7462
7463 if(!waitbusy (ai)){
7464 printk(KERN_INFO "Waitbusy hang before RESET\n");
7465 return -EBUSY;
7466 }
7467
7468 OUT4500(ai,COMMAND,CMD_SOFTRESET);
7469
7470 ssleep(1); /* WAS 600 12/7/00 */
7471
7472 if(!waitbusy (ai)){
7473 printk(KERN_INFO "Waitbusy hang AFTER RESET\n");
7474 return -EBUSY;
7475 }
7476 return 0;
7477}
7478
7479/* STEP 2)
7480 * Put the card in legendary flash
7481 * mode
7482 */
7483
7484int setflashmode (struct airo_info *ai) {
7485 set_bit (FLAG_FLASHING, &ai->flags);
7486
7487 OUT4500(ai, SWS0, FLASH_COMMAND);
7488 OUT4500(ai, SWS1, FLASH_COMMAND);
7489 if (probe) {
7490 OUT4500(ai, SWS0, FLASH_COMMAND);
7491 OUT4500(ai, COMMAND,0x10);
7492 } else {
7493 OUT4500(ai, SWS2, FLASH_COMMAND);
7494 OUT4500(ai, SWS3, FLASH_COMMAND);
7495 OUT4500(ai, COMMAND,0);
7496 }
7497 msleep(500); /* 500ms delay */
7498
7499 if(!waitbusy(ai)) {
7500 clear_bit (FLAG_FLASHING, &ai->flags);
7501 printk(KERN_INFO "Waitbusy hang after setflash mode\n");
7502 return -EIO;
7503 }
7504 return 0;
7505}
7506
7507/* Put character to SWS0 wait for dwelltime
7508 * x 50us for echo .
7509 */
7510
7511int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
7512 int echo;
7513 int waittime;
7514
7515 byte |= 0x8000;
7516
7517 if(dwelltime == 0 )
7518 dwelltime = 200;
7519
7520 waittime=dwelltime;
7521
7522 /* Wait for busy bit d15 to go false indicating buffer empty */
7523 while ((IN4500 (ai, SWS0) & 0x8000) && waittime > 0) {
7524 udelay (50);
7525 waittime -= 50;
7526 }
7527
7528 /* timeout for busy clear wait */
7529 if(waittime <= 0 ){
7530 printk(KERN_INFO "flash putchar busywait timeout! \n");
7531 return -EBUSY;
7532 }
7533
7534 /* Port is clear now write byte and wait for it to echo back */
7535 do {
7536 OUT4500(ai,SWS0,byte);
7537 udelay(50);
7538 dwelltime -= 50;
7539 echo = IN4500(ai,SWS1);
7540 } while (dwelltime >= 0 && echo != byte);
7541
7542 OUT4500(ai,SWS1,0);
7543
7544 return (echo == byte) ? 0 : -EIO;
7545}
7546
7547/*
7548 * Get a character from the card matching matchbyte
7549 * Step 3)
7550 */
7551int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime){
7552 int rchar;
7553 unsigned char rbyte=0;
7554
7555 do {
7556 rchar = IN4500(ai,SWS1);
7557
7558 if(dwelltime && !(0x8000 & rchar)){
7559 dwelltime -= 10;
7560 mdelay(10);
7561 continue;
7562 }
7563 rbyte = 0xff & rchar;
7564
7565 if( (rbyte == matchbyte) && (0x8000 & rchar) ){
7566 OUT4500(ai,SWS1,0);
7567 return 0;
7568 }
7569 if( rbyte == 0x81 || rbyte == 0x82 || rbyte == 0x83 || rbyte == 0x1a || 0xffff == rchar)
7570 break;
7571 OUT4500(ai,SWS1,0);
7572
7573 }while(dwelltime > 0);
7574 return -EIO;
7575}
7576
7577/*
7578 * Transfer 32k of firmware data from user buffer to our buffer and
7579 * send to the card
7580 */
7581
7582int flashputbuf(struct airo_info *ai){
7583 int nwords;
7584
7585 /* Write stuff */
7586 if (test_bit(FLAG_MPI,&ai->flags))
7587 memcpy_toio(ai->pciaux + 0x8000, ai->flash, FLASHSIZE);
7588 else {
7589 OUT4500(ai,AUXPAGE,0x100);
7590 OUT4500(ai,AUXOFF,0);
7591
7592 for(nwords=0;nwords != FLASHSIZE / 2;nwords++){
7593 OUT4500(ai,AUXDATA,ai->flash[nwords] & 0xffff);
7594 }
7595 }
7596 OUT4500(ai,SWS0,0x8000);
7597
7598 return 0;
7599}
7600
7601/*
7602 *
7603 */
7604int flashrestart(struct airo_info *ai,struct net_device *dev){
7605 int i,status;
7606
7607 ssleep(1); /* Added 12/7/00 */
7608 clear_bit (FLAG_FLASHING, &ai->flags);
7609 if (test_bit(FLAG_MPI, &ai->flags)) {
7610 status = mpi_init_descriptors(ai);
7611 if (status != SUCCESS)
7612 return status;
7613 }
7614 status = setup_card(ai, dev->dev_addr, 1);
7615
7616 if (!test_bit(FLAG_MPI,&ai->flags))
7617 for( i = 0; i < MAX_FIDS; i++ ) {
7618 ai->fids[i] = transmit_allocate
7619 ( ai, 2312, i >= MAX_FIDS / 2 );
7620 }
7621
7622 ssleep(1); /* Added 12/7/00 */
7623 return status;
7624}
7625#endif /* CISCO_EXT */
7626
7627/*
7628 This program is free software; you can redistribute it and/or
7629 modify it under the terms of the GNU General Public License
7630 as published by the Free Software Foundation; either version 2
7631 of the License, or (at your option) any later version.
7632
7633 This program is distributed in the hope that it will be useful,
7634 but WITHOUT ANY WARRANTY; without even the implied warranty of
7635 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7636 GNU General Public License for more details.
7637
7638 In addition:
7639
7640 Redistribution and use in source and binary forms, with or without
7641 modification, are permitted provided that the following conditions
7642 are met:
7643
7644 1. Redistributions of source code must retain the above copyright
7645 notice, this list of conditions and the following disclaimer.
7646 2. Redistributions in binary form must reproduce the above copyright
7647 notice, this list of conditions and the following disclaimer in the
7648 documentation and/or other materials provided with the distribution.
7649 3. The name of the author may not be used to endorse or promote
7650 products derived from this software without specific prior written
7651 permission.
7652
7653 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
7654 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
7655 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7656 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
7657 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
7658 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
7659 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
7660 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
7661 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
7662 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
7663 POSSIBILITY OF SUCH DAMAGE.
7664*/
7665
7666module_init(airo_init_module);
7667module_exit(airo_cleanup_module);
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
new file mode 100644
index 000000000000..fbf53af6cda4
--- /dev/null
+++ b/drivers/net/wireless/airo_cs.c
@@ -0,0 +1,622 @@
1/*======================================================================
2
3 Aironet driver for 4500 and 4800 series cards
4
5 This code is released under both the GPL version 2 and BSD licenses.
6 Either license may be used. The respective licenses are found at
7 the end of this file.
8
9 This code was developed by Benjamin Reed <breed@users.sourceforge.net>
10 including portions of which come from the Aironet PC4500
11 Developer's Reference Manual and used with permission. Copyright
12 (C) 1999 Benjamin Reed. All Rights Reserved. Permission to use
13 code in the Developer's manual was granted for this driver by
14 Aironet.
15
16 In addition this module was derived from dummy_cs.
17 The initial developer of dummy_cs is David A. Hinds
18 <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
19 are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
20
21======================================================================*/
22
23#include <linux/config.h>
24#ifdef __IN_PCMCIA_PACKAGE__
25#include <pcmcia/k_compat.h>
26#endif
27#include <linux/init.h>
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/ptrace.h>
31#include <linux/slab.h>
32#include <linux/string.h>
33#include <linux/timer.h>
34#include <linux/netdevice.h>
35
36#include <pcmcia/version.h>
37#include <pcmcia/cs_types.h>
38#include <pcmcia/cs.h>
39#include <pcmcia/cistpl.h>
40#include <pcmcia/cisreg.h>
41#include <pcmcia/ds.h>
42
43#include <asm/io.h>
44#include <asm/system.h>
45
46/*
47 All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
48 you do not define PCMCIA_DEBUG at all, all the debug code will be
49 left out. If you compile with PCMCIA_DEBUG=0, the debug code will
50 be present but disabled -- but it can then be enabled for specific
51 modules at load time with a 'pc_debug=#' option to insmod.
52*/
53#ifdef PCMCIA_DEBUG
54static int pc_debug = PCMCIA_DEBUG;
55module_param(pc_debug, int, 0);
56static char *version = "$Revision: 1.2 $";
57#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
58#else
59#define DEBUG(n, args...)
60#endif
61
62/*====================================================================*/
63
64MODULE_AUTHOR("Benjamin Reed");
65MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
66 cards. This is the module that links the PCMCIA card \
67 with the airo module.");
68MODULE_LICENSE("Dual BSD/GPL");
69MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
70
71/*====================================================================*/
72
73/*
74 The event() function is this driver's Card Services event handler.
75 It will be called by Card Services when an appropriate card status
76 event is received. The config() and release() entry points are
77 used to configure or release a socket, in response to card
78 insertion and ejection events. They are invoked from the airo_cs
79 event handler.
80*/
81
82struct net_device *init_airo_card( int, int, int, struct device * );
83void stop_airo_card( struct net_device *, int );
84int reset_airo_card( struct net_device * );
85
86static void airo_config(dev_link_t *link);
87static void airo_release(dev_link_t *link);
88static int airo_event(event_t event, int priority,
89 event_callback_args_t *args);
90
91/*
92 The attach() and detach() entry points are used to create and destroy
93 "instances" of the driver, where each instance represents everything
94 needed to manage one actual PCMCIA card.
95*/
96
97static dev_link_t *airo_attach(void);
98static void airo_detach(dev_link_t *);
99
100/*
101 You'll also need to prototype all the functions that will actually
102 be used to talk to your device. See 'pcmem_cs' for a good example
103 of a fully self-sufficient driver; the other drivers rely more or
104 less on other parts of the kernel.
105*/
106
107/*
108 The dev_info variable is the "key" that is used to match up this
109 device driver with appropriate cards, through the card configuration
110 database.
111*/
112
113static dev_info_t dev_info = "airo_cs";
114
115/*
116 A linked list of "instances" of the aironet device. Each actual
117 PCMCIA card corresponds to one device instance, and is described
118 by one dev_link_t structure (defined in ds.h).
119
120 You may not want to use a linked list for this -- for example, the
121 memory card driver uses an array of dev_link_t pointers, where minor
122 device numbers are used to derive the corresponding array index.
123*/
124
125static dev_link_t *dev_list = NULL;
126
127/*
128 A dev_link_t structure has fields for most things that are needed
129 to keep track of a socket, but there will usually be some device
130 specific information that also needs to be kept track of. The
131 'priv' pointer in a dev_link_t structure can be used to point to
132 a device-specific private data structure, like this.
133
134 A driver needs to provide a dev_node_t structure for each device
135 on a card. In some cases, there is only one device per card (for
136 example, ethernet cards, modems). In other cases, there may be
137 many actual or logical devices (SCSI adapters, memory cards with
138 multiple partitions). The dev_node_t structures need to be kept
139 in a linked list starting at the 'dev' field of a dev_link_t
140 structure. We allocate them in the card's private data structure,
141 because they generally shouldn't be allocated dynamically.
142
143 In this case, we also provide a flag to indicate if a device is
144 "stopped" due to a power management event, or card ejection. The
145 device IO routines can use a flag like this to throttle IO to a
146 card that is not ready to accept it.
147*/
148
149typedef struct local_info_t {
150 dev_node_t node;
151 struct net_device *eth_dev;
152} local_info_t;
153
154/*======================================================================
155
156 airo_attach() creates an "instance" of the driver, allocating
157 local data structures for one device. The device is registered
158 with Card Services.
159
160 The dev_link structure is initialized, but we don't actually
161 configure the card at this point -- we wait until we receive a
162 card insertion event.
163
164 ======================================================================*/
165
166static dev_link_t *airo_attach(void)
167{
168 client_reg_t client_reg;
169 dev_link_t *link;
170 local_info_t *local;
171 int ret;
172
173 DEBUG(0, "airo_attach()\n");
174
175 /* Initialize the dev_link_t structure */
176 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
177 if (!link) {
178 printk(KERN_ERR "airo_cs: no memory for new device\n");
179 return NULL;
180 }
181 memset(link, 0, sizeof(struct dev_link_t));
182
183 /* Interrupt setup */
184 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
185 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
186 link->irq.Handler = NULL;
187
188 /*
189 General socket configuration defaults can go here. In this
190 client, we assume very little, and rely on the CIS for almost
191 everything. In most clients, many details (i.e., number, sizes,
192 and attributes of IO windows) are fixed by the nature of the
193 device, and can be hard-wired here.
194 */
195 link->conf.Attributes = 0;
196 link->conf.Vcc = 50;
197 link->conf.IntType = INT_MEMORY_AND_IO;
198
199 /* Allocate space for private device-specific data */
200 local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
201 if (!local) {
202 printk(KERN_ERR "airo_cs: no memory for new device\n");
203 kfree (link);
204 return NULL;
205 }
206 memset(local, 0, sizeof(local_info_t));
207 link->priv = local;
208
209 /* Register with Card Services */
210 link->next = dev_list;
211 dev_list = link;
212 client_reg.dev_info = &dev_info;
213 client_reg.EventMask =
214 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
215 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
216 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
217 client_reg.event_handler = &airo_event;
218 client_reg.Version = 0x0210;
219 client_reg.event_callback_args.client_data = link;
220 ret = pcmcia_register_client(&link->handle, &client_reg);
221 if (ret != 0) {
222 cs_error(link->handle, RegisterClient, ret);
223 airo_detach(link);
224 return NULL;
225 }
226
227 return link;
228} /* airo_attach */
229
230/*======================================================================
231
232 This deletes a driver "instance". The device is de-registered
233 with Card Services. If it has been released, all local data
234 structures are freed. Otherwise, the structures will be freed
235 when the device is released.
236
237 ======================================================================*/
238
239static void airo_detach(dev_link_t *link)
240{
241 dev_link_t **linkp;
242
243 DEBUG(0, "airo_detach(0x%p)\n", link);
244
245 /* Locate device structure */
246 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
247 if (*linkp == link) break;
248 if (*linkp == NULL)
249 return;
250
251 if (link->state & DEV_CONFIG)
252 airo_release(link);
253
254 if ( ((local_info_t*)link->priv)->eth_dev ) {
255 stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
256 }
257 ((local_info_t*)link->priv)->eth_dev = NULL;
258
259 /* Break the link with Card Services */
260 if (link->handle)
261 pcmcia_deregister_client(link->handle);
262
263
264
265 /* Unlink device structure, free pieces */
266 *linkp = link->next;
267 if (link->priv) {
268 kfree(link->priv);
269 }
270 kfree(link);
271
272} /* airo_detach */
273
274/*======================================================================
275
276 airo_config() is scheduled to run after a CARD_INSERTION event
277 is received, to configure the PCMCIA socket, and to make the
278 device available to the system.
279
280 ======================================================================*/
281
282#define CS_CHECK(fn, ret) \
283do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
284
285static void airo_config(dev_link_t *link)
286{
287 client_handle_t handle;
288 tuple_t tuple;
289 cisparse_t parse;
290 local_info_t *dev;
291 int last_fn, last_ret;
292 u_char buf[64];
293 win_req_t req;
294 memreq_t map;
295
296 handle = link->handle;
297 dev = link->priv;
298
299 DEBUG(0, "airo_config(0x%p)\n", link);
300
301 /*
302 This reads the card's CONFIG tuple to find its configuration
303 registers.
304 */
305 tuple.DesiredTuple = CISTPL_CONFIG;
306 tuple.Attributes = 0;
307 tuple.TupleData = buf;
308 tuple.TupleDataMax = sizeof(buf);
309 tuple.TupleOffset = 0;
310 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
311 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
312 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
313 link->conf.ConfigBase = parse.config.base;
314 link->conf.Present = parse.config.rmask[0];
315
316 /* Configure card */
317 link->state |= DEV_CONFIG;
318
319 /*
320 In this loop, we scan the CIS for configuration table entries,
321 each of which describes a valid card configuration, including
322 voltage, IO window, memory window, and interrupt settings.
323
324 We make no assumptions about the card to be configured: we use
325 just the information available in the CIS. In an ideal world,
326 this would work for any PCMCIA card, but it requires a complete
327 and accurate CIS. In practice, a driver usually "knows" most of
328 these things without consulting the CIS, and most client drivers
329 will only use the CIS to fill in implementation-defined details.
330 */
331 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
332 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
333 while (1) {
334 cistpl_cftable_entry_t dflt = { 0 };
335 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
336 if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
337 pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
338 goto next_entry;
339
340 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
341 if (cfg->index == 0) goto next_entry;
342 link->conf.ConfigIndex = cfg->index;
343
344 /* Does this card need audio output? */
345 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
346 link->conf.Attributes |= CONF_ENABLE_SPKR;
347 link->conf.Status = CCSR_AUDIO_ENA;
348 }
349
350 /* Use power settings for Vcc and Vpp if present */
351 /* Note that the CIS values need to be rescaled */
352 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM))
353 link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
354 else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM))
355 link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
356
357 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
358 link->conf.Vpp1 = link->conf.Vpp2 =
359 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
360 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
361 link->conf.Vpp1 = link->conf.Vpp2 =
362 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
363
364 /* Do we need to allocate an interrupt? */
365 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
366 link->conf.Attributes |= CONF_ENABLE_IRQ;
367
368 /* IO window settings */
369 link->io.NumPorts1 = link->io.NumPorts2 = 0;
370 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
371 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
372 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
373 if (!(io->flags & CISTPL_IO_8BIT))
374 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
375 if (!(io->flags & CISTPL_IO_16BIT))
376 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
377 link->io.BasePort1 = io->win[0].base;
378 link->io.NumPorts1 = io->win[0].len;
379 if (io->nwin > 1) {
380 link->io.Attributes2 = link->io.Attributes1;
381 link->io.BasePort2 = io->win[1].base;
382 link->io.NumPorts2 = io->win[1].len;
383 }
384 }
385
386 /* This reserves IO space but doesn't actually enable it */
387 if (pcmcia_request_io(link->handle, &link->io) != 0)
388 goto next_entry;
389
390 /*
391 Now set up a common memory window, if needed. There is room
392 in the dev_link_t structure for one memory window handle,
393 but if the base addresses need to be saved, or if multiple
394 windows are needed, the info should go in the private data
395 structure for this device.
396
397 Note that the memory window base is a physical address, and
398 needs to be mapped to virtual space with ioremap() before it
399 is used.
400 */
401 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
402 cistpl_mem_t *mem =
403 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
404 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
405 req.Base = mem->win[0].host_addr;
406 req.Size = mem->win[0].len;
407 req.AccessSpeed = 0;
408 if (pcmcia_request_window(&link->handle, &req, &link->win) != 0)
409 goto next_entry;
410 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
411 if (pcmcia_map_mem_page(link->win, &map) != 0)
412 goto next_entry;
413 }
414 /* If we got this far, we're cool! */
415 break;
416
417 next_entry:
418 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
419 }
420
421 /*
422 Allocate an interrupt line. Note that this does not assign a
423 handler to the interrupt, unless the 'Handler' member of the
424 irq structure is initialized.
425 */
426 if (link->conf.Attributes & CONF_ENABLE_IRQ)
427 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
428
429 /*
430 This actually configures the PCMCIA socket -- setting up
431 the I/O windows and the interrupt mapping, and putting the
432 card and host interface into "Memory and IO" mode.
433 */
434 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
435 ((local_info_t*)link->priv)->eth_dev =
436 init_airo_card( link->irq.AssignedIRQ,
437 link->io.BasePort1, 1, &handle_to_dev(handle) );
438 if (!((local_info_t*)link->priv)->eth_dev) goto cs_failed;
439
440 /*
441 At this point, the dev_node_t structure(s) need to be
442 initialized and arranged in a linked list at link->dev.
443 */
444 strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
445 dev->node.major = dev->node.minor = 0;
446 link->dev = &dev->node;
447
448 /* Finally, report what we've done */
449 printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
450 dev->node.dev_name, link->conf.ConfigIndex,
451 link->conf.Vcc/10, link->conf.Vcc%10);
452 if (link->conf.Vpp1)
453 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
454 if (link->conf.Attributes & CONF_ENABLE_IRQ)
455 printk(", irq %d", link->irq.AssignedIRQ);
456 if (link->io.NumPorts1)
457 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
458 link->io.BasePort1+link->io.NumPorts1-1);
459 if (link->io.NumPorts2)
460 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
461 link->io.BasePort2+link->io.NumPorts2-1);
462 if (link->win)
463 printk(", mem 0x%06lx-0x%06lx", req.Base,
464 req.Base+req.Size-1);
465 printk("\n");
466
467 link->state &= ~DEV_CONFIG_PENDING;
468 return;
469
470 cs_failed:
471 cs_error(link->handle, last_fn, last_ret);
472 airo_release(link);
473
474} /* airo_config */
475
476/*======================================================================
477
478 After a card is removed, airo_release() will unregister the
479 device, and release the PCMCIA configuration. If the device is
480 still open, this will be postponed until it is closed.
481
482 ======================================================================*/
483
484static void airo_release(dev_link_t *link)
485{
486 DEBUG(0, "airo_release(0x%p)\n", link);
487
488 /* Unlink the device chain */
489 link->dev = NULL;
490
491 /*
492 In a normal driver, additional code may be needed to release
493 other kernel data structures associated with this device.
494 */
495
496 /* Don't bother checking to see if these succeed or not */
497 if (link->win)
498 pcmcia_release_window(link->win);
499 pcmcia_release_configuration(link->handle);
500 if (link->io.NumPorts1)
501 pcmcia_release_io(link->handle, &link->io);
502 if (link->irq.AssignedIRQ)
503 pcmcia_release_irq(link->handle, &link->irq);
504 link->state &= ~DEV_CONFIG;
505}
506
507/*======================================================================
508
509 The card status event handler. Mostly, this schedules other
510 stuff to run after an event is received.
511
512 When a CARD_REMOVAL event is received, we immediately set a
513 private flag to block future accesses to this device. All the
514 functions that actually access the device should check this flag
515 to make sure the card is still present.
516
517 ======================================================================*/
518
519static int airo_event(event_t event, int priority,
520 event_callback_args_t *args)
521{
522 dev_link_t *link = args->client_data;
523 local_info_t *local = link->priv;
524
525 DEBUG(1, "airo_event(0x%06x)\n", event);
526
527 switch (event) {
528 case CS_EVENT_CARD_REMOVAL:
529 link->state &= ~DEV_PRESENT;
530 if (link->state & DEV_CONFIG) {
531 netif_device_detach(local->eth_dev);
532 airo_release(link);
533 }
534 break;
535 case CS_EVENT_CARD_INSERTION:
536 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
537 airo_config(link);
538 break;
539 case CS_EVENT_PM_SUSPEND:
540 link->state |= DEV_SUSPEND;
541 /* Fall through... */
542 case CS_EVENT_RESET_PHYSICAL:
543 if (link->state & DEV_CONFIG) {
544 netif_device_detach(local->eth_dev);
545 pcmcia_release_configuration(link->handle);
546 }
547 break;
548 case CS_EVENT_PM_RESUME:
549 link->state &= ~DEV_SUSPEND;
550 /* Fall through... */
551 case CS_EVENT_CARD_RESET:
552 if (link->state & DEV_CONFIG) {
553 pcmcia_request_configuration(link->handle, &link->conf);
554 reset_airo_card(local->eth_dev);
555 netif_device_attach(local->eth_dev);
556 }
557 break;
558 }
559 return 0;
560} /* airo_event */
561
562static struct pcmcia_driver airo_driver = {
563 .owner = THIS_MODULE,
564 .drv = {
565 .name = "airo_cs",
566 },
567 .attach = airo_attach,
568 .detach = airo_detach,
569};
570
571static int airo_cs_init(void)
572{
573 return pcmcia_register_driver(&airo_driver);
574}
575
576static void airo_cs_cleanup(void)
577{
578 pcmcia_unregister_driver(&airo_driver);
579 BUG_ON(dev_list != NULL);
580}
581
582/*
583 This program is free software; you can redistribute it and/or
584 modify it under the terms of the GNU General Public License
585 as published by the Free Software Foundation; either version 2
586 of the License, or (at your option) any later version.
587
588 This program is distributed in the hope that it will be useful,
589 but WITHOUT ANY WARRANTY; without even the implied warranty of
590 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
591 GNU General Public License for more details.
592
593 In addition:
594
595 Redistribution and use in source and binary forms, with or without
596 modification, are permitted provided that the following conditions
597 are met:
598
599 1. Redistributions of source code must retain the above copyright
600 notice, this list of conditions and the following disclaimer.
601 2. Redistributions in binary form must reproduce the above copyright
602 notice, this list of conditions and the following disclaimer in the
603 documentation and/or other materials provided with the distribution.
604 3. The name of the author may not be used to endorse or promote
605 products derived from this software without specific prior written
606 permission.
607
608 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
609 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
610 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
611 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
612 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
613 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
614 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
615 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
616 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
617 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
618 POSSIBILITY OF SUCH DAMAGE.
619*/
620
621module_init(airo_cs_init);
622module_exit(airo_cs_cleanup);
diff --git a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c
new file mode 100644
index 000000000000..a1dc2a196087
--- /dev/null
+++ b/drivers/net/wireless/airport.c
@@ -0,0 +1,304 @@
1/* airport.c
2 *
3 * A driver for "Hermes" chipset based Apple Airport wireless
4 * card.
5 *
6 * Copyright notice & release notes in file orinoco.c
7 *
8 * Note specific to airport stub:
9 *
10 * 0.05 : first version of the new split driver
11 * 0.06 : fix possible hang on powerup, add sleep support
12 */
13
14#define DRIVER_NAME "airport"
15#define PFX DRIVER_NAME ": "
16
17#include <linux/config.h>
18
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/ptrace.h>
23#include <linux/slab.h>
24#include <linux/string.h>
25#include <linux/timer.h>
26#include <linux/ioport.h>
27#include <linux/netdevice.h>
28#include <linux/if_arp.h>
29#include <linux/etherdevice.h>
30#include <linux/wireless.h>
31
32#include <asm/io.h>
33#include <asm/system.h>
34#include <asm/current.h>
35#include <asm/prom.h>
36#include <asm/machdep.h>
37#include <asm/pmac_feature.h>
38#include <asm/irq.h>
39#include <asm/uaccess.h>
40
41#include "orinoco.h"
42
43#define AIRPORT_IO_LEN (0x1000) /* one page */
44
45struct airport {
46 struct macio_dev *mdev;
47 void __iomem *vaddr;
48 int irq_requested;
49 int ndev_registered;
50};
51
52static int
53airport_suspend(struct macio_dev *mdev, u32 state)
54{
55 struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
56 struct orinoco_private *priv = netdev_priv(dev);
57 unsigned long flags;
58 int err;
59
60 printk(KERN_DEBUG "%s: Airport entering sleep mode\n", dev->name);
61
62 err = orinoco_lock(priv, &flags);
63 if (err) {
64 printk(KERN_ERR "%s: hw_unavailable on PBOOK_SLEEP_NOW\n",
65 dev->name);
66 return 0;
67 }
68
69 err = __orinoco_down(dev);
70 if (err)
71 printk(KERN_WARNING "%s: PBOOK_SLEEP_NOW: Error %d downing interface\n",
72 dev->name, err);
73
74 netif_device_detach(dev);
75
76 priv->hw_unavailable++;
77
78 orinoco_unlock(priv, &flags);
79
80 disable_irq(dev->irq);
81 pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0);
82
83 return 0;
84}
85
86static int
87airport_resume(struct macio_dev *mdev)
88{
89 struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
90 struct orinoco_private *priv = netdev_priv(dev);
91 unsigned long flags;
92 int err;
93
94 printk(KERN_DEBUG "%s: Airport waking up\n", dev->name);
95
96 pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
97 msleep(200);
98
99 enable_irq(dev->irq);
100
101 err = orinoco_reinit_firmware(dev);
102 if (err) {
103 printk(KERN_ERR "%s: Error %d re-initializing firmware on PBOOK_WAKE\n",
104 dev->name, err);
105 return 0;
106 }
107
108 spin_lock_irqsave(&priv->lock, flags);
109
110 netif_device_attach(dev);
111
112 priv->hw_unavailable--;
113
114 if (priv->open && (! priv->hw_unavailable)) {
115 err = __orinoco_up(dev);
116 if (err)
117 printk(KERN_ERR "%s: Error %d restarting card on PBOOK_WAKE\n",
118 dev->name, err);
119 }
120
121
122 spin_unlock_irqrestore(&priv->lock, flags);
123
124 return 0;
125}
126
127static int
128airport_detach(struct macio_dev *mdev)
129{
130 struct net_device *dev = dev_get_drvdata(&mdev->ofdev.dev);
131 struct orinoco_private *priv = netdev_priv(dev);
132 struct airport *card = priv->card;
133
134 if (card->ndev_registered)
135 unregister_netdev(dev);
136 card->ndev_registered = 0;
137
138 if (card->irq_requested)
139 free_irq(dev->irq, dev);
140 card->irq_requested = 0;
141
142 if (card->vaddr)
143 iounmap(card->vaddr);
144 card->vaddr = NULL;
145
146 macio_release_resource(mdev, 0);
147
148 pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 0);
149 ssleep(1);
150
151 macio_set_drvdata(mdev, NULL);
152 free_orinocodev(dev);
153
154 return 0;
155}
156
157static int airport_hard_reset(struct orinoco_private *priv)
158{
159 /* It would be nice to power cycle the Airport for a real hard
160 * reset, but for some reason although it appears to
161 * re-initialize properly, it falls in a screaming heap
162 * shortly afterwards. */
163#if 0
164 struct net_device *dev = priv->ndev;
165 struct airport *card = priv->card;
166
167 /* Vitally important. If we don't do this it seems we get an
168 * interrupt somewhere during the power cycle, since
169 * hw_unavailable is already set it doesn't get ACKed, we get
170 * into an interrupt loop and the the PMU decides to turn us
171 * off. */
172 disable_irq(dev->irq);
173
174 pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(card->mdev), 0, 0);
175 ssleep(1);
176 pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(card->mdev), 0, 1);
177 ssleep(1);
178
179 enable_irq(dev->irq);
180 ssleep(1);
181#endif
182
183 return 0;
184}
185
186static int
187airport_attach(struct macio_dev *mdev, const struct of_match *match)
188{
189 struct orinoco_private *priv;
190 struct net_device *dev;
191 struct airport *card;
192 unsigned long phys_addr;
193 hermes_t *hw;
194
195 if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) {
196 printk(KERN_ERR PFX "Wrong interrupt/addresses in OF tree\n");
197 return -ENODEV;
198 }
199
200 /* Allocate space for private device-specific data */
201 dev = alloc_orinocodev(sizeof(*card), airport_hard_reset);
202 if (! dev) {
203 printk(KERN_ERR PFX "Cannot allocate network device\n");
204 return -ENODEV;
205 }
206 priv = netdev_priv(dev);
207 card = priv->card;
208
209 hw = &priv->hw;
210 card->mdev = mdev;
211
212 if (macio_request_resource(mdev, 0, "airport")) {
213 printk(KERN_ERR PFX "can't request IO resource !\n");
214 free_orinocodev(dev);
215 return -EBUSY;
216 }
217
218 SET_MODULE_OWNER(dev);
219 SET_NETDEV_DEV(dev, &mdev->ofdev.dev);
220
221 macio_set_drvdata(mdev, dev);
222
223 /* Setup interrupts & base address */
224 dev->irq = macio_irq(mdev, 0);
225 phys_addr = macio_resource_start(mdev, 0); /* Physical address */
226 printk(KERN_DEBUG PFX "Physical address %lx\n", phys_addr);
227 dev->base_addr = phys_addr;
228 card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
229 if (!card->vaddr) {
230 printk(KERN_ERR PFX "ioremap() failed\n");
231 goto failed;
232 }
233
234 hermes_struct_init(hw, card->vaddr, HERMES_16BIT_REGSPACING);
235
236 /* Power up card */
237 pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
238 ssleep(1);
239
240 /* Reset it before we get the interrupt */
241 hermes_init(hw);
242
243 if (request_irq(dev->irq, orinoco_interrupt, 0, dev->name, dev)) {
244 printk(KERN_ERR PFX "Couldn't get IRQ %d\n", dev->irq);
245 goto failed;
246 }
247 card->irq_requested = 1;
248
249 /* Tell the stack we exist */
250 if (register_netdev(dev) != 0) {
251 printk(KERN_ERR PFX "register_netdev() failed\n");
252 goto failed;
253 }
254 printk(KERN_DEBUG PFX "Card registered for interface %s\n", dev->name);
255 card->ndev_registered = 1;
256 return 0;
257 failed:
258 airport_detach(mdev);
259 return -ENODEV;
260} /* airport_attach */
261
262
263static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
264 " (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
265MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
266MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
267MODULE_LICENSE("Dual MPL/GPL");
268
269static struct of_match airport_match[] =
270{
271 {
272 .name = "radio",
273 .type = OF_ANY_MATCH,
274 .compatible = OF_ANY_MATCH
275 },
276 {},
277};
278
279static struct macio_driver airport_driver =
280{
281 .name = DRIVER_NAME,
282 .match_table = airport_match,
283 .probe = airport_attach,
284 .remove = airport_detach,
285 .suspend = airport_suspend,
286 .resume = airport_resume,
287};
288
289static int __init
290init_airport(void)
291{
292 printk(KERN_DEBUG "%s\n", version);
293
294 return macio_register_driver(&airport_driver);
295}
296
297static void __exit
298exit_airport(void)
299{
300 return macio_unregister_driver(&airport_driver);
301}
302
303module_init(init_airport);
304module_exit(exit_airport);
diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c
new file mode 100644
index 000000000000..4f304c6e693a
--- /dev/null
+++ b/drivers/net/wireless/arlan-main.c
@@ -0,0 +1,1896 @@
1/*
2 * Copyright (C) 1997 Cullen Jennings
3 * Copyright (C) 1998 Elmer Joandiu, elmer@ylenurme.ee
4 * GNU General Public License applies
5 * This module provides support for the Arlan 655 card made by Aironet
6 */
7
8#include <linux/config.h>
9#include "arlan.h"
10
11#if BITS_PER_LONG != 32
12# error FIXME: this driver requires a 32-bit platform
13#endif
14
15static const char *arlan_version = "C.Jennigs 97 & Elmer.Joandi@ut.ee Oct'98, http://www.ylenurme.ee/~elmer/655/";
16
17struct net_device *arlan_device[MAX_ARLANS];
18
19static int SID = SIDUNKNOWN;
20static int radioNodeId = radioNodeIdUNKNOWN;
21static char encryptionKey[12] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
22int arlan_debug = debugUNKNOWN;
23static int spreadingCode = spreadingCodeUNKNOWN;
24static int channelNumber = channelNumberUNKNOWN;
25static int channelSet = channelSetUNKNOWN;
26static int systemId = systemIdUNKNOWN;
27static int registrationMode = registrationModeUNKNOWN;
28static int keyStart;
29static int tx_delay_ms;
30static int retries = 5;
31static int tx_queue_len = 1;
32static int arlan_EEPROM_bad;
33
34#ifdef ARLAN_DEBUGGING
35
36static int arlan_entry_debug;
37static int arlan_exit_debug;
38static int testMemory = testMemoryUNKNOWN;
39static int irq = irqUNKNOWN;
40static int txScrambled = 1;
41static int mdebug;
42
43module_param(irq, int, 0);
44module_param(mdebug, int, 0);
45module_param(testMemory, int, 0);
46module_param(arlan_entry_debug, int, 0);
47module_param(arlan_exit_debug, int, 0);
48module_param(txScrambled, int, 0);
49MODULE_PARM_DESC(irq, "(unused)");
50MODULE_PARM_DESC(testMemory, "(unused)");
51MODULE_PARM_DESC(mdebug, "Arlan multicast debugging (0-1)");
52#endif
53
54module_param(arlan_debug, int, 0);
55module_param(spreadingCode, int, 0);
56module_param(channelNumber, int, 0);
57module_param(channelSet, int, 0);
58module_param(systemId, int, 0);
59module_param(registrationMode, int, 0);
60module_param(radioNodeId, int, 0);
61module_param(SID, int, 0);
62module_param(keyStart, int, 0);
63module_param(tx_delay_ms, int, 0);
64module_param(retries, int, 0);
65module_param(tx_queue_len, int, 0);
66module_param(arlan_EEPROM_bad, int, 0);
67MODULE_PARM_DESC(arlan_debug, "Arlan debug enable (0-1)");
68MODULE_PARM_DESC(retries, "Arlan maximum packet retransmisions");
69#ifdef ARLAN_ENTRY_EXIT_DEBUGGING
70MODULE_PARM_DESC(arlan_entry_debug, "Arlan driver function entry debugging");
71MODULE_PARM_DESC(arlan_exit_debug, "Arlan driver function exit debugging");
72MODULE_PARM_DESC(arlan_entry_and_exit_debug, "Arlan driver function entry and exit debugging");
73#else
74MODULE_PARM_DESC(arlan_entry_debug, "(ignored)");
75MODULE_PARM_DESC(arlan_exit_debug, "(ignored)");
76MODULE_PARM_DESC(arlan_entry_and_exit_debug, "(ignored)");
77#endif
78
79struct arlan_conf_stru arlan_conf[MAX_ARLANS];
80static int arlans_found;
81
82static int arlan_open(struct net_device *dev);
83static int arlan_tx(struct sk_buff *skb, struct net_device *dev);
84static irqreturn_t arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs);
85static int arlan_close(struct net_device *dev);
86static struct net_device_stats *
87 arlan_statistics (struct net_device *dev);
88static void arlan_set_multicast (struct net_device *dev);
89static int arlan_hw_tx (struct net_device* dev, char *buf, int length );
90static int arlan_hw_config (struct net_device * dev);
91static void arlan_tx_done_interrupt (struct net_device * dev, int status);
92static void arlan_rx_interrupt (struct net_device * dev, u_char rxStatus, u_short, u_short);
93static void arlan_process_interrupt (struct net_device * dev);
94static void arlan_tx_timeout (struct net_device *dev);
95
96static inline long us2ticks(int us)
97{
98 return us * (1000000 / HZ);
99}
100
101
102#ifdef ARLAN_ENTRY_EXIT_DEBUGGING
103#define ARLAN_DEBUG_ENTRY(name) \
104 {\
105 struct timeval timev;\
106 do_gettimeofday(&timev);\
107 if (arlan_entry_debug || arlan_entry_and_exit_debug)\
108 printk("--->>>" name " %ld " "\n",((long int) timev.tv_sec * 1000000 + timev.tv_usec));\
109 }
110#define ARLAN_DEBUG_EXIT(name) \
111 {\
112 struct timeval timev;\
113 do_gettimeofday(&timev);\
114 if (arlan_exit_debug || arlan_entry_and_exit_debug)\
115 printk("<<<---" name " %ld " "\n",((long int) timev.tv_sec * 1000000 + timev.tv_usec) );\
116 }
117#else
118#define ARLAN_DEBUG_ENTRY(name)
119#define ARLAN_DEBUG_EXIT(name)
120#endif
121
122
123#define arlan_interrupt_ack(dev)\
124 clearClearInterrupt(dev);\
125 setClearInterrupt(dev);
126
127static inline int arlan_drop_tx(struct net_device *dev)
128{
129 struct arlan_private *priv = netdev_priv(dev);
130
131 priv->stats.tx_errors++;
132 if (priv->Conf->tx_delay_ms)
133 {
134 priv->tx_done_delayed = jiffies + priv->Conf->tx_delay_ms * HZ / 1000 + 1;
135 }
136 else
137 {
138 priv->waiting_command_mask &= ~ARLAN_COMMAND_TX;
139 TXHEAD(dev).offset = 0;
140 TXTAIL(dev).offset = 0;
141 priv->txLast = 0;
142 priv->bad = 0;
143 if (!priv->under_reset && !priv->under_config)
144 netif_wake_queue (dev);
145 }
146 return 1;
147}
148
149
150int arlan_command(struct net_device *dev, int command_p)
151{
152 struct arlan_private *priv = netdev_priv(dev);
153 volatile struct arlan_shmem __iomem *arlan = priv->card;
154 struct arlan_conf_stru *conf = priv->Conf;
155 int udelayed = 0;
156 int i = 0;
157 unsigned long flags;
158
159 ARLAN_DEBUG_ENTRY("arlan_command");
160
161 if (priv->card_polling_interval)
162 priv->card_polling_interval = 1;
163
164 if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS)
165 printk(KERN_DEBUG "arlan_command, %lx commandByte %x waiting %lx incoming %x \n",
166 jiffies, READSHMB(arlan->commandByte),
167 priv->waiting_command_mask, command_p);
168
169 priv->waiting_command_mask |= command_p;
170
171 if (priv->waiting_command_mask & ARLAN_COMMAND_RESET)
172 if (time_after(jiffies, priv->lastReset + 5 * HZ))
173 priv->waiting_command_mask &= ~ARLAN_COMMAND_RESET;
174
175 if (priv->waiting_command_mask & ARLAN_COMMAND_INT_ACK)
176 {
177 arlan_interrupt_ack(dev);
178 priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_ACK;
179 }
180 if (priv->waiting_command_mask & ARLAN_COMMAND_INT_ENABLE)
181 {
182 setInterruptEnable(dev);
183 priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_ENABLE;
184 }
185
186 /* Card access serializing lock */
187 spin_lock_irqsave(&priv->lock, flags);
188
189 /* Check cards status and waiting */
190
191 if (priv->waiting_command_mask & (ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW))
192 {
193 while (priv->waiting_command_mask & (ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW))
194 {
195 if (READSHMB(arlan->resetFlag) ||
196 READSHMB(arlan->commandByte)) /* ||
197 (readControlRegister(dev) & ARLAN_ACCESS))
198 */
199 udelay(40);
200 else
201 priv->waiting_command_mask &= ~(ARLAN_COMMAND_LONG_WAIT_NOW | ARLAN_COMMAND_WAIT_NOW);
202
203 udelayed++;
204
205 if (priv->waiting_command_mask & ARLAN_COMMAND_LONG_WAIT_NOW)
206 {
207 if (udelayed * 40 > 1000000)
208 {
209 printk(KERN_ERR "%s long wait too long \n", dev->name);
210 priv->waiting_command_mask |= ARLAN_COMMAND_RESET;
211 break;
212 }
213 }
214 else if (priv->waiting_command_mask & ARLAN_COMMAND_WAIT_NOW)
215 {
216 if (udelayed * 40 > 1000)
217 {
218 printk(KERN_ERR "%s short wait too long \n", dev->name);
219 goto bad_end;
220 }
221 }
222 }
223 }
224 else
225 {
226 i = 0;
227 while ((READSHMB(arlan->resetFlag) ||
228 READSHMB(arlan->commandByte)) &&
229 conf->pre_Command_Wait > (i++) * 10)
230 udelay(10);
231
232
233 if ((READSHMB(arlan->resetFlag) ||
234 READSHMB(arlan->commandByte)) &&
235 !(priv->waiting_command_mask & ARLAN_COMMAND_RESET))
236 {
237 goto card_busy_end;
238 }
239 }
240 if (priv->waiting_command_mask & ARLAN_COMMAND_RESET)
241 priv->under_reset = 1;
242 if (priv->waiting_command_mask & ARLAN_COMMAND_CONF)
243 priv->under_config = 1;
244
245 /* Issuing command */
246 arlan_lock_card_access(dev);
247 if (priv->waiting_command_mask & ARLAN_COMMAND_POWERUP)
248 {
249 // if (readControlRegister(dev) & (ARLAN_ACCESS && ARLAN_POWER))
250 setPowerOn(dev);
251 arlan_interrupt_lancpu(dev);
252 priv->waiting_command_mask &= ~ARLAN_COMMAND_POWERUP;
253 priv->waiting_command_mask |= ARLAN_COMMAND_RESET;
254 priv->card_polling_interval = HZ / 10;
255 }
256 else if (priv->waiting_command_mask & ARLAN_COMMAND_ACTIVATE)
257 {
258 WRITESHMB(arlan->commandByte, ARLAN_COM_ACTIVATE);
259 arlan_interrupt_lancpu(dev);
260 priv->waiting_command_mask &= ~ARLAN_COMMAND_ACTIVATE;
261 priv->card_polling_interval = HZ / 10;
262 }
263 else if (priv->waiting_command_mask & ARLAN_COMMAND_RX_ABORT)
264 {
265 if (priv->rx_command_given)
266 {
267 WRITESHMB(arlan->commandByte, ARLAN_COM_RX_ABORT);
268 arlan_interrupt_lancpu(dev);
269 priv->rx_command_given = 0;
270 }
271 priv->waiting_command_mask &= ~ARLAN_COMMAND_RX_ABORT;
272 priv->card_polling_interval = 1;
273 }
274 else if (priv->waiting_command_mask & ARLAN_COMMAND_TX_ABORT)
275 {
276 if (priv->tx_command_given)
277 {
278 WRITESHMB(arlan->commandByte, ARLAN_COM_TX_ABORT);
279 arlan_interrupt_lancpu(dev);
280 priv->tx_command_given = 0;
281 }
282 priv->waiting_command_mask &= ~ARLAN_COMMAND_TX_ABORT;
283 priv->card_polling_interval = 1;
284 }
285 else if (priv->waiting_command_mask & ARLAN_COMMAND_RESET)
286 {
287 priv->under_reset=1;
288 netif_stop_queue (dev);
289
290 arlan_drop_tx(dev);
291 if (priv->tx_command_given || priv->rx_command_given)
292 {
293 printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name);
294 }
295 netif_stop_queue (dev);
296 if (arlan_debug & ARLAN_DEBUG_RESET)
297 printk(KERN_ERR "%s: Doing chip reset\n", dev->name);
298 priv->lastReset = jiffies;
299 WRITESHM(arlan->commandByte, 0, u_char);
300 /* hold card in reset state */
301 setHardwareReset(dev);
302 /* set reset flag and then release reset */
303 WRITESHM(arlan->resetFlag, 0xff, u_char);
304 clearChannelAttention(dev);
305 clearHardwareReset(dev);
306 priv->card_polling_interval = HZ / 4;
307 priv->waiting_command_mask &= ~ARLAN_COMMAND_RESET;
308 priv->waiting_command_mask |= ARLAN_COMMAND_INT_RACK;
309// priv->waiting_command_mask |= ARLAN_COMMAND_INT_RENABLE;
310// priv->waiting_command_mask |= ARLAN_COMMAND_RX;
311 }
312 else if (priv->waiting_command_mask & ARLAN_COMMAND_INT_RACK)
313 {
314 clearHardwareReset(dev);
315 clearClearInterrupt(dev);
316 setClearInterrupt(dev);
317 setInterruptEnable(dev);
318 priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_RACK;
319 priv->waiting_command_mask |= ARLAN_COMMAND_CONF;
320 priv->under_config = 1;
321 priv->under_reset = 0;
322 }
323 else if (priv->waiting_command_mask & ARLAN_COMMAND_INT_RENABLE)
324 {
325 setInterruptEnable(dev);
326 priv->waiting_command_mask &= ~ARLAN_COMMAND_INT_RENABLE;
327 }
328 else if (priv->waiting_command_mask & ARLAN_COMMAND_CONF)
329 {
330 if (priv->tx_command_given || priv->rx_command_given)
331 {
332 printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name);
333 }
334 arlan_drop_tx(dev);
335 setInterruptEnable(dev);
336 arlan_hw_config(dev);
337 arlan_interrupt_lancpu(dev);
338 priv->waiting_command_mask &= ~ARLAN_COMMAND_CONF;
339 priv->card_polling_interval = HZ / 10;
340// priv->waiting_command_mask |= ARLAN_COMMAND_INT_RACK;
341// priv->waiting_command_mask |= ARLAN_COMMAND_INT_ENABLE;
342 priv->waiting_command_mask |= ARLAN_COMMAND_CONF_WAIT;
343 }
344 else if (priv->waiting_command_mask & ARLAN_COMMAND_CONF_WAIT)
345 {
346 if (READSHMB(arlan->configuredStatusFlag) != 0 &&
347 READSHMB(arlan->diagnosticInfo) == 0xff)
348 {
349 priv->waiting_command_mask &= ~ARLAN_COMMAND_CONF_WAIT;
350 priv->waiting_command_mask |= ARLAN_COMMAND_RX;
351 priv->waiting_command_mask |= ARLAN_COMMAND_TBUSY_CLEAR;
352 priv->card_polling_interval = HZ / 10;
353 priv->tx_command_given = 0;
354 priv->under_config = 0;
355 }
356 else
357 {
358 priv->card_polling_interval = 1;
359 if (arlan_debug & ARLAN_DEBUG_TIMING)
360 printk(KERN_ERR "configure delayed \n");
361 }
362 }
363 else if (priv->waiting_command_mask & ARLAN_COMMAND_RX)
364 {
365 if (!registrationBad(dev))
366 {
367 setInterruptEnable(dev);
368 memset_io(arlan->commandParameter, 0, 0xf);
369 WRITESHMB(arlan->commandByte, ARLAN_COM_INT | ARLAN_COM_RX_ENABLE);
370 WRITESHMB(arlan->commandParameter[0], conf->rxParameter);
371 arlan_interrupt_lancpu(dev);
372 priv->rx_command_given = 0; // mnjah, bad
373 priv->waiting_command_mask &= ~ARLAN_COMMAND_RX;
374 priv->card_polling_interval = 1;
375 }
376 else
377 priv->card_polling_interval = 2;
378 }
379 else if (priv->waiting_command_mask & ARLAN_COMMAND_TBUSY_CLEAR)
380 {
381 if ( !registrationBad(dev) &&
382 (netif_queue_stopped(dev) || !netif_running(dev)) )
383 {
384 priv->waiting_command_mask &= ~ARLAN_COMMAND_TBUSY_CLEAR;
385 netif_wake_queue (dev);
386 }
387 }
388 else if (priv->waiting_command_mask & ARLAN_COMMAND_TX)
389 {
390 if (!test_and_set_bit(0, (void *) &priv->tx_command_given))
391 {
392 if (time_after(jiffies,
393 priv->tx_last_sent + us2ticks(conf->rx_tweak1))
394 || time_before(jiffies,
395 priv->last_rx_int_ack_time + us2ticks(conf->rx_tweak2)))
396 {
397 setInterruptEnable(dev);
398 memset_io(arlan->commandParameter, 0, 0xf);
399 WRITESHMB(arlan->commandByte, ARLAN_COM_TX_ENABLE | ARLAN_COM_INT);
400 memcpy_toio(arlan->commandParameter, &TXLAST(dev), 14);
401// for ( i=1 ; i < 15 ; i++) printk("%02x:",READSHMB(arlan->commandParameter[i]));
402 priv->tx_last_sent = jiffies;
403 arlan_interrupt_lancpu(dev);
404 priv->tx_command_given = 1;
405 priv->waiting_command_mask &= ~ARLAN_COMMAND_TX;
406 priv->card_polling_interval = 1;
407 }
408 else
409 {
410 priv->tx_command_given = 0;
411 priv->card_polling_interval = 1;
412 }
413 }
414 else if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS)
415 printk(KERN_ERR "tx command when tx chain locked \n");
416 }
417 else if (priv->waiting_command_mask & ARLAN_COMMAND_NOOPINT)
418 {
419 {
420 WRITESHMB(arlan->commandByte, ARLAN_COM_NOP | ARLAN_COM_INT);
421 }
422 arlan_interrupt_lancpu(dev);
423 priv->waiting_command_mask &= ~ARLAN_COMMAND_NOOPINT;
424 priv->card_polling_interval = HZ / 3;
425 }
426 else if (priv->waiting_command_mask & ARLAN_COMMAND_NOOP)
427 {
428 WRITESHMB(arlan->commandByte, ARLAN_COM_NOP);
429 arlan_interrupt_lancpu(dev);
430 priv->waiting_command_mask &= ~ARLAN_COMMAND_NOOP;
431 priv->card_polling_interval = HZ / 3;
432 }
433 else if (priv->waiting_command_mask & ARLAN_COMMAND_SLOW_POLL)
434 {
435 WRITESHMB(arlan->commandByte, ARLAN_COM_GOTO_SLOW_POLL);
436 arlan_interrupt_lancpu(dev);
437 priv->waiting_command_mask &= ~ARLAN_COMMAND_SLOW_POLL;
438 priv->card_polling_interval = HZ / 3;
439 }
440 else if (priv->waiting_command_mask & ARLAN_COMMAND_POWERDOWN)
441 {
442 setPowerOff(dev);
443 if (arlan_debug & ARLAN_DEBUG_CARD_STATE)
444 printk(KERN_WARNING "%s: Arlan Going Standby\n", dev->name);
445 priv->waiting_command_mask &= ~ARLAN_COMMAND_POWERDOWN;
446 priv->card_polling_interval = 3 * HZ;
447 }
448 arlan_unlock_card_access(dev);
449 for (i = 0; READSHMB(arlan->commandByte) && i < 20; i++)
450 udelay(10);
451 if (READSHMB(arlan->commandByte))
452 if (arlan_debug & ARLAN_DEBUG_CARD_STATE)
453 printk(KERN_ERR "card busy leaving command %lx\n", priv->waiting_command_mask);
454
455 spin_unlock_irqrestore(&priv->lock, flags);
456 ARLAN_DEBUG_EXIT("arlan_command");
457 priv->last_command_buff_free_time = jiffies;
458 return 0;
459
460card_busy_end:
461 if (time_after(jiffies, priv->last_command_buff_free_time + HZ))
462 priv->waiting_command_mask |= ARLAN_COMMAND_CLEAN_AND_RESET;
463
464 if (arlan_debug & ARLAN_DEBUG_CARD_STATE)
465 printk(KERN_ERR "%s arlan_command card busy end \n", dev->name);
466 spin_unlock_irqrestore(&priv->lock, flags);
467 ARLAN_DEBUG_EXIT("arlan_command");
468 return 1;
469
470bad_end:
471 printk(KERN_ERR "%s arlan_command bad end \n", dev->name);
472
473 spin_unlock_irqrestore(&priv->lock, flags);
474 ARLAN_DEBUG_EXIT("arlan_command");
475
476 return -1;
477}
478
479static inline void arlan_command_process(struct net_device *dev)
480{
481 struct arlan_private *priv = netdev_priv(dev);
482
483 int times = 0;
484 while (priv->waiting_command_mask && times < 8)
485 {
486 if (priv->waiting_command_mask)
487 {
488 if (arlan_command(dev, 0))
489 break;
490 times++;
491 }
492 /* if long command, we won't repeat trying */ ;
493 if (priv->card_polling_interval > 1)
494 break;
495 times++;
496 }
497}
498
499
500static inline void arlan_retransmit_now(struct net_device *dev)
501{
502 struct arlan_private *priv = netdev_priv(dev);
503
504
505 ARLAN_DEBUG_ENTRY("arlan_retransmit_now");
506 if (TXLAST(dev).offset == 0)
507 {
508 if (TXHEAD(dev).offset)
509 {
510 priv->txLast = 0;
511 IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_DEBUG "TX buff switch to head \n");
512
513 }
514 else if (TXTAIL(dev).offset)
515 {
516 IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_DEBUG "TX buff switch to tail \n");
517 priv->txLast = 1;
518 }
519 else
520 IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "ReTransmit buff empty");
521 netif_wake_queue (dev);
522 return;
523
524 }
525 arlan_command(dev, ARLAN_COMMAND_TX);
526
527 priv->Conf->driverRetransmissions++;
528 priv->retransmissions++;
529
530 IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk("Retransmit %d bytes \n", TXLAST(dev).length);
531
532 ARLAN_DEBUG_EXIT("arlan_retransmit_now");
533}
534
535
536
537static void arlan_registration_timer(unsigned long data)
538{
539 struct net_device *dev = (struct net_device *) data;
540 struct arlan_private *priv = netdev_priv(dev);
541 int bh_mark_needed = 0;
542 int next_tick = 1;
543 long lostTime = ((long)jiffies - (long)priv->registrationLastSeen)
544 * (1000/HZ);
545
546 if (registrationBad(dev))
547 {
548 priv->registrationLostCount++;
549 if (lostTime > 7000 && lostTime < 7200)
550 {
551 printk(KERN_NOTICE "%s registration Lost \n", dev->name);
552 }
553 if (lostTime / priv->reRegisterExp > 2000)
554 arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_CONF);
555 if (lostTime / (priv->reRegisterExp) > 3500)
556 arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET);
557 if (priv->reRegisterExp < 400)
558 priv->reRegisterExp += 2;
559 if (lostTime > 7200)
560 {
561 next_tick = HZ;
562 arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET);
563 }
564 }
565 else
566 {
567 if (priv->Conf->registrationMode && lostTime > 10000 &&
568 priv->registrationLostCount)
569 {
570 printk(KERN_NOTICE "%s registration is back after %ld milliseconds\n",
571 dev->name, lostTime);
572 }
573 priv->registrationLastSeen = jiffies;
574 priv->registrationLostCount = 0;
575 priv->reRegisterExp = 1;
576 if (!netif_running(dev) )
577 netif_wake_queue(dev);
578 if (time_after(priv->tx_last_sent,priv->tx_last_cleared) &&
579 time_after(jiffies, priv->tx_last_sent * 5*HZ) ){
580 arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET);
581 priv->tx_last_cleared = jiffies;
582 }
583 }
584
585
586 if (!registrationBad(dev) && priv->ReTransmitRequested)
587 {
588 IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
589 printk(KERN_ERR "Retransmit from timer \n");
590 priv->ReTransmitRequested = 0;
591 arlan_retransmit_now(dev);
592 }
593 if (!registrationBad(dev) &&
594 time_after(jiffies, priv->tx_done_delayed) &&
595 priv->tx_done_delayed != 0)
596 {
597 TXLAST(dev).offset = 0;
598 if (priv->txLast)
599 priv->txLast = 0;
600 else if (TXTAIL(dev).offset)
601 priv->txLast = 1;
602 if (TXLAST(dev).offset)
603 {
604 arlan_retransmit_now(dev);
605 dev->trans_start = jiffies;
606 }
607 if (!(TXHEAD(dev).offset && TXTAIL(dev).offset))
608 {
609 netif_wake_queue (dev);
610 }
611 priv->tx_done_delayed = 0;
612 bh_mark_needed = 1;
613 }
614 if (bh_mark_needed)
615 {
616 netif_wake_queue (dev);
617 }
618 arlan_process_interrupt(dev);
619
620 if (next_tick < priv->card_polling_interval)
621 next_tick = priv->card_polling_interval;
622
623 priv->timer.expires = jiffies + next_tick;
624
625 add_timer(&priv->timer);
626}
627
628
629#ifdef ARLAN_DEBUGGING
630
631static void arlan_print_registers(struct net_device *dev, int line)
632{
633 struct arlan_private *priv = netdev_priv(dev);
634 volatile struct arlan_shmem *arlan = priv->card;
635
636 u_char hostcpuLock, lancpuLock, controlRegister, cntrlRegImage,
637 txStatus, rxStatus, interruptInProgress, commandByte;
638
639
640 ARLAN_DEBUG_ENTRY("arlan_print_registers");
641 READSHM(interruptInProgress, arlan->interruptInProgress, u_char);
642 READSHM(hostcpuLock, arlan->hostcpuLock, u_char);
643 READSHM(lancpuLock, arlan->lancpuLock, u_char);
644 READSHM(controlRegister, arlan->controlRegister, u_char);
645 READSHM(cntrlRegImage, arlan->cntrlRegImage, u_char);
646 READSHM(txStatus, arlan->txStatus, u_char);
647 READSHM(rxStatus, arlan->rxStatus, u_char);
648 READSHM(commandByte, arlan->commandByte, u_char);
649
650 printk(KERN_WARNING "line %04d IP %02x HL %02x LL %02x CB %02x CR %02x CRI %02x TX %02x RX %02x\n",
651 line, interruptInProgress, hostcpuLock, lancpuLock, commandByte,
652 controlRegister, cntrlRegImage, txStatus, rxStatus);
653
654 ARLAN_DEBUG_EXIT("arlan_print_registers");
655}
656#endif
657
658
659static int arlan_hw_tx(struct net_device *dev, char *buf, int length)
660{
661 int i;
662
663 struct arlan_private *priv = netdev_priv(dev);
664 volatile struct arlan_shmem __iomem *arlan = priv->card;
665 struct arlan_conf_stru *conf = priv->Conf;
666
667 int tailStarts = 0x800;
668 int headEnds = 0x0;
669
670
671 ARLAN_DEBUG_ENTRY("arlan_hw_tx");
672 if (TXHEAD(dev).offset)
673 headEnds = (((TXHEAD(dev).offset + TXHEAD(dev).length - offsetof(struct arlan_shmem, txBuffer)) / 64) + 1) * 64;
674 if (TXTAIL(dev).offset)
675 tailStarts = 0x800 - (((TXTAIL(dev).offset - offsetof(struct arlan_shmem, txBuffer)) / 64) + 2) * 64;
676
677
678 if (!TXHEAD(dev).offset && length < tailStarts)
679 {
680 IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
681 printk(KERN_ERR "TXHEAD insert, tailStart %d\n", tailStarts);
682
683 TXHEAD(dev).offset =
684 offsetof(struct arlan_shmem, txBuffer);
685 TXHEAD(dev).length = length - ARLAN_FAKE_HDR_LEN;
686 for (i = 0; i < 6; i++)
687 TXHEAD(dev).dest[i] = buf[i];
688 TXHEAD(dev).clear = conf->txClear;
689 TXHEAD(dev).retries = conf->txRetries; /* 0 is use default */
690 TXHEAD(dev).routing = conf->txRouting;
691 TXHEAD(dev).scrambled = conf->txScrambled;
692 memcpy_toio((char __iomem *)arlan + TXHEAD(dev).offset, buf + ARLAN_FAKE_HDR_LEN, TXHEAD(dev).length);
693 }
694 else if (!TXTAIL(dev).offset && length < (0x800 - headEnds))
695 {
696 IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
697 printk(KERN_ERR "TXTAIL insert, headEnd %d\n", headEnds);
698
699 TXTAIL(dev).offset =
700 offsetof(struct arlan_shmem, txBuffer) + 0x800 - (length / 64 + 2) * 64;
701 TXTAIL(dev).length = length - ARLAN_FAKE_HDR_LEN;
702 for (i = 0; i < 6; i++)
703 TXTAIL(dev).dest[i] = buf[i];
704 TXTAIL(dev).clear = conf->txClear;
705 TXTAIL(dev).retries = conf->txRetries;
706 TXTAIL(dev).routing = conf->txRouting;
707 TXTAIL(dev).scrambled = conf->txScrambled;
708 memcpy_toio(((char __iomem *)arlan + TXTAIL(dev).offset), buf + ARLAN_FAKE_HDR_LEN, TXTAIL(dev).length);
709 }
710 else
711 {
712 netif_stop_queue (dev);
713 IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
714 printk(KERN_ERR "TX TAIL & HEAD full, return, tailStart %d headEnd %d\n", tailStarts, headEnds);
715 return -1;
716 }
717 priv->out_bytes += length;
718 priv->out_bytes10 += length;
719 if (conf->measure_rate < 1)
720 conf->measure_rate = 1;
721 if (time_after(jiffies, priv->out_time + conf->measure_rate * HZ))
722 {
723 conf->out_speed = priv->out_bytes / conf->measure_rate;
724 priv->out_bytes = 0;
725 priv->out_time = jiffies;
726 }
727 if (time_after(jiffies, priv->out_time10 + conf->measure_rate * 10*HZ))
728 {
729 conf->out_speed10 = priv->out_bytes10 / (10 * conf->measure_rate);
730 priv->out_bytes10 = 0;
731 priv->out_time10 = jiffies;
732 }
733 if (TXHEAD(dev).offset && TXTAIL(dev).offset)
734 {
735 netif_stop_queue (dev);
736 return 0;
737 }
738 else
739 netif_start_queue (dev);
740
741
742 IFDEBUG(ARLAN_DEBUG_HEADER_DUMP)
743 printk(KERN_WARNING "%s Transmit t %2x:%2x:%2x:%2x:%2x:%2x f %2x:%2x:%2x:%2x:%2x:%2x \n", dev->name,
744 (unsigned char) buf[0], (unsigned char) buf[1], (unsigned char) buf[2], (unsigned char) buf[3],
745 (unsigned char) buf[4], (unsigned char) buf[5], (unsigned char) buf[6], (unsigned char) buf[7],
746 (unsigned char) buf[8], (unsigned char) buf[9], (unsigned char) buf[10], (unsigned char) buf[11]);
747
748 IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "TX command prepare for buffer %d\n", priv->txLast);
749
750 arlan_command(dev, ARLAN_COMMAND_TX);
751
752 priv->tx_last_sent = jiffies;
753
754 IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk("%s TX Qued %d bytes \n", dev->name, length);
755
756 ARLAN_DEBUG_EXIT("arlan_hw_tx");
757
758 return 0;
759}
760
761
762static int arlan_hw_config(struct net_device *dev)
763{
764 struct arlan_private *priv = netdev_priv(dev);
765 volatile struct arlan_shmem __iomem *arlan = priv->card;
766 struct arlan_conf_stru *conf = priv->Conf;
767
768 ARLAN_DEBUG_ENTRY("arlan_hw_config");
769
770 printk(KERN_NOTICE "%s arlan configure called \n", dev->name);
771 if (arlan_EEPROM_bad)
772 printk(KERN_NOTICE "arlan configure with eeprom bad option \n");
773
774
775 WRITESHM(arlan->spreadingCode, conf->spreadingCode, u_char);
776 WRITESHM(arlan->channelSet, conf->channelSet, u_char);
777
778 if (arlan_EEPROM_bad)
779 WRITESHM(arlan->defaultChannelSet, conf->channelSet, u_char);
780
781 WRITESHM(arlan->channelNumber, conf->channelNumber, u_char);
782
783 WRITESHM(arlan->scramblingDisable, conf->scramblingDisable, u_char);
784 WRITESHM(arlan->txAttenuation, conf->txAttenuation, u_char);
785
786 WRITESHM(arlan->systemId, conf->systemId, u_int);
787
788 WRITESHM(arlan->maxRetries, conf->maxRetries, u_char);
789 WRITESHM(arlan->receiveMode, conf->receiveMode, u_char);
790 WRITESHM(arlan->priority, conf->priority, u_char);
791 WRITESHM(arlan->rootOrRepeater, conf->rootOrRepeater, u_char);
792 WRITESHM(arlan->SID, conf->SID, u_int);
793
794 WRITESHM(arlan->registrationMode, conf->registrationMode, u_char);
795
796 WRITESHM(arlan->registrationFill, conf->registrationFill, u_char);
797 WRITESHM(arlan->localTalkAddress, conf->localTalkAddress, u_char);
798 WRITESHM(arlan->codeFormat, conf->codeFormat, u_char);
799 WRITESHM(arlan->numChannels, conf->numChannels, u_char);
800 WRITESHM(arlan->channel1, conf->channel1, u_char);
801 WRITESHM(arlan->channel2, conf->channel2, u_char);
802 WRITESHM(arlan->channel3, conf->channel3, u_char);
803 WRITESHM(arlan->channel4, conf->channel4, u_char);
804 WRITESHM(arlan->radioNodeId, conf->radioNodeId, u_short);
805 WRITESHM(arlan->SID, conf->SID, u_int);
806 WRITESHM(arlan->waitTime, conf->waitTime, u_short);
807 WRITESHM(arlan->lParameter, conf->lParameter, u_short);
808 memcpy_toio(&(arlan->_15), &(conf->_15), 3);
809 WRITESHM(arlan->_15, conf->_15, u_short);
810 WRITESHM(arlan->headerSize, conf->headerSize, u_short);
811 if (arlan_EEPROM_bad)
812 WRITESHM(arlan->hardwareType, conf->hardwareType, u_char);
813 WRITESHM(arlan->radioType, conf->radioType, u_char);
814 if (arlan_EEPROM_bad)
815 WRITESHM(arlan->radioModule, conf->radioType, u_char);
816
817 memcpy_toio(arlan->encryptionKey + keyStart, encryptionKey, 8);
818 memcpy_toio(arlan->name, conf->siteName, 16);
819
820 WRITESHMB(arlan->commandByte, ARLAN_COM_INT | ARLAN_COM_CONF); /* do configure */
821 memset_io(arlan->commandParameter, 0, 0xf); /* 0xf */
822 memset_io(arlan->commandParameter + 1, 0, 2);
823 if (conf->writeEEPROM)
824 {
825 memset_io(arlan->commandParameter, conf->writeEEPROM, 1);
826// conf->writeEEPROM=0;
827 }
828 if (conf->registrationMode && conf->registrationInterrupts)
829 memset_io(arlan->commandParameter + 3, 1, 1);
830 else
831 memset_io(arlan->commandParameter + 3, 0, 1);
832
833 priv->irq_test_done = 0;
834
835 if (conf->tx_queue_len)
836 dev->tx_queue_len = conf->tx_queue_len;
837 udelay(100);
838
839 ARLAN_DEBUG_EXIT("arlan_hw_config");
840 return 0;
841}
842
843
844static int arlan_read_card_configuration(struct net_device *dev)
845{
846 u_char tlx415;
847 struct arlan_private *priv = netdev_priv(dev);
848 volatile struct arlan_shmem __iomem *arlan = priv->card;
849 struct arlan_conf_stru *conf = priv->Conf;
850
851 ARLAN_DEBUG_ENTRY("arlan_read_card_configuration");
852
853 if (radioNodeId == radioNodeIdUNKNOWN)
854 {
855 READSHM(conf->radioNodeId, arlan->radioNodeId, u_short);
856 }
857 else
858 conf->radioNodeId = radioNodeId;
859
860 if (SID == SIDUNKNOWN)
861 {
862 READSHM(conf->SID, arlan->SID, u_int);
863 }
864 else conf->SID = SID;
865
866 if (spreadingCode == spreadingCodeUNKNOWN)
867 {
868 READSHM(conf->spreadingCode, arlan->spreadingCode, u_char);
869 }
870 else
871 conf->spreadingCode = spreadingCode;
872
873 if (channelSet == channelSetUNKNOWN)
874 {
875 READSHM(conf->channelSet, arlan->channelSet, u_char);
876 }
877 else conf->channelSet = channelSet;
878
879 if (channelNumber == channelNumberUNKNOWN)
880 {
881 READSHM(conf->channelNumber, arlan->channelNumber, u_char);
882 }
883 else conf->channelNumber = channelNumber;
884
885 READSHM(conf->scramblingDisable, arlan->scramblingDisable, u_char);
886 READSHM(conf->txAttenuation, arlan->txAttenuation, u_char);
887
888 if (systemId == systemIdUNKNOWN)
889 {
890 READSHM(conf->systemId, arlan->systemId, u_int);
891 }
892 else conf->systemId = systemId;
893
894 READSHM(conf->maxDatagramSize, arlan->maxDatagramSize, u_short);
895 READSHM(conf->maxFrameSize, arlan->maxFrameSize, u_short);
896 READSHM(conf->maxRetries, arlan->maxRetries, u_char);
897 READSHM(conf->receiveMode, arlan->receiveMode, u_char);
898 READSHM(conf->priority, arlan->priority, u_char);
899 READSHM(conf->rootOrRepeater, arlan->rootOrRepeater, u_char);
900
901 if (SID == SIDUNKNOWN)
902 {
903 READSHM(conf->SID, arlan->SID, u_int);
904 }
905 else conf->SID = SID;
906
907 if (registrationMode == registrationModeUNKNOWN)
908 {
909 READSHM(conf->registrationMode, arlan->registrationMode, u_char);
910 }
911 else conf->registrationMode = registrationMode;
912
913 READSHM(conf->registrationFill, arlan->registrationFill, u_char);
914 READSHM(conf->localTalkAddress, arlan->localTalkAddress, u_char);
915 READSHM(conf->codeFormat, arlan->codeFormat, u_char);
916 READSHM(conf->numChannels, arlan->numChannels, u_char);
917 READSHM(conf->channel1, arlan->channel1, u_char);
918 READSHM(conf->channel2, arlan->channel2, u_char);
919 READSHM(conf->channel3, arlan->channel3, u_char);
920 READSHM(conf->channel4, arlan->channel4, u_char);
921 READSHM(conf->waitTime, arlan->waitTime, u_short);
922 READSHM(conf->lParameter, arlan->lParameter, u_short);
923 READSHM(conf->_15, arlan->_15, u_short);
924 READSHM(conf->headerSize, arlan->headerSize, u_short);
925 READSHM(conf->hardwareType, arlan->hardwareType, u_char);
926 READSHM(conf->radioType, arlan->radioModule, u_char);
927
928 if (conf->radioType == 0)
929 conf->radioType = 0xc;
930
931 WRITESHM(arlan->configStatus, 0xA5, u_char);
932 READSHM(tlx415, arlan->configStatus, u_char);
933
934 if (tlx415 != 0xA5)
935 printk(KERN_INFO "%s tlx415 chip \n", dev->name);
936
937 conf->txClear = 0;
938 conf->txRetries = 1;
939 conf->txRouting = 1;
940 conf->txScrambled = 0;
941 conf->rxParameter = 1;
942 conf->txTimeoutMs = 4000;
943 conf->waitCardTimeout = 100000;
944 conf->receiveMode = ARLAN_RCV_CLEAN;
945 memcpy_fromio(conf->siteName, arlan->name, 16);
946 conf->siteName[16] = '\0';
947 conf->retries = retries;
948 conf->tx_delay_ms = tx_delay_ms;
949 conf->ReTransmitPacketMaxSize = 200;
950 conf->waitReTransmitPacketMaxSize = 200;
951 conf->txAckTimeoutMs = 900;
952 conf->fastReTransCount = 3;
953
954 ARLAN_DEBUG_EXIT("arlan_read_card_configuration");
955
956 return 0;
957}
958
959
960static int lastFoundAt = 0xbe000;
961
962
963/*
964 * This is the real probe routine. Linux has a history of friendly device
965 * probes on the ISA bus. A good device probes avoids doing writes, and
966 * verifies that the correct device exists and functions.
967 */
968#define ARLAN_SHMEM_SIZE 0x2000
969static int __init arlan_check_fingerprint(unsigned long memaddr)
970{
971 static const char probeText[] = "TELESYSTEM SLW INC. ARLAN \0";
972 volatile struct arlan_shmem __iomem *arlan = (struct arlan_shmem *) memaddr;
973 unsigned long paddr = virt_to_phys((void *) memaddr);
974 char tempBuf[49];
975
976 ARLAN_DEBUG_ENTRY("arlan_check_fingerprint");
977
978 if (!request_mem_region(paddr, ARLAN_SHMEM_SIZE, "arlan")) {
979 // printk(KERN_WARNING "arlan: memory region %lx excluded from probing \n",paddr);
980 return -ENODEV;
981 }
982
983 memcpy_fromio(tempBuf, arlan->textRegion, 29);
984 tempBuf[30] = 0;
985
986 /* check for card at this address */
987 if (0 != strncmp(tempBuf, probeText, 29)){
988 release_mem_region(paddr, ARLAN_SHMEM_SIZE);
989 return -ENODEV;
990 }
991
992// printk(KERN_INFO "arlan found at 0x%x \n",memaddr);
993 ARLAN_DEBUG_EXIT("arlan_check_fingerprint");
994
995 return 0;
996}
997
998static int arlan_change_mtu(struct net_device *dev, int new_mtu)
999{
1000 struct arlan_private *priv = netdev_priv(dev);
1001 struct arlan_conf_stru *conf = priv->Conf;
1002
1003 ARLAN_DEBUG_ENTRY("arlan_change_mtu");
1004 if (new_mtu > 2032)
1005 return -EINVAL;
1006 dev->mtu = new_mtu;
1007 if (new_mtu < 256)
1008 new_mtu = 256; /* cards book suggests 1600 */
1009 conf->maxDatagramSize = new_mtu;
1010 conf->maxFrameSize = new_mtu + 48;
1011
1012 arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_CONF);
1013 printk(KERN_NOTICE "%s mtu changed to %d \n", dev->name, new_mtu);
1014
1015 ARLAN_DEBUG_EXIT("arlan_change_mtu");
1016
1017 return 0;
1018}
1019
1020static int arlan_mac_addr(struct net_device *dev, void *p)
1021{
1022 struct sockaddr *addr = p;
1023
1024
1025 ARLAN_DEBUG_ENTRY("arlan_mac_addr");
1026 return -EINVAL;
1027
1028 if (!netif_running(dev))
1029 return -EBUSY;
1030 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
1031
1032 ARLAN_DEBUG_EXIT("arlan_mac_addr");
1033 return 0;
1034}
1035
1036
1037
1038static int __init arlan_setup_device(struct net_device *dev, int num)
1039{
1040 struct arlan_private *ap = netdev_priv(dev);
1041 int err;
1042
1043 ARLAN_DEBUG_ENTRY("arlan_setup_device");
1044
1045 ap->conf = (struct arlan_shmem *)(ap+1);
1046
1047 dev->tx_queue_len = tx_queue_len;
1048 dev->open = arlan_open;
1049 dev->stop = arlan_close;
1050 dev->hard_start_xmit = arlan_tx;
1051 dev->get_stats = arlan_statistics;
1052 dev->set_multicast_list = arlan_set_multicast;
1053 dev->change_mtu = arlan_change_mtu;
1054 dev->set_mac_address = arlan_mac_addr;
1055 dev->tx_timeout = arlan_tx_timeout;
1056 dev->watchdog_timeo = 3*HZ;
1057
1058 ap->irq_test_done = 0;
1059 ap->Conf = &arlan_conf[num];
1060
1061 ap->Conf->pre_Command_Wait = 40;
1062 ap->Conf->rx_tweak1 = 30;
1063 ap->Conf->rx_tweak2 = 0;
1064
1065
1066 err = register_netdev(dev);
1067 if (err) {
1068 release_mem_region(virt_to_phys((void *) dev->mem_start),
1069 ARLAN_SHMEM_SIZE);
1070 free_netdev(dev);
1071 return err;
1072 }
1073 arlan_device[num] = dev;
1074 ARLAN_DEBUG_EXIT("arlan_setup_device");
1075 return 0;
1076}
1077
1078static int __init arlan_probe_here(struct net_device *dev,
1079 unsigned long memaddr)
1080{
1081 struct arlan_private *ap = netdev_priv(dev);
1082
1083 ARLAN_DEBUG_ENTRY("arlan_probe_here");
1084
1085 if (arlan_check_fingerprint(memaddr))
1086 return -ENODEV;
1087
1088 printk(KERN_NOTICE "%s: Arlan found at %x, \n ", dev->name,
1089 (int) virt_to_phys((void*)memaddr));
1090
1091 ap->card = (void *) memaddr;
1092 dev->mem_start = memaddr;
1093 dev->mem_end = memaddr + ARLAN_SHMEM_SIZE-1;
1094
1095 if (dev->irq < 2)
1096 {
1097 READSHM(dev->irq, ap->card->irqLevel, u_char);
1098 } else if (dev->irq == 2)
1099 dev->irq = 9;
1100
1101 arlan_read_card_configuration(dev);
1102
1103 ARLAN_DEBUG_EXIT("arlan_probe_here");
1104 return 0;
1105}
1106
1107
1108static int arlan_open(struct net_device *dev)
1109{
1110 struct arlan_private *priv = netdev_priv(dev);
1111 volatile struct arlan_shmem __iomem *arlan = priv->card;
1112 int ret = 0;
1113
1114 ARLAN_DEBUG_ENTRY("arlan_open");
1115
1116 ret = request_irq(dev->irq, &arlan_interrupt, 0, dev->name, dev);
1117 if (ret)
1118 {
1119 printk(KERN_ERR "%s: unable to get IRQ %d .\n",
1120 dev->name, dev->irq);
1121 return ret;
1122 }
1123
1124
1125 priv->bad = 0;
1126 priv->lastReset = 0;
1127 priv->reset = 0;
1128 memcpy_fromio(dev->dev_addr, arlan->lanCardNodeId, 6);
1129 memset(dev->broadcast, 0xff, 6);
1130 dev->tx_queue_len = tx_queue_len;
1131 priv->interrupt_processing_active = 0;
1132 spin_lock_init(&priv->lock);
1133
1134 netif_start_queue (dev);
1135
1136 priv->registrationLostCount = 0;
1137 priv->registrationLastSeen = jiffies;
1138 priv->txLast = 0;
1139 priv->tx_command_given = 0;
1140 priv->rx_command_given = 0;
1141
1142 priv->reRegisterExp = 1;
1143 priv->tx_last_sent = jiffies - 1;
1144 priv->tx_last_cleared = jiffies;
1145 priv->Conf->writeEEPROM = 0;
1146 priv->Conf->registrationInterrupts = 1;
1147
1148 init_timer(&priv->timer);
1149 priv->timer.expires = jiffies + HZ / 10;
1150 priv->timer.data = (unsigned long) dev;
1151 priv->timer.function = &arlan_registration_timer; /* timer handler */
1152
1153 arlan_command(dev, ARLAN_COMMAND_POWERUP | ARLAN_COMMAND_LONG_WAIT_NOW);
1154 mdelay(200);
1155 add_timer(&priv->timer);
1156
1157 ARLAN_DEBUG_EXIT("arlan_open");
1158 return 0;
1159}
1160
1161
1162static void arlan_tx_timeout (struct net_device *dev)
1163{
1164 printk(KERN_ERR "%s: arlan transmit timed out, kernel decided\n", dev->name);
1165 /* Try to restart the adaptor. */
1166 arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET);
1167 // dev->trans_start = jiffies;
1168 // netif_start_queue (dev);
1169}
1170
1171
1172static int arlan_tx(struct sk_buff *skb, struct net_device *dev)
1173{
1174 short length;
1175 unsigned char *buf;
1176
1177 ARLAN_DEBUG_ENTRY("arlan_tx");
1178
1179 length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1180 buf = skb->data;
1181
1182 if (length + 0x12 > 0x800) {
1183 printk(KERN_ERR "TX RING overflow \n");
1184 netif_stop_queue (dev);
1185 }
1186
1187 if (arlan_hw_tx(dev, buf, length) == -1)
1188 goto bad_end;
1189
1190 dev->trans_start = jiffies;
1191
1192 dev_kfree_skb(skb);
1193
1194 arlan_process_interrupt(dev);
1195 ARLAN_DEBUG_EXIT("arlan_tx");
1196 return 0;
1197
1198bad_end:
1199 arlan_process_interrupt(dev);
1200 netif_stop_queue (dev);
1201 ARLAN_DEBUG_EXIT("arlan_tx");
1202 return 1;
1203}
1204
1205
1206static inline int DoNotReTransmitCrap(struct net_device *dev)
1207{
1208 struct arlan_private *priv = netdev_priv(dev);
1209
1210 if (TXLAST(dev).length < priv->Conf->ReTransmitPacketMaxSize)
1211 return 1;
1212 return 0;
1213
1214}
1215
1216static inline int DoNotWaitReTransmitCrap(struct net_device *dev)
1217{
1218 struct arlan_private *priv = netdev_priv(dev);
1219
1220 if (TXLAST(dev).length < priv->Conf->waitReTransmitPacketMaxSize)
1221 return 1;
1222 return 0;
1223}
1224
1225static inline void arlan_queue_retransmit(struct net_device *dev)
1226{
1227 struct arlan_private *priv = netdev_priv(dev);
1228
1229 ARLAN_DEBUG_ENTRY("arlan_queue_retransmit");
1230
1231 if (DoNotWaitReTransmitCrap(dev))
1232 {
1233 arlan_drop_tx(dev);
1234 } else
1235 priv->ReTransmitRequested++;
1236
1237 ARLAN_DEBUG_EXIT("arlan_queue_retransmit");
1238}
1239
1240static inline void RetryOrFail(struct net_device *dev)
1241{
1242 struct arlan_private *priv = netdev_priv(dev);
1243
1244 ARLAN_DEBUG_ENTRY("RetryOrFail");
1245
1246 if (priv->retransmissions > priv->Conf->retries ||
1247 DoNotReTransmitCrap(dev))
1248 {
1249 arlan_drop_tx(dev);
1250 }
1251 else if (priv->bad <= priv->Conf->fastReTransCount)
1252 {
1253 arlan_retransmit_now(dev);
1254 }
1255 else arlan_queue_retransmit(dev);
1256
1257 ARLAN_DEBUG_EXIT("RetryOrFail");
1258}
1259
1260
1261static void arlan_tx_done_interrupt(struct net_device *dev, int status)
1262{
1263 struct arlan_private *priv = netdev_priv(dev);
1264
1265 ARLAN_DEBUG_ENTRY("arlan_tx_done_interrupt");
1266
1267 priv->tx_last_cleared = jiffies;
1268 priv->tx_command_given = 0;
1269 switch (status)
1270 {
1271 case 1:
1272 {
1273 IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
1274 printk("arlan intr: transmit OK\n");
1275 priv->stats.tx_packets++;
1276 priv->bad = 0;
1277 priv->reset = 0;
1278 priv->retransmissions = 0;
1279 if (priv->Conf->tx_delay_ms)
1280 {
1281 priv->tx_done_delayed = jiffies + (priv->Conf->tx_delay_ms * HZ) / 1000 + 1;
1282 }
1283 else
1284 {
1285 TXLAST(dev).offset = 0;
1286 if (priv->txLast)
1287 priv->txLast = 0;
1288 else if (TXTAIL(dev).offset)
1289 priv->txLast = 1;
1290 if (TXLAST(dev).offset)
1291 {
1292 arlan_retransmit_now(dev);
1293 dev->trans_start = jiffies;
1294 }
1295 if (!TXHEAD(dev).offset || !TXTAIL(dev).offset)
1296 {
1297 netif_wake_queue (dev);
1298 }
1299 }
1300 }
1301 break;
1302
1303 case 2:
1304 {
1305 IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
1306 printk("arlan intr: transmit timed out\n");
1307 priv->bad += 1;
1308 //arlan_queue_retransmit(dev);
1309 RetryOrFail(dev);
1310 }
1311 break;
1312
1313 case 3:
1314 {
1315 IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
1316 printk("arlan intr: transmit max retries\n");
1317 priv->bad += 1;
1318 priv->reset = 0;
1319 //arlan_queue_retransmit(dev);
1320 RetryOrFail(dev);
1321 }
1322 break;
1323
1324 case 4:
1325 {
1326 IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
1327 printk("arlan intr: transmit aborted\n");
1328 priv->bad += 1;
1329 arlan_queue_retransmit(dev);
1330 //RetryOrFail(dev);
1331 }
1332 break;
1333
1334 case 5:
1335 {
1336 IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
1337 printk("arlan intr: transmit not registered\n");
1338 priv->bad += 1;
1339 //debug=101;
1340 arlan_queue_retransmit(dev);
1341 }
1342 break;
1343
1344 case 6:
1345 {
1346 IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
1347 printk("arlan intr: transmit destination full\n");
1348 priv->bad += 1;
1349 priv->reset = 0;
1350 //arlan_drop_tx(dev);
1351 arlan_queue_retransmit(dev);
1352 }
1353 break;
1354
1355 case 7:
1356 {
1357 IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
1358 printk("arlan intr: transmit unknown ack\n");
1359 priv->bad += 1;
1360 priv->reset = 0;
1361 arlan_queue_retransmit(dev);
1362 }
1363 break;
1364
1365 case 8:
1366 {
1367 IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
1368 printk("arlan intr: transmit dest mail box full\n");
1369 priv->bad += 1;
1370 priv->reset = 0;
1371 //arlan_drop_tx(dev);
1372 arlan_queue_retransmit(dev);
1373 }
1374 break;
1375
1376 case 9:
1377 {
1378 IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
1379 printk("arlan intr: transmit root dest not reg.\n");
1380 priv->bad += 1;
1381 priv->reset = 1;
1382 //arlan_drop_tx(dev);
1383 arlan_queue_retransmit(dev);
1384 }
1385 break;
1386
1387 default:
1388 {
1389 printk(KERN_ERR "arlan intr: transmit status unknown\n");
1390 priv->bad += 1;
1391 priv->reset = 1;
1392 arlan_drop_tx(dev);
1393 }
1394 }
1395
1396 ARLAN_DEBUG_EXIT("arlan_tx_done_interrupt");
1397}
1398
1399
1400static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short rxOffset, u_short pkt_len)
1401{
1402 char *skbtmp;
1403 int i = 0;
1404
1405 struct arlan_private *priv = netdev_priv(dev);
1406 volatile struct arlan_shmem __iomem *arlan = priv->card;
1407 struct arlan_conf_stru *conf = priv->Conf;
1408
1409
1410 ARLAN_DEBUG_ENTRY("arlan_rx_interrupt");
1411 // by spec, not WRITESHMB(arlan->rxStatus,0x00);
1412 // prohibited here arlan_command(dev, ARLAN_COMMAND_RX);
1413
1414 if (pkt_len < 10 || pkt_len > 2048)
1415 {
1416 printk(KERN_WARNING "%s: got too short or long packet, len %d \n", dev->name, pkt_len);
1417 return;
1418 }
1419 if (rxOffset + pkt_len > 0x2000)
1420 {
1421 printk("%s: got too long packet, len %d offset %x\n", dev->name, pkt_len, rxOffset);
1422 return;
1423 }
1424 priv->in_bytes += pkt_len;
1425 priv->in_bytes10 += pkt_len;
1426 if (conf->measure_rate < 1)
1427 conf->measure_rate = 1;
1428 if (time_after(jiffies, priv->in_time + conf->measure_rate * HZ))
1429 {
1430 conf->in_speed = priv->in_bytes / conf->measure_rate;
1431 priv->in_bytes = 0;
1432 priv->in_time = jiffies;
1433 }
1434 if (time_after(jiffies, priv->in_time10 + conf->measure_rate * 10*HZ))
1435 {
1436 conf->in_speed10 = priv->in_bytes10 / (10 * conf->measure_rate);
1437 priv->in_bytes10 = 0;
1438 priv->in_time10 = jiffies;
1439 }
1440 DEBUGSHM(1, "arlan rcv pkt rxStatus= %d ", arlan->rxStatus, u_char);
1441 switch (rxStatus)
1442 {
1443 case 1:
1444 case 2:
1445 case 3:
1446 {
1447 /* Malloc up new buffer. */
1448 struct sk_buff *skb;
1449
1450 DEBUGSHM(50, "arlan recv pkt offs=%d\n", arlan->rxOffset, u_short);
1451 DEBUGSHM(1, "arlan rxFrmType = %d \n", arlan->rxFrmType, u_char);
1452 DEBUGSHM(1, KERN_INFO "arlan rx scrambled = %d \n", arlan->scrambled, u_char);
1453
1454 /* here we do multicast filtering to avoid slow 8-bit memcopy */
1455#ifdef ARLAN_MULTICAST
1456 if (!(dev->flags & IFF_ALLMULTI) &&
1457 !(dev->flags & IFF_PROMISC) &&
1458 dev->mc_list)
1459 {
1460 char hw_dst_addr[6];
1461 struct dev_mc_list *dmi = dev->mc_list;
1462 int i;
1463
1464 memcpy_fromio(hw_dst_addr, arlan->ultimateDestAddress, 6);
1465 if (hw_dst_addr[0] == 0x01)
1466 {
1467 if (mdebug)
1468 if (hw_dst_addr[1] == 0x00)
1469 printk(KERN_ERR "%s mcast 0x0100 \n", dev->name);
1470 else if (hw_dst_addr[1] == 0x40)
1471 printk(KERN_ERR "%s m/bcast 0x0140 \n", dev->name);
1472 while (dmi)
1473 { if (dmi->dmi_addrlen == 6)
1474 {
1475 if (arlan_debug & ARLAN_DEBUG_HEADER_DUMP)
1476 printk(KERN_ERR "%s mcl %2x:%2x:%2x:%2x:%2x:%2x \n", dev->name,
1477 dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2],
1478 dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]);
1479 for (i = 0; i < 6; i++)
1480 if (dmi->dmi_addr[i] != hw_dst_addr[i])
1481 break;
1482 if (i == 6)
1483 break;
1484 }
1485 else
1486 printk(KERN_ERR "%s: invalid multicast address length given.\n", dev->name);
1487 dmi = dmi->next;
1488 }
1489 /* we reach here if multicast filtering is on and packet
1490 * is multicast and not for receive */
1491 goto end_of_interrupt;
1492 }
1493 }
1494#endif // ARLAN_MULTICAST
1495 /* multicast filtering ends here */
1496 pkt_len += ARLAN_FAKE_HDR_LEN;
1497
1498 skb = dev_alloc_skb(pkt_len + 4);
1499 if (skb == NULL)
1500 {
1501 printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name);
1502 priv->stats.rx_dropped++;
1503 break;
1504 }
1505 skb_reserve(skb, 2);
1506 skb->dev = dev;
1507 skbtmp = skb_put(skb, pkt_len);
1508
1509 memcpy_fromio(skbtmp + ARLAN_FAKE_HDR_LEN, ((char __iomem *) arlan) + rxOffset, pkt_len - ARLAN_FAKE_HDR_LEN);
1510 memcpy_fromio(skbtmp, arlan->ultimateDestAddress, 6);
1511 memcpy_fromio(skbtmp + 6, arlan->rxSrc, 6);
1512 WRITESHMB(arlan->rxStatus, 0x00);
1513 arlan_command(dev, ARLAN_COMMAND_RX);
1514
1515 IFDEBUG(ARLAN_DEBUG_HEADER_DUMP)
1516 {
1517 char immedDestAddress[6];
1518 char immedSrcAddress[6];
1519 memcpy_fromio(immedDestAddress, arlan->immedDestAddress, 6);
1520 memcpy_fromio(immedSrcAddress, arlan->immedSrcAddress, 6);
1521
1522 printk(KERN_WARNING "%s t %2x:%2x:%2x:%2x:%2x:%2x f %2x:%2x:%2x:%2x:%2x:%2x imd %2x:%2x:%2x:%2x:%2x:%2x ims %2x:%2x:%2x:%2x:%2x:%2x\n", dev->name,
1523 (unsigned char) skbtmp[0], (unsigned char) skbtmp[1], (unsigned char) skbtmp[2], (unsigned char) skbtmp[3],
1524 (unsigned char) skbtmp[4], (unsigned char) skbtmp[5], (unsigned char) skbtmp[6], (unsigned char) skbtmp[7],
1525 (unsigned char) skbtmp[8], (unsigned char) skbtmp[9], (unsigned char) skbtmp[10], (unsigned char) skbtmp[11],
1526 immedDestAddress[0], immedDestAddress[1], immedDestAddress[2],
1527 immedDestAddress[3], immedDestAddress[4], immedDestAddress[5],
1528 immedSrcAddress[0], immedSrcAddress[1], immedSrcAddress[2],
1529 immedSrcAddress[3], immedSrcAddress[4], immedSrcAddress[5]);
1530 }
1531 skb->protocol = eth_type_trans(skb, dev);
1532 IFDEBUG(ARLAN_DEBUG_HEADER_DUMP)
1533 if (skb->protocol != 0x608 && skb->protocol != 0x8)
1534 {
1535 for (i = 0; i <= 22; i++)
1536 printk("%02x:", (u_char) skbtmp[i + 12]);
1537 printk(KERN_ERR "\n");
1538 printk(KERN_WARNING "arlan kernel pkt type trans %x \n", skb->protocol);
1539 }
1540 netif_rx(skb);
1541 dev->last_rx = jiffies;
1542 priv->stats.rx_packets++;
1543 priv->stats.rx_bytes += pkt_len;
1544 }
1545 break;
1546
1547 default:
1548 printk(KERN_ERR "arlan intr: received unknown status\n");
1549 priv->stats.rx_crc_errors++;
1550 break;
1551 }
1552 ARLAN_DEBUG_EXIT("arlan_rx_interrupt");
1553}
1554
1555static void arlan_process_interrupt(struct net_device *dev)
1556{
1557 struct arlan_private *priv = netdev_priv(dev);
1558 volatile struct arlan_shmem __iomem *arlan = priv->card;
1559 u_char rxStatus = READSHMB(arlan->rxStatus);
1560 u_char txStatus = READSHMB(arlan->txStatus);
1561 u_short rxOffset = READSHMS(arlan->rxOffset);
1562 u_short pkt_len = READSHMS(arlan->rxLength);
1563 int interrupt_count = 0;
1564
1565 ARLAN_DEBUG_ENTRY("arlan_process_interrupt");
1566
1567 if (test_and_set_bit(0, (void *) &priv->interrupt_processing_active))
1568 {
1569 if (arlan_debug & ARLAN_DEBUG_CHAIN_LOCKS)
1570 printk(KERN_ERR "interrupt chain reentering \n");
1571 goto end_int_process;
1572 }
1573 while ((rxStatus || txStatus || priv->interrupt_ack_requested)
1574 && (interrupt_count < 5))
1575 {
1576 if (rxStatus)
1577 priv->last_rx_int_ack_time = jiffies;
1578
1579 arlan_command(dev, ARLAN_COMMAND_INT_ACK);
1580 arlan_command(dev, ARLAN_COMMAND_INT_ENABLE);
1581
1582 IFDEBUG(ARLAN_DEBUG_INTERRUPT)
1583 printk(KERN_ERR "%s: got IRQ rx %x tx %x comm %x rxOff %x rxLen %x \n",
1584 dev->name, rxStatus, txStatus, READSHMB(arlan->commandByte),
1585 rxOffset, pkt_len);
1586
1587 if (rxStatus == 0 && txStatus == 0)
1588 {
1589 if (priv->irq_test_done)
1590 {
1591 if (!registrationBad(dev))
1592 IFDEBUG(ARLAN_DEBUG_INTERRUPT) printk(KERN_ERR "%s unknown interrupt(nop? regLost ?) reason tx %d rx %d ",
1593 dev->name, txStatus, rxStatus);
1594 } else {
1595 IFDEBUG(ARLAN_DEBUG_INTERRUPT)
1596 printk(KERN_INFO "%s irq $%d test OK \n", dev->name, dev->irq);
1597
1598 }
1599 priv->interrupt_ack_requested = 0;
1600 goto ends;
1601 }
1602 if (txStatus != 0)
1603 {
1604 WRITESHMB(arlan->txStatus, 0x00);
1605 arlan_tx_done_interrupt(dev, txStatus);
1606 goto ends;
1607 }
1608 if (rxStatus == 1 || rxStatus == 2)
1609 { /* a packet waiting */
1610 arlan_rx_interrupt(dev, rxStatus, rxOffset, pkt_len);
1611 goto ends;
1612 }
1613 if (rxStatus > 2 && rxStatus < 0xff)
1614 {
1615 WRITESHMB(arlan->rxStatus, 0x00);
1616 printk(KERN_ERR "%s unknown rxStatus reason tx %d rx %d ",
1617 dev->name, txStatus, rxStatus);
1618 goto ends;
1619 }
1620 if (rxStatus == 0xff)
1621 {
1622 WRITESHMB(arlan->rxStatus, 0x00);
1623 arlan_command(dev, ARLAN_COMMAND_RX);
1624 if (registrationBad(dev))
1625 netif_device_detach(dev);
1626 if (!registrationBad(dev))
1627 {
1628 priv->registrationLastSeen = jiffies;
1629 if (!netif_queue_stopped(dev) && !priv->under_reset && !priv->under_config)
1630 netif_wake_queue (dev);
1631 }
1632 goto ends;
1633 }
1634ends:
1635
1636 arlan_command_process(dev);
1637
1638 rxStatus = READSHMB(arlan->rxStatus);
1639 txStatus = READSHMB(arlan->txStatus);
1640 rxOffset = READSHMS(arlan->rxOffset);
1641 pkt_len = READSHMS(arlan->rxLength);
1642
1643
1644 priv->irq_test_done = 1;
1645
1646 interrupt_count++;
1647 }
1648 priv->interrupt_processing_active = 0;
1649
1650end_int_process:
1651 arlan_command_process(dev);
1652
1653 ARLAN_DEBUG_EXIT("arlan_process_interrupt");
1654 return;
1655}
1656
1657static irqreturn_t arlan_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1658{
1659 struct net_device *dev = dev_id;
1660 struct arlan_private *priv = netdev_priv(dev);
1661 volatile struct arlan_shmem __iomem *arlan = priv->card;
1662 u_char rxStatus = READSHMB(arlan->rxStatus);
1663 u_char txStatus = READSHMB(arlan->txStatus);
1664
1665 ARLAN_DEBUG_ENTRY("arlan_interrupt");
1666
1667
1668 if (!rxStatus && !txStatus)
1669 priv->interrupt_ack_requested++;
1670
1671 arlan_process_interrupt(dev);
1672
1673 priv->irq_test_done = 1;
1674
1675 ARLAN_DEBUG_EXIT("arlan_interrupt");
1676 return IRQ_HANDLED;
1677
1678}
1679
1680
1681static int arlan_close(struct net_device *dev)
1682{
1683 struct arlan_private *priv = netdev_priv(dev);
1684
1685 ARLAN_DEBUG_ENTRY("arlan_close");
1686
1687 del_timer_sync(&priv->timer);
1688
1689 arlan_command(dev, ARLAN_COMMAND_POWERDOWN);
1690
1691 IFDEBUG(ARLAN_DEBUG_STARTUP)
1692 printk(KERN_NOTICE "%s: Closing device\n", dev->name);
1693
1694 netif_stop_queue(dev);
1695 free_irq(dev->irq, dev);
1696
1697 ARLAN_DEBUG_EXIT("arlan_close");
1698 return 0;
1699}
1700
1701#ifdef ARLAN_DEBUGGING
1702static long alignLong(volatile u_char * ptr)
1703{
1704 long ret;
1705 memcpy_fromio(&ret, (void *) ptr, 4);
1706 return ret;
1707}
1708#endif
1709
1710/*
1711 * Get the current statistics.
1712 * This may be called with the card open or closed.
1713 */
1714
1715static struct net_device_stats *arlan_statistics(struct net_device *dev)
1716{
1717 struct arlan_private *priv = netdev_priv(dev);
1718 volatile struct arlan_shmem __iomem *arlan = priv->card;
1719
1720
1721 ARLAN_DEBUG_ENTRY("arlan_statistics");
1722
1723 /* Update the statistics from the device registers. */
1724
1725 READSHM(priv->stats.collisions, arlan->numReTransmissions, u_int);
1726 READSHM(priv->stats.rx_crc_errors, arlan->numCRCErrors, u_int);
1727 READSHM(priv->stats.rx_dropped, arlan->numFramesDiscarded, u_int);
1728 READSHM(priv->stats.rx_fifo_errors, arlan->numRXBufferOverflows, u_int);
1729 READSHM(priv->stats.rx_frame_errors, arlan->numReceiveFramesLost, u_int);
1730 READSHM(priv->stats.rx_over_errors, arlan->numRXOverruns, u_int);
1731 READSHM(priv->stats.rx_packets, arlan->numDatagramsReceived, u_int);
1732 READSHM(priv->stats.tx_aborted_errors, arlan->numAbortErrors, u_int);
1733 READSHM(priv->stats.tx_carrier_errors, arlan->numStatusTimeouts, u_int);
1734 READSHM(priv->stats.tx_dropped, arlan->numDatagramsDiscarded, u_int);
1735 READSHM(priv->stats.tx_fifo_errors, arlan->numTXUnderruns, u_int);
1736 READSHM(priv->stats.tx_packets, arlan->numDatagramsTransmitted, u_int);
1737 READSHM(priv->stats.tx_window_errors, arlan->numHoldOffs, u_int);
1738
1739 ARLAN_DEBUG_EXIT("arlan_statistics");
1740
1741 return &priv->stats;
1742}
1743
1744
1745static void arlan_set_multicast(struct net_device *dev)
1746{
1747 struct arlan_private *priv = netdev_priv(dev);
1748 volatile struct arlan_shmem __iomem *arlan = priv->card;
1749 struct arlan_conf_stru *conf = priv->Conf;
1750 int board_conf_needed = 0;
1751
1752
1753 ARLAN_DEBUG_ENTRY("arlan_set_multicast");
1754
1755 if (dev->flags & IFF_PROMISC)
1756 {
1757 unsigned char recMode;
1758 READSHM(recMode, arlan->receiveMode, u_char);
1759 conf->receiveMode = (ARLAN_RCV_PROMISC | ARLAN_RCV_CONTROL);
1760 if (conf->receiveMode != recMode)
1761 board_conf_needed = 1;
1762 }
1763 else
1764 {
1765 /* turn off promiscuous mode */
1766 unsigned char recMode;
1767 READSHM(recMode, arlan->receiveMode, u_char);
1768 conf->receiveMode = ARLAN_RCV_CLEAN | ARLAN_RCV_CONTROL;
1769 if (conf->receiveMode != recMode)
1770 board_conf_needed = 1;
1771 }
1772 if (board_conf_needed)
1773 arlan_command(dev, ARLAN_COMMAND_CONF);
1774
1775 ARLAN_DEBUG_EXIT("arlan_set_multicast");
1776}
1777
1778
1779struct net_device * __init arlan_probe(int unit)
1780{
1781 struct net_device *dev;
1782 int err;
1783 int m;
1784
1785 ARLAN_DEBUG_ENTRY("arlan_probe");
1786
1787 if (arlans_found == MAX_ARLANS)
1788 return ERR_PTR(-ENODEV);
1789
1790 /*
1791 * Reserve space for local data and a copy of the shared memory
1792 * that is used by the /proc interface.
1793 */
1794 dev = alloc_etherdev(sizeof(struct arlan_private)
1795 + sizeof(struct arlan_shmem));
1796 if (!dev)
1797 return ERR_PTR(-ENOMEM);
1798
1799 SET_MODULE_OWNER(dev);
1800
1801 if (unit >= 0) {
1802 sprintf(dev->name, "eth%d", unit);
1803 netdev_boot_setup_check(dev);
1804
1805 if (dev->mem_start) {
1806 if (arlan_probe_here(dev, dev->mem_start) == 0)
1807 goto found;
1808 goto not_found;
1809 }
1810
1811 }
1812
1813
1814 for (m = (int)phys_to_virt(lastFoundAt) + ARLAN_SHMEM_SIZE;
1815 m <= (int)phys_to_virt(0xDE000);
1816 m += ARLAN_SHMEM_SIZE)
1817 {
1818 if (arlan_probe_here(dev, m) == 0)
1819 {
1820 lastFoundAt = (int)virt_to_phys((void*)m);
1821 goto found;
1822 }
1823 }
1824
1825 if (lastFoundAt == 0xbe000)
1826 printk(KERN_ERR "arlan: No Arlan devices found \n");
1827
1828 not_found:
1829 free_netdev(dev);
1830 return ERR_PTR(-ENODEV);
1831
1832 found:
1833 err = arlan_setup_device(dev, arlans_found);
1834 if (err)
1835 dev = ERR_PTR(err);
1836 else if (!arlans_found++)
1837 printk(KERN_INFO "Arlan driver %s\n", arlan_version);
1838
1839 return dev;
1840}
1841
1842#ifdef MODULE
1843int init_module(void)
1844{
1845 int i = 0;
1846
1847 ARLAN_DEBUG_ENTRY("init_module");
1848
1849 if (channelSet != channelSetUNKNOWN || channelNumber != channelNumberUNKNOWN || systemId != systemIdUNKNOWN)
1850 return -EINVAL;
1851
1852 for (i = 0; i < MAX_ARLANS; i++) {
1853 struct net_device *dev = arlan_probe(i);
1854
1855 if (IS_ERR(dev))
1856 return PTR_ERR(dev);
1857 }
1858 init_arlan_proc();
1859 printk(KERN_INFO "Arlan driver %s\n", arlan_version);
1860 ARLAN_DEBUG_EXIT("init_module");
1861 return 0;
1862}
1863
1864
1865void cleanup_module(void)
1866{
1867 int i = 0;
1868 struct net_device *dev;
1869
1870 ARLAN_DEBUG_ENTRY("cleanup_module");
1871
1872 IFDEBUG(ARLAN_DEBUG_SHUTDOWN)
1873 printk(KERN_INFO "arlan: unloading module\n");
1874
1875 cleanup_arlan_proc();
1876
1877 for (i = 0; i < MAX_ARLANS; i++)
1878 {
1879 dev = arlan_device[i];
1880 if (dev) {
1881 arlan_command(dev, ARLAN_COMMAND_POWERDOWN );
1882
1883 unregister_netdev(dev);
1884 release_mem_region(virt_to_phys((void *) dev->mem_start),
1885 ARLAN_SHMEM_SIZE);
1886 free_netdev(dev);
1887 arlan_device[i] = NULL;
1888 }
1889 }
1890
1891 ARLAN_DEBUG_EXIT("cleanup_module");
1892}
1893
1894
1895#endif
1896MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/arlan-proc.c b/drivers/net/wireless/arlan-proc.c
new file mode 100644
index 000000000000..a2cca521f444
--- /dev/null
+++ b/drivers/net/wireless/arlan-proc.c
@@ -0,0 +1,1262 @@
1#include <linux/config.h>
2#include "arlan.h"
3
4#include <linux/sysctl.h>
5
6#ifdef CONFIG_PROC_FS
7
8/* void enableReceive(struct net_device* dev);
9*/
10
11
12
13#define ARLAN_STR_SIZE 0x2ff0
14#define DEV_ARLAN_INFO 1
15#define DEV_ARLAN 1
16#define SARLG(type,var) {\
17 pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n", #var, READSHMB(priva->card->var)); \
18 }
19
20#define SARLBN(type,var,nn) {\
21 pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x",#var);\
22 for (i=0; i < nn; i++ ) pos += sprintf(arlan_drive_info+pos, "%02x",READSHMB(priva->card->var[i]));\
23 pos += sprintf(arlan_drive_info+pos, "\n"); \
24 }
25
26#define SARLBNpln(type,var,nn) {\
27 for (i=0; i < nn; i++ ) pos += sprintf(arlan_drive_info+pos, "%02x",READSHMB(priva->card->var[i]));\
28 }
29
30#define SARLSTR(var,nn) {\
31 char tmpStr[400];\
32 int tmpLn = nn;\
33 if (nn > 399 ) tmpLn = 399; \
34 memcpy(tmpStr,(char *) priva->conf->var,tmpLn);\
35 tmpStr[tmpLn] = 0; \
36 pos += sprintf(arlan_drive_info+pos, "%s\t=\t%s \n",#var,priva->conf->var);\
37 }
38
39#define SARLUC(var) SARLG(u_char, var)
40#define SARLUCN(var,nn) SARLBN(u_char,var, nn)
41#define SARLUS(var) SARLG(u_short, var)
42#define SARLUSN(var,nn) SARLBN(u_short,var, nn)
43#define SARLUI(var) SARLG(u_int, var)
44
45#define SARLUSA(var) {\
46 u_short tmpVar;\
47 memcpy(&tmpVar, (short *) priva->conf->var,2); \
48 pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n",#var, tmpVar);\
49}
50
51#define SARLUIA(var) {\
52 u_int tmpVar;\
53 memcpy(&tmpVar, (int* )priva->conf->var,4); \
54 pos += sprintf(arlan_drive_info+pos, "%s\t=\t0x%x\n",#var, tmpVar);\
55}
56
57
58static const char *arlan_diagnostic_info_string(struct net_device *dev)
59{
60
61 struct arlan_private *priv = netdev_priv(dev);
62 volatile struct arlan_shmem __iomem *arlan = priv->card;
63 u_char diagnosticInfo;
64
65 READSHM(diagnosticInfo, arlan->diagnosticInfo, u_char);
66
67 switch (diagnosticInfo)
68 {
69 case 0xFF:
70 return "Diagnostic info is OK";
71 case 0xFE:
72 return "ERROR EPROM Checksum error ";
73 case 0xFD:
74 return "ERROR Local Ram Test Failed ";
75 case 0xFC:
76 return "ERROR SCC failure ";
77 case 0xFB:
78 return "ERROR BackBone failure ";
79 case 0xFA:
80 return "ERROR transceiver not found ";
81 case 0xF9:
82 return "ERROR no more address space ";
83 case 0xF8:
84 return "ERROR Checksum error ";
85 case 0xF7:
86 return "ERROR Missing SS Code";
87 case 0xF6:
88 return "ERROR Invalid config format";
89 case 0xF5:
90 return "ERROR Reserved errorcode F5";
91 case 0xF4:
92 return "ERROR Invalid spreading code/channel number";
93 case 0xF3:
94 return "ERROR Load Code Error";
95 case 0xF2:
96 return "ERROR Reserver errorcode F2 ";
97 case 0xF1:
98 return "ERROR Invalid command receivec by LAN card ";
99 case 0xF0:
100 return "ERROR Invalid parameter found in command ";
101 case 0xEF:
102 return "ERROR On-chip timer failure ";
103 case 0xEE:
104 return "ERROR T410 timer failure ";
105 case 0xED:
106 return "ERROR Too Many TxEnable commands ";
107 case 0xEC:
108 return "ERROR EEPROM error on radio module ";
109 default:
110 return "ERROR unknown Diagnostic info reply code ";
111 }
112}
113
114static const char *arlan_hardware_type_string(struct net_device *dev)
115{
116 u_char hardwareType;
117 struct arlan_private *priv = netdev_priv(dev);
118 volatile struct arlan_shmem __iomem *arlan = priv->card;
119
120 READSHM(hardwareType, arlan->hardwareType, u_char);
121 switch (hardwareType)
122 {
123 case 0x00:
124 return "type A450";
125 case 0x01:
126 return "type A650 ";
127 case 0x04:
128 return "type TMA coproc";
129 case 0x0D:
130 return "type A650E ";
131 case 0x18:
132 return "type TMA coproc Australian";
133 case 0x19:
134 return "type A650A ";
135 case 0x26:
136 return "type TMA coproc European";
137 case 0x2E:
138 return "type A655 ";
139 case 0x2F:
140 return "type A655A ";
141 case 0x30:
142 return "type A655E ";
143 case 0x0B:
144 return "type A670 ";
145 case 0x0C:
146 return "type A670E ";
147 case 0x2D:
148 return "type A670A ";
149 case 0x0F:
150 return "type A411T";
151 case 0x16:
152 return "type A411TA";
153 case 0x1B:
154 return "type A440T";
155 case 0x1C:
156 return "type A412T";
157 case 0x1E:
158 return "type A412TA";
159 case 0x22:
160 return "type A411TE";
161 case 0x24:
162 return "type A412TE";
163 case 0x27:
164 return "type A671T ";
165 case 0x29:
166 return "type A671TA ";
167 case 0x2B:
168 return "type A671TE ";
169 case 0x31:
170 return "type A415T ";
171 case 0x33:
172 return "type A415TA ";
173 case 0x35:
174 return "type A415TE ";
175 case 0x37:
176 return "type A672";
177 case 0x39:
178 return "type A672A ";
179 case 0x3B:
180 return "type A672T";
181 case 0x6B:
182 return "type IC2200";
183 default:
184 return "type A672T";
185 }
186}
187#ifdef ARLAN_DEBUGGING
188static void arlan_print_diagnostic_info(struct net_device *dev)
189{
190 int i;
191 u_char diagnosticInfo;
192 u_short diagnosticOffset;
193 u_char hardwareType;
194 struct arlan_private *priv = netdev_priv(dev);
195 volatile struct arlan_shmem __iomem *arlan = priv->card;
196
197 // ARLAN_DEBUG_ENTRY("arlan_print_diagnostic_info");
198
199 if (READSHMB(arlan->configuredStatusFlag) == 0)
200 printk("Arlan: Card NOT configured\n");
201 else
202 printk("Arlan: Card is configured\n");
203
204 READSHM(diagnosticInfo, arlan->diagnosticInfo, u_char);
205 READSHM(diagnosticOffset, arlan->diagnosticOffset, u_short);
206
207 printk(KERN_INFO "%s\n", arlan_diagnostic_info_string(dev));
208
209 if (diagnosticInfo != 0xff)
210 printk("%s arlan: Diagnostic Offset %d \n", dev->name, diagnosticOffset);
211
212 printk("arlan: LAN CODE ID = ");
213 for (i = 0; i < 6; i++)
214 DEBUGSHM(1, "%03d:", arlan->lanCardNodeId[i], u_char);
215 printk("\n");
216
217 printk("arlan: Arlan BroadCast address = ");
218 for (i = 0; i < 6; i++)
219 DEBUGSHM(1, "%03d:", arlan->broadcastAddress[i], u_char);
220 printk("\n");
221
222 READSHM(hardwareType, arlan->hardwareType, u_char);
223 printk(KERN_INFO "%s\n", arlan_hardware_type_string(dev));
224
225
226 DEBUGSHM(1, "arlan: channelNumber=%d\n", arlan->channelNumber, u_char);
227 DEBUGSHM(1, "arlan: channelSet=%d\n", arlan->channelSet, u_char);
228 DEBUGSHM(1, "arlan: spreadingCode=%d\n", arlan->spreadingCode, u_char);
229 DEBUGSHM(1, "arlan: radioNodeId=%d\n", arlan->radioNodeId, u_short);
230 DEBUGSHM(1, "arlan: SID =%d\n", arlan->SID, u_short);
231 DEBUGSHM(1, "arlan: rxOffset=%d\n", arlan->rxOffset, u_short);
232
233 DEBUGSHM(1, "arlan: registration mode is %d\n", arlan->registrationMode, u_char);
234
235 printk("arlan: name= ");
236 IFDEBUG(1)
237
238 for (i = 0; i < 16; i++)
239 {
240 char c;
241 READSHM(c, arlan->name[i], char);
242 if (c)
243 printk("%c", c);
244 }
245 printk("\n");
246
247// ARLAN_DEBUG_EXIT("arlan_print_diagnostic_info");
248
249}
250
251
252/****************************** TEST MEMORY **************/
253
254static int arlan_hw_test_memory(struct net_device *dev)
255{
256 u_char *ptr;
257 int i;
258 int memlen = sizeof(struct arlan_shmem) - 0xF; /* avoid control register */
259 volatile char *arlan_mem = (char *) (dev->mem_start);
260 struct arlan_private *priv = netdev_priv(dev);
261 volatile struct arlan_shmem __iomem *arlan = priv->card;
262 char pattern;
263
264 ptr = NULL;
265
266 /* hold card in reset state */
267 setHardwareReset(dev);
268
269 /* test memory */
270 pattern = 0;
271 for (i = 0; i < memlen; i++)
272 WRITESHM(arlan_mem[i], ((u_char) pattern++), u_char);
273
274 pattern = 0;
275 for (i = 0; i < memlen; i++)
276 {
277 char res;
278 READSHM(res, arlan_mem[i], char);
279 if (res != pattern++)
280 {
281 printk(KERN_ERR "Arlan driver memory test 1 failed \n");
282 return -1;
283 }
284 }
285
286 pattern = 0;
287 for (i = 0; i < memlen; i++)
288 WRITESHM(arlan_mem[i], ~(pattern++), char);
289
290 pattern = 0;
291 for (i = 0; i < memlen; i++)
292 {
293 char res;
294 READSHM(res, arlan_mem[i], char);
295 if (res != ~(pattern++))
296 {
297 printk(KERN_ERR "Arlan driver memory test 2 failed \n");
298 return -1;
299 }
300 }
301
302 /* zero memory */
303 for (i = 0; i < memlen; i++)
304 WRITESHM(arlan_mem[i], 0x00, char);
305
306 IFDEBUG(1) printk(KERN_INFO "Arlan: memory tests ok\n");
307
308 /* set reset flag and then release reset */
309 WRITESHM(arlan->resetFlag, 0xff, u_char);
310
311 clearChannelAttention(dev);
312 clearHardwareReset(dev);
313
314 /* wait for reset flag to become zero, we'll wait for two seconds */
315 if (arlan_command(dev, ARLAN_COMMAND_LONG_WAIT_NOW))
316 {
317 printk(KERN_ERR "%s arlan: failed to come back from memory test\n", dev->name);
318 return -1;
319 }
320 return 0;
321}
322
323static int arlan_setup_card_by_book(struct net_device *dev)
324{
325 u_char irqLevel, configuredStatusFlag;
326 struct arlan_private *priv = netdev_priv(dev);
327 volatile struct arlan_shmem __iomem *arlan = priv->card;
328
329// ARLAN_DEBUG_ENTRY("arlan_setup_card");
330
331 READSHM(configuredStatusFlag, arlan->configuredStatusFlag, u_char);
332
333 IFDEBUG(10)
334 if (configuredStatusFlag != 0)
335 IFDEBUG(10) printk("arlan: CARD IS CONFIGURED\n");
336 else
337 IFDEBUG(10) printk("arlan: card is NOT configured\n");
338
339 if (testMemory || (READSHMB(arlan->diagnosticInfo) != 0xff))
340 if (arlan_hw_test_memory(dev))
341 return -1;
342
343 DEBUGSHM(4, "arlan configuredStatus = %d \n", arlan->configuredStatusFlag, u_char);
344 DEBUGSHM(4, "arlan driver diagnostic: 0x%2x\n", arlan->diagnosticInfo, u_char);
345
346 /* issue nop command - no interrupt */
347 arlan_command(dev, ARLAN_COMMAND_NOOP);
348 if (arlan_command(dev, ARLAN_COMMAND_WAIT_NOW) != 0)
349 return -1;
350
351 IFDEBUG(50) printk("1st Noop successfully executed !!\n");
352
353 /* try to turn on the arlan interrupts */
354 clearClearInterrupt(dev);
355 setClearInterrupt(dev);
356 setInterruptEnable(dev);
357
358 /* issue nop command - with interrupt */
359
360 arlan_command(dev, ARLAN_COMMAND_NOOPINT);
361 if (arlan_command(dev, ARLAN_COMMAND_WAIT_NOW) != 0)
362 return -1;
363
364
365 IFDEBUG(50) printk("2nd Noop successfully executed !!\n");
366
367 READSHM(irqLevel, arlan->irqLevel, u_char)
368
369 if (irqLevel != dev->irq)
370 {
371 IFDEBUG(1) printk(KERN_WARNING "arlan dip switches set irq to %d\n", irqLevel);
372 printk(KERN_WARNING "device driver irq set to %d - does not match\n", dev->irq);
373 dev->irq = irqLevel;
374 }
375 else
376 IFDEBUG(2) printk("irq level is OK\n");
377
378
379 IFDEBUG(3) arlan_print_diagnostic_info(dev);
380
381 arlan_command(dev, ARLAN_COMMAND_CONF);
382
383 READSHM(configuredStatusFlag, arlan->configuredStatusFlag, u_char);
384 if (configuredStatusFlag == 0)
385 {
386 printk(KERN_WARNING "arlan configure failed\n");
387 return -1;
388 }
389 arlan_command(dev, ARLAN_COMMAND_LONG_WAIT_NOW);
390 arlan_command(dev, ARLAN_COMMAND_RX);
391 arlan_command(dev, ARLAN_COMMAND_LONG_WAIT_NOW);
392 printk(KERN_NOTICE "%s: arlan driver version %s loaded\n",
393 dev->name, arlan_version);
394
395// ARLAN_DEBUG_EXIT("arlan_setup_card");
396
397 return 0; /* no errors */
398}
399#endif
400
401#ifdef ARLAN_PROC_INTERFACE
402#ifdef ARLAN_PROC_SHM_DUMP
403
404static char arlan_drive_info[ARLAN_STR_SIZE] = "A655\n\0";
405
406static int arlan_sysctl_info(ctl_table * ctl, int write, struct file *filp,
407 void __user *buffer, size_t * lenp, loff_t *ppos)
408{
409 int i;
410 int retv, pos, devnum;
411 struct arlan_private *priva = NULL;
412 struct net_device *dev;
413 pos = 0;
414 if (write)
415 {
416 printk("wrirte: ");
417 for (i = 0; i < 100; i++)
418 printk("adi %x \n", arlan_drive_info[i]);
419 }
420 if (ctl->procname == NULL || arlan_drive_info == NULL)
421 {
422 printk(KERN_WARNING " procname is NULL in sysctl_table or arlan_drive_info is NULL \n at arlan module\n ");
423 return -1;
424 }
425 devnum = ctl->procname[5] - '0';
426 if (devnum < 0 || devnum > MAX_ARLANS - 1)
427 {
428 printk(KERN_WARNING "too strange devnum in procfs parse\n ");
429 return -1;
430 }
431 else if (arlan_device[devnum] == NULL)
432 {
433 if (ctl->procname)
434 pos += sprintf(arlan_drive_info + pos, "\t%s\n\n", ctl->procname);
435 pos += sprintf(arlan_drive_info + pos, "No device found here \n");
436 goto final;
437 }
438 else
439 priva = arlan_device[devnum]->priv;
440
441 if (priva == NULL)
442 {
443 printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
444 return -1;
445 }
446 dev = arlan_device[devnum];
447
448 memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
449
450 pos = sprintf(arlan_drive_info, "Arlan info \n");
451 /* Header Signature */
452 SARLSTR(textRegion, 48);
453 SARLUC(resetFlag);
454 pos += sprintf(arlan_drive_info + pos, "diagnosticInfo\t=\t%s \n", arlan_diagnostic_info_string(dev));
455 SARLUC(diagnosticInfo);
456 SARLUS(diagnosticOffset);
457 SARLUCN(_1, 12);
458 SARLUCN(lanCardNodeId, 6);
459 SARLUCN(broadcastAddress, 6);
460 pos += sprintf(arlan_drive_info + pos, "hardwareType =\t %s \n", arlan_hardware_type_string(dev));
461 SARLUC(hardwareType);
462 SARLUC(majorHardwareVersion);
463 SARLUC(minorHardwareVersion);
464 SARLUC(radioModule);
465 SARLUC(defaultChannelSet);
466 SARLUCN(_2, 47);
467
468 /* Control/Status Block - 0x0080 */
469 SARLUC(interruptInProgress);
470 SARLUC(cntrlRegImage);
471
472 SARLUCN(_3, 14);
473 SARLUC(commandByte);
474 SARLUCN(commandParameter, 15);
475
476 /* Receive Status - 0x00a0 */
477 SARLUC(rxStatus);
478 SARLUC(rxFrmType);
479 SARLUS(rxOffset);
480 SARLUS(rxLength);
481 SARLUCN(rxSrc, 6);
482 SARLUC(rxBroadcastFlag);
483 SARLUC(rxQuality);
484 SARLUC(scrambled);
485 SARLUCN(_4, 1);
486
487 /* Transmit Status - 0x00b0 */
488 SARLUC(txStatus);
489 SARLUC(txAckQuality);
490 SARLUC(numRetries);
491 SARLUCN(_5, 14);
492 SARLUCN(registeredRouter, 6);
493 SARLUCN(backboneRouter, 6);
494 SARLUC(registrationStatus);
495 SARLUC(configuredStatusFlag);
496 SARLUCN(_6, 1);
497 SARLUCN(ultimateDestAddress, 6);
498 SARLUCN(immedDestAddress, 6);
499 SARLUCN(immedSrcAddress, 6);
500 SARLUS(rxSequenceNumber);
501 SARLUC(assignedLocaltalkAddress);
502 SARLUCN(_7, 27);
503
504 /* System Parameter Block */
505
506 /* - Driver Parameters (Novell Specific) */
507
508 SARLUS(txTimeout);
509 SARLUS(transportTime);
510 SARLUCN(_8, 4);
511
512 /* - Configuration Parameters */
513 SARLUC(irqLevel);
514 SARLUC(spreadingCode);
515 SARLUC(channelSet);
516 SARLUC(channelNumber);
517 SARLUS(radioNodeId);
518 SARLUCN(_9, 2);
519 SARLUC(scramblingDisable);
520 SARLUC(radioType);
521 SARLUS(routerId);
522 SARLUCN(_10, 9);
523 SARLUC(txAttenuation);
524 SARLUIA(systemId);
525 SARLUS(globalChecksum);
526 SARLUCN(_11, 4);
527 SARLUS(maxDatagramSize);
528 SARLUS(maxFrameSize);
529 SARLUC(maxRetries);
530 SARLUC(receiveMode);
531 SARLUC(priority);
532 SARLUC(rootOrRepeater);
533 SARLUCN(specifiedRouter, 6);
534 SARLUS(fastPollPeriod);
535 SARLUC(pollDecay);
536 SARLUSA(fastPollDelay);
537 SARLUC(arlThreshold);
538 SARLUC(arlDecay);
539 SARLUCN(_12, 1);
540 SARLUS(specRouterTimeout);
541 SARLUCN(_13, 5);
542
543 /* Scrambled Area */
544 SARLUIA(SID);
545 SARLUCN(encryptionKey, 12);
546 SARLUIA(_14);
547 SARLUSA(waitTime);
548 SARLUSA(lParameter);
549 SARLUCN(_15, 3);
550 SARLUS(headerSize);
551 SARLUS(sectionChecksum);
552
553 SARLUC(registrationMode);
554 SARLUC(registrationFill);
555 SARLUS(pollPeriod);
556 SARLUS(refreshPeriod);
557 SARLSTR(name, 16);
558 SARLUCN(NID, 6);
559 SARLUC(localTalkAddress);
560 SARLUC(codeFormat);
561 SARLUC(numChannels);
562 SARLUC(channel1);
563 SARLUC(channel2);
564 SARLUC(channel3);
565 SARLUC(channel4);
566 SARLUCN(SSCode, 59);
567
568/* SARLUCN( _16, 0x140);
569 */
570 /* Statistics Block - 0x0300 */
571 SARLUC(hostcpuLock);
572 SARLUC(lancpuLock);
573 SARLUCN(resetTime, 18);
574 SARLUIA(numDatagramsTransmitted);
575 SARLUIA(numReTransmissions);
576 SARLUIA(numFramesDiscarded);
577 SARLUIA(numDatagramsReceived);
578 SARLUIA(numDuplicateReceivedFrames);
579 SARLUIA(numDatagramsDiscarded);
580 SARLUS(maxNumReTransmitDatagram);
581 SARLUS(maxNumReTransmitFrames);
582 SARLUS(maxNumConsecutiveDuplicateFrames);
583 /* misaligned here so we have to go to characters */
584 SARLUIA(numBytesTransmitted);
585 SARLUIA(numBytesReceived);
586 SARLUIA(numCRCErrors);
587 SARLUIA(numLengthErrors);
588 SARLUIA(numAbortErrors);
589 SARLUIA(numTXUnderruns);
590 SARLUIA(numRXOverruns);
591 SARLUIA(numHoldOffs);
592 SARLUIA(numFramesTransmitted);
593 SARLUIA(numFramesReceived);
594 SARLUIA(numReceiveFramesLost);
595 SARLUIA(numRXBufferOverflows);
596 SARLUIA(numFramesDiscardedAddrMismatch);
597 SARLUIA(numFramesDiscardedSIDMismatch);
598 SARLUIA(numPollsTransmistted);
599 SARLUIA(numPollAcknowledges);
600 SARLUIA(numStatusTimeouts);
601 SARLUIA(numNACKReceived);
602 SARLUS(auxCmd);
603 SARLUCN(dumpPtr, 4);
604 SARLUC(dumpVal);
605 SARLUC(wireTest);
606
607 /* next 4 seems too long for procfs, over single page ?
608 SARLUCN( _17, 0x86);
609 SARLUCN( txBuffer, 0x800);
610 SARLUCN( rxBuffer, 0x800);
611 SARLUCN( _18, 0x0bff);
612 */
613
614 pos += sprintf(arlan_drive_info + pos, "rxRing\t=\t0x");
615 for (i = 0; i < 0x50; i++)
616 pos += sprintf(arlan_drive_info + pos, "%02x", ((char *) priva->conf)[priva->conf->rxOffset + i]);
617 pos += sprintf(arlan_drive_info + pos, "\n");
618
619 SARLUC(configStatus);
620 SARLUC(_22);
621 SARLUC(progIOCtrl);
622 SARLUC(shareMBase);
623 SARLUC(controlRegister);
624
625 pos += sprintf(arlan_drive_info + pos, " total %d chars\n", pos);
626 if (ctl)
627 if (ctl->procname)
628 pos += sprintf(arlan_drive_info + pos, " driver name : %s\n", ctl->procname);
629final:
630 *lenp = pos;
631
632 if (!write)
633 retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos);
634 else
635 {
636 *lenp = 0;
637 return -1;
638 }
639 return retv;
640}
641
642
643static int arlan_sysctl_info161719(ctl_table * ctl, int write, struct file *filp,
644 void __user *buffer, size_t * lenp, loff_t *ppos)
645{
646 int i;
647 int retv, pos, devnum;
648 struct arlan_private *priva = NULL;
649
650 pos = 0;
651 devnum = ctl->procname[5] - '0';
652 if (arlan_device[devnum] == NULL)
653 {
654 pos += sprintf(arlan_drive_info + pos, "No device found here \n");
655 goto final;
656 }
657 else
658 priva = arlan_device[devnum]->priv;
659 if (priva == NULL)
660 {
661 printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
662 return -1;
663 }
664 memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
665 SARLUCN(_16, 0xC0);
666 SARLUCN(_17, 0x6A);
667 SARLUCN(_18, 14);
668 SARLUCN(_19, 0x86);
669 SARLUCN(_21, 0x3fd);
670
671final:
672 *lenp = pos;
673 retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos);
674 return retv;
675}
676
677static int arlan_sysctl_infotxRing(ctl_table * ctl, int write, struct file *filp,
678 void __user *buffer, size_t * lenp, loff_t *ppos)
679{
680 int i;
681 int retv, pos, devnum;
682 struct arlan_private *priva = NULL;
683
684 pos = 0;
685 devnum = ctl->procname[5] - '0';
686 if (arlan_device[devnum] == NULL)
687 {
688 pos += sprintf(arlan_drive_info + pos, "No device found here \n");
689 goto final;
690 }
691 else
692 priva = arlan_device[devnum]->priv;
693 if (priva == NULL)
694 {
695 printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
696 return -1;
697 }
698 memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
699 SARLBNpln(u_char, txBuffer, 0x800);
700final:
701 *lenp = pos;
702 retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos);
703 return retv;
704}
705
706static int arlan_sysctl_inforxRing(ctl_table * ctl, int write, struct file *filp,
707 void __user *buffer, size_t * lenp, loff_t *ppos)
708{
709 int i;
710 int retv, pos, devnum;
711 struct arlan_private *priva = NULL;
712
713 pos = 0;
714 devnum = ctl->procname[5] - '0';
715 if (arlan_device[devnum] == NULL)
716 {
717 pos += sprintf(arlan_drive_info + pos, "No device found here \n");
718 goto final;
719 } else
720 priva = arlan_device[devnum]->priv;
721 if (priva == NULL)
722 {
723 printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
724 return -1;
725 }
726 memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
727 SARLBNpln(u_char, rxBuffer, 0x800);
728final:
729 *lenp = pos;
730 retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos);
731 return retv;
732}
733
734static int arlan_sysctl_info18(ctl_table * ctl, int write, struct file *filp,
735 void __user *buffer, size_t * lenp, loff_t *ppos)
736{
737 int i;
738 int retv, pos, devnum;
739 struct arlan_private *priva = NULL;
740
741 pos = 0;
742 devnum = ctl->procname[5] - '0';
743 if (arlan_device[devnum] == NULL)
744 {
745 pos += sprintf(arlan_drive_info + pos, "No device found here \n");
746 goto final;
747 }
748 else
749 priva = arlan_device[devnum]->priv;
750 if (priva == NULL)
751 {
752 printk(KERN_WARNING " Could not find the device private in arlan procsys, bad\n ");
753 return -1;
754 }
755 memcpy_fromio(priva->conf, priva->card, sizeof(struct arlan_shmem));
756 SARLBNpln(u_char, _18, 0x800);
757
758final:
759 *lenp = pos;
760 retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos);
761 return retv;
762}
763
764
765#endif /* #ifdef ARLAN_PROC_SHM_DUMP */
766
767
768static char conf_reset_result[200];
769
770static int arlan_configure(ctl_table * ctl, int write, struct file *filp,
771 void __user *buffer, size_t * lenp, loff_t *ppos)
772{
773 int pos = 0;
774 int devnum = ctl->procname[6] - '0';
775 struct arlan_private *priv;
776
777 if (devnum < 0 || devnum > MAX_ARLANS - 1)
778 {
779 printk(KERN_WARNING "too strange devnum in procfs parse\n ");
780 return -1;
781 }
782 else if (arlan_device[devnum] != NULL)
783 {
784 priv = arlan_device[devnum]->priv;
785
786 arlan_command(arlan_device[devnum], ARLAN_COMMAND_CLEAN_AND_CONF);
787 }
788 else
789 return -1;
790
791 *lenp = pos;
792 return proc_dostring(ctl, write, filp, buffer, lenp, ppos);
793}
794
795static int arlan_sysctl_reset(ctl_table * ctl, int write, struct file *filp,
796 void __user *buffer, size_t * lenp, loff_t *ppos)
797{
798 int pos = 0;
799 int devnum = ctl->procname[5] - '0';
800 struct arlan_private *priv;
801
802 if (devnum < 0 || devnum > MAX_ARLANS - 1)
803 {
804 printk(KERN_WARNING "too strange devnum in procfs parse\n ");
805 return -1;
806 }
807 else if (arlan_device[devnum] != NULL)
808 {
809 priv = arlan_device[devnum]->priv;
810 arlan_command(arlan_device[devnum], ARLAN_COMMAND_CLEAN_AND_RESET);
811
812 } else
813 return -1;
814 *lenp = pos + 3;
815 return proc_dostring(ctl, write, filp, buffer, lenp, ppos);
816}
817
818
819/* Place files in /proc/sys/dev/arlan */
820#define CTBLN(num,card,nam) \
821 { .ctl_name = num,\
822 .procname = #nam,\
823 .data = &(arlan_conf[card].nam),\
824 .maxlen = sizeof(int), .mode = 0600, .proc_handler = &proc_dointvec}
825#ifdef ARLAN_DEBUGGING
826
827#define ARLAN_PROC_DEBUG_ENTRIES \
828 { .ctl_name = 48, .procname = "entry_exit_debug",\
829 .data = &arlan_entry_and_exit_debug,\
830 .maxlen = sizeof(int), .mode = 0600, .proc_handler = &proc_dointvec},\
831 { .ctl_name = 49, .procname = "debug", .data = &arlan_debug,\
832 .maxlen = sizeof(int), .mode = 0600, .proc_handler = &proc_dointvec},
833#else
834#define ARLAN_PROC_DEBUG_ENTRIES
835#endif
836
837#define ARLAN_SYSCTL_TABLE_TOTAL(cardNo)\
838 CTBLN(1,cardNo,spreadingCode),\
839 CTBLN(2,cardNo, channelNumber),\
840 CTBLN(3,cardNo, scramblingDisable),\
841 CTBLN(4,cardNo, txAttenuation),\
842 CTBLN(5,cardNo, systemId), \
843 CTBLN(6,cardNo, maxDatagramSize),\
844 CTBLN(7,cardNo, maxFrameSize),\
845 CTBLN(8,cardNo, maxRetries),\
846 CTBLN(9,cardNo, receiveMode),\
847 CTBLN(10,cardNo, priority),\
848 CTBLN(11,cardNo, rootOrRepeater),\
849 CTBLN(12,cardNo, SID),\
850 CTBLN(13,cardNo, registrationMode),\
851 CTBLN(14,cardNo, registrationFill),\
852 CTBLN(15,cardNo, localTalkAddress),\
853 CTBLN(16,cardNo, codeFormat),\
854 CTBLN(17,cardNo, numChannels),\
855 CTBLN(18,cardNo, channel1),\
856 CTBLN(19,cardNo, channel2),\
857 CTBLN(20,cardNo, channel3),\
858 CTBLN(21,cardNo, channel4),\
859 CTBLN(22,cardNo, txClear),\
860 CTBLN(23,cardNo, txRetries),\
861 CTBLN(24,cardNo, txRouting),\
862 CTBLN(25,cardNo, txScrambled),\
863 CTBLN(26,cardNo, rxParameter),\
864 CTBLN(27,cardNo, txTimeoutMs),\
865 CTBLN(28,cardNo, waitCardTimeout),\
866 CTBLN(29,cardNo, channelSet), \
867 {.ctl_name = 30, .procname = "name",\
868 .data = arlan_conf[cardNo].siteName,\
869 .maxlen = 16, .mode = 0600, .proc_handler = &proc_dostring},\
870 CTBLN(31,cardNo,waitTime),\
871 CTBLN(32,cardNo,lParameter),\
872 CTBLN(33,cardNo,_15),\
873 CTBLN(34,cardNo,headerSize),\
874 CTBLN(36,cardNo,tx_delay_ms),\
875 CTBLN(37,cardNo,retries),\
876 CTBLN(38,cardNo,ReTransmitPacketMaxSize),\
877 CTBLN(39,cardNo,waitReTransmitPacketMaxSize),\
878 CTBLN(40,cardNo,fastReTransCount),\
879 CTBLN(41,cardNo,driverRetransmissions),\
880 CTBLN(42,cardNo,txAckTimeoutMs),\
881 CTBLN(43,cardNo,registrationInterrupts),\
882 CTBLN(44,cardNo,hardwareType),\
883 CTBLN(45,cardNo,radioType),\
884 CTBLN(46,cardNo,writeEEPROM),\
885 CTBLN(47,cardNo,writeRadioType),\
886 ARLAN_PROC_DEBUG_ENTRIES\
887 CTBLN(50,cardNo,in_speed),\
888 CTBLN(51,cardNo,out_speed),\
889 CTBLN(52,cardNo,in_speed10),\
890 CTBLN(53,cardNo,out_speed10),\
891 CTBLN(54,cardNo,in_speed_max),\
892 CTBLN(55,cardNo,out_speed_max),\
893 CTBLN(56,cardNo,measure_rate),\
894 CTBLN(57,cardNo,pre_Command_Wait),\
895 CTBLN(58,cardNo,rx_tweak1),\
896 CTBLN(59,cardNo,rx_tweak2),\
897 CTBLN(60,cardNo,tx_queue_len),\
898
899
900
901static ctl_table arlan_conf_table0[] =
902{
903 ARLAN_SYSCTL_TABLE_TOTAL(0)
904
905#ifdef ARLAN_PROC_SHM_DUMP
906 {
907 .ctl_name = 150,
908 .procname = "arlan0-txRing",
909 .data = &arlan_drive_info,
910 .maxlen = ARLAN_STR_SIZE,
911 .mode = 0400,
912 .proc_handler = &arlan_sysctl_infotxRing,
913 },
914 {
915 .ctl_name = 151,
916 .procname = "arlan0-rxRing",
917 .data = &arlan_drive_info,
918 .maxlen = ARLAN_STR_SIZE,
919 .mode = 0400,
920 .proc_handler = &arlan_sysctl_inforxRing,
921 },
922 {
923 .ctl_name = 152,
924 .procname = "arlan0-18",
925 .data = &arlan_drive_info,
926 .maxlen = ARLAN_STR_SIZE,
927 .mode = 0400,
928 .proc_handler = &arlan_sysctl_info18,
929 },
930 {
931 .ctl_name = 153,
932 .procname = "arlan0-ring",
933 .data = &arlan_drive_info,
934 .maxlen = ARLAN_STR_SIZE,
935 .mode = 0400,
936 .proc_handler = &arlan_sysctl_info161719,
937 },
938 {
939 .ctl_name = 154,
940 .procname = "arlan0-shm-cpy",
941 .data = &arlan_drive_info,
942 .maxlen = ARLAN_STR_SIZE,
943 .mode = 0400,
944 .proc_handler = &arlan_sysctl_info,
945 },
946#endif
947 {
948 .ctl_name = 155,
949 .procname = "config0",
950 .data = &conf_reset_result,
951 .maxlen = 100,
952 .mode = 0400,
953 .proc_handler = &arlan_configure
954 },
955 {
956 .ctl_name = 156,
957 .procname = "reset0",
958 .data = &conf_reset_result,
959 .maxlen = 100,
960 .mode = 0400,
961 .proc_handler = &arlan_sysctl_reset,
962 },
963 { .ctl_name = 0 }
964};
965
966static ctl_table arlan_conf_table1[] =
967{
968
969 ARLAN_SYSCTL_TABLE_TOTAL(1)
970
971#ifdef ARLAN_PROC_SHM_DUMP
972 {
973 .ctl_name = 150,
974 .procname = "arlan1-txRing",
975 .data = &arlan_drive_info,
976 .maxlen = ARLAN_STR_SIZE,
977 .mode = 0400,
978 .proc_handler = &arlan_sysctl_infotxRing,
979 },
980 {
981 .ctl_name = 151,
982 .procname = "arlan1-rxRing",
983 .data = &arlan_drive_info,
984 .maxlen = ARLAN_STR_SIZE,
985 .mode = 0400,
986 .proc_handler = &arlan_sysctl_inforxRing,
987 },
988 {
989 .ctl_name = 152,
990 .procname = "arlan1-18",
991 .data = &arlan_drive_info,
992 .maxlen = ARLAN_STR_SIZE,
993 .mode = 0400,
994 .proc_handler = &arlan_sysctl_info18,
995 },
996 {
997 .ctl_name = 153,
998 .procname = "arlan1-ring",
999 .data = &arlan_drive_info,
1000 .maxlen = ARLAN_STR_SIZE,
1001 .mode = 0400,
1002 .proc_handler = &arlan_sysctl_info161719,
1003 },
1004 {
1005 .ctl_name = 154,
1006 .procname = "arlan1-shm-cpy",
1007 .data = &arlan_drive_info,
1008 .maxlen = ARLAN_STR_SIZE,
1009 .mode = 0400,
1010 .proc_handler = &arlan_sysctl_info,
1011 },
1012#endif
1013 {
1014 .ctl_name = 155,
1015 .procname = "config1",
1016 .data = &conf_reset_result,
1017 .maxlen = 100,
1018 .mode = 0400,
1019 .proc_handler = &arlan_configure,
1020 },
1021 {
1022 .ctl_name = 156,
1023 .procname = "reset1",
1024 .data = &conf_reset_result,
1025 .maxlen = 100,
1026 .mode = 0400,
1027 .proc_handler = &arlan_sysctl_reset,
1028 },
1029 { .ctl_name = 0 }
1030};
1031
1032static ctl_table arlan_conf_table2[] =
1033{
1034
1035 ARLAN_SYSCTL_TABLE_TOTAL(2)
1036
1037#ifdef ARLAN_PROC_SHM_DUMP
1038 {
1039 .ctl_name = 150,
1040 .procname = "arlan2-txRing",
1041 .data = &arlan_drive_info,
1042 .maxlen = ARLAN_STR_SIZE,
1043 .mode = 0400,
1044 .proc_handler = &arlan_sysctl_infotxRing,
1045 },
1046 {
1047 .ctl_name = 151,
1048 .procname = "arlan2-rxRing",
1049 .data = &arlan_drive_info,
1050 .maxlen = ARLAN_STR_SIZE,
1051 .mode = 0400,
1052 .proc_handler = &arlan_sysctl_inforxRing,
1053 },
1054 {
1055 .ctl_name = 152,
1056 .procname = "arlan2-18",
1057 .data = &arlan_drive_info,
1058 .maxlen = ARLAN_STR_SIZE,
1059 .mode = 0400,
1060 .proc_handler = &arlan_sysctl_info18,
1061 },
1062 {
1063 .ctl_name = 153,
1064 .procname = "arlan2-ring",
1065 .data = &arlan_drive_info,
1066 .maxlen = ARLAN_STR_SIZE,
1067 .mode = 0400,
1068 .proc_handler = &arlan_sysctl_info161719,
1069 },
1070 {
1071 .ctl_name = 154,
1072 .procname = "arlan2-shm-cpy",
1073 .data = &arlan_drive_info,
1074 .maxlen = ARLAN_STR_SIZE,
1075 .mode = 0400,
1076 .proc_handler = &arlan_sysctl_info,
1077 },
1078#endif
1079 {
1080 .ctl_name = 155,
1081 .procname = "config2",
1082 .data = &conf_reset_result,
1083 .maxlen = 100,
1084 .mode = 0400,
1085 .proc_handler = &arlan_configure,
1086 },
1087 {
1088 .ctl_name = 156,
1089 .procname = "reset2",
1090 .data = &conf_reset_result,
1091 .maxlen = 100,
1092 .mode = 0400,
1093 .proc_handler = &arlan_sysctl_reset,
1094 },
1095 { .ctl_name = 0 }
1096};
1097
1098static ctl_table arlan_conf_table3[] =
1099{
1100
1101 ARLAN_SYSCTL_TABLE_TOTAL(3)
1102
1103#ifdef ARLAN_PROC_SHM_DUMP
1104 {
1105 .ctl_name = 150,
1106 .procname = "arlan3-txRing",
1107 .data = &arlan_drive_info,
1108 .maxlen = ARLAN_STR_SIZE,
1109 .mode = 0400,
1110 .proc_handler = &arlan_sysctl_infotxRing,
1111 },
1112 {
1113 .ctl_name = 151,
1114 .procname = "arlan3-rxRing",
1115 .data = &arlan_drive_info,
1116 .maxlen = ARLAN_STR_SIZE,
1117 .mode = 0400,
1118 .proc_handler = &arlan_sysctl_inforxRing,
1119 },
1120 {
1121 .ctl_name = 152,
1122 .procname = "arlan3-18",
1123 .data = &arlan_drive_info,
1124 .maxlen = ARLAN_STR_SIZE,
1125 .mode = 0400,
1126 .proc_handler = &arlan_sysctl_info18,
1127 },
1128 {
1129 .ctl_name = 153,
1130 .procname = "arlan3-ring",
1131 .data = &arlan_drive_info,
1132 .maxlen = ARLAN_STR_SIZE,
1133 .mode = 0400,
1134 .proc_handler = &arlan_sysctl_info161719,
1135 },
1136 {
1137 .ctl_name = 154,
1138 .procname = "arlan3-shm-cpy",
1139 .data = &arlan_drive_info,
1140 .maxlen = ARLAN_STR_SIZE,
1141 .mode = 0400,
1142 .proc_handler = &arlan_sysctl_info,
1143 },
1144#endif
1145 {
1146 .ctl_name = 155,
1147 .procname = "config3",
1148 .data = &conf_reset_result,
1149 .maxlen = 100,
1150 .mode = 0400,
1151 .proc_handler = &arlan_configure,
1152 },
1153 {
1154 .ctl_name = 156,
1155 .procname = "reset3",
1156 .data = &conf_reset_result,
1157 .maxlen = 100,
1158 .mode = 0400,
1159 .proc_handler = &arlan_sysctl_reset,
1160 },
1161 { .ctl_name = 0 }
1162};
1163
1164
1165
1166static ctl_table arlan_table[] =
1167{
1168 {
1169 .ctl_name = 0,
1170 .procname = "arlan0",
1171 .maxlen = 0,
1172 .mode = 0600,
1173 .child = arlan_conf_table0,
1174 },
1175 {
1176 .ctl_name = 0,
1177 .procname = "arlan1",
1178 .maxlen = 0,
1179 .mode = 0600,
1180 .child = arlan_conf_table1,
1181 },
1182 {
1183 .ctl_name = 0,
1184 .procname = "arlan2",
1185 .maxlen = 0,
1186 .mode = 0600,
1187 .child = arlan_conf_table2,
1188 },
1189 {
1190 .ctl_name = 0,
1191 .procname = "arlan3",
1192 .maxlen = 0,
1193 .mode = 0600,
1194 .child = arlan_conf_table3,
1195 },
1196 { .ctl_name = 0 }
1197};
1198
1199#else
1200
1201static ctl_table arlan_table[MAX_ARLANS + 1] =
1202{
1203 { .ctl_name = 0 }
1204};
1205#endif
1206#else
1207
1208static ctl_table arlan_table[MAX_ARLANS + 1] =
1209{
1210 { .ctl_name = 0 }
1211};
1212#endif
1213
1214
1215// static int mmtu = 1234;
1216
1217static ctl_table arlan_root_table[] =
1218{
1219 {
1220 .ctl_name = 254,
1221 .procname = "arlan",
1222 .maxlen = 0,
1223 .mode = 0555,
1224 .child = arlan_table,
1225 },
1226 { .ctl_name = 0 }
1227};
1228
1229/* Make sure that /proc/sys/dev is there */
1230//static ctl_table arlan_device_root_table[] =
1231//{
1232// {CTL_DEV, "dev", NULL, 0, 0555, arlan_root_table},
1233// {0}
1234//};
1235
1236
1237#ifdef CONFIG_PROC_FS
1238static struct ctl_table_header *arlan_device_sysctl_header;
1239
1240int __init init_arlan_proc(void)
1241{
1242
1243 int i = 0;
1244 if (arlan_device_sysctl_header)
1245 return 0;
1246 for (i = 0; i < MAX_ARLANS && arlan_device[i]; i++)
1247 arlan_table[i].ctl_name = i + 1;
1248 arlan_device_sysctl_header = register_sysctl_table(arlan_root_table, 0);
1249 if (!arlan_device_sysctl_header)
1250 return -1;
1251
1252 return 0;
1253
1254}
1255
1256void __exit cleanup_arlan_proc(void)
1257{
1258 unregister_sysctl_table(arlan_device_sysctl_header);
1259 arlan_device_sysctl_header = NULL;
1260
1261}
1262#endif
diff --git a/drivers/net/wireless/arlan.h b/drivers/net/wireless/arlan.h
new file mode 100644
index 000000000000..70a6d7b83c4a
--- /dev/null
+++ b/drivers/net/wireless/arlan.h
@@ -0,0 +1,541 @@
1/*
2 * Copyright (C) 1997 Cullen Jennings
3 * Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500
4 * GNU General Public License applies
5 */
6
7#include <linux/module.h>
8#include <linux/config.h>
9#include <linux/kernel.h>
10#include <linux/types.h>
11#include <linux/skbuff.h>
12#include <linux/if_ether.h> /* For the statistics structure. */
13#include <linux/if_arp.h> /* For ARPHRD_ETHER */
14#include <linux/ptrace.h>
15#include <linux/ioport.h>
16#include <linux/in.h>
17#include <linux/slab.h>
18#include <linux/string.h>
19#include <linux/timer.h>
20
21#include <linux/init.h>
22#include <linux/bitops.h>
23#include <asm/system.h>
24#include <asm/io.h>
25#include <linux/errno.h>
26#include <linux/delay.h>
27#include <linux/netdevice.h>
28#include <linux/etherdevice.h>
29
30
31//#define ARLAN_DEBUGGING 1
32
33#define ARLAN_PROC_INTERFACE
34#define MAX_ARLANS 4 /* not more than 4 ! */
35#define ARLAN_PROC_SHM_DUMP /* shows all card registers, makes driver way larger */
36
37#define ARLAN_MAX_MULTICAST_ADDRS 16
38#define ARLAN_RCV_CLEAN 0
39#define ARLAN_RCV_PROMISC 1
40#define ARLAN_RCV_CONTROL 2
41
42#ifdef CONFIG_PROC_FS
43extern int init_arlan_proc(void);
44extern void cleanup_arlan_proc(void);
45#else
46#define init_arlan_proc() ({ 0; })
47#define cleanup_arlan_proc() do { } while (0)
48#endif
49
50extern struct net_device *arlan_device[MAX_ARLANS];
51extern int arlan_debug;
52extern int arlan_entry_debug;
53extern int arlan_exit_debug;
54extern int testMemory;
55extern int arlan_command(struct net_device * dev, int command);
56
57#define SIDUNKNOWN -1
58#define radioNodeIdUNKNOWN -1
59#define irqUNKNOWN 0
60#define debugUNKNOWN 0
61#define testMemoryUNKNOWN 1
62#define spreadingCodeUNKNOWN 0
63#define channelNumberUNKNOWN 0
64#define channelSetUNKNOWN 0
65#define systemIdUNKNOWN -1
66#define registrationModeUNKNOWN -1
67
68
69#define IFDEBUG( L ) if ( (L) & arlan_debug )
70#define ARLAN_FAKE_HDR_LEN 12
71
72#ifdef ARLAN_DEBUGGING
73 #define DEBUG 1
74 #define ARLAN_ENTRY_EXIT_DEBUGGING 1
75 #define ARLAN_DEBUG(a,b) printk(KERN_DEBUG a, b)
76#else
77 #define ARLAN_DEBUG(a,b)
78#endif
79
80#define ARLAN_SHMEM_SIZE 0x2000
81
82struct arlan_shmem
83{
84 /* Header Signature */
85 volatile char textRegion[48];
86 volatile u_char resetFlag;
87 volatile u_char diagnosticInfo;
88 volatile u_short diagnosticOffset;
89 volatile u_char _1[12];
90 volatile u_char lanCardNodeId[6];
91 volatile u_char broadcastAddress[6];
92 volatile u_char hardwareType;
93 volatile u_char majorHardwareVersion;
94 volatile u_char minorHardwareVersion;
95 volatile u_char radioModule;// shows EEPROM, can be overridden at 0x111
96 volatile u_char defaultChannelSet; // shows EEProm, can be overriiden at 0x10A
97 volatile u_char _2[47];
98
99 /* Control/Status Block - 0x0080 */
100 volatile u_char interruptInProgress; /* not used by lancpu */
101 volatile u_char cntrlRegImage; /* not used by lancpu */
102 volatile u_char _3[13];
103 volatile u_char dumpByte;
104 volatile u_char commandByte; /* non-zero = active */
105 volatile u_char commandParameter[15];
106
107 /* Receive Status - 0x00a0 */
108 volatile u_char rxStatus; /* 1- data, 2-control, 0xff - registr change */
109 volatile u_char rxFrmType;
110 volatile u_short rxOffset;
111 volatile u_short rxLength;
112 volatile u_char rxSrc[6];
113 volatile u_char rxBroadcastFlag;
114 volatile u_char rxQuality;
115 volatile u_char scrambled;
116 volatile u_char _4[1];
117
118 /* Transmit Status - 0x00b0 */
119 volatile u_char txStatus;
120 volatile u_char txAckQuality;
121 volatile u_char numRetries;
122 volatile u_char _5[14];
123 volatile u_char registeredRouter[6];
124 volatile u_char backboneRouter[6];
125 volatile u_char registrationStatus;
126 volatile u_char configuredStatusFlag;
127 volatile u_char _6[1];
128 volatile u_char ultimateDestAddress[6];
129 volatile u_char immedDestAddress[6];
130 volatile u_char immedSrcAddress[6];
131 volatile u_short rxSequenceNumber;
132 volatile u_char assignedLocaltalkAddress;
133 volatile u_char _7[27];
134
135 /* System Parameter Block */
136
137 /* - Driver Parameters (Novell Specific) */
138
139 volatile u_short txTimeout;
140 volatile u_short transportTime;
141 volatile u_char _8[4];
142
143 /* - Configuration Parameters */
144 volatile u_char irqLevel;
145 volatile u_char spreadingCode;
146 volatile u_char channelSet;
147 volatile u_char channelNumber;
148 volatile u_short radioNodeId;
149 volatile u_char _9[2];
150 volatile u_char scramblingDisable;
151 volatile u_char radioType;
152 volatile u_short routerId;
153 volatile u_char _10[9];
154 volatile u_char txAttenuation;
155 volatile u_char systemId[4];
156 volatile u_short globalChecksum;
157 volatile u_char _11[4];
158 volatile u_short maxDatagramSize;
159 volatile u_short maxFrameSize;
160 volatile u_char maxRetries;
161 volatile u_char receiveMode;
162 volatile u_char priority;
163 volatile u_char rootOrRepeater;
164 volatile u_char specifiedRouter[6];
165 volatile u_short fastPollPeriod;
166 volatile u_char pollDecay;
167 volatile u_char fastPollDelay[2];
168 volatile u_char arlThreshold;
169 volatile u_char arlDecay;
170 volatile u_char _12[1];
171 volatile u_short specRouterTimeout;
172 volatile u_char _13[5];
173
174 /* Scrambled Area */
175 volatile u_char SID[4];
176 volatile u_char encryptionKey[12];
177 volatile u_char _14[2];
178 volatile u_char waitTime[2];
179 volatile u_char lParameter[2];
180 volatile u_char _15[3];
181 volatile u_short headerSize;
182 volatile u_short sectionChecksum;
183
184 volatile u_char registrationMode;
185 volatile u_char registrationFill;
186 volatile u_short pollPeriod;
187 volatile u_short refreshPeriod;
188 volatile u_char name[16];
189 volatile u_char NID[6];
190 volatile u_char localTalkAddress;
191 volatile u_char codeFormat;
192 volatile u_char numChannels;
193 volatile u_char channel1;
194 volatile u_char channel2;
195 volatile u_char channel3;
196 volatile u_char channel4;
197 volatile u_char SSCode[59];
198
199 volatile u_char _16[0xC0];
200 volatile u_short auxCmd;
201 volatile u_char dumpPtr[4];
202 volatile u_char dumpVal;
203 volatile u_char _17[0x6A];
204 volatile u_char wireTest;
205 volatile u_char _18[14];
206
207 /* Statistics Block - 0x0300 */
208 volatile u_char hostcpuLock;
209 volatile u_char lancpuLock;
210 volatile u_char resetTime[18];
211
212 volatile u_char numDatagramsTransmitted[4];
213 volatile u_char numReTransmissions[4];
214 volatile u_char numFramesDiscarded[4];
215 volatile u_char numDatagramsReceived[4];
216 volatile u_char numDuplicateReceivedFrames[4];
217 volatile u_char numDatagramsDiscarded[4];
218
219 volatile u_short maxNumReTransmitDatagram;
220 volatile u_short maxNumReTransmitFrames;
221 volatile u_short maxNumConsecutiveDuplicateFrames;
222 /* misaligned here so we have to go to characters */
223
224 volatile u_char numBytesTransmitted[4];
225 volatile u_char numBytesReceived[4];
226 volatile u_char numCRCErrors[4];
227 volatile u_char numLengthErrors[4];
228 volatile u_char numAbortErrors[4];
229 volatile u_char numTXUnderruns[4];
230 volatile u_char numRXOverruns[4];
231 volatile u_char numHoldOffs[4];
232 volatile u_char numFramesTransmitted[4];
233 volatile u_char numFramesReceived[4];
234 volatile u_char numReceiveFramesLost[4];
235 volatile u_char numRXBufferOverflows[4];
236 volatile u_char numFramesDiscardedAddrMismatch[4];
237 volatile u_char numFramesDiscardedSIDMismatch[4];
238 volatile u_char numPollsTransmistted[4];
239 volatile u_char numPollAcknowledges[4];
240 volatile u_char numStatusTimeouts[4];
241 volatile u_char numNACKReceived[4];
242
243 volatile u_char _19[0x86];
244
245 volatile u_char txBuffer[0x800];
246 volatile u_char rxBuffer[0x800];
247
248 volatile u_char _20[0x800];
249 volatile u_char _21[0x3fb];
250 volatile u_char configStatus;
251 volatile u_char _22;
252 volatile u_char progIOCtrl;
253 volatile u_char shareMBase;
254 volatile u_char controlRegister;
255};
256
257struct arlan_conf_stru {
258 int spreadingCode;
259 int channelSet;
260 int channelNumber;
261 int scramblingDisable;
262 int txAttenuation;
263 int systemId;
264 int maxDatagramSize;
265 int maxFrameSize;
266 int maxRetries;
267 int receiveMode;
268 int priority;
269 int rootOrRepeater;
270 int SID;
271 int radioNodeId;
272 int registrationMode;
273 int registrationFill;
274 int localTalkAddress;
275 int codeFormat;
276 int numChannels;
277 int channel1;
278 int channel2;
279 int channel3;
280 int channel4;
281 int txClear;
282 int txRetries;
283 int txRouting;
284 int txScrambled;
285 int rxParameter;
286 int txTimeoutMs;
287 int txAckTimeoutMs;
288 int waitCardTimeout;
289 int waitTime;
290 int lParameter;
291 int _15;
292 int headerSize;
293 int retries;
294 int tx_delay_ms;
295 int waitReTransmitPacketMaxSize;
296 int ReTransmitPacketMaxSize;
297 int fastReTransCount;
298 int driverRetransmissions;
299 int registrationInterrupts;
300 int hardwareType;
301 int radioType;
302 int writeRadioType;
303 int writeEEPROM;
304 char siteName[17];
305 int measure_rate;
306 int in_speed;
307 int out_speed;
308 int in_speed10;
309 int out_speed10;
310 int in_speed_max;
311 int out_speed_max;
312 int pre_Command_Wait;
313 int rx_tweak1;
314 int rx_tweak2;
315 int tx_queue_len;
316};
317
318extern struct arlan_conf_stru arlan_conf[MAX_ARLANS];
319
320struct TxParam
321{
322 volatile short offset;
323 volatile short length;
324 volatile u_char dest[6];
325 volatile unsigned char clear;
326 volatile unsigned char retries;
327 volatile unsigned char routing;
328 volatile unsigned char scrambled;
329};
330
331#define TX_RING_SIZE 2
332/* Information that need to be kept for each board. */
333struct arlan_private {
334 struct net_device_stats stats;
335 struct arlan_shmem __iomem * card;
336 struct arlan_shmem * conf;
337
338 struct arlan_conf_stru * Conf;
339 int bad;
340 int reset;
341 unsigned long lastReset;
342 struct timer_list timer;
343 struct timer_list tx_delay_timer;
344 struct timer_list tx_retry_timer;
345 struct timer_list rx_check_timer;
346
347 int registrationLostCount;
348 int reRegisterExp;
349 int irq_test_done;
350
351 struct TxParam txRing[TX_RING_SIZE];
352 char reTransmitBuff[0x800];
353 int txLast;
354 unsigned ReTransmitRequested;
355 unsigned long tx_done_delayed;
356 unsigned long registrationLastSeen;
357
358 unsigned long tx_last_sent;
359 unsigned long tx_last_cleared;
360 unsigned long retransmissions;
361 unsigned long interrupt_ack_requested;
362 spinlock_t lock;
363 unsigned long waiting_command_mask;
364 unsigned long card_polling_interval;
365 unsigned long last_command_buff_free_time;
366
367 int under_reset;
368 int under_config;
369 int rx_command_given;
370 int tx_command_given;
371 unsigned long interrupt_processing_active;
372 unsigned long last_rx_int_ack_time;
373 unsigned long in_bytes;
374 unsigned long out_bytes;
375 unsigned long in_time;
376 unsigned long out_time;
377 unsigned long in_time10;
378 unsigned long out_time10;
379 unsigned long in_bytes10;
380 unsigned long out_bytes10;
381 int init_etherdev_alloc;
382};
383
384
385
386#define ARLAN_CLEAR 0x00
387#define ARLAN_RESET 0x01
388#define ARLAN_CHANNEL_ATTENTION 0x02
389#define ARLAN_INTERRUPT_ENABLE 0x04
390#define ARLAN_CLEAR_INTERRUPT 0x08
391#define ARLAN_POWER 0x40
392#define ARLAN_ACCESS 0x80
393
394#define ARLAN_COM_CONF 0x01
395#define ARLAN_COM_RX_ENABLE 0x03
396#define ARLAN_COM_RX_ABORT 0x04
397#define ARLAN_COM_TX_ENABLE 0x05
398#define ARLAN_COM_TX_ABORT 0x06
399#define ARLAN_COM_NOP 0x07
400#define ARLAN_COM_STANDBY 0x08
401#define ARLAN_COM_ACTIVATE 0x09
402#define ARLAN_COM_GOTO_SLOW_POLL 0x0a
403#define ARLAN_COM_INT 0x80
404
405
406#define TXLAST(dev) (((struct arlan_private *)netdev_priv(dev))->txRing[((struct arlan_private *)netdev_priv(dev))->txLast])
407#define TXHEAD(dev) (((struct arlan_private *)netdev_priv(dev))->txRing[0])
408#define TXTAIL(dev) (((struct arlan_private *)netdev_priv(dev))->txRing[1])
409
410#define TXBuffStart(dev) offsetof(struct arlan_shmem, txBuffer)
411#define TXBuffEnd(dev) offsetof(struct arlan_shmem, xxBuffer)
412
413#define READSHM(to,from,atype) {\
414 atype tmp;\
415 memcpy_fromio(&(tmp),&(from),sizeof(atype));\
416 to = tmp;\
417 }
418
419#define READSHMEM(from,atype)\
420 atype from; \
421 READSHM(from, arlan->from, atype);
422
423#define WRITESHM(to,from,atype) \
424 { atype tmpSHM = from;\
425 memcpy_toio(&(to),&tmpSHM,sizeof(atype));\
426 }
427
428#define DEBUGSHM(levelSHM,stringSHM,stuff,atype) \
429 { atype tmpSHM; \
430 memcpy_fromio(&tmpSHM,&(stuff),sizeof(atype));\
431 IFDEBUG(levelSHM) printk(stringSHM,tmpSHM);\
432 }
433
434#define WRITESHMB(to, val) \
435 writeb(val,&(to))
436#define READSHMB(to) \
437 readb(&(to))
438#define WRITESHMS(to, val) \
439 writew(val,&(to))
440#define READSHMS(to) \
441 readw(&(to))
442#define WRITESHMI(to, val) \
443 writel(val,&(to))
444#define READSHMI(to) \
445 readl(&(to))
446
447
448
449
450
451#define registrationBad(dev)\
452 ( ( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationMode) > 0) && \
453 ( READSHMB(((struct arlan_private *)netdev_priv(dev))->card->registrationStatus) == 0) )
454
455
456#define readControlRegister(dev)\
457 READSHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage)
458
459#define writeControlRegister(dev, v){\
460 WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->cntrlRegImage ,((v) &0xF) );\
461 WRITESHMB(((struct arlan_private *)netdev_priv(dev))->card->controlRegister ,(v) );}
462
463
464#define arlan_interrupt_lancpu(dev) {\
465 int cr; \
466 \
467 cr = readControlRegister(dev);\
468 if (cr & ARLAN_CHANNEL_ATTENTION){ \
469 writeControlRegister(dev, (cr & ~ARLAN_CHANNEL_ATTENTION));\
470 }else \
471 writeControlRegister(dev, (cr | ARLAN_CHANNEL_ATTENTION));\
472}
473
474#define clearChannelAttention(dev){ \
475 writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CHANNEL_ATTENTION);}
476#define setHardwareReset(dev) {\
477 writeControlRegister(dev,readControlRegister(dev) | ARLAN_RESET);}
478#define clearHardwareReset(dev) {\
479 writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_RESET);}
480#define setInterruptEnable(dev){\
481 writeControlRegister(dev,readControlRegister(dev) | ARLAN_INTERRUPT_ENABLE) ;}
482#define clearInterruptEnable(dev){\
483 writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_INTERRUPT_ENABLE) ;}
484#define setClearInterrupt(dev){\
485 writeControlRegister(dev,readControlRegister(dev) | ARLAN_CLEAR_INTERRUPT) ;}
486#define clearClearInterrupt(dev){\
487 writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_CLEAR_INTERRUPT);}
488#define setPowerOff(dev){\
489 writeControlRegister(dev,readControlRegister(dev) | (ARLAN_POWER && ARLAN_ACCESS));\
490 writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);}
491#define setPowerOn(dev){\
492 writeControlRegister(dev,readControlRegister(dev) & ~(ARLAN_POWER)); }
493#define arlan_lock_card_access(dev){\
494 writeControlRegister(dev,readControlRegister(dev) & ~ARLAN_ACCESS);}
495#define arlan_unlock_card_access(dev){\
496 writeControlRegister(dev,readControlRegister(dev) | ARLAN_ACCESS ); }
497
498
499
500
501#define ARLAN_COMMAND_RX 0x000001
502#define ARLAN_COMMAND_NOOP 0x000002
503#define ARLAN_COMMAND_NOOPINT 0x000004
504#define ARLAN_COMMAND_TX 0x000008
505#define ARLAN_COMMAND_CONF 0x000010
506#define ARLAN_COMMAND_RESET 0x000020
507#define ARLAN_COMMAND_TX_ABORT 0x000040
508#define ARLAN_COMMAND_RX_ABORT 0x000080
509#define ARLAN_COMMAND_POWERDOWN 0x000100
510#define ARLAN_COMMAND_POWERUP 0x000200
511#define ARLAN_COMMAND_SLOW_POLL 0x000400
512#define ARLAN_COMMAND_ACTIVATE 0x000800
513#define ARLAN_COMMAND_INT_ACK 0x001000
514#define ARLAN_COMMAND_INT_ENABLE 0x002000
515#define ARLAN_COMMAND_WAIT_NOW 0x004000
516#define ARLAN_COMMAND_LONG_WAIT_NOW 0x008000
517#define ARLAN_COMMAND_STANDBY 0x010000
518#define ARLAN_COMMAND_INT_RACK 0x020000
519#define ARLAN_COMMAND_INT_RENABLE 0x040000
520#define ARLAN_COMMAND_CONF_WAIT 0x080000
521#define ARLAN_COMMAND_TBUSY_CLEAR 0x100000
522#define ARLAN_COMMAND_CLEAN_AND_CONF (ARLAN_COMMAND_TX_ABORT\
523 | ARLAN_COMMAND_RX_ABORT\
524 | ARLAN_COMMAND_CONF)
525#define ARLAN_COMMAND_CLEAN_AND_RESET (ARLAN_COMMAND_TX_ABORT\
526 | ARLAN_COMMAND_RX_ABORT\
527 | ARLAN_COMMAND_RESET)
528
529
530
531#define ARLAN_DEBUG_CHAIN_LOCKS 0x00001
532#define ARLAN_DEBUG_RESET 0x00002
533#define ARLAN_DEBUG_TIMING 0x00004
534#define ARLAN_DEBUG_CARD_STATE 0x00008
535#define ARLAN_DEBUG_TX_CHAIN 0x00010
536#define ARLAN_DEBUG_MULTICAST 0x00020
537#define ARLAN_DEBUG_HEADER_DUMP 0x00040
538#define ARLAN_DEBUG_INTERRUPT 0x00080
539#define ARLAN_DEBUG_STARTUP 0x00100
540#define ARLAN_DEBUG_SHUTDOWN 0x00200
541
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
new file mode 100644
index 000000000000..18a7d38d2a13
--- /dev/null
+++ b/drivers/net/wireless/atmel.c
@@ -0,0 +1,4272 @@
1/*** -*- linux-c -*- **********************************************************
2
3 Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
4
5 Copyright 2000-2001 ATMEL Corporation.
6 Copyright 2003-2004 Simon Kelley.
7
8 This code was developed from version 2.1.1 of the Atmel drivers,
9 released by Atmel corp. under the GPL in December 2002. It also
10 includes code from the Linux aironet drivers (C) Benjamin Reed,
11 and the Linux PCMCIA package, (C) David Hinds and the Linux wireless
12 extensions, (C) Jean Tourrilhes.
13
14 The firmware module for reading the MAC address of the card comes from
15 net.russotto.AtmelMACFW, written by Matthew T. Russotto and copyright
16 by him. net.russotto.AtmelMACFW is used under the GPL license version 2.
17 This file contains the module in binary form and, under the terms
18 of the GPL, in source form. The source is located at the end of the file.
19
20 This program is free software; you can redistribute it and/or modify
21 it under the terms of the GNU General Public License as published by
22 the Free Software Foundation; either version 2 of the License, or
23 (at your option) any later version.
24
25 This software is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 GNU General Public License for more details.
29
30 You should have received a copy of the GNU General Public License
31 along with Atmel wireless lan drivers; if not, write to the Free Software
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33
34 For all queries about this code, please contact the current author,
35 Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
36
37 Credit is due to HP UK and Cambridge Online Systems Ltd for supplying
38 hardware used during development of this driver.
39
40******************************************************************************/
41
42#include <linux/config.h>
43#include <linux/init.h>
44
45#include <linux/kernel.h>
46#include <linux/sched.h>
47#include <linux/ptrace.h>
48#include <linux/slab.h>
49#include <linux/string.h>
50#include <linux/ctype.h>
51#include <linux/timer.h>
52#include <asm/io.h>
53#include <asm/system.h>
54#include <asm/uaccess.h>
55#include <linux/module.h>
56#include <linux/netdevice.h>
57#include <linux/etherdevice.h>
58#include <linux/skbuff.h>
59#include <linux/if_arp.h>
60#include <linux/ioport.h>
61#include <linux/fcntl.h>
62#include <linux/delay.h>
63#include <linux/wireless.h>
64#include <net/iw_handler.h>
65#include <linux/byteorder/generic.h>
66#include <linux/crc32.h>
67#include <linux/proc_fs.h>
68#include <linux/device.h>
69#include <linux/moduleparam.h>
70#include <linux/firmware.h>
71#include "ieee802_11.h"
72#include "atmel.h"
73
74#define DRIVER_MAJOR 0
75#define DRIVER_MINOR 96
76
77MODULE_AUTHOR("Simon Kelley");
78MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
79MODULE_LICENSE("GPL");
80MODULE_SUPPORTED_DEVICE("Atmel at76c50x wireless cards");
81
82/* The name of the firmware file to be loaded
83 over-rides any automatic selection */
84static char *firmware = NULL;
85module_param(firmware, charp, 0);
86
87/* table of firmware file names */
88static struct {
89 AtmelFWType fw_type;
90 const char *fw_file;
91 const char *fw_file_ext;
92} fw_table[] = {
93 { ATMEL_FW_TYPE_502, "atmel_at76c502", "bin" },
94 { ATMEL_FW_TYPE_502D, "atmel_at76c502d", "bin" },
95 { ATMEL_FW_TYPE_502E, "atmel_at76c502e", "bin" },
96 { ATMEL_FW_TYPE_502_3COM, "atmel_at76c502_3com", "bin" },
97 { ATMEL_FW_TYPE_504, "atmel_at76c504", "bin" },
98 { ATMEL_FW_TYPE_504_2958, "atmel_at76c504_2958", "bin" },
99 { ATMEL_FW_TYPE_504A_2958,"atmel_at76c504a_2958","bin" },
100 { ATMEL_FW_TYPE_506, "atmel_at76c506", "bin" },
101 { ATMEL_FW_TYPE_NONE, NULL, NULL }
102};
103
104#define MAX_SSID_LENGTH 32
105#define MGMT_JIFFIES (256 * HZ / 100)
106
107#define MAX_BSS_ENTRIES 64
108
109/* registers */
110#define GCR 0x00 // (SIR0) General Configuration Register
111#define BSR 0x02 // (SIR1) Bank Switching Select Register
112#define AR 0x04
113#define DR 0x08
114#define MR1 0x12 // Mirror Register 1
115#define MR2 0x14 // Mirror Register 2
116#define MR3 0x16 // Mirror Register 3
117#define MR4 0x18 // Mirror Register 4
118
119#define GPR1 0x0c
120#define GPR2 0x0e
121#define GPR3 0x10
122//
123// Constants for the GCR register.
124//
125#define GCR_REMAP 0x0400 // Remap internal SRAM to 0
126#define GCR_SWRES 0x0080 // BIU reset (ARM and PAI are NOT reset)
127#define GCR_CORES 0x0060 // Core Reset (ARM and PAI are reset)
128#define GCR_ENINT 0x0002 // Enable Interrupts
129#define GCR_ACKINT 0x0008 // Acknowledge Interrupts
130
131#define BSS_SRAM 0x0200 // AMBA module selection --> SRAM
132#define BSS_IRAM 0x0100 // AMBA module selection --> IRAM
133//
134// Constants for the MR registers.
135//
136#define MAC_INIT_COMPLETE 0x0001 // MAC init has been completed
137#define MAC_BOOT_COMPLETE 0x0010 // MAC boot has been completed
138#define MAC_INIT_OK 0x0002 // MAC boot has been completed
139
140#define C80211_SUBTYPE_MGMT_ASS_REQUEST 0x00
141#define C80211_SUBTYPE_MGMT_ASS_RESPONSE 0x10
142#define C80211_SUBTYPE_MGMT_REASS_REQUEST 0x20
143#define C80211_SUBTYPE_MGMT_REASS_RESPONSE 0x30
144#define C80211_SUBTYPE_MGMT_ProbeRequest 0x40
145#define C80211_SUBTYPE_MGMT_ProbeResponse 0x50
146#define C80211_SUBTYPE_MGMT_BEACON 0x80
147#define C80211_SUBTYPE_MGMT_ATIM 0x90
148#define C80211_SUBTYPE_MGMT_DISASSOSIATION 0xA0
149#define C80211_SUBTYPE_MGMT_Authentication 0xB0
150#define C80211_SUBTYPE_MGMT_Deauthentication 0xC0
151
152#define C80211_MGMT_AAN_OPENSYSTEM 0x0000
153#define C80211_MGMT_AAN_SHAREDKEY 0x0001
154
155#define C80211_MGMT_CAPABILITY_ESS 0x0001 // see 802.11 p.58
156#define C80211_MGMT_CAPABILITY_IBSS 0x0002 // - " -
157#define C80211_MGMT_CAPABILITY_CFPollable 0x0004 // - " -
158#define C80211_MGMT_CAPABILITY_CFPollRequest 0x0008 // - " -
159#define C80211_MGMT_CAPABILITY_Privacy 0x0010 // - " -
160
161#define C80211_MGMT_SC_Success 0
162#define C80211_MGMT_SC_Unspecified 1
163#define C80211_MGMT_SC_SupportCapabilities 10
164#define C80211_MGMT_SC_ReassDenied 11
165#define C80211_MGMT_SC_AssDenied 12
166#define C80211_MGMT_SC_AuthAlgNotSupported 13
167#define C80211_MGMT_SC_AuthTransSeqNumError 14
168#define C80211_MGMT_SC_AuthRejectChallenge 15
169#define C80211_MGMT_SC_AuthRejectTimeout 16
170#define C80211_MGMT_SC_AssDeniedHandleAP 17
171#define C80211_MGMT_SC_AssDeniedBSSRate 18
172
173#define C80211_MGMT_ElementID_SSID 0
174#define C80211_MGMT_ElementID_SupportedRates 1
175#define C80211_MGMT_ElementID_ChallengeText 16
176#define C80211_MGMT_CAPABILITY_ShortPreamble 0x0020
177
178#define MIB_MAX_DATA_BYTES 212
179#define MIB_HEADER_SIZE 4 /* first four fields */
180
181struct get_set_mib {
182 u8 type;
183 u8 size;
184 u8 index;
185 u8 reserved;
186 u8 data[MIB_MAX_DATA_BYTES];
187};
188
189struct rx_desc {
190 u32 Next;
191 u16 MsduPos;
192 u16 MsduSize;
193
194 u8 State;
195 u8 Status;
196 u8 Rate;
197 u8 Rssi;
198 u8 LinkQuality;
199 u8 PreambleType;
200 u16 Duration;
201 u32 RxTime;
202
203};
204
205#define RX_DESC_FLAG_VALID 0x80
206#define RX_DESC_FLAG_CONSUMED 0x40
207#define RX_DESC_FLAG_IDLE 0x00
208
209#define RX_STATUS_SUCCESS 0x00
210
211#define RX_DESC_MSDU_POS_OFFSET 4
212#define RX_DESC_MSDU_SIZE_OFFSET 6
213#define RX_DESC_FLAGS_OFFSET 8
214#define RX_DESC_STATUS_OFFSET 9
215#define RX_DESC_RSSI_OFFSET 11
216#define RX_DESC_LINK_QUALITY_OFFSET 12
217#define RX_DESC_PREAMBLE_TYPE_OFFSET 13
218#define RX_DESC_DURATION_OFFSET 14
219#define RX_DESC_RX_TIME_OFFSET 16
220
221
222struct tx_desc {
223 u32 NextDescriptor;
224 u16 TxStartOfFrame;
225 u16 TxLength;
226
227 u8 TxState;
228 u8 TxStatus;
229 u8 RetryCount;
230
231 u8 TxRate;
232
233 u8 KeyIndex;
234 u8 ChiperType;
235 u8 ChipreLength;
236 u8 Reserved1;
237
238 u8 Reserved;
239 u8 PacketType;
240 u16 HostTxLength;
241
242};
243
244
245#define TX_DESC_NEXT_OFFSET 0
246#define TX_DESC_POS_OFFSET 4
247#define TX_DESC_SIZE_OFFSET 6
248#define TX_DESC_FLAGS_OFFSET 8
249#define TX_DESC_STATUS_OFFSET 9
250#define TX_DESC_RETRY_OFFSET 10
251#define TX_DESC_RATE_OFFSET 11
252#define TX_DESC_KEY_INDEX_OFFSET 12
253#define TX_DESC_CIPHER_TYPE_OFFSET 13
254#define TX_DESC_CIPHER_LENGTH_OFFSET 14
255#define TX_DESC_PACKET_TYPE_OFFSET 17
256#define TX_DESC_HOST_LENGTH_OFFSET 18
257
258
259
260///////////////////////////////////////////////////////
261// Host-MAC interface
262///////////////////////////////////////////////////////
263
264#define TX_STATUS_SUCCESS 0x00
265
266#define TX_FIRM_OWN 0x80
267#define TX_DONE 0x40
268
269
270#define TX_ERROR 0x01
271
272#define TX_PACKET_TYPE_DATA 0x01
273#define TX_PACKET_TYPE_MGMT 0x02
274
275#define ISR_EMPTY 0x00 // no bits set in ISR
276#define ISR_TxCOMPLETE 0x01 // packet transmitted
277#define ISR_RxCOMPLETE 0x02 // packet received
278#define ISR_RxFRAMELOST 0x04 // Rx Frame lost
279#define ISR_FATAL_ERROR 0x08 // Fatal error
280#define ISR_COMMAND_COMPLETE 0x10 // command completed
281#define ISR_OUT_OF_RANGE 0x20 // command completed
282#define ISR_IBSS_MERGE 0x40 // (4.1.2.30): IBSS merge
283#define ISR_GENERIC_IRQ 0x80
284
285
286#define Local_Mib_Type 0x01
287#define Mac_Address_Mib_Type 0x02
288#define Mac_Mib_Type 0x03
289#define Statistics_Mib_Type 0x04
290#define Mac_Mgmt_Mib_Type 0x05
291#define Mac_Wep_Mib_Type 0x06
292#define Phy_Mib_Type 0x07
293#define Multi_Domain_MIB 0x08
294
295#define MAC_MGMT_MIB_CUR_BSSID_POS 14
296#define MAC_MIB_FRAG_THRESHOLD_POS 8
297#define MAC_MIB_RTS_THRESHOLD_POS 10
298#define MAC_MIB_SHORT_RETRY_POS 16
299#define MAC_MIB_LONG_RETRY_POS 17
300#define MAC_MIB_SHORT_RETRY_LIMIT_POS 16
301#define MAC_MGMT_MIB_BEACON_PER_POS 0
302#define MAC_MGMT_MIB_STATION_ID_POS 6
303#define MAC_MGMT_MIB_CUR_PRIVACY_POS 11
304#define MAC_MGMT_MIB_CUR_BSSID_POS 14
305#define MAC_MGMT_MIB_PS_MODE_POS 53
306#define MAC_MGMT_MIB_LISTEN_INTERVAL_POS 54
307#define MAC_MGMT_MIB_MULTI_DOMAIN_IMPLEMENTED 56
308#define MAC_MGMT_MIB_MULTI_DOMAIN_ENABLED 57
309#define PHY_MIB_CHANNEL_POS 14
310#define PHY_MIB_RATE_SET_POS 20
311#define PHY_MIB_REG_DOMAIN_POS 26
312#define LOCAL_MIB_AUTO_TX_RATE_POS 3
313#define LOCAL_MIB_SSID_SIZE 5
314#define LOCAL_MIB_TX_PROMISCUOUS_POS 6
315#define LOCAL_MIB_TX_MGMT_RATE_POS 7
316#define LOCAL_MIB_TX_CONTROL_RATE_POS 8
317#define LOCAL_MIB_PREAMBLE_TYPE 9
318#define MAC_ADDR_MIB_MAC_ADDR_POS 0
319
320
321#define CMD_Set_MIB_Vars 0x01
322#define CMD_Get_MIB_Vars 0x02
323#define CMD_Scan 0x03
324#define CMD_Join 0x04
325#define CMD_Start 0x05
326#define CMD_EnableRadio 0x06
327#define CMD_DisableRadio 0x07
328#define CMD_SiteSurvey 0x0B
329
330#define CMD_STATUS_IDLE 0x00
331#define CMD_STATUS_COMPLETE 0x01
332#define CMD_STATUS_UNKNOWN 0x02
333#define CMD_STATUS_INVALID_PARAMETER 0x03
334#define CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
335#define CMD_STATUS_TIME_OUT 0x07
336#define CMD_STATUS_IN_PROGRESS 0x08
337#define CMD_STATUS_REJECTED_RADIO_OFF 0x09
338#define CMD_STATUS_HOST_ERROR 0xFF
339#define CMD_STATUS_BUSY 0xFE
340
341
342#define CMD_BLOCK_COMMAND_OFFSET 0
343#define CMD_BLOCK_STATUS_OFFSET 1
344#define CMD_BLOCK_PARAMETERS_OFFSET 4
345
346#define SCAN_OPTIONS_SITE_SURVEY 0x80
347
348#define MGMT_FRAME_BODY_OFFSET 24
349#define MAX_AUTHENTICATION_RETRIES 3
350#define MAX_ASSOCIATION_RETRIES 3
351
352#define AUTHENTICATION_RESPONSE_TIME_OUT 1000
353
354#define MAX_WIRELESS_BODY 2316 /* mtu is 2312, CRC is 4 */
355#define LOOP_RETRY_LIMIT 500000
356
357#define ACTIVE_MODE 1
358#define PS_MODE 2
359
360#define MAX_ENCRYPTION_KEYS 4
361#define MAX_ENCRYPTION_KEY_SIZE 40
362
363///////////////////////////////////////////////////////////////////////////
364// 802.11 related definitions
365///////////////////////////////////////////////////////////////////////////
366
367//
368// Regulatory Domains
369//
370
371#define REG_DOMAIN_FCC 0x10 //Channels 1-11 USA
372#define REG_DOMAIN_DOC 0x20 //Channel 1-11 Canada
373#define REG_DOMAIN_ETSI 0x30 //Channel 1-13 Europe (ex Spain/France)
374#define REG_DOMAIN_SPAIN 0x31 //Channel 10-11 Spain
375#define REG_DOMAIN_FRANCE 0x32 //Channel 10-13 France
376#define REG_DOMAIN_MKK 0x40 //Channel 14 Japan
377#define REG_DOMAIN_MKK1 0x41 //Channel 1-14 Japan(MKK1)
378#define REG_DOMAIN_ISRAEL 0x50 //Channel 3-9 ISRAEL
379
380#define BSS_TYPE_AD_HOC 1
381#define BSS_TYPE_INFRASTRUCTURE 2
382
383#define SCAN_TYPE_ACTIVE 0
384#define SCAN_TYPE_PASSIVE 1
385
386#define LONG_PREAMBLE 0
387#define SHORT_PREAMBLE 1
388#define AUTO_PREAMBLE 2
389
390#define DATA_FRAME_WS_HEADER_SIZE 30
391
392/* promiscuous mode control */
393#define PROM_MODE_OFF 0x0
394#define PROM_MODE_UNKNOWN 0x1
395#define PROM_MODE_CRC_FAILED 0x2
396#define PROM_MODE_DUPLICATED 0x4
397#define PROM_MODE_MGMT 0x8
398#define PROM_MODE_CTRL 0x10
399#define PROM_MODE_BAD_PROTOCOL 0x20
400
401
402#define IFACE_INT_STATUS_OFFSET 0
403#define IFACE_INT_MASK_OFFSET 1
404#define IFACE_LOCKOUT_HOST_OFFSET 2
405#define IFACE_LOCKOUT_MAC_OFFSET 3
406#define IFACE_FUNC_CTRL_OFFSET 28
407#define IFACE_MAC_STAT_OFFSET 30
408#define IFACE_GENERIC_INT_TYPE_OFFSET 32
409
410#define CIPHER_SUITE_NONE 0
411#define CIPHER_SUITE_WEP_64 1
412#define CIPHER_SUITE_TKIP 2
413#define CIPHER_SUITE_AES 3
414#define CIPHER_SUITE_CCX 4
415#define CIPHER_SUITE_WEP_128 5
416
417//
418// IFACE MACROS & definitions
419//
420//
421
422// FuncCtrl field:
423//
424#define FUNC_CTRL_TxENABLE 0x10
425#define FUNC_CTRL_RxENABLE 0x20
426#define FUNC_CTRL_INIT_COMPLETE 0x01
427
428/* A stub firmware image which reads the MAC address from NVRAM on the card.
429 For copyright information and source see the end of this file. */
430static u8 mac_reader[] = {
431 0x06,0x00,0x00,0xea,0x04,0x00,0x00,0xea,0x03,0x00,0x00,0xea,0x02,0x00,0x00,0xea,
432 0x01,0x00,0x00,0xea,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xea,0xfe,0xff,0xff,0xea,
433 0xd3,0x00,0xa0,0xe3,0x00,0xf0,0x21,0xe1,0x0e,0x04,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
434 0x81,0x11,0xa0,0xe1,0x00,0x10,0x81,0xe3,0x00,0x10,0x80,0xe5,0x1c,0x10,0x90,0xe5,
435 0x10,0x10,0xc1,0xe3,0x1c,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3,0x08,0x10,0x80,0xe5,
436 0x02,0x03,0xa0,0xe3,0x00,0x10,0xa0,0xe3,0xb0,0x10,0xc0,0xe1,0xb4,0x10,0xc0,0xe1,
437 0xb8,0x10,0xc0,0xe1,0xbc,0x10,0xc0,0xe1,0x56,0xdc,0xa0,0xe3,0x21,0x00,0x00,0xeb,
438 0x0a,0x00,0xa0,0xe3,0x1a,0x00,0x00,0xeb,0x10,0x00,0x00,0xeb,0x07,0x00,0x00,0xeb,
439 0x02,0x03,0xa0,0xe3,0x02,0x14,0xa0,0xe3,0xb4,0x10,0xc0,0xe1,0x4c,0x10,0x9f,0xe5,
440 0xbc,0x10,0xc0,0xe1,0x10,0x10,0xa0,0xe3,0xb8,0x10,0xc0,0xe1,0xfe,0xff,0xff,0xea,
441 0x00,0x40,0x2d,0xe9,0x00,0x20,0xa0,0xe3,0x02,0x3c,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
442 0x28,0x00,0x9f,0xe5,0x37,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,
443 0x00,0x40,0x2d,0xe9,0x12,0x2e,0xa0,0xe3,0x06,0x30,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
444 0x02,0x04,0xa0,0xe3,0x2f,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,
445 0x00,0x02,0x00,0x02,0x80,0x01,0x90,0xe0,0x01,0x00,0x00,0x0a,0x01,0x00,0x50,0xe2,
446 0xfc,0xff,0xff,0xea,0x1e,0xff,0x2f,0xe1,0x80,0x10,0xa0,0xe3,0xf3,0x06,0xa0,0xe3,
447 0x00,0x10,0x80,0xe5,0x00,0x10,0xa0,0xe3,0x00,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3,
448 0x04,0x10,0x80,0xe5,0x00,0x10,0x80,0xe5,0x0e,0x34,0xa0,0xe3,0x1c,0x10,0x93,0xe5,
449 0x02,0x1a,0x81,0xe3,0x1c,0x10,0x83,0xe5,0x58,0x11,0x9f,0xe5,0x30,0x10,0x80,0xe5,
450 0x54,0x11,0x9f,0xe5,0x34,0x10,0x80,0xe5,0x38,0x10,0x80,0xe5,0x3c,0x10,0x80,0xe5,
451 0x10,0x10,0x90,0xe5,0x08,0x00,0x90,0xe5,0x1e,0xff,0x2f,0xe1,0xf3,0x16,0xa0,0xe3,
452 0x08,0x00,0x91,0xe5,0x05,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,0x10,0x00,0x91,0xe5,
453 0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0xff,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,
454 0x10,0x00,0x91,0xe5,0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5,
455 0x10,0x00,0x91,0xe5,0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5,
456 0xff,0x00,0x00,0xe2,0x1e,0xff,0x2f,0xe1,0x30,0x40,0x2d,0xe9,0x00,0x50,0xa0,0xe1,
457 0x03,0x40,0xa0,0xe1,0xa2,0x02,0xa0,0xe1,0x08,0x00,0x00,0xe2,0x03,0x00,0x80,0xe2,
458 0xd8,0x10,0x9f,0xe5,0x00,0x00,0xc1,0xe5,0x01,0x20,0xc1,0xe5,0xe2,0xff,0xff,0xeb,
459 0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x1a,0x14,0x00,0xa0,0xe3,0xc4,0xff,0xff,0xeb,
460 0x04,0x20,0xa0,0xe1,0x05,0x10,0xa0,0xe1,0x02,0x00,0xa0,0xe3,0x01,0x00,0x00,0xeb,
461 0x30,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x70,0x40,0x2d,0xe9,0xf3,0x46,0xa0,0xe3,
462 0x00,0x30,0xa0,0xe3,0x00,0x00,0x50,0xe3,0x08,0x00,0x00,0x9a,0x8c,0x50,0x9f,0xe5,
463 0x03,0x60,0xd5,0xe7,0x0c,0x60,0x84,0xe5,0x10,0x60,0x94,0xe5,0x02,0x00,0x16,0xe3,
464 0xfc,0xff,0xff,0x0a,0x01,0x30,0x83,0xe2,0x00,0x00,0x53,0xe1,0xf7,0xff,0xff,0x3a,
465 0xff,0x30,0xa0,0xe3,0x0c,0x30,0x84,0xe5,0x08,0x00,0x94,0xe5,0x10,0x00,0x94,0xe5,
466 0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x94,0xe5,0x00,0x00,0xa0,0xe3,
467 0x00,0x00,0x52,0xe3,0x0b,0x00,0x00,0x9a,0x10,0x50,0x94,0xe5,0x02,0x00,0x15,0xe3,
468 0xfc,0xff,0xff,0x0a,0x0c,0x30,0x84,0xe5,0x10,0x50,0x94,0xe5,0x01,0x00,0x15,0xe3,
469 0xfc,0xff,0xff,0x0a,0x08,0x50,0x94,0xe5,0x01,0x50,0xc1,0xe4,0x01,0x00,0x80,0xe2,
470 0x02,0x00,0x50,0xe1,0xf3,0xff,0xff,0x3a,0xc8,0x00,0xa0,0xe3,0x98,0xff,0xff,0xeb,
471 0x70,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x01,0x0c,0x00,0x02,0x01,0x02,0x00,0x02,
472 0x00,0x01,0x00,0x02
473};
474
475struct atmel_private {
476 void *card; /* Bus dependent stucture varies for PCcard */
477 int (*present_callback)(void *); /* And callback which uses it */
478 char firmware_id[32];
479 AtmelFWType firmware_type;
480 u8 *firmware;
481 int firmware_length;
482 struct timer_list management_timer;
483 struct net_device *dev;
484 struct device *sys_dev;
485 struct iw_statistics wstats;
486 struct net_device_stats stats; // device stats
487 spinlock_t irqlock, timerlock; // spinlocks
488 enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
489 enum {
490 CARD_TYPE_PARALLEL_FLASH,
491 CARD_TYPE_SPI_FLASH,
492 CARD_TYPE_EEPROM
493 } card_type;
494 int do_rx_crc; /* If we need to CRC incoming packets */
495 int probe_crc; /* set if we don't yet know */
496 int crc_ok_cnt, crc_ko_cnt; /* counters for probing */
497 u16 rx_desc_head;
498 u16 tx_desc_free, tx_desc_head, tx_desc_tail, tx_desc_previous;
499 u16 tx_free_mem, tx_buff_head, tx_buff_tail;
500
501 u16 frag_seq, frag_len, frag_no;
502 u8 frag_source[6];
503
504 u8 wep_is_on, default_key, exclude_unencrypted, encryption_level;
505 u8 group_cipher_suite, pairwise_cipher_suite;
506 u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
507 int wep_key_len[MAX_ENCRYPTION_KEYS];
508 int use_wpa, radio_on_broken; /* firmware dependent stuff. */
509
510 u16 host_info_base;
511 struct host_info_struct {
512 /* NB this is matched to the hardware, don't change. */
513 u8 volatile int_status;
514 u8 volatile int_mask;
515 u8 volatile lockout_host;
516 u8 volatile lockout_mac;
517
518 u16 tx_buff_pos;
519 u16 tx_buff_size;
520 u16 tx_desc_pos;
521 u16 tx_desc_count;
522
523 u16 rx_buff_pos;
524 u16 rx_buff_size;
525 u16 rx_desc_pos;
526 u16 rx_desc_count;
527
528 u16 build_version;
529 u16 command_pos;
530
531 u16 major_version;
532 u16 minor_version;
533
534 u16 func_ctrl;
535 u16 mac_status;
536 u16 generic_IRQ_type;
537 u8 reserved[2];
538 } host_info;
539
540 enum {
541 STATION_STATE_SCANNING,
542 STATION_STATE_JOINNING,
543 STATION_STATE_AUTHENTICATING,
544 STATION_STATE_ASSOCIATING,
545 STATION_STATE_READY,
546 STATION_STATE_REASSOCIATING,
547 STATION_STATE_DOWN,
548 STATION_STATE_MGMT_ERROR
549 } station_state;
550
551 int operating_mode, power_mode;
552 time_t last_qual;
553 int beacons_this_sec;
554 int channel;
555 int reg_domain, config_reg_domain;
556 int tx_rate;
557 int auto_tx_rate;
558 int rts_threshold;
559 int frag_threshold;
560 int long_retry, short_retry;
561 int preamble;
562 int default_beacon_period, beacon_period, listen_interval;
563 int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;
564 int AuthenticationRequestRetryCnt, AssociationRequestRetryCnt, ReAssociationRequestRetryCnt;
565 enum {
566 SITE_SURVEY_IDLE,
567 SITE_SURVEY_IN_PROGRESS,
568 SITE_SURVEY_COMPLETED
569 } site_survey_state;
570 time_t last_survey;
571
572 int station_was_associated, station_is_associated;
573 int fast_scan;
574
575 struct bss_info {
576 int channel;
577 int SSIDsize;
578 int RSSI;
579 int UsingWEP;
580 int preamble;
581 int beacon_period;
582 int BSStype;
583 u8 BSSID[6];
584 u8 SSID[MAX_SSID_LENGTH];
585 } BSSinfo[MAX_BSS_ENTRIES];
586 int BSS_list_entries, current_BSS;
587 int connect_to_any_BSS;
588 int SSID_size, new_SSID_size;
589 u8 CurrentBSSID[6], BSSID[6];
590 u8 SSID[MAX_SSID_LENGTH], new_SSID[MAX_SSID_LENGTH];
591 u64 last_beacon_timestamp;
592 u8 rx_buf[MAX_WIRELESS_BODY];
593
594};
595
596static u8 atmel_basic_rates[4] = {0x82,0x84,0x0b,0x16};
597
598static const struct {
599 int reg_domain;
600 int min, max;
601 char *name;
602} channel_table[] = { { REG_DOMAIN_FCC, 1, 11, "USA" },
603 { REG_DOMAIN_DOC, 1, 11, "Canada" },
604 { REG_DOMAIN_ETSI, 1, 13, "Europe" },
605 { REG_DOMAIN_SPAIN, 10, 11, "Spain" },
606 { REG_DOMAIN_FRANCE, 10, 13, "France" },
607 { REG_DOMAIN_MKK, 14, 14, "MKK" },
608 { REG_DOMAIN_MKK1, 1, 14, "MKK1" },
609 { REG_DOMAIN_ISRAEL, 3, 9, "Israel"} };
610
611static void build_wpa_mib(struct atmel_private *priv);
612static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
613static void atmel_copy_to_card(struct net_device *dev, u16 dest, unsigned char *src, u16 len);
614static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, u16 src, u16 len);
615static void atmel_set_gcr(struct net_device *dev, u16 mask);
616static void atmel_clear_gcr(struct net_device *dev, u16 mask);
617static int atmel_lock_mac(struct atmel_private *priv);
618static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
619static void atmel_command_irq(struct atmel_private *priv);
620static int atmel_validate_channel(struct atmel_private *priv, int channel);
621static void atmel_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header,
622 u16 frame_len, u8 rssi);
623static void atmel_management_timer(u_long a);
624static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);
625static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);
626static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header,
627 u8 *body, int body_len);
628
629static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
630static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data);
631static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, u16 data);
632static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len);
633static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len);
634static void atmel_scan(struct atmel_private *priv, int specific_ssid);
635static void atmel_join_bss(struct atmel_private *priv, int bss_index);
636static void atmel_smooth_qual(struct atmel_private *priv);
637static void atmel_writeAR(struct net_device *dev, u16 data);
638static int probe_atmel_card(struct net_device *dev);
639static int reset_atmel_card(struct net_device *dev );
640static void atmel_enter_state(struct atmel_private *priv, int new_state);
641int atmel_open (struct net_device *dev);
642
643static inline u16 atmel_hi(struct atmel_private *priv, u16 offset)
644{
645 return priv->host_info_base + offset;
646}
647
648static inline u16 atmel_co(struct atmel_private *priv, u16 offset)
649{
650 return priv->host_info.command_pos + offset;
651}
652
653static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16 desc)
654{
655 return priv->host_info.rx_desc_pos + (sizeof(struct rx_desc) * desc) + offset;
656}
657
658static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16 desc)
659{
660 return priv->host_info.tx_desc_pos + (sizeof(struct tx_desc) * desc) + offset;
661}
662
663static inline u8 atmel_read8(struct net_device *dev, u16 offset)
664{
665 return inb(dev->base_addr + offset);
666}
667
668static inline void atmel_write8(struct net_device *dev, u16 offset, u8 data)
669{
670 outb(data, dev->base_addr + offset);
671}
672
673static inline u16 atmel_read16(struct net_device *dev, u16 offset)
674{
675 return inw(dev->base_addr + offset);
676}
677
678static inline void atmel_write16(struct net_device *dev, u16 offset, u16 data)
679{
680 outw(data, dev->base_addr + offset);
681}
682
683static inline u8 atmel_rmem8(struct atmel_private *priv, u16 pos)
684{
685 atmel_writeAR(priv->dev, pos);
686 return atmel_read8(priv->dev, DR);
687}
688
689static inline void atmel_wmem8(struct atmel_private *priv, u16 pos, u16 data)
690{
691 atmel_writeAR(priv->dev, pos);
692 atmel_write8(priv->dev, DR, data);
693}
694
695static inline u16 atmel_rmem16(struct atmel_private *priv, u16 pos)
696{
697 atmel_writeAR(priv->dev, pos);
698 return atmel_read16(priv->dev, DR);
699}
700
701static inline void atmel_wmem16(struct atmel_private *priv, u16 pos, u16 data)
702{
703 atmel_writeAR(priv->dev, pos);
704 atmel_write16(priv->dev, DR, data);
705}
706
707static const struct iw_handler_def atmel_handler_def;
708
709static void tx_done_irq(struct atmel_private *priv)
710{
711 int i;
712
713 for (i = 0;
714 atmel_rmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head)) == TX_DONE &&
715 i < priv->host_info.tx_desc_count;
716 i++) {
717
718 u8 status = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_STATUS_OFFSET, priv->tx_desc_head));
719 u16 msdu_size = atmel_rmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_head));
720 u8 type = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_head));
721
722 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head), 0);
723
724 priv->tx_free_mem += msdu_size;
725 priv->tx_desc_free++;
726
727 if (priv->tx_buff_head + msdu_size > (priv->host_info.tx_buff_pos + priv->host_info.tx_buff_size))
728 priv->tx_buff_head = 0;
729 else
730 priv->tx_buff_head += msdu_size;
731
732 if (priv->tx_desc_head < (priv->host_info.tx_desc_count - 1))
733 priv->tx_desc_head++ ;
734 else
735 priv->tx_desc_head = 0;
736
737 if (type == TX_PACKET_TYPE_DATA) {
738 if (status == TX_STATUS_SUCCESS)
739 priv->stats.tx_packets++;
740 else
741 priv->stats.tx_errors++;
742 netif_wake_queue(priv->dev);
743 }
744 }
745}
746
747static u16 find_tx_buff(struct atmel_private *priv, u16 len)
748{
749 u16 bottom_free = priv->host_info.tx_buff_size - priv->tx_buff_tail;
750
751 if (priv->tx_desc_free == 3 || priv->tx_free_mem < len)
752 return 0;
753
754 if (bottom_free >= len)
755 return priv->host_info.tx_buff_pos + priv->tx_buff_tail;
756
757 if (priv->tx_free_mem - bottom_free >= len) {
758 priv->tx_buff_tail = 0;
759 return priv->host_info.tx_buff_pos;
760 }
761
762 return 0;
763}
764
765static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 len, u16 buff, u8 type)
766{
767 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, priv->tx_desc_tail), buff);
768 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_tail), len);
769 if (!priv->use_wpa)
770 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_HOST_LENGTH_OFFSET, priv->tx_desc_tail), len);
771 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_tail), type);
772 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RATE_OFFSET, priv->tx_desc_tail), priv->tx_rate);
773 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RETRY_OFFSET, priv->tx_desc_tail), 0);
774 if (priv->use_wpa) {
775 int cipher_type, cipher_length;
776 if (is_bcast) {
777 cipher_type = priv->group_cipher_suite;
778 if (cipher_type == CIPHER_SUITE_WEP_64 ||
779 cipher_type == CIPHER_SUITE_WEP_128 )
780 cipher_length = 8;
781 else if (cipher_type == CIPHER_SUITE_TKIP)
782 cipher_length = 12;
783 else if (priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_64 ||
784 priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_128) {
785 cipher_type = priv->pairwise_cipher_suite;
786 cipher_length = 8;
787 } else {
788 cipher_type = CIPHER_SUITE_NONE;
789 cipher_length = 0;
790 }
791 } else {
792 cipher_type = priv->pairwise_cipher_suite;
793 if (cipher_type == CIPHER_SUITE_WEP_64 ||
794 cipher_type == CIPHER_SUITE_WEP_128 )
795 cipher_length = 8;
796 else if (cipher_type == CIPHER_SUITE_TKIP)
797 cipher_length = 12;
798 else if (priv->group_cipher_suite == CIPHER_SUITE_WEP_64 ||
799 priv->group_cipher_suite == CIPHER_SUITE_WEP_128) {
800 cipher_type = priv->group_cipher_suite;
801 cipher_length = 8;
802 } else {
803 cipher_type = CIPHER_SUITE_NONE;
804 cipher_length = 0;
805 }
806 }
807
808 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_TYPE_OFFSET, priv->tx_desc_tail),
809 cipher_type);
810 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_LENGTH_OFFSET, priv->tx_desc_tail),
811 cipher_length);
812 }
813 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_tail), 0x80000000L);
814 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_tail), TX_FIRM_OWN);
815 if (priv->tx_desc_previous != priv->tx_desc_tail)
816 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_previous), 0);
817 priv->tx_desc_previous = priv->tx_desc_tail;
818 if (priv->tx_desc_tail < (priv->host_info.tx_desc_count -1 ))
819 priv->tx_desc_tail++;
820 else
821 priv->tx_desc_tail = 0;
822 priv->tx_desc_free--;
823 priv->tx_free_mem -= len;
824
825}
826
827static int start_tx (struct sk_buff *skb, struct net_device *dev)
828{
829 struct atmel_private *priv = netdev_priv(dev);
830 struct ieee802_11_hdr header;
831 unsigned long flags;
832 u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
833 u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
834
835 if (priv->card && priv->present_callback &&
836 !(*priv->present_callback)(priv->card)) {
837 priv->stats.tx_errors++;
838 dev_kfree_skb(skb);
839 return 0;
840 }
841
842 if (priv->station_state != STATION_STATE_READY) {
843 priv->stats.tx_errors++;
844 dev_kfree_skb(skb);
845 return 0;
846 }
847
848 /* first ensure the timer func cannot run */
849 spin_lock_bh(&priv->timerlock);
850 /* then stop the hardware ISR */
851 spin_lock_irqsave(&priv->irqlock, flags);
852 /* nb doing the above in the opposite order will deadlock */
853
854 /* The Wireless Header is 30 bytes. In the Ethernet packet we "cut" the
855 12 first bytes (containing DA/SA) and put them in the appropriate fields of
856 the Wireless Header. Thus the packet length is then the initial + 18 (+30-12) */
857
858 if (!(buff = find_tx_buff(priv, len + 18))) {
859 priv->stats.tx_dropped++;
860 spin_unlock_irqrestore(&priv->irqlock, flags);
861 spin_unlock_bh(&priv->timerlock);
862 netif_stop_queue(dev);
863 return 1;
864 }
865
866 frame_ctl = IEEE802_11_FTYPE_DATA;
867 header.duration_id = 0;
868 header.seq_ctl = 0;
869 if (priv->wep_is_on)
870 frame_ctl |= IEEE802_11_FCTL_WEP;
871 if (priv->operating_mode == IW_MODE_ADHOC) {
872 memcpy(&header.addr1, skb->data, 6);
873 memcpy(&header.addr2, dev->dev_addr, 6);
874 memcpy(&header.addr3, priv->BSSID, 6);
875 } else {
876 frame_ctl |= IEEE802_11_FCTL_TODS;
877 memcpy(&header.addr1, priv->CurrentBSSID, 6);
878 memcpy(&header.addr2, dev->dev_addr, 6);
879 memcpy(&header.addr3, skb->data, 6);
880 }
881
882 if (priv->use_wpa)
883 memcpy(&header.addr4, SNAP_RFC1024, 6);
884
885 header.frame_ctl = cpu_to_le16(frame_ctl);
886 /* Copy the wireless header into the card */
887 atmel_copy_to_card(dev, buff, (unsigned char *)&header, DATA_FRAME_WS_HEADER_SIZE);
888 /* Copy the packet sans its 802.3 header addresses which have been replaced */
889 atmel_copy_to_card(dev, buff + DATA_FRAME_WS_HEADER_SIZE, skb->data + 12, len - 12);
890 priv->tx_buff_tail += len - 12 + DATA_FRAME_WS_HEADER_SIZE;
891
892 /* low bit of first byte of destination tells us if broadcast */
893 tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA);
894 dev->trans_start = jiffies;
895 priv->stats.tx_bytes += len;
896
897 spin_unlock_irqrestore(&priv->irqlock, flags);
898 spin_unlock_bh(&priv->timerlock);
899 dev_kfree_skb(skb);
900
901 return 0;
902}
903
904static void atmel_transmit_management_frame(struct atmel_private *priv,
905 struct ieee802_11_hdr *header,
906 u8 *body, int body_len)
907{
908 u16 buff;
909 int len = MGMT_FRAME_BODY_OFFSET + body_len;
910
911 if (!(buff = find_tx_buff(priv, len)))
912 return;
913
914 atmel_copy_to_card(priv->dev, buff, (u8 *)header, MGMT_FRAME_BODY_OFFSET);
915 atmel_copy_to_card(priv->dev, buff + MGMT_FRAME_BODY_OFFSET, body, body_len);
916 priv->tx_buff_tail += len;
917 tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
918}
919
920static void fast_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *header,
921 u16 msdu_size, u16 rx_packet_loc, u32 crc)
922{
923 /* fast path: unfragmented packet copy directly into skbuf */
924 u8 mac4[6];
925 struct sk_buff *skb;
926 unsigned char *skbp;
927
928 /* get the final, mac 4 header field, this tells us encapsulation */
929 atmel_copy_to_host(priv->dev, mac4, rx_packet_loc + 24, 6);
930 msdu_size -= 6;
931
932 if (priv->do_rx_crc) {
933 crc = crc32_le(crc, mac4, 6);
934 msdu_size -= 4;
935 }
936
937 if (!(skb = dev_alloc_skb(msdu_size + 14))) {
938 priv->stats.rx_dropped++;
939 return;
940 }
941
942 skb_reserve(skb, 2);
943 skbp = skb_put(skb, msdu_size + 12);
944 atmel_copy_to_host(priv->dev, skbp + 12, rx_packet_loc + 30, msdu_size);
945
946 if (priv->do_rx_crc) {
947 u32 netcrc;
948 crc = crc32_le(crc, skbp + 12, msdu_size);
949 atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + 30 + msdu_size, 4);
950 if ((crc ^ 0xffffffff) != netcrc) {
951 priv->stats.rx_crc_errors++;
952 dev_kfree_skb(skb);
953 return;
954 }
955 }
956
957 memcpy(skbp, header->addr1, 6); /* destination address */
958 if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS)
959 memcpy(&skbp[6], header->addr3, 6);
960 else
961 memcpy(&skbp[6], header->addr2, 6); /* source address */
962
963 priv->dev->last_rx=jiffies;
964 skb->dev = priv->dev;
965 skb->protocol = eth_type_trans(skb, priv->dev);
966 skb->ip_summed = CHECKSUM_NONE;
967 netif_rx(skb);
968 priv->stats.rx_bytes += 12 + msdu_size;
969 priv->stats.rx_packets++;
970}
971
972/* Test to see if the packet in card memory at packet_loc has a valid CRC
973 It doesn't matter that this is slow: it is only used to proble the first few packets. */
974static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
975{
976 int i = msdu_size - 4;
977 u32 netcrc, crc = 0xffffffff;
978
979 if (msdu_size < 4)
980 return 0;
981
982 atmel_copy_to_host(priv->dev, (void *)&netcrc, packet_loc + i, 4);
983
984 atmel_writeAR(priv->dev, packet_loc);
985 while (i--) {
986 u8 octet = atmel_read8(priv->dev, DR);
987 crc = crc32_le(crc, &octet, 1);
988 }
989
990 return (crc ^ 0xffffffff) == netcrc;
991}
992
993static void frag_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *header,
994 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags)
995{
996 u8 mac4[6];
997 u8 source[6];
998 struct sk_buff *skb;
999
1000 if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS)
1001 memcpy(source, header->addr3, 6);
1002 else
1003 memcpy(source, header->addr2, 6);
1004
1005 rx_packet_loc += 24; /* skip header */
1006
1007 if (priv->do_rx_crc)
1008 msdu_size -= 4;
1009
1010 if (frag_no == 0) { /* first fragment */
1011 atmel_copy_to_host(priv->dev, mac4, rx_packet_loc, 6);
1012 msdu_size -= 6;
1013 rx_packet_loc += 6;
1014
1015 if (priv->do_rx_crc)
1016 crc = crc32_le(crc, mac4, 6);
1017
1018 priv->frag_seq = seq_no;
1019 priv->frag_no = 1;
1020 priv->frag_len = msdu_size;
1021 memcpy(priv->frag_source, source, 6);
1022 memcpy(&priv->rx_buf[6], source, 6);
1023 memcpy(priv->rx_buf, header->addr1, 6);
1024
1025 atmel_copy_to_host(priv->dev, &priv->rx_buf[12], rx_packet_loc, msdu_size);
1026
1027 if (priv->do_rx_crc) {
1028 u32 netcrc;
1029 crc = crc32_le(crc, &priv->rx_buf[12], msdu_size);
1030 atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
1031 if ((crc ^ 0xffffffff) != netcrc) {
1032 priv->stats.rx_crc_errors++;
1033 memset(priv->frag_source, 0xff, 6);
1034 }
1035 }
1036
1037 } else if (priv->frag_no == frag_no &&
1038 priv->frag_seq == seq_no &&
1039 memcmp(priv->frag_source, source, 6) == 0) {
1040
1041 atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len],
1042 rx_packet_loc, msdu_size);
1043 if (priv->do_rx_crc) {
1044 u32 netcrc;
1045 crc = crc32_le(crc,
1046 &priv->rx_buf[12 + priv->frag_len],
1047 msdu_size);
1048 atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
1049 if ((crc ^ 0xffffffff) != netcrc) {
1050 priv->stats.rx_crc_errors++;
1051 memset(priv->frag_source, 0xff, 6);
1052 more_frags = 1; /* don't send broken assembly */
1053 }
1054 }
1055
1056 priv->frag_len += msdu_size;
1057 priv->frag_no++;
1058
1059 if (!more_frags) { /* last one */
1060 memset(priv->frag_source, 0xff, 6);
1061 if (!(skb = dev_alloc_skb(priv->frag_len + 14))) {
1062 priv->stats.rx_dropped++;
1063 } else {
1064 skb_reserve(skb, 2);
1065 memcpy(skb_put(skb, priv->frag_len + 12),
1066 priv->rx_buf,
1067 priv->frag_len + 12);
1068 priv->dev->last_rx = jiffies;
1069 skb->dev = priv->dev;
1070 skb->protocol = eth_type_trans(skb, priv->dev);
1071 skb->ip_summed = CHECKSUM_NONE;
1072 netif_rx(skb);
1073 priv->stats.rx_bytes += priv->frag_len + 12;
1074 priv->stats.rx_packets++;
1075 }
1076 }
1077
1078 } else
1079 priv->wstats.discard.fragment++;
1080}
1081
1082static void rx_done_irq(struct atmel_private *priv)
1083{
1084 int i;
1085 struct ieee802_11_hdr header;
1086
1087 for (i = 0;
1088 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
1089 i < priv->host_info.rx_desc_count;
1090 i++) {
1091
1092 u16 msdu_size, rx_packet_loc, frame_ctl, seq_control;
1093 u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head));
1094 u32 crc = 0xffffffff;
1095
1096 if (status != RX_STATUS_SUCCESS) {
1097 if (status == 0xc1) /* determined by experiment */
1098 priv->wstats.discard.nwid++;
1099 else
1100 priv->stats.rx_errors++;
1101 goto next;
1102 }
1103
1104 msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head));
1105 rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
1106
1107 if (msdu_size < 30) {
1108 priv->stats.rx_errors++;
1109 goto next;
1110 }
1111
1112 /* Get header as far as end of seq_ctl */
1113 atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
1114 frame_ctl = le16_to_cpu(header.frame_ctl);
1115 seq_control = le16_to_cpu(header.seq_ctl);
1116
1117 /* probe for CRC use here if needed once five packets have arrived with
1118 the same crc status, we assume we know what's happening and stop probing */
1119 if (priv->probe_crc) {
1120 if (!priv->wep_is_on || !(frame_ctl & IEEE802_11_FCTL_WEP)) {
1121 priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
1122 } else {
1123 priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24);
1124 }
1125 if (priv->do_rx_crc) {
1126 if (priv->crc_ok_cnt++ > 5)
1127 priv->probe_crc = 0;
1128 } else {
1129 if (priv->crc_ko_cnt++ > 5)
1130 priv->probe_crc = 0;
1131 }
1132 }
1133
1134 /* don't CRC header when WEP in use */
1135 if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE802_11_FCTL_WEP))) {
1136 crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
1137 }
1138 msdu_size -= 24; /* header */
1139
1140 if ((frame_ctl & IEEE802_11_FCTL_FTYPE) == IEEE802_11_FTYPE_DATA) {
1141
1142 int more_fragments = frame_ctl & IEEE802_11_FCTL_MOREFRAGS;
1143 u8 packet_fragment_no = seq_control & IEEE802_11_SCTL_FRAG;
1144 u16 packet_sequence_no = (seq_control & IEEE802_11_SCTL_SEQ) >> 4;
1145
1146 if (!more_fragments && packet_fragment_no == 0 ) {
1147 fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
1148 } else {
1149 frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc,
1150 packet_sequence_no, packet_fragment_no, more_fragments);
1151 }
1152 }
1153
1154 if ((frame_ctl & IEEE802_11_FCTL_FTYPE) == IEEE802_11_FTYPE_MGMT) {
1155 /* copy rest of packet into buffer */
1156 atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
1157
1158 /* we use the same buffer for frag reassembly and control packets */
1159 memset(priv->frag_source, 0xff, 6);
1160
1161 if (priv->do_rx_crc) {
1162 /* last 4 octets is crc */
1163 msdu_size -= 4;
1164 crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size);
1165 if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) {
1166 priv->stats.rx_crc_errors++;
1167 goto next;
1168 }
1169 }
1170
1171 atmel_management_frame(priv, &header, msdu_size,
1172 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head)));
1173 }
1174
1175 next:
1176 /* release descriptor */
1177 atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);
1178
1179 if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1))
1180 priv->rx_desc_head++;
1181 else
1182 priv->rx_desc_head = 0;
1183 }
1184}
1185
1186static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1187{
1188 struct net_device *dev = (struct net_device *) dev_id;
1189 struct atmel_private *priv = netdev_priv(dev);
1190 u8 isr;
1191 int i = -1;
1192 static u8 irq_order[] = {
1193 ISR_OUT_OF_RANGE,
1194 ISR_RxCOMPLETE,
1195 ISR_TxCOMPLETE,
1196 ISR_RxFRAMELOST,
1197 ISR_FATAL_ERROR,
1198 ISR_COMMAND_COMPLETE,
1199 ISR_IBSS_MERGE,
1200 ISR_GENERIC_IRQ
1201 };
1202
1203
1204 if (priv->card && priv->present_callback &&
1205 !(*priv->present_callback)(priv->card))
1206 return IRQ_HANDLED;
1207
1208 /* In this state upper-level code assumes it can mess with
1209 the card unhampered by interrupts which may change register state.
1210 Note that even though the card shouldn't generate interrupts
1211 the inturrupt line may be shared. This allows card setup
1212 to go on without disabling interrupts for a long time. */
1213 if (priv->station_state == STATION_STATE_DOWN)
1214 return IRQ_NONE;
1215
1216 atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
1217
1218 while (1) {
1219 if (!atmel_lock_mac(priv)) {
1220 /* failed to contact card */
1221 printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1222 return IRQ_HANDLED;
1223 }
1224
1225 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1226 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1227
1228 if (!isr) {
1229 atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
1230 return i == -1 ? IRQ_NONE : IRQ_HANDLED;
1231 }
1232
1233 atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
1234
1235 for (i = 0; i < sizeof(irq_order)/sizeof(u8); i++)
1236 if (isr & irq_order[i])
1237 break;
1238
1239 if (!atmel_lock_mac(priv)) {
1240 /* failed to contact card */
1241 printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1242 return IRQ_HANDLED;
1243 }
1244
1245 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1246 isr ^= irq_order[i];
1247 atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr);
1248 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1249
1250 switch (irq_order[i]) {
1251
1252 case ISR_OUT_OF_RANGE:
1253 if (priv->operating_mode == IW_MODE_INFRA &&
1254 priv->station_state == STATION_STATE_READY) {
1255 priv->station_is_associated = 0;
1256 atmel_scan(priv, 1);
1257 }
1258 break;
1259
1260 case ISR_RxFRAMELOST:
1261 priv->wstats.discard.misc++;
1262 /* fall through */
1263 case ISR_RxCOMPLETE:
1264 rx_done_irq(priv);
1265 break;
1266
1267 case ISR_TxCOMPLETE:
1268 tx_done_irq(priv);
1269 break;
1270
1271 case ISR_FATAL_ERROR:
1272 printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name);
1273 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
1274 break;
1275
1276 case ISR_COMMAND_COMPLETE:
1277 atmel_command_irq(priv);
1278 break;
1279
1280 case ISR_IBSS_MERGE:
1281 atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
1282 priv->CurrentBSSID, 6);
1283 /* The WPA stuff cares about the current AP address */
1284 if (priv->use_wpa)
1285 build_wpa_mib(priv);
1286 break;
1287 case ISR_GENERIC_IRQ:
1288 printk(KERN_INFO "%s: Generic_irq received.\n", dev->name);
1289 break;
1290 }
1291 }
1292}
1293
1294
1295static struct net_device_stats *atmel_get_stats (struct net_device *dev)
1296{
1297 struct atmel_private *priv = netdev_priv(dev);
1298 return &priv->stats;
1299}
1300
1301static struct iw_statistics *atmel_get_wireless_stats (struct net_device *dev)
1302{
1303 struct atmel_private *priv = netdev_priv(dev);
1304
1305 /* update the link quality here in case we are seeing no beacons
1306 at all to drive the process */
1307 atmel_smooth_qual(priv);
1308
1309 priv->wstats.status = priv->station_state;
1310
1311 if (priv->operating_mode == IW_MODE_INFRA) {
1312 if (priv->station_state != STATION_STATE_READY) {
1313 priv->wstats.qual.qual = 0;
1314 priv->wstats.qual.level = 0;
1315 priv->wstats.qual.updated = (IW_QUAL_QUAL_INVALID
1316 | IW_QUAL_LEVEL_INVALID);
1317 }
1318 priv->wstats.qual.noise = 0;
1319 priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1320 } else {
1321 /* Quality levels cannot be determined in ad-hoc mode,
1322 because we can 'hear' more that one remote station. */
1323 priv->wstats.qual.qual = 0;
1324 priv->wstats.qual.level = 0;
1325 priv->wstats.qual.noise = 0;
1326 priv->wstats.qual.updated = IW_QUAL_QUAL_INVALID
1327 | IW_QUAL_LEVEL_INVALID
1328 | IW_QUAL_NOISE_INVALID;
1329 priv->wstats.miss.beacon = 0;
1330 }
1331
1332 return (&priv->wstats);
1333}
1334
1335static int atmel_change_mtu(struct net_device *dev, int new_mtu)
1336{
1337 if ((new_mtu < 68) || (new_mtu > 2312))
1338 return -EINVAL;
1339 dev->mtu = new_mtu;
1340 return 0;
1341}
1342
1343static int atmel_set_mac_address(struct net_device *dev, void *p)
1344{
1345 struct sockaddr *addr = p;
1346
1347 memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
1348 return atmel_open(dev);
1349}
1350
1351EXPORT_SYMBOL(atmel_open);
1352
1353int atmel_open (struct net_device *dev)
1354{
1355 struct atmel_private *priv = netdev_priv(dev);
1356 int i, channel;
1357
1358 /* any scheduled timer is no longer needed and might screw things up.. */
1359 del_timer_sync(&priv->management_timer);
1360
1361 /* Interrupts will not touch the card once in this state... */
1362 priv->station_state = STATION_STATE_DOWN;
1363
1364 if (priv->new_SSID_size) {
1365 memcpy(priv->SSID, priv->new_SSID, priv->new_SSID_size);
1366 priv->SSID_size = priv->new_SSID_size;
1367 priv->new_SSID_size = 0;
1368 }
1369 priv->BSS_list_entries = 0;
1370
1371 priv->AuthenticationRequestRetryCnt = 0;
1372 priv->AssociationRequestRetryCnt = 0;
1373 priv->ReAssociationRequestRetryCnt = 0;
1374 priv->CurrentAuthentTransactionSeqNum = 0x0001;
1375 priv->ExpectedAuthentTransactionSeqNum = 0x0002;
1376
1377 priv->site_survey_state = SITE_SURVEY_IDLE;
1378 priv->station_is_associated = 0;
1379
1380 if (!reset_atmel_card(dev))
1381 return -EAGAIN;
1382
1383 if (priv->config_reg_domain) {
1384 priv->reg_domain = priv->config_reg_domain;
1385 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS, priv->reg_domain);
1386 } else {
1387 priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS);
1388 for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++)
1389 if (priv->reg_domain == channel_table[i].reg_domain)
1390 break;
1391 if (i == sizeof(channel_table)/sizeof(channel_table[0])) {
1392 priv->reg_domain = REG_DOMAIN_MKK1;
1393 printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
1394 }
1395 }
1396
1397 if ((channel = atmel_validate_channel(priv, priv->channel)))
1398 priv->channel = channel;
1399
1400 /* this moves station_state on.... */
1401 atmel_scan(priv, 1);
1402
1403 atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */
1404 return 0;
1405}
1406
1407static int atmel_close (struct net_device *dev)
1408{
1409 struct atmel_private *priv = netdev_priv(dev);
1410
1411 atmel_enter_state(priv, STATION_STATE_DOWN);
1412
1413 if (priv->bus_type == BUS_TYPE_PCCARD)
1414 atmel_write16(dev, GCR, 0x0060);
1415 atmel_write16(dev, GCR, 0x0040);
1416 return 0;
1417}
1418
1419static int atmel_validate_channel(struct atmel_private *priv, int channel)
1420{
1421 /* check that channel is OK, if so return zero,
1422 else return suitable default channel */
1423 int i;
1424
1425 for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++)
1426 if (priv->reg_domain == channel_table[i].reg_domain) {
1427 if (channel >= channel_table[i].min &&
1428 channel <= channel_table[i].max)
1429 return 0;
1430 else
1431 return channel_table[i].min;
1432 }
1433 return 0;
1434}
1435
1436static int atmel_proc_output (char *buf, struct atmel_private *priv)
1437{
1438 int i;
1439 char *p = buf;
1440 char *s, *r, *c;
1441
1442 p += sprintf(p, "Driver version:\t\t%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR);
1443
1444 if (priv->station_state != STATION_STATE_DOWN) {
1445 p += sprintf(p, "Firmware version:\t%d.%d build %d\nFirmware location:\t",
1446 priv->host_info.major_version,
1447 priv->host_info.minor_version,
1448 priv->host_info.build_version);
1449
1450 if (priv->card_type != CARD_TYPE_EEPROM)
1451 p += sprintf(p, "on card\n");
1452 else if (priv->firmware)
1453 p += sprintf(p, "%s loaded by host\n", priv->firmware_id);
1454 else
1455 p += sprintf(p, "%s loaded by hotplug\n", priv->firmware_id);
1456
1457 switch(priv->card_type) {
1458 case CARD_TYPE_PARALLEL_FLASH: c = "Parallel flash"; break;
1459 case CARD_TYPE_SPI_FLASH: c = "SPI flash\n"; break;
1460 case CARD_TYPE_EEPROM: c = "EEPROM"; break;
1461 default: c = "<unknown>";
1462 }
1463
1464
1465 r = "<unknown>";
1466 for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++)
1467 if (priv->reg_domain == channel_table[i].reg_domain)
1468 r = channel_table[i].name;
1469
1470 p += sprintf(p, "MAC memory type:\t%s\n", c);
1471 p += sprintf(p, "Regulatory domain:\t%s\n", r);
1472 p += sprintf(p, "Host CRC checking:\t%s\n",
1473 priv->do_rx_crc ? "On" : "Off");
1474 p += sprintf(p, "WPA-capable firmware:\t%s\n",
1475 priv->use_wpa ? "Yes" : "No");
1476 }
1477
1478 switch(priv->station_state) {
1479 case STATION_STATE_SCANNING: s = "Scanning"; break;
1480 case STATION_STATE_JOINNING: s = "Joining"; break;
1481 case STATION_STATE_AUTHENTICATING: s = "Authenticating"; break;
1482 case STATION_STATE_ASSOCIATING: s = "Associating"; break;
1483 case STATION_STATE_READY: s = "Ready"; break;
1484 case STATION_STATE_REASSOCIATING: s = "Reassociating"; break;
1485 case STATION_STATE_MGMT_ERROR: s = "Management error"; break;
1486 case STATION_STATE_DOWN: s = "Down"; break;
1487 default: s = "<unknown>";
1488 }
1489
1490 p += sprintf(p, "Current state:\t\t%s\n", s);
1491 return p - buf;
1492}
1493
1494static int atmel_read_proc(char *page, char **start, off_t off,
1495 int count, int *eof, void *data)
1496{
1497 struct atmel_private *priv = data;
1498 int len = atmel_proc_output (page, priv);
1499 if (len <= off+count) *eof = 1;
1500 *start = page + off;
1501 len -= off;
1502 if (len>count) len = count;
1503 if (len<0) len = 0;
1504 return len;
1505}
1506
1507struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWType fw_type,
1508 struct device *sys_dev, int (*card_present)(void *), void *card)
1509{
1510 struct net_device *dev;
1511 struct atmel_private *priv;
1512 int rc;
1513
1514 /* Create the network device object. */
1515 dev = alloc_etherdev(sizeof(*priv));
1516 if (!dev) {
1517 printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n");
1518 return NULL;
1519 }
1520 if (dev_alloc_name(dev, dev->name) < 0) {
1521 printk(KERN_ERR "atmel: Couldn't get name!\n");
1522 goto err_out_free;
1523 }
1524
1525 priv = netdev_priv(dev);
1526 priv->dev = dev;
1527 priv->sys_dev = sys_dev;
1528 priv->present_callback = card_present;
1529 priv->card = card;
1530 priv->firmware = NULL;
1531 priv->firmware_id[0] = '\0';
1532 priv->firmware_type = fw_type;
1533 if (firmware) /* module parameter */
1534 strcpy(priv->firmware_id, firmware);
1535 priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
1536 priv->station_state = STATION_STATE_DOWN;
1537 priv->do_rx_crc = 0;
1538 /* For PCMCIA cards, some chips need CRC, some don't
1539 so we have to probe. */
1540 if (priv->bus_type == BUS_TYPE_PCCARD) {
1541 priv->probe_crc = 1;
1542 priv->crc_ok_cnt = priv->crc_ko_cnt = 0;
1543 } else
1544 priv->probe_crc = 0;
1545 memset(&priv->stats, 0, sizeof(priv->stats));
1546 memset(&priv->wstats, 0, sizeof(priv->wstats));
1547 priv->last_qual = jiffies;
1548 priv->last_beacon_timestamp = 0;
1549 memset(priv->frag_source, 0xff, sizeof(priv->frag_source));
1550 memset(priv->BSSID, 0, 6);
1551 priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
1552 priv->station_was_associated = 0;
1553
1554 priv->last_survey = jiffies;
1555 priv->preamble = LONG_PREAMBLE;
1556 priv->operating_mode = IW_MODE_INFRA;
1557 priv->connect_to_any_BSS = 0;
1558 priv->config_reg_domain = 0;
1559 priv->reg_domain = 0;
1560 priv->tx_rate = 3;
1561 priv->auto_tx_rate = 1;
1562 priv->channel = 4;
1563 priv->power_mode = 0;
1564 priv->SSID[0] = '\0';
1565 priv->SSID_size = 0;
1566 priv->new_SSID_size = 0;
1567 priv->frag_threshold = 2346;
1568 priv->rts_threshold = 2347;
1569 priv->short_retry = 7;
1570 priv->long_retry = 4;
1571
1572 priv->wep_is_on = 0;
1573 priv->default_key = 0;
1574 priv->encryption_level = 0;
1575 priv->exclude_unencrypted = 0;
1576 priv->group_cipher_suite = priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1577 priv->use_wpa = 0;
1578 memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
1579 memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1580
1581 priv->default_beacon_period = priv->beacon_period = 100;
1582 priv->listen_interval = 1;
1583
1584 init_timer(&priv->management_timer);
1585 spin_lock_init(&priv->irqlock);
1586 spin_lock_init(&priv->timerlock);
1587 priv->management_timer.function = atmel_management_timer;
1588 priv->management_timer.data = (unsigned long) dev;
1589
1590 dev->open = atmel_open;
1591 dev->stop = atmel_close;
1592 dev->change_mtu = atmel_change_mtu;
1593 dev->set_mac_address = atmel_set_mac_address;
1594 dev->hard_start_xmit = start_tx;
1595 dev->get_stats = atmel_get_stats;
1596 dev->get_wireless_stats = atmel_get_wireless_stats;
1597 dev->wireless_handlers = (struct iw_handler_def *)&atmel_handler_def;
1598 dev->do_ioctl = atmel_ioctl;
1599 dev->irq = irq;
1600 dev->base_addr = port;
1601
1602 SET_NETDEV_DEV(dev, sys_dev);
1603
1604 if ((rc = request_irq(dev->irq, service_interrupt, SA_SHIRQ, dev->name, dev))) {
1605 printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc );
1606 goto err_out_free;
1607 }
1608
1609 if (priv->bus_type == BUS_TYPE_PCI &&
1610 !request_region( dev->base_addr, 64, dev->name )) {
1611 goto err_out_irq;
1612 }
1613
1614 if (register_netdev(dev))
1615 goto err_out_res;
1616
1617 if (!probe_atmel_card(dev)){
1618 unregister_netdev(dev);
1619 goto err_out_res;
1620 }
1621
1622 netif_carrier_off(dev);
1623
1624 create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv);
1625
1626 printk(KERN_INFO "%s: Atmel at76c50x wireless. Version %d.%d simon@thekelleys.org.uk\n",
1627 dev->name, DRIVER_MAJOR, DRIVER_MINOR);
1628
1629 SET_MODULE_OWNER(dev);
1630 return dev;
1631
1632 err_out_res:
1633 if (priv->bus_type == BUS_TYPE_PCI)
1634 release_region( dev->base_addr, 64 );
1635 err_out_irq:
1636 free_irq(dev->irq, dev);
1637 err_out_free:
1638 free_netdev(dev);
1639 return NULL;
1640}
1641
1642EXPORT_SYMBOL(init_atmel_card);
1643
1644void stop_atmel_card(struct net_device *dev, int freeres)
1645{
1646 struct atmel_private *priv = netdev_priv(dev);
1647
1648 /* put a brick on it... */
1649 if (priv->bus_type == BUS_TYPE_PCCARD)
1650 atmel_write16(dev, GCR, 0x0060);
1651 atmel_write16(dev, GCR, 0x0040);
1652
1653 del_timer_sync(&priv->management_timer);
1654 unregister_netdev(dev);
1655 remove_proc_entry("driver/atmel", NULL);
1656 free_irq(dev->irq, dev);
1657 if (priv->firmware)
1658 kfree(priv->firmware);
1659 if (freeres) {
1660 /* PCMCIA frees this stuff, so only for PCI */
1661 release_region(dev->base_addr, 64);
1662 }
1663 free_netdev(dev);
1664}
1665
1666EXPORT_SYMBOL(stop_atmel_card);
1667
1668static int atmel_set_essid(struct net_device *dev,
1669 struct iw_request_info *info,
1670 struct iw_point *dwrq,
1671 char *extra)
1672{
1673 struct atmel_private *priv = netdev_priv(dev);
1674
1675 /* Check if we asked for `any' */
1676 if(dwrq->flags == 0) {
1677 priv->connect_to_any_BSS = 1;
1678 } else {
1679 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1680
1681 priv->connect_to_any_BSS = 0;
1682
1683 /* Check the size of the string */
1684 if (dwrq->length > MAX_SSID_LENGTH + 1)
1685 return -E2BIG ;
1686 if (index != 0)
1687 return -EINVAL;
1688
1689 memcpy(priv->new_SSID, extra, dwrq->length - 1);
1690 priv->new_SSID_size = dwrq->length - 1;
1691 }
1692
1693 return -EINPROGRESS;
1694}
1695
1696static int atmel_get_essid(struct net_device *dev,
1697 struct iw_request_info *info,
1698 struct iw_point *dwrq,
1699 char *extra)
1700{
1701 struct atmel_private *priv = netdev_priv(dev);
1702
1703 /* Get the current SSID */
1704 if (priv->new_SSID_size != 0) {
1705 memcpy(extra, priv->new_SSID, priv->new_SSID_size);
1706 extra[priv->new_SSID_size] = '\0';
1707 dwrq->length = priv->new_SSID_size + 1;
1708 } else {
1709 memcpy(extra, priv->SSID, priv->SSID_size);
1710 extra[priv->SSID_size] = '\0';
1711 dwrq->length = priv->SSID_size + 1;
1712 }
1713
1714 dwrq->flags = !priv->connect_to_any_BSS; /* active */
1715
1716 return 0;
1717}
1718
1719static int atmel_get_wap(struct net_device *dev,
1720 struct iw_request_info *info,
1721 struct sockaddr *awrq,
1722 char *extra)
1723{
1724 struct atmel_private *priv = netdev_priv(dev);
1725 memcpy(awrq->sa_data, priv->CurrentBSSID, 6);
1726 awrq->sa_family = ARPHRD_ETHER;
1727
1728 return 0;
1729}
1730
1731static int atmel_set_encode(struct net_device *dev,
1732 struct iw_request_info *info,
1733 struct iw_point *dwrq,
1734 char *extra)
1735{
1736 struct atmel_private *priv = netdev_priv(dev);
1737
1738 /* Basic checking: do we have a key to set ?
1739 * Note : with the new API, it's impossible to get a NULL pointer.
1740 * Therefore, we need to check a key size == 0 instead.
1741 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
1742 * when no key is present (only change flags), but older versions
1743 * don't do it. - Jean II */
1744 if (dwrq->length > 0) {
1745 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1746 int current_index = priv->default_key;
1747 /* Check the size of the key */
1748 if (dwrq->length > 13) {
1749 return -EINVAL;
1750 }
1751 /* Check the index (none -> use current) */
1752 if (index < 0 || index >= 4)
1753 index = current_index;
1754 else
1755 priv->default_key = index;
1756 /* Set the length */
1757 if (dwrq->length > 5)
1758 priv->wep_key_len[index] = 13;
1759 else
1760 if (dwrq->length > 0)
1761 priv->wep_key_len[index] = 5;
1762 else
1763 /* Disable the key */
1764 priv->wep_key_len[index] = 0;
1765 /* Check if the key is not marked as invalid */
1766 if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
1767 /* Cleanup */
1768 memset(priv->wep_keys[index], 0, 13);
1769 /* Copy the key in the driver */
1770 memcpy(priv->wep_keys[index], extra, dwrq->length);
1771 }
1772 /* WE specify that if a valid key is set, encryption
1773 * should be enabled (user may turn it off later)
1774 * This is also how "iwconfig ethX key on" works */
1775 if (index == current_index &&
1776 priv->wep_key_len[index] > 0) {
1777 priv->wep_is_on = 1;
1778 priv->exclude_unencrypted = 1;
1779 if (priv->wep_key_len[index] > 5) {
1780 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1781 priv->encryption_level = 2;
1782 } else {
1783 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1784 priv->encryption_level = 1;
1785 }
1786 }
1787 } else {
1788 /* Do we want to just set the transmit key index ? */
1789 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1790 if ( index>=0 && index < 4 ) {
1791 priv->default_key = index;
1792 } else
1793 /* Don't complain if only change the mode */
1794 if(!dwrq->flags & IW_ENCODE_MODE) {
1795 return -EINVAL;
1796 }
1797 }
1798 /* Read the flags */
1799 if(dwrq->flags & IW_ENCODE_DISABLED) {
1800 priv->wep_is_on = 0;
1801 priv->encryption_level = 0;
1802 priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1803 } else {
1804 priv->wep_is_on = 1;
1805 if (priv->wep_key_len[priv->default_key] > 5) {
1806 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1807 priv->encryption_level = 2;
1808 } else {
1809 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1810 priv->encryption_level = 1;
1811 }
1812 }
1813 if(dwrq->flags & IW_ENCODE_RESTRICTED)
1814 priv->exclude_unencrypted = 1;
1815 if(dwrq->flags & IW_ENCODE_OPEN)
1816 priv->exclude_unencrypted = 0;
1817
1818 return -EINPROGRESS; /* Call commit handler */
1819}
1820
1821
1822static int atmel_get_encode(struct net_device *dev,
1823 struct iw_request_info *info,
1824 struct iw_point *dwrq,
1825 char *extra)
1826{
1827 struct atmel_private *priv = netdev_priv(dev);
1828 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1829
1830 if (!priv->wep_is_on)
1831 dwrq->flags = IW_ENCODE_DISABLED;
1832 else if (priv->exclude_unencrypted)
1833 dwrq->flags = IW_ENCODE_RESTRICTED;
1834 else
1835 dwrq->flags = IW_ENCODE_OPEN;
1836
1837 /* Which key do we want ? -1 -> tx index */
1838 if (index < 0 || index >= 4)
1839 index = priv->default_key;
1840 dwrq->flags |= index + 1;
1841 /* Copy the key to the user buffer */
1842 dwrq->length = priv->wep_key_len[index];
1843 if (dwrq->length > 16) {
1844 dwrq->length=0;
1845 } else {
1846 memset(extra, 0, 16);
1847 memcpy(extra, priv->wep_keys[index], dwrq->length);
1848 }
1849
1850 return 0;
1851}
1852
1853static int atmel_get_name(struct net_device *dev,
1854 struct iw_request_info *info,
1855 char *cwrq,
1856 char *extra)
1857{
1858 strcpy(cwrq, "IEEE 802.11-DS");
1859 return 0;
1860}
1861
1862static int atmel_set_rate(struct net_device *dev,
1863 struct iw_request_info *info,
1864 struct iw_param *vwrq,
1865 char *extra)
1866{
1867 struct atmel_private *priv = netdev_priv(dev);
1868
1869 if (vwrq->fixed == 0) {
1870 priv->tx_rate = 3;
1871 priv->auto_tx_rate = 1;
1872 } else {
1873 priv->auto_tx_rate = 0;
1874
1875 /* Which type of value ? */
1876 if((vwrq->value < 4) && (vwrq->value >= 0)) {
1877 /* Setting by rate index */
1878 priv->tx_rate = vwrq->value;
1879 } else {
1880 /* Setting by frequency value */
1881 switch (vwrq->value) {
1882 case 1000000: priv->tx_rate = 0; break;
1883 case 2000000: priv->tx_rate = 1; break;
1884 case 5500000: priv->tx_rate = 2; break;
1885 case 11000000: priv->tx_rate = 3; break;
1886 default: return -EINVAL;
1887 }
1888 }
1889 }
1890
1891 return -EINPROGRESS;
1892}
1893
1894static int atmel_set_mode(struct net_device *dev,
1895 struct iw_request_info *info,
1896 __u32 *uwrq,
1897 char *extra)
1898{
1899 struct atmel_private *priv = netdev_priv(dev);
1900
1901 if (*uwrq != IW_MODE_ADHOC && *uwrq != IW_MODE_INFRA)
1902 return -EINVAL;
1903
1904 priv->operating_mode = *uwrq;
1905 return -EINPROGRESS;
1906}
1907
1908static int atmel_get_mode(struct net_device *dev,
1909 struct iw_request_info *info,
1910 __u32 *uwrq,
1911 char *extra)
1912{
1913 struct atmel_private *priv = netdev_priv(dev);
1914
1915 *uwrq = priv->operating_mode;
1916 return 0;
1917}
1918
1919static int atmel_get_rate(struct net_device *dev,
1920 struct iw_request_info *info,
1921 struct iw_param *vwrq,
1922 char *extra)
1923{
1924 struct atmel_private *priv = netdev_priv(dev);
1925
1926 if (priv->auto_tx_rate) {
1927 vwrq->fixed = 0;
1928 vwrq->value = 11000000;
1929 } else {
1930 vwrq->fixed = 1;
1931 switch(priv->tx_rate) {
1932 case 0: vwrq->value = 1000000; break;
1933 case 1: vwrq->value = 2000000; break;
1934 case 2: vwrq->value = 5500000; break;
1935 case 3: vwrq->value = 11000000; break;
1936 }
1937 }
1938 return 0;
1939}
1940
1941static int atmel_set_power(struct net_device *dev,
1942 struct iw_request_info *info,
1943 struct iw_param *vwrq,
1944 char *extra)
1945{
1946 struct atmel_private *priv = netdev_priv(dev);
1947 priv->power_mode = vwrq->disabled ? 0 : 1;
1948 return -EINPROGRESS;
1949}
1950
1951static int atmel_get_power(struct net_device *dev,
1952 struct iw_request_info *info,
1953 struct iw_param *vwrq,
1954 char *extra)
1955{
1956 struct atmel_private *priv = netdev_priv(dev);
1957 vwrq->disabled = priv->power_mode ? 0 : 1;
1958 vwrq->flags = IW_POWER_ON;
1959 return 0;
1960}
1961
1962static int atmel_set_retry(struct net_device *dev,
1963 struct iw_request_info *info,
1964 struct iw_param *vwrq,
1965 char *extra)
1966{
1967 struct atmel_private *priv = netdev_priv(dev);
1968
1969 if(!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
1970 if(vwrq->flags & IW_RETRY_MAX)
1971 priv->long_retry = vwrq->value;
1972 else if (vwrq->flags & IW_RETRY_MIN)
1973 priv->short_retry = vwrq->value;
1974 else {
1975 /* No modifier : set both */
1976 priv->long_retry = vwrq->value;
1977 priv->short_retry = vwrq->value;
1978 }
1979 return -EINPROGRESS;
1980 }
1981
1982 return -EINVAL;
1983}
1984
1985static int atmel_get_retry(struct net_device *dev,
1986 struct iw_request_info *info,
1987 struct iw_param *vwrq,
1988 char *extra)
1989{
1990 struct atmel_private *priv = netdev_priv(dev);
1991
1992 vwrq->disabled = 0; /* Can't be disabled */
1993
1994 /* Note : by default, display the min retry number */
1995 if((vwrq->flags & IW_RETRY_MAX)) {
1996 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
1997 vwrq->value = priv->long_retry;
1998 } else {
1999 vwrq->flags = IW_RETRY_LIMIT;
2000 vwrq->value = priv->short_retry;
2001 if(priv->long_retry != priv->short_retry)
2002 vwrq->flags |= IW_RETRY_MIN;
2003 }
2004
2005 return 0;
2006}
2007
2008static int atmel_set_rts(struct net_device *dev,
2009 struct iw_request_info *info,
2010 struct iw_param *vwrq,
2011 char *extra)
2012{
2013 struct atmel_private *priv = netdev_priv(dev);
2014 int rthr = vwrq->value;
2015
2016 if(vwrq->disabled)
2017 rthr = 2347;
2018 if((rthr < 0) || (rthr > 2347)) {
2019 return -EINVAL;
2020 }
2021 priv->rts_threshold = rthr;
2022
2023 return -EINPROGRESS; /* Call commit handler */
2024}
2025
2026static int atmel_get_rts(struct net_device *dev,
2027 struct iw_request_info *info,
2028 struct iw_param *vwrq,
2029 char *extra)
2030{
2031 struct atmel_private *priv = netdev_priv(dev);
2032
2033 vwrq->value = priv->rts_threshold;
2034 vwrq->disabled = (vwrq->value >= 2347);
2035 vwrq->fixed = 1;
2036
2037 return 0;
2038}
2039
2040static int atmel_set_frag(struct net_device *dev,
2041 struct iw_request_info *info,
2042 struct iw_param *vwrq,
2043 char *extra)
2044{
2045 struct atmel_private *priv = netdev_priv(dev);
2046 int fthr = vwrq->value;
2047
2048 if(vwrq->disabled)
2049 fthr = 2346;
2050 if((fthr < 256) || (fthr > 2346)) {
2051 return -EINVAL;
2052 }
2053 fthr &= ~0x1; /* Get an even value - is it really needed ??? */
2054 priv->frag_threshold = fthr;
2055
2056 return -EINPROGRESS; /* Call commit handler */
2057}
2058
2059static int atmel_get_frag(struct net_device *dev,
2060 struct iw_request_info *info,
2061 struct iw_param *vwrq,
2062 char *extra)
2063{
2064 struct atmel_private *priv = netdev_priv(dev);
2065
2066 vwrq->value = priv->frag_threshold;
2067 vwrq->disabled = (vwrq->value >= 2346);
2068 vwrq->fixed = 1;
2069
2070 return 0;
2071}
2072
2073static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
2074 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
2075
2076static int atmel_set_freq(struct net_device *dev,
2077 struct iw_request_info *info,
2078 struct iw_freq *fwrq,
2079 char *extra)
2080{
2081 struct atmel_private *priv = netdev_priv(dev);
2082 int rc = -EINPROGRESS; /* Call commit handler */
2083
2084 /* If setting by frequency, convert to a channel */
2085 if((fwrq->e == 1) &&
2086 (fwrq->m >= (int) 241200000) &&
2087 (fwrq->m <= (int) 248700000)) {
2088 int f = fwrq->m / 100000;
2089 int c = 0;
2090 while((c < 14) && (f != frequency_list[c]))
2091 c++;
2092 /* Hack to fall through... */
2093 fwrq->e = 0;
2094 fwrq->m = c + 1;
2095 }
2096 /* Setting by channel number */
2097 if((fwrq->m > 1000) || (fwrq->e > 0))
2098 rc = -EOPNOTSUPP;
2099 else {
2100 int channel = fwrq->m;
2101 if (atmel_validate_channel(priv, channel) == 0) {
2102 priv->channel = channel;
2103 } else {
2104 rc = -EINVAL;
2105 }
2106 }
2107 return rc;
2108}
2109
2110static int atmel_get_freq(struct net_device *dev,
2111 struct iw_request_info *info,
2112 struct iw_freq *fwrq,
2113 char *extra)
2114{
2115 struct atmel_private *priv = netdev_priv(dev);
2116
2117 fwrq->m = priv->channel;
2118 fwrq->e = 0;
2119 return 0;
2120}
2121
2122static int atmel_set_scan(struct net_device *dev,
2123 struct iw_request_info *info,
2124 struct iw_param *vwrq,
2125 char *extra)
2126{
2127 struct atmel_private *priv = netdev_priv(dev);
2128 unsigned long flags;
2129
2130 /* Note : you may have realised that, as this is a SET operation,
2131 * this is privileged and therefore a normal user can't
2132 * perform scanning.
2133 * This is not an error, while the device perform scanning,
2134 * traffic doesn't flow, so it's a perfect DoS...
2135 * Jean II */
2136
2137 if (priv->station_state == STATION_STATE_DOWN)
2138 return -EAGAIN;
2139
2140 /* Timeout old surveys. */
2141 if ((jiffies - priv->last_survey) > (20 * HZ))
2142 priv->site_survey_state = SITE_SURVEY_IDLE;
2143 priv->last_survey = jiffies;
2144
2145 /* Initiate a scan command */
2146 if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
2147 return -EBUSY;
2148
2149 del_timer_sync(&priv->management_timer);
2150 spin_lock_irqsave(&priv->irqlock, flags);
2151
2152 priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
2153 priv->fast_scan = 0;
2154 atmel_scan(priv, 0);
2155 spin_unlock_irqrestore(&priv->irqlock, flags);
2156
2157 return 0;
2158}
2159
2160static int atmel_get_scan(struct net_device *dev,
2161 struct iw_request_info *info,
2162 struct iw_point *dwrq,
2163 char *extra)
2164{
2165 struct atmel_private *priv = netdev_priv(dev);
2166 int i;
2167 char *current_ev = extra;
2168 struct iw_event iwe;
2169
2170 if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
2171 return -EAGAIN;
2172
2173 for(i=0; i<priv->BSS_list_entries; i++) {
2174 iwe.cmd = SIOCGIWAP;
2175 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2176 memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
2177 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN);
2178
2179 iwe.u.data.length = priv->BSSinfo[i].SSIDsize;
2180 if (iwe.u.data.length > 32)
2181 iwe.u.data.length = 32;
2182 iwe.cmd = SIOCGIWESSID;
2183 iwe.u.data.flags = 1;
2184 current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, priv->BSSinfo[i].SSID);
2185
2186 iwe.cmd = SIOCGIWMODE;
2187 iwe.u.mode = priv->BSSinfo[i].BSStype;
2188 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN);
2189
2190 iwe.cmd = SIOCGIWFREQ;
2191 iwe.u.freq.m = priv->BSSinfo[i].channel;
2192 iwe.u.freq.e = 0;
2193 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN);
2194
2195 iwe.cmd = SIOCGIWENCODE;
2196 if (priv->BSSinfo[i].UsingWEP)
2197 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2198 else
2199 iwe.u.data.flags = IW_ENCODE_DISABLED;
2200 iwe.u.data.length = 0;
2201 current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, NULL);
2202
2203 }
2204
2205 /* Length of data */
2206 dwrq->length = (current_ev - extra);
2207 dwrq->flags = 0;
2208
2209 return 0;
2210}
2211
2212static int atmel_get_range(struct net_device *dev,
2213 struct iw_request_info *info,
2214 struct iw_point *dwrq,
2215 char *extra)
2216{
2217 struct atmel_private *priv = netdev_priv(dev);
2218 struct iw_range *range = (struct iw_range *) extra;
2219 int k,i,j;
2220
2221 dwrq->length = sizeof(struct iw_range);
2222 memset(range, 0, sizeof(range));
2223 range->min_nwid = 0x0000;
2224 range->max_nwid = 0x0000;
2225 range->num_channels = 0;
2226 for (j = 0; j < sizeof(channel_table)/sizeof(channel_table[0]); j++)
2227 if (priv->reg_domain == channel_table[j].reg_domain) {
2228 range->num_channels = channel_table[j].max - channel_table[j].min + 1;
2229 break;
2230 }
2231 if (range->num_channels != 0) {
2232 for(k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
2233 range->freq[k].i = i; /* List index */
2234 range->freq[k].m = frequency_list[i-1] * 100000;
2235 range->freq[k++].e = 1; /* Values in table in MHz -> * 10^5 * 10 */
2236 }
2237 range->num_frequency = k;
2238 }
2239
2240 range->max_qual.qual = 100;
2241 range->max_qual.level = 100;
2242 range->max_qual.noise = 0;
2243 range->max_qual.updated = IW_QUAL_NOISE_INVALID;
2244
2245 range->avg_qual.qual = 50;
2246 range->avg_qual.level = 50;
2247 range->avg_qual.noise = 0;
2248 range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
2249
2250 range->sensitivity = 0;
2251
2252 range->bitrate[0] = 1000000;
2253 range->bitrate[1] = 2000000;
2254 range->bitrate[2] = 5500000;
2255 range->bitrate[3] = 11000000;
2256 range->num_bitrates = 4;
2257
2258 range->min_rts = 0;
2259 range->max_rts = 2347;
2260 range->min_frag = 256;
2261 range->max_frag = 2346;
2262
2263 range->encoding_size[0] = 5;
2264 range->encoding_size[1] = 13;
2265 range->num_encoding_sizes = 2;
2266 range->max_encoding_tokens = 4;
2267
2268 range->pmp_flags = IW_POWER_ON;
2269 range->pmt_flags = IW_POWER_ON;
2270 range->pm_capa = 0;
2271
2272 range->we_version_source = WIRELESS_EXT;
2273 range->we_version_compiled = WIRELESS_EXT;
2274 range->retry_capa = IW_RETRY_LIMIT ;
2275 range->retry_flags = IW_RETRY_LIMIT;
2276 range->r_time_flags = 0;
2277 range->min_retry = 1;
2278 range->max_retry = 65535;
2279
2280 return 0;
2281}
2282
2283static int atmel_set_wap(struct net_device *dev,
2284 struct iw_request_info *info,
2285 struct sockaddr *awrq,
2286 char *extra)
2287{
2288 struct atmel_private *priv = netdev_priv(dev);
2289 int i;
2290 static const u8 bcast[] = { 255, 255, 255, 255, 255, 255 };
2291 unsigned long flags;
2292
2293 if (awrq->sa_family != ARPHRD_ETHER)
2294 return -EINVAL;
2295
2296 if (memcmp(bcast, awrq->sa_data, 6) == 0) {
2297 del_timer_sync(&priv->management_timer);
2298 spin_lock_irqsave(&priv->irqlock, flags);
2299 atmel_scan(priv, 1);
2300 spin_unlock_irqrestore(&priv->irqlock, flags);
2301 return 0;
2302 }
2303
2304 for(i=0; i<priv->BSS_list_entries; i++) {
2305 if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
2306 if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) {
2307 return -EINVAL;
2308 } else if (priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) {
2309 return -EINVAL;
2310 } else {
2311 del_timer_sync(&priv->management_timer);
2312 spin_lock_irqsave(&priv->irqlock, flags);
2313 atmel_join_bss(priv, i);
2314 spin_unlock_irqrestore(&priv->irqlock, flags);
2315 return 0;
2316 }
2317 }
2318 }
2319
2320 return -EINVAL;
2321}
2322
2323static int atmel_config_commit(struct net_device *dev,
2324 struct iw_request_info *info, /* NULL */
2325 void *zwrq, /* NULL */
2326 char *extra) /* NULL */
2327{
2328 return atmel_open(dev);
2329}
2330
2331static const iw_handler atmel_handler[] =
2332{
2333 (iw_handler) atmel_config_commit, /* SIOCSIWCOMMIT */
2334 (iw_handler) atmel_get_name, /* SIOCGIWNAME */
2335 (iw_handler) NULL, /* SIOCSIWNWID */
2336 (iw_handler) NULL, /* SIOCGIWNWID */
2337 (iw_handler) atmel_set_freq, /* SIOCSIWFREQ */
2338 (iw_handler) atmel_get_freq, /* SIOCGIWFREQ */
2339 (iw_handler) atmel_set_mode, /* SIOCSIWMODE */
2340 (iw_handler) atmel_get_mode, /* SIOCGIWMODE */
2341 (iw_handler) NULL, /* SIOCSIWSENS */
2342 (iw_handler) NULL, /* SIOCGIWSENS */
2343 (iw_handler) NULL, /* SIOCSIWRANGE */
2344 (iw_handler) atmel_get_range, /* SIOCGIWRANGE */
2345 (iw_handler) NULL, /* SIOCSIWPRIV */
2346 (iw_handler) NULL, /* SIOCGIWPRIV */
2347 (iw_handler) NULL, /* SIOCSIWSTATS */
2348 (iw_handler) NULL, /* SIOCGIWSTATS */
2349 (iw_handler) NULL, /* SIOCSIWSPY */
2350 (iw_handler) NULL, /* SIOCGIWSPY */
2351 (iw_handler) NULL, /* -- hole -- */
2352 (iw_handler) NULL, /* -- hole -- */
2353 (iw_handler) atmel_set_wap, /* SIOCSIWAP */
2354 (iw_handler) atmel_get_wap, /* SIOCGIWAP */
2355 (iw_handler) NULL, /* -- hole -- */
2356 (iw_handler) NULL, /* SIOCGIWAPLIST */
2357 (iw_handler) atmel_set_scan, /* SIOCSIWSCAN */
2358 (iw_handler) atmel_get_scan, /* SIOCGIWSCAN */
2359 (iw_handler) atmel_set_essid, /* SIOCSIWESSID */
2360 (iw_handler) atmel_get_essid, /* SIOCGIWESSID */
2361 (iw_handler) NULL, /* SIOCSIWNICKN */
2362 (iw_handler) NULL, /* SIOCGIWNICKN */
2363 (iw_handler) NULL, /* -- hole -- */
2364 (iw_handler) NULL, /* -- hole -- */
2365 (iw_handler) atmel_set_rate, /* SIOCSIWRATE */
2366 (iw_handler) atmel_get_rate, /* SIOCGIWRATE */
2367 (iw_handler) atmel_set_rts, /* SIOCSIWRTS */
2368 (iw_handler) atmel_get_rts, /* SIOCGIWRTS */
2369 (iw_handler) atmel_set_frag, /* SIOCSIWFRAG */
2370 (iw_handler) atmel_get_frag, /* SIOCGIWFRAG */
2371 (iw_handler) NULL, /* SIOCSIWTXPOW */
2372 (iw_handler) NULL, /* SIOCGIWTXPOW */
2373 (iw_handler) atmel_set_retry, /* SIOCSIWRETRY */
2374 (iw_handler) atmel_get_retry, /* SIOCGIWRETRY */
2375 (iw_handler) atmel_set_encode, /* SIOCSIWENCODE */
2376 (iw_handler) atmel_get_encode, /* SIOCGIWENCODE */
2377 (iw_handler) atmel_set_power, /* SIOCSIWPOWER */
2378 (iw_handler) atmel_get_power, /* SIOCGIWPOWER */
2379};
2380
2381
2382static const iw_handler atmel_private_handler[] =
2383{
2384 NULL, /* SIOCIWFIRSTPRIV */
2385};
2386
2387typedef struct atmel_priv_ioctl {
2388 char id[32];
2389 unsigned char __user *data;
2390 unsigned short len;
2391} atmel_priv_ioctl;
2392
2393
2394#define ATMELFWL SIOCIWFIRSTPRIV
2395#define ATMELIDIFC ATMELFWL + 1
2396#define ATMELRD ATMELFWL + 2
2397#define ATMELMAGIC 0x51807
2398#define REGDOMAINSZ 20
2399
2400static const struct iw_priv_args atmel_private_args[] = {
2401/*{ cmd, set_args, get_args, name } */
2402 { ATMELFWL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (atmel_priv_ioctl), IW_PRIV_TYPE_NONE, "atmelfwl" },
2403 { ATMELIDIFC, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "atmelidifc" },
2404 { ATMELRD, IW_PRIV_TYPE_CHAR | REGDOMAINSZ, IW_PRIV_TYPE_NONE, "regdomain" },
2405};
2406
2407static const struct iw_handler_def atmel_handler_def =
2408{
2409 .num_standard = sizeof(atmel_handler)/sizeof(iw_handler),
2410 .num_private = sizeof(atmel_private_handler)/sizeof(iw_handler),
2411 .num_private_args = sizeof(atmel_private_args)/sizeof(struct iw_priv_args),
2412 .standard = (iw_handler *) atmel_handler,
2413 .private = (iw_handler *) atmel_private_handler,
2414 .private_args = (struct iw_priv_args *) atmel_private_args
2415};
2416
2417static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2418{
2419 int i, rc = 0;
2420 struct atmel_private *priv = netdev_priv(dev);
2421 atmel_priv_ioctl com;
2422 struct iwreq *wrq = (struct iwreq *) rq;
2423 unsigned char *new_firmware;
2424 char domain[REGDOMAINSZ+1];
2425
2426 switch (cmd) {
2427 case SIOCGIWPRIV:
2428 if(wrq->u.data.pointer) {
2429 /* Set the number of ioctl available */
2430 wrq->u.data.length = sizeof(atmel_private_args) / sizeof(atmel_private_args[0]);
2431
2432 /* Copy structure to the user buffer */
2433 if (copy_to_user(wrq->u.data.pointer,
2434 (u_char *) atmel_private_args,
2435 sizeof(atmel_private_args)))
2436 rc = -EFAULT;
2437 }
2438 break;
2439
2440 case ATMELIDIFC:
2441 wrq->u.param.value = ATMELMAGIC;
2442 break;
2443
2444 case ATMELFWL:
2445 if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
2446 rc = -EFAULT;
2447 break;
2448 }
2449
2450 if (!capable(CAP_NET_ADMIN)) {
2451 rc = -EPERM;
2452 break;
2453 }
2454
2455 if (!(new_firmware = kmalloc(com.len, GFP_KERNEL))) {
2456 rc = -ENOMEM;
2457 break;
2458 }
2459
2460 if (copy_from_user(new_firmware, com.data, com.len)) {
2461 kfree(new_firmware);
2462 rc = -EFAULT;
2463 break;
2464 }
2465
2466 if (priv->firmware)
2467 kfree(priv->firmware);
2468
2469 priv->firmware = new_firmware;
2470 priv->firmware_length = com.len;
2471 strncpy(priv->firmware_id, com.id, 31);
2472 priv->firmware_id[31] = '\0';
2473 break;
2474
2475 case ATMELRD:
2476 if (copy_from_user(domain, rq->ifr_data, REGDOMAINSZ)) {
2477 rc = -EFAULT;
2478 break;
2479 }
2480
2481 if (!capable(CAP_NET_ADMIN)) {
2482 rc = -EPERM;
2483 break;
2484 }
2485
2486 domain[REGDOMAINSZ] = 0;
2487 rc = -EINVAL;
2488 for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++) {
2489 /* strcasecmp doesn't exist in the library */
2490 char *a = channel_table[i].name;
2491 char *b = domain;
2492 while (*a) {
2493 char c1 = *a++;
2494 char c2 = *b++;
2495 if (tolower(c1) != tolower(c2))
2496 break;
2497 }
2498 if (!*a && !*b) {
2499 priv->config_reg_domain = channel_table[i].reg_domain;
2500 rc = 0;
2501 }
2502 }
2503
2504 if (rc == 0 && priv->station_state != STATION_STATE_DOWN)
2505 rc = atmel_open(dev);
2506 break;
2507
2508 default:
2509 rc = -EOPNOTSUPP;
2510 }
2511
2512 return rc;
2513}
2514
2515struct auth_body {
2516 u16 alg;
2517 u16 trans_seq;
2518 u16 status;
2519 u8 el_id;
2520 u8 chall_text_len;
2521 u8 chall_text[253];
2522};
2523
2524static void atmel_enter_state(struct atmel_private *priv, int new_state)
2525{
2526 int old_state = priv->station_state;
2527
2528 if (new_state == old_state)
2529 return;
2530
2531 priv->station_state = new_state;
2532
2533 if (new_state == STATION_STATE_READY) {
2534 netif_start_queue(priv->dev);
2535 netif_carrier_on(priv->dev);
2536 }
2537
2538 if (old_state == STATION_STATE_READY) {
2539 netif_carrier_off(priv->dev);
2540 if (netif_running(priv->dev))
2541 netif_stop_queue(priv->dev);
2542 priv->last_beacon_timestamp = 0;
2543 }
2544}
2545
2546static void atmel_scan(struct atmel_private *priv, int specific_ssid)
2547{
2548 struct {
2549 u8 BSSID[6];
2550 u8 SSID[MAX_SSID_LENGTH];
2551 u8 scan_type;
2552 u8 channel;
2553 u16 BSS_type;
2554 u16 min_channel_time;
2555 u16 max_channel_time;
2556 u8 options;
2557 u8 SSID_size;
2558 } cmd;
2559
2560 memset(cmd.BSSID, 0xff, 6);
2561
2562 if (priv->fast_scan) {
2563 cmd.SSID_size = priv->SSID_size;
2564 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2565 cmd.min_channel_time = cpu_to_le16(10);
2566 cmd.max_channel_time = cpu_to_le16(50);
2567 } else {
2568 priv->BSS_list_entries = 0;
2569 cmd.SSID_size = 0;
2570 cmd.min_channel_time = cpu_to_le16(10);
2571 cmd.max_channel_time = cpu_to_le16(120);
2572 }
2573
2574 cmd.options = 0;
2575
2576 if (!specific_ssid)
2577 cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
2578
2579 cmd.channel = (priv->channel & 0x7f);
2580 cmd.scan_type = SCAN_TYPE_ACTIVE;
2581 cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ?
2582 BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
2583
2584 atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
2585
2586 /* This must come after all hardware access to avoid being messed up
2587 by stuff happening in interrupt context after we leave STATE_DOWN */
2588 atmel_enter_state(priv, STATION_STATE_SCANNING);
2589}
2590
2591static void join(struct atmel_private *priv, int type)
2592{
2593 struct {
2594 u8 BSSID[6];
2595 u8 SSID[MAX_SSID_LENGTH];
2596 u8 BSS_type; /* this is a short in a scan command - weird */
2597 u8 channel;
2598 u16 timeout;
2599 u8 SSID_size;
2600 u8 reserved;
2601 } cmd;
2602
2603 cmd.SSID_size = priv->SSID_size;
2604 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2605 memcpy(cmd.BSSID, priv->CurrentBSSID, 6);
2606 cmd.channel = (priv->channel & 0x7f);
2607 cmd.BSS_type = type;
2608 cmd.timeout = cpu_to_le16(2000);
2609
2610 atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
2611}
2612
2613
2614static void start(struct atmel_private *priv, int type)
2615{
2616 struct {
2617 u8 BSSID[6];
2618 u8 SSID[MAX_SSID_LENGTH];
2619 u8 BSS_type;
2620 u8 channel;
2621 u8 SSID_size;
2622 u8 reserved[3];
2623 } cmd;
2624
2625 cmd.SSID_size = priv->SSID_size;
2626 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2627 memcpy(cmd.BSSID, priv->BSSID, 6);
2628 cmd.BSS_type = type;
2629 cmd.channel = (priv->channel & 0x7f);
2630
2631 atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd));
2632}
2633
2634static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 channel)
2635{
2636 int rejoin = 0;
2637 int new = capability & C80211_MGMT_CAPABILITY_ShortPreamble ?
2638 SHORT_PREAMBLE : LONG_PREAMBLE;
2639
2640 if (priv->preamble != new) {
2641 priv->preamble = new;
2642 rejoin = 1;
2643 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
2644 }
2645
2646 if (priv->channel != channel) {
2647 priv->channel = channel;
2648 rejoin = 1;
2649 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
2650 }
2651
2652 if (rejoin) {
2653 priv->station_is_associated = 0;
2654 atmel_enter_state(priv, STATION_STATE_JOINNING);
2655
2656 if (priv->operating_mode == IW_MODE_INFRA)
2657 join(priv, BSS_TYPE_INFRASTRUCTURE);
2658 else
2659 join(priv, BSS_TYPE_AD_HOC);
2660 }
2661}
2662
2663
2664static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len)
2665{
2666 struct ieee802_11_hdr header;
2667 struct auth_body auth;
2668
2669 header.frame_ctl = cpu_to_le16(IEEE802_11_FTYPE_MGMT | IEEE802_11_STYPE_AUTH);
2670 header.duration_id = cpu_to_le16(0x8000);
2671 header.seq_ctl = 0;
2672 memcpy(header.addr1, priv->CurrentBSSID, 6);
2673 memcpy(header.addr2, priv->dev->dev_addr, 6);
2674 memcpy(header.addr3, priv->CurrentBSSID, 6);
2675
2676 if (priv->wep_is_on) {
2677 auth.alg = cpu_to_le16(C80211_MGMT_AAN_SHAREDKEY);
2678 /* no WEP for authentication frames with TrSeqNo 1 */
2679 if (priv->CurrentAuthentTransactionSeqNum != 1)
2680 header.frame_ctl |= cpu_to_le16(IEEE802_11_FCTL_WEP);
2681 } else {
2682 auth.alg = cpu_to_le16(C80211_MGMT_AAN_OPENSYSTEM);
2683 }
2684
2685 auth.status = 0;
2686 auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
2687 priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1;
2688 priv->CurrentAuthentTransactionSeqNum += 2;
2689
2690 if (challenge_len != 0) {
2691 auth.el_id = 16; /* challenge_text */
2692 auth.chall_text_len = challenge_len;
2693 memcpy(auth.chall_text, challenge, challenge_len);
2694 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 8 + challenge_len);
2695 } else {
2696 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 6);
2697 }
2698}
2699
2700static void send_association_request(struct atmel_private *priv, int is_reassoc)
2701{
2702 u8 *ssid_el_p;
2703 int bodysize;
2704 struct ieee802_11_hdr header;
2705 struct ass_req_format {
2706 u16 capability;
2707 u16 listen_interval;
2708 u8 ap[6]; /* nothing after here directly accessible */
2709 u8 ssid_el_id;
2710 u8 ssid_len;
2711 u8 ssid[MAX_SSID_LENGTH];
2712 u8 sup_rates_el_id;
2713 u8 sup_rates_len;
2714 u8 rates[4];
2715 } body;
2716
2717 header.frame_ctl = cpu_to_le16(IEEE802_11_FTYPE_MGMT |
2718 (is_reassoc ? IEEE802_11_STYPE_REASSOC_REQ : IEEE802_11_STYPE_ASSOC_REQ));
2719 header.duration_id = cpu_to_le16(0x8000);
2720 header.seq_ctl = 0;
2721
2722 memcpy(header.addr1, priv->CurrentBSSID, 6);
2723 memcpy(header.addr2, priv->dev->dev_addr, 6);
2724 memcpy(header.addr3, priv->CurrentBSSID, 6);
2725
2726 body.capability = cpu_to_le16(C80211_MGMT_CAPABILITY_ESS);
2727 if (priv->wep_is_on)
2728 body.capability |= cpu_to_le16(C80211_MGMT_CAPABILITY_Privacy);
2729 if (priv->preamble == SHORT_PREAMBLE)
2730 body.capability |= cpu_to_le16(C80211_MGMT_CAPABILITY_ShortPreamble);
2731
2732 body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
2733
2734 /* current AP address - only in reassoc frame */
2735 if (is_reassoc) {
2736 memcpy(body.ap, priv->CurrentBSSID, 6);
2737 ssid_el_p = (u8 *)&body.ssid_el_id;
2738 bodysize = 18 + priv->SSID_size;
2739 } else {
2740 ssid_el_p = (u8 *)&body.ap[0];
2741 bodysize = 12 + priv->SSID_size;
2742 }
2743
2744 ssid_el_p[0]= C80211_MGMT_ElementID_SSID;
2745 ssid_el_p[1] = priv->SSID_size;
2746 memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
2747 ssid_el_p[2 + priv->SSID_size] = C80211_MGMT_ElementID_SupportedRates;
2748 ssid_el_p[3 + priv->SSID_size] = 4; /* len of suported rates */
2749 memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
2750
2751 atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
2752}
2753
2754static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee802_11_hdr *header)
2755{
2756 if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS)
2757 return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
2758 else
2759 return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
2760}
2761
2762static int retrieve_bss(struct atmel_private *priv)
2763{
2764 int i;
2765 int max_rssi = -128;
2766 int max_index = -1;
2767
2768 if (priv->BSS_list_entries == 0)
2769 return -1;
2770
2771 if (priv->connect_to_any_BSS) {
2772 /* Select a BSS with the max-RSSI but of the same type and of the same WEP mode
2773 and that it is not marked as 'bad' (i.e. we had previously failed to connect to
2774 this BSS with the settings that we currently use) */
2775 priv->current_BSS = 0;
2776 for(i=0; i<priv->BSS_list_entries; i++) {
2777 if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
2778 ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) ||
2779 (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
2780 !(priv->BSSinfo[i].channel & 0x80)) {
2781 max_rssi = priv->BSSinfo[i].RSSI;
2782 priv->current_BSS = max_index = i;
2783 }
2784
2785 }
2786 return max_index;
2787 }
2788
2789 for(i=0; i<priv->BSS_list_entries; i++) {
2790 if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
2791 memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
2792 priv->operating_mode == priv->BSSinfo[i].BSStype &&
2793 atmel_validate_channel(priv, priv->BSSinfo[i].channel) == 0) {
2794 if (priv->BSSinfo[i].RSSI >= max_rssi) {
2795 max_rssi = priv->BSSinfo[i].RSSI;
2796 max_index = i;
2797 }
2798 }
2799 }
2800 return max_index;
2801}
2802
2803
2804static void store_bss_info(struct atmel_private *priv, struct ieee802_11_hdr *header,
2805 u16 capability, u16 beacon_period, u8 channel, u8 rssi,
2806 u8 ssid_len, u8 *ssid, int is_beacon)
2807{
2808 u8 *bss = capability & C80211_MGMT_CAPABILITY_ESS ? header->addr2 : header->addr3;
2809 int i, index;
2810
2811 for (index = -1, i = 0; i < priv->BSS_list_entries; i++)
2812 if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0)
2813 index = i;
2814
2815 /* If we process a probe and an entry from this BSS exists
2816 we will update the BSS entry with the info from this BSS.
2817 If we process a beacon we will only update RSSI */
2818
2819 if (index == -1) {
2820 if (priv->BSS_list_entries == MAX_BSS_ENTRIES)
2821 return;
2822 index = priv->BSS_list_entries++;
2823 memcpy(priv->BSSinfo[index].BSSID, bss, 6);
2824 priv->BSSinfo[index].RSSI = rssi;
2825 } else {
2826 if (rssi > priv->BSSinfo[index].RSSI)
2827 priv->BSSinfo[index].RSSI = rssi;
2828 if (is_beacon)
2829 return;
2830 }
2831
2832 priv->BSSinfo[index].channel = channel;
2833 priv->BSSinfo[index].beacon_period = beacon_period;
2834 priv->BSSinfo[index].UsingWEP = capability & C80211_MGMT_CAPABILITY_Privacy;
2835 memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len);
2836 priv->BSSinfo[index].SSIDsize = ssid_len;
2837
2838 if (capability & C80211_MGMT_CAPABILITY_IBSS)
2839 priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
2840 else if (capability & C80211_MGMT_CAPABILITY_ESS)
2841 priv->BSSinfo[index].BSStype =IW_MODE_INFRA;
2842
2843 priv->BSSinfo[index].preamble = capability & C80211_MGMT_CAPABILITY_ShortPreamble ?
2844 SHORT_PREAMBLE : LONG_PREAMBLE;
2845}
2846
2847static void authenticate(struct atmel_private *priv, u16 frame_len)
2848{
2849 struct auth_body *auth = (struct auth_body *)priv->rx_buf;
2850 u16 status = le16_to_cpu(auth->status);
2851 u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
2852
2853 if (status == C80211_MGMT_SC_Success && !priv->wep_is_on) {
2854 /* no WEP */
2855 if (priv->station_was_associated) {
2856 atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
2857 send_association_request(priv, 1);
2858 return;
2859 } else {
2860 atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
2861 send_association_request(priv, 0);
2862 return;
2863 }
2864 }
2865
2866 if (status == C80211_MGMT_SC_Success && priv->wep_is_on) {
2867 /* WEP */
2868 if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
2869 return;
2870
2871 if (trans_seq_no == 0x0002 &&
2872 auth->el_id == C80211_MGMT_ElementID_ChallengeText) {
2873 send_authentication_request(priv, auth->chall_text, auth->chall_text_len);
2874 return;
2875 }
2876
2877 if (trans_seq_no == 0x0004) {
2878 if(priv->station_was_associated) {
2879 atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
2880 send_association_request(priv, 1);
2881 return;
2882 } else {
2883 atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
2884 send_association_request(priv, 0);
2885 return;
2886 }
2887 }
2888 }
2889
2890 if (status == C80211_MGMT_SC_AuthAlgNotSupported && priv->connect_to_any_BSS) {
2891 int bss_index;
2892
2893 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
2894
2895 if ((bss_index = retrieve_bss(priv)) != -1) {
2896 atmel_join_bss(priv, bss_index);
2897 return;
2898 }
2899 }
2900
2901
2902 priv->AuthenticationRequestRetryCnt = 0;
2903 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
2904 priv->station_is_associated = 0;
2905}
2906
2907static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
2908{
2909 struct ass_resp_format {
2910 u16 capability;
2911 u16 status;
2912 u16 ass_id;
2913 u8 el_id;
2914 u8 length;
2915 u8 rates[4];
2916 } *ass_resp = (struct ass_resp_format *)priv->rx_buf;
2917
2918 u16 status = le16_to_cpu(ass_resp->status);
2919 u16 ass_id = le16_to_cpu(ass_resp->ass_id);
2920 u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
2921
2922 if (frame_len < 8 + rates_len)
2923 return;
2924
2925 if (status == C80211_MGMT_SC_Success) {
2926 if (subtype == C80211_SUBTYPE_MGMT_ASS_RESPONSE)
2927 priv->AssociationRequestRetryCnt = 0;
2928 else
2929 priv->ReAssociationRequestRetryCnt = 0;
2930
2931 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
2932 atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
2933 if (priv->power_mode == 0) {
2934 priv->listen_interval = 1;
2935 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
2936 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
2937 } else {
2938 priv->listen_interval = 2;
2939 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, PS_MODE);
2940 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
2941 }
2942
2943 priv->station_is_associated = 1;
2944 priv->station_was_associated = 1;
2945 atmel_enter_state(priv, STATION_STATE_READY);
2946 return;
2947 }
2948
2949 if (subtype == C80211_SUBTYPE_MGMT_ASS_RESPONSE &&
2950 status != C80211_MGMT_SC_AssDeniedBSSRate &&
2951 status != C80211_MGMT_SC_SupportCapabilities &&
2952 priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
2953 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
2954 priv->AssociationRequestRetryCnt++;
2955 send_association_request(priv, 0);
2956 return;
2957 }
2958
2959 if (subtype == C80211_SUBTYPE_MGMT_REASS_RESPONSE &&
2960 status != C80211_MGMT_SC_AssDeniedBSSRate &&
2961 status != C80211_MGMT_SC_SupportCapabilities &&
2962 priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
2963 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
2964 priv->ReAssociationRequestRetryCnt++;
2965 send_association_request(priv, 1);
2966 return;
2967 }
2968
2969 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
2970 priv->station_is_associated = 0;
2971
2972 if(priv->connect_to_any_BSS) {
2973 int bss_index;
2974 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
2975
2976 if ((bss_index = retrieve_bss(priv)) != -1)
2977 atmel_join_bss(priv, bss_index);
2978
2979 }
2980}
2981
2982void atmel_join_bss(struct atmel_private *priv, int bss_index)
2983{
2984 struct bss_info *bss = &priv->BSSinfo[bss_index];
2985
2986 memcpy(priv->CurrentBSSID, bss->BSSID, 6);
2987 memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize);
2988
2989 /* The WPA stuff cares about the current AP address */
2990 if (priv->use_wpa)
2991 build_wpa_mib(priv);
2992
2993 /* When switching to AdHoc turn OFF Power Save if needed */
2994
2995 if (bss->BSStype == IW_MODE_ADHOC &&
2996 priv->operating_mode != IW_MODE_ADHOC &&
2997 priv->power_mode) {
2998 priv->power_mode = 0;
2999 priv->listen_interval = 1;
3000 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3001 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3002 }
3003
3004 priv->operating_mode = bss->BSStype;
3005 priv->channel = bss->channel & 0x7f;
3006 priv->beacon_period = bss->beacon_period;
3007
3008 if (priv->preamble != bss->preamble) {
3009 priv->preamble = bss->preamble;
3010 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
3011 }
3012
3013 if (!priv->wep_is_on && bss->UsingWEP) {
3014 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3015 priv->station_is_associated = 0;
3016 return;
3017 }
3018
3019 if (priv->wep_is_on && !bss->UsingWEP) {
3020 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3021 priv->station_is_associated = 0;
3022 return;
3023 }
3024
3025 atmel_enter_state(priv, STATION_STATE_JOINNING);
3026
3027 if (priv->operating_mode == IW_MODE_INFRA)
3028 join(priv, BSS_TYPE_INFRASTRUCTURE);
3029 else
3030 join(priv, BSS_TYPE_AD_HOC);
3031}
3032
3033
3034static void restart_search(struct atmel_private *priv)
3035{
3036 int bss_index;
3037
3038 if (!priv->connect_to_any_BSS) {
3039 atmel_scan(priv, 1);
3040 } else {
3041 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3042
3043 if ((bss_index = retrieve_bss(priv)) != -1)
3044 atmel_join_bss(priv, bss_index);
3045 else
3046 atmel_scan(priv, 0);
3047
3048 }
3049}
3050
3051static void smooth_rssi(struct atmel_private *priv, u8 rssi)
3052{
3053 u8 old = priv->wstats.qual.level;
3054 u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
3055
3056 switch (priv->firmware_type) {
3057 case ATMEL_FW_TYPE_502E:
3058 max_rssi = 63; /* 502-rmfd-reve max by experiment */
3059 break;
3060 default:
3061 break;
3062 }
3063
3064 rssi = rssi * 100 / max_rssi;
3065 if((rssi + old) % 2)
3066 priv->wstats.qual.level = ((rssi + old)/2) + 1;
3067 else
3068 priv->wstats.qual.level = ((rssi + old)/2);
3069 priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
3070 priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
3071}
3072
3073static void atmel_smooth_qual(struct atmel_private *priv)
3074{
3075 unsigned long time_diff = (jiffies - priv->last_qual)/HZ;
3076 while (time_diff--) {
3077 priv->last_qual += HZ;
3078 priv->wstats.qual.qual = priv->wstats.qual.qual/2;
3079 priv->wstats.qual.qual +=
3080 priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
3081 priv->beacons_this_sec = 0;
3082 }
3083 priv->wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
3084 priv->wstats.qual.updated &= ~IW_QUAL_QUAL_INVALID;
3085}
3086
3087/* deals with incoming managment frames. */
3088static void atmel_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header,
3089 u16 frame_len, u8 rssi)
3090{
3091 u16 subtype;
3092
3093 switch (subtype = le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_STYPE) {
3094 case C80211_SUBTYPE_MGMT_BEACON :
3095 case C80211_SUBTYPE_MGMT_ProbeResponse:
3096
3097 /* beacon frame has multiple variable-length fields -
3098 never let an engineer loose with a data structure design. */
3099 {
3100 struct beacon_format {
3101 u64 timestamp;
3102 u16 interval;
3103 u16 capability;
3104 u8 ssid_el_id;
3105 u8 ssid_length;
3106 /* ssid here */
3107 u8 rates_el_id;
3108 u8 rates_length;
3109 /* rates here */
3110 u8 ds_el_id;
3111 u8 ds_length;
3112 /* ds here */
3113 } *beacon = (struct beacon_format *)priv->rx_buf;
3114
3115 u8 channel, rates_length, ssid_length;
3116 u64 timestamp = le64_to_cpu(beacon->timestamp);
3117 u16 beacon_interval = le16_to_cpu(beacon->interval);
3118 u16 capability = le16_to_cpu(beacon->capability);
3119 u8 *beaconp = priv->rx_buf;
3120 ssid_length = beacon->ssid_length;
3121 /* this blows chunks. */
3122 if (frame_len < 14 || frame_len < ssid_length + 15)
3123 return;
3124 rates_length = beaconp[beacon->ssid_length + 15];
3125 if (frame_len < ssid_length + rates_length + 18)
3126 return;
3127 if (ssid_length > MAX_SSID_LENGTH)
3128 return;
3129 channel = beaconp[ssid_length + rates_length + 18];
3130
3131 if (priv->station_state == STATION_STATE_READY) {
3132 smooth_rssi(priv, rssi);
3133 if (is_frame_from_current_bss(priv, header)) {
3134 priv->beacons_this_sec++;
3135 atmel_smooth_qual(priv);
3136 if (priv->last_beacon_timestamp) {
3137 /* Note truncate this to 32 bits - kernel can't divide a long long */
3138 u32 beacon_delay = timestamp - priv->last_beacon_timestamp;
3139 int beacons = beacon_delay / (beacon_interval * 1000);
3140 if (beacons > 1)
3141 priv->wstats.miss.beacon += beacons - 1;
3142 }
3143 priv->last_beacon_timestamp = timestamp;
3144 handle_beacon_probe(priv, capability, channel);
3145 }
3146 }
3147
3148 if (priv->station_state == STATION_STATE_SCANNING )
3149 store_bss_info(priv, header, capability, beacon_interval, channel,
3150 rssi, ssid_length, &beacon->rates_el_id,
3151 subtype == C80211_SUBTYPE_MGMT_BEACON) ;
3152 }
3153 break;
3154
3155 case C80211_SUBTYPE_MGMT_Authentication:
3156
3157 if (priv->station_state == STATION_STATE_AUTHENTICATING)
3158 authenticate(priv, frame_len);
3159
3160 break;
3161
3162 case C80211_SUBTYPE_MGMT_ASS_RESPONSE:
3163 case C80211_SUBTYPE_MGMT_REASS_RESPONSE:
3164
3165 if (priv->station_state == STATION_STATE_ASSOCIATING ||
3166 priv->station_state == STATION_STATE_REASSOCIATING)
3167 associate(priv, frame_len, subtype);
3168
3169 break;
3170
3171 case C80211_SUBTYPE_MGMT_DISASSOSIATION:
3172 if (priv->station_is_associated &&
3173 priv->operating_mode == IW_MODE_INFRA &&
3174 is_frame_from_current_bss(priv, header)) {
3175 priv->station_was_associated = 0;
3176 priv->station_is_associated = 0;
3177
3178 atmel_enter_state(priv, STATION_STATE_JOINNING);
3179 join(priv, BSS_TYPE_INFRASTRUCTURE);
3180 }
3181
3182 break;
3183
3184 case C80211_SUBTYPE_MGMT_Deauthentication:
3185 if (priv->operating_mode == IW_MODE_INFRA &&
3186 is_frame_from_current_bss(priv, header)) {
3187 priv->station_was_associated = 0;
3188
3189 atmel_enter_state(priv, STATION_STATE_JOINNING);
3190 join(priv, BSS_TYPE_INFRASTRUCTURE);
3191 }
3192
3193 break;
3194 }
3195}
3196
3197/* run when timer expires */
3198static void atmel_management_timer(u_long a)
3199{
3200 struct net_device *dev = (struct net_device *) a;
3201 struct atmel_private *priv = netdev_priv(dev);
3202 unsigned long flags;
3203
3204 /* Check if the card has been yanked. */
3205 if (priv->card && priv->present_callback &&
3206 !(*priv->present_callback)(priv->card))
3207 return;
3208
3209 spin_lock_irqsave(&priv->irqlock, flags);
3210
3211 switch (priv->station_state) {
3212
3213 case STATION_STATE_AUTHENTICATING:
3214 if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
3215 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3216 priv->station_is_associated = 0;
3217 priv->AuthenticationRequestRetryCnt = 0;
3218 restart_search(priv);
3219 } else {
3220 priv->AuthenticationRequestRetryCnt++;
3221 priv->CurrentAuthentTransactionSeqNum = 0x0001;
3222 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3223 send_authentication_request(priv, NULL, 0);
3224 }
3225
3226 break;
3227
3228 case STATION_STATE_ASSOCIATING:
3229 if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3230 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3231 priv->station_is_associated = 0;
3232 priv->AssociationRequestRetryCnt = 0;
3233 restart_search(priv);
3234 } else {
3235 priv->AssociationRequestRetryCnt++;
3236 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3237 send_association_request(priv, 0);
3238 }
3239
3240 break;
3241
3242 case STATION_STATE_REASSOCIATING:
3243 if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3244 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3245 priv->station_is_associated = 0;
3246 priv->ReAssociationRequestRetryCnt = 0;
3247 restart_search(priv);
3248 } else {
3249 priv->ReAssociationRequestRetryCnt++;
3250 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3251 send_association_request(priv, 1);
3252 }
3253
3254 break;
3255
3256 default:
3257 break;
3258 }
3259
3260 spin_unlock_irqrestore(&priv->irqlock, flags);
3261}
3262
3263static void atmel_command_irq(struct atmel_private *priv)
3264{
3265 u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
3266 u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
3267 int fast_scan;
3268
3269 if (status == CMD_STATUS_IDLE ||
3270 status == CMD_STATUS_IN_PROGRESS)
3271 return;
3272
3273 switch (command){
3274
3275 case CMD_Start:
3276 if (status == CMD_STATUS_COMPLETE) {
3277 priv->station_was_associated = priv->station_is_associated;
3278 atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
3279 (u8 *)priv->CurrentBSSID, 6);
3280 atmel_enter_state(priv, STATION_STATE_READY);
3281 }
3282 break;
3283
3284 case CMD_Scan:
3285 fast_scan = priv->fast_scan;
3286 priv->fast_scan = 0;
3287
3288 if (status != CMD_STATUS_COMPLETE) {
3289 atmel_scan(priv, 1);
3290 } else {
3291 int bss_index = retrieve_bss(priv);
3292 if (bss_index != -1) {
3293 atmel_join_bss(priv, bss_index);
3294 } else if (priv->operating_mode == IW_MODE_ADHOC &&
3295 priv->SSID_size != 0) {
3296 start(priv, BSS_TYPE_AD_HOC);
3297 } else {
3298 priv->fast_scan = !fast_scan;
3299 atmel_scan(priv, 1);
3300 }
3301 priv->site_survey_state = SITE_SURVEY_COMPLETED;
3302 }
3303 break;
3304
3305 case CMD_SiteSurvey:
3306 priv->fast_scan = 0;
3307
3308 if (status != CMD_STATUS_COMPLETE)
3309 return;
3310
3311 priv->site_survey_state = SITE_SURVEY_COMPLETED;
3312 if (priv->station_is_associated) {
3313 atmel_enter_state(priv, STATION_STATE_READY);
3314 } else {
3315 atmel_scan(priv, 1);
3316 }
3317 break;
3318
3319 case CMD_Join:
3320 if (status == CMD_STATUS_COMPLETE) {
3321 if (priv->operating_mode == IW_MODE_ADHOC) {
3322 priv->station_was_associated = priv->station_is_associated;
3323 atmel_enter_state(priv, STATION_STATE_READY);
3324 } else {
3325 priv->AuthenticationRequestRetryCnt = 0;
3326 atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
3327
3328 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3329 priv->CurrentAuthentTransactionSeqNum = 0x0001;
3330 send_authentication_request(priv, NULL, 0);
3331 }
3332 return;
3333 }
3334
3335 atmel_scan(priv, 1);
3336
3337 }
3338}
3339
3340static int atmel_wakeup_firmware(struct atmel_private *priv)
3341{
3342 struct host_info_struct *iface = &priv->host_info;
3343 u16 mr1, mr3;
3344 int i;
3345
3346 if (priv->card_type == CARD_TYPE_SPI_FLASH)
3347 atmel_set_gcr(priv->dev, GCR_REMAP);
3348
3349 /* wake up on-board processor */
3350 atmel_clear_gcr(priv->dev, 0x0040);
3351 atmel_write16(priv->dev, BSR, BSS_SRAM);
3352
3353 if (priv->card_type == CARD_TYPE_SPI_FLASH)
3354 mdelay(100);
3355
3356 /* and wait for it */
3357 for (i = LOOP_RETRY_LIMIT; i; i--) {
3358 mr1 = atmel_read16(priv->dev, MR1);
3359 mr3 = atmel_read16(priv->dev, MR3);
3360
3361 if (mr3 & MAC_BOOT_COMPLETE)
3362 break;
3363 if (mr1 & MAC_BOOT_COMPLETE &&
3364 priv->bus_type == BUS_TYPE_PCCARD)
3365 break;
3366 }
3367
3368 if (i == 0) {
3369 printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
3370 return 0;
3371 }
3372
3373 if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
3374 printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
3375 return 0;
3376 }
3377
3378 /* now check for completion of MAC initialization through
3379 the FunCtrl field of the IFACE, poll MR1 to detect completion of
3380 MAC initialization, check completion status, set interrupt mask,
3381 enables interrupts and calls Tx and Rx initialization functions */
3382
3383 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
3384
3385 for (i = LOOP_RETRY_LIMIT; i; i--) {
3386 mr1 = atmel_read16(priv->dev, MR1);
3387 mr3 = atmel_read16(priv->dev, MR3);
3388
3389 if (mr3 & MAC_INIT_COMPLETE)
3390 break;
3391 if (mr1 & MAC_INIT_COMPLETE &&
3392 priv->bus_type == BUS_TYPE_PCCARD)
3393 break;
3394 }
3395
3396 if (i == 0) {
3397 printk(KERN_ALERT "%s: MAC failed to initialise.\n", priv->dev->name);
3398 return 0;
3399 }
3400
3401 /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
3402 if ((mr3 & MAC_INIT_COMPLETE) &&
3403 !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
3404 printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name);
3405 return 0;
3406 }
3407 if ((mr1 & MAC_INIT_COMPLETE) &&
3408 !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) {
3409 printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name);
3410 return 0;
3411 }
3412
3413 atmel_copy_to_host(priv->dev, (unsigned char *)iface,
3414 priv->host_info_base, sizeof(*iface));
3415
3416 iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
3417 iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
3418 iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
3419 iface->tx_desc_count = le16_to_cpu(iface->tx_desc_count);
3420 iface->rx_buff_pos = le16_to_cpu(iface->rx_buff_pos);
3421 iface->rx_buff_size = le16_to_cpu(iface->rx_buff_size);
3422 iface->rx_desc_pos = le16_to_cpu(iface->rx_desc_pos);
3423 iface->rx_desc_count = le16_to_cpu(iface->rx_desc_count);
3424 iface->build_version = le16_to_cpu(iface->build_version);
3425 iface->command_pos = le16_to_cpu(iface->command_pos);
3426 iface->major_version = le16_to_cpu(iface->major_version);
3427 iface->minor_version = le16_to_cpu(iface->minor_version);
3428 iface->func_ctrl = le16_to_cpu(iface->func_ctrl);
3429 iface->mac_status = le16_to_cpu(iface->mac_status);
3430
3431 return 1;
3432}
3433
3434/* determine type of memory and MAC address */
3435static int probe_atmel_card(struct net_device *dev)
3436{
3437 int rc = 0;
3438 struct atmel_private *priv = netdev_priv(dev);
3439
3440 /* reset pccard */
3441 if (priv->bus_type == BUS_TYPE_PCCARD)
3442 atmel_write16(dev, GCR, 0x0060);
3443
3444 atmel_write16(dev, GCR, 0x0040);
3445 mdelay(500);
3446
3447 if (atmel_read16(dev, MR2) == 0) {
3448 /* No stored firmware so load a small stub which just
3449 tells us the MAC address */
3450 int i;
3451 priv->card_type = CARD_TYPE_EEPROM;
3452 atmel_write16(dev, BSR, BSS_IRAM);
3453 atmel_copy_to_card(dev, 0, mac_reader, sizeof(mac_reader));
3454 atmel_set_gcr(dev, GCR_REMAP);
3455 atmel_clear_gcr(priv->dev, 0x0040);
3456 atmel_write16(dev, BSR, BSS_SRAM);
3457 for (i = LOOP_RETRY_LIMIT; i; i--)
3458 if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
3459 break;
3460 if (i == 0) {
3461 printk(KERN_ALERT "%s: MAC failed to boot MAC address reader.\n", dev->name);
3462 } else {
3463 atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6);
3464 /* got address, now squash it again until the network
3465 interface is opened */
3466 if (priv->bus_type == BUS_TYPE_PCCARD)
3467 atmel_write16(dev, GCR, 0x0060);
3468 atmel_write16(dev, GCR, 0x0040);
3469 rc = 1;
3470 }
3471 } else if (atmel_read16(dev, MR4) == 0) {
3472 /* Mac address easy in this case. */
3473 priv->card_type = CARD_TYPE_PARALLEL_FLASH;
3474 atmel_write16(dev, BSR, 1);
3475 atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6);
3476 atmel_write16(dev, BSR, 0x200);
3477 rc = 1;
3478 } else {
3479 /* Standard firmware in flash, boot it up and ask
3480 for the Mac Address */
3481 priv->card_type = CARD_TYPE_SPI_FLASH;
3482 if (atmel_wakeup_firmware(priv)) {
3483 atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
3484
3485 /* got address, now squash it again until the network
3486 interface is opened */
3487 if (priv->bus_type == BUS_TYPE_PCCARD)
3488 atmel_write16(dev, GCR, 0x0060);
3489 atmel_write16(dev, GCR, 0x0040);
3490 rc = 1;
3491 }
3492 }
3493
3494 if (rc) {
3495 if (dev->dev_addr[0] == 0xFF) {
3496 u8 default_mac[] = {0x00,0x04, 0x25, 0x00, 0x00, 0x00};
3497 printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
3498 memcpy(dev->dev_addr, default_mac, 6);
3499 }
3500 printk(KERN_INFO "%s: MAC address %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
3501 dev->name,
3502 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
3503 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
3504
3505 }
3506
3507 return rc;
3508}
3509
3510static void build_wep_mib(struct atmel_private *priv)
3511/* Move the encyption information on the MIB structure.
3512 This routine is for the pre-WPA firmware: later firmware has
3513 a different format MIB and a different routine. */
3514{
3515 struct { /* NB this is matched to the hardware, don't change. */
3516 u8 wep_is_on;
3517 u8 default_key; /* 0..3 */
3518 u8 reserved;
3519 u8 exclude_unencrypted;
3520
3521 u32 WEPICV_error_count;
3522 u32 WEP_excluded_count;
3523
3524 u8 wep_keys[MAX_ENCRYPTION_KEYS][13];
3525 u8 encryption_level; /* 0, 1, 2 */
3526 u8 reserved2[3];
3527 } mib;
3528 int i;
3529
3530 mib.wep_is_on = priv->wep_is_on;
3531 if (priv->wep_is_on) {
3532 if (priv->wep_key_len[priv->default_key] > 5)
3533 mib.encryption_level = 2;
3534 else
3535 mib.encryption_level = 1;
3536 } else {
3537 mib.encryption_level = 0;
3538 }
3539
3540 mib.default_key = priv->default_key;
3541 mib.exclude_unencrypted = priv->exclude_unencrypted;
3542
3543 for(i = 0; i < MAX_ENCRYPTION_KEYS; i++)
3544 memcpy(mib.wep_keys[i], priv->wep_keys[i], 13);
3545
3546 atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3547}
3548
3549static void build_wpa_mib(struct atmel_private *priv)
3550{
3551 /* This is for the later (WPA enabled) firmware. */
3552
3553 struct { /* NB this is matched to the hardware, don't change. */
3554 u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
3555 u8 receiver_address[6];
3556 u8 wep_is_on;
3557 u8 default_key; /* 0..3 */
3558 u8 group_key;
3559 u8 exclude_unencrypted;
3560 u8 encryption_type;
3561 u8 reserved;
3562
3563 u32 WEPICV_error_count;
3564 u32 WEP_excluded_count;
3565
3566 u8 key_RSC[4][8];
3567 } mib;
3568
3569 int i;
3570
3571 mib.wep_is_on = priv->wep_is_on;
3572 mib.exclude_unencrypted = priv->exclude_unencrypted;
3573 memcpy(mib.receiver_address, priv->CurrentBSSID, 6);
3574
3575 /* zero all the keys before adding in valid ones. */
3576 memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value));
3577
3578 if (priv->wep_is_on) {
3579 /* There's a comment in the Atmel code to the effect that this is only valid
3580 when still using WEP, it may need to be set to something to use WPA */
3581 memset(mib.key_RSC, 0, sizeof(mib.key_RSC));
3582
3583 mib.default_key = mib.group_key = 255;
3584 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
3585 if (priv->wep_key_len[i] > 0) {
3586 memcpy(mib.cipher_default_key_value[i], priv->wep_keys[i], MAX_ENCRYPTION_KEY_SIZE);
3587 if (i == priv->default_key) {
3588 mib.default_key = i;
3589 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7;
3590 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite;
3591 } else {
3592 mib.group_key = i;
3593 priv->group_cipher_suite = priv->pairwise_cipher_suite;
3594 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
3595 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
3596 }
3597 }
3598 }
3599 if (mib.default_key == 255)
3600 mib.default_key = mib.group_key != 255 ? mib.group_key : 0;
3601 if (mib.group_key == 255)
3602 mib.group_key = mib.default_key;
3603
3604 }
3605
3606 atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3607}
3608
3609static int reset_atmel_card(struct net_device *dev)
3610{
3611 /* do everything necessary to wake up the hardware, including
3612 waiting for the lightning strike and throwing the knife switch....
3613
3614 set all the Mib values which matter in the card to match
3615 their settings in the atmel_private structure. Some of these
3616 can be altered on the fly, but many (WEP, infrastucture or ad-hoc)
3617 can only be changed by tearing down the world and coming back through
3618 here.
3619
3620 This routine is also responsible for initialising some
3621 hardware-specific fields in the atmel_private structure,
3622 including a copy of the firmware's hostinfo stucture
3623 which is the route into the rest of the firmare datastructures. */
3624
3625 struct atmel_private *priv = netdev_priv(dev);
3626 u8 configuration;
3627
3628 /* data to add to the firmware names, in priority order
3629 this implemenents firmware versioning */
3630
3631 static char *firmware_modifier[] = {
3632 "-wpa",
3633 "",
3634 NULL
3635 };
3636
3637 /* reset pccard */
3638 if (priv->bus_type == BUS_TYPE_PCCARD)
3639 atmel_write16(priv->dev, GCR, 0x0060);
3640
3641 /* stop card , disable interrupts */
3642 atmel_write16(priv->dev, GCR, 0x0040);
3643
3644 if (priv->card_type == CARD_TYPE_EEPROM) {
3645 /* copy in firmware if needed */
3646 const struct firmware *fw_entry = NULL;
3647 unsigned char *fw;
3648 int len = priv->firmware_length;
3649 if (!(fw = priv->firmware)) {
3650 if (priv->firmware_type == ATMEL_FW_TYPE_NONE) {
3651 if (strlen(priv->firmware_id) == 0) {
3652 printk(KERN_INFO
3653 "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
3654 dev->name);
3655 printk(KERN_INFO
3656 "%s: if not, use the firmware= module parameter.\n",
3657 dev->name);
3658 strcpy(priv->firmware_id, "atmel_at76c502.bin");
3659 }
3660 if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) != 0) {
3661 printk(KERN_ALERT
3662 "%s: firmware %s is missing, cannot continue.\n",
3663 dev->name, priv->firmware_id);
3664 return 0;
3665 }
3666 } else {
3667 int fw_index = 0;
3668 int success = 0;
3669
3670 /* get firmware filename entry based on firmware type ID */
3671 while (fw_table[fw_index].fw_type != priv->firmware_type
3672 && fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
3673 fw_index++;
3674
3675 /* construct the actual firmware file name */
3676 if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
3677 int i;
3678 for (i = 0; firmware_modifier[i]; i++) {
3679 snprintf(priv->firmware_id, 32, "%s%s.%s", fw_table[fw_index].fw_file,
3680 firmware_modifier[i], fw_table[fw_index].fw_file_ext);
3681 priv->firmware_id[31] = '\0';
3682 if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) {
3683 success = 1;
3684 break;
3685 }
3686 }
3687 }
3688 if (!success) {
3689 printk(KERN_ALERT
3690 "%s: firmware %s is missing, cannot start.\n",
3691 dev->name, priv->firmware_id);
3692 priv->firmware_id[0] = '\0';
3693 return 0;
3694 }
3695 }
3696
3697 fw = fw_entry->data;
3698 len = fw_entry->size;
3699 }
3700
3701 if (len <= 0x6000) {
3702 atmel_write16(priv->dev, BSR, BSS_IRAM);
3703 atmel_copy_to_card(priv->dev, 0, fw, len);
3704 atmel_set_gcr(priv->dev, GCR_REMAP);
3705 } else {
3706 /* Remap */
3707 atmel_set_gcr(priv->dev, GCR_REMAP);
3708 atmel_write16(priv->dev, BSR, BSS_IRAM);
3709 atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
3710 atmel_write16(priv->dev, BSR, 0x2ff);
3711 atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000);
3712 }
3713
3714 if (fw_entry)
3715 release_firmware(fw_entry);
3716 }
3717
3718 if (!atmel_wakeup_firmware(priv))
3719 return 0;
3720
3721 /* Check the version and set the correct flag for wpa stuff,
3722 old and new firmware is incompatible.
3723 The pre-wpa 3com firmware reports major version 5,
3724 the wpa 3com firmware is major version 4 and doesn't need
3725 the 3com broken-ness filter. */
3726 priv->use_wpa = (priv->host_info.major_version == 4);
3727 priv->radio_on_broken = (priv->host_info.major_version == 5);
3728
3729 /* unmask all irq sources */
3730 atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
3731
3732 /* int Tx system and enable Tx */
3733 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
3734 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
3735 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
3736 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
3737
3738 priv->tx_desc_free = priv->host_info.tx_desc_count;
3739 priv->tx_desc_head = 0;
3740 priv->tx_desc_tail = 0;
3741 priv->tx_desc_previous = 0;
3742 priv->tx_free_mem = priv->host_info.tx_buff_size;
3743 priv->tx_buff_head = 0;
3744 priv->tx_buff_tail = 0;
3745
3746 configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3747 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3748 configuration | FUNC_CTRL_TxENABLE);
3749
3750 /* init Rx system and enable */
3751 priv->rx_desc_head = 0;
3752
3753 configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
3754 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
3755 configuration | FUNC_CTRL_RxENABLE);
3756
3757 if (!priv->radio_on_broken) {
3758 if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
3759 CMD_STATUS_REJECTED_RADIO_OFF) {
3760 printk(KERN_INFO
3761 "%s: cannot turn the radio on. (Hey radio, you're beautiful!)\n",
3762 dev->name);
3763 return 0;
3764 }
3765 }
3766
3767 /* set up enough MIB values to run. */
3768 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
3769 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_TX_PROMISCUOUS_POS, PROM_MODE_OFF);
3770 atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_RTS_THRESHOLD_POS, priv->rts_threshold);
3771 atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_FRAG_THRESHOLD_POS, priv->frag_threshold);
3772 atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
3773 atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
3774 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
3775 atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS,
3776 priv->dev->dev_addr, 6);
3777 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3778 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3779 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_BEACON_PER_POS, priv->default_beacon_period);
3780 atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, atmel_basic_rates, 4);
3781 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_PRIVACY_POS, priv->wep_is_on);
3782 if (priv->use_wpa)
3783 build_wpa_mib(priv);
3784 else
3785 build_wep_mib(priv);
3786
3787 return 1;
3788}
3789
3790static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size)
3791{
3792 if (cmd)
3793 atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET),
3794 cmd, cmd_size);
3795
3796 atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
3797 atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
3798}
3799
3800static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size)
3801{
3802 int i, status;
3803
3804 atmel_send_command(priv, command, cmd, cmd_size);
3805
3806 for (i = 5000; i; i--) {
3807 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
3808 if (status != CMD_STATUS_IDLE &&
3809 status != CMD_STATUS_IN_PROGRESS)
3810 break;
3811 udelay(20);
3812 }
3813
3814 if (i == 0) {
3815 printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name);
3816 status = CMD_STATUS_HOST_ERROR;
3817 } else {
3818 if (command != CMD_EnableRadio)
3819 status = CMD_STATUS_COMPLETE;
3820 }
3821
3822 return status;
3823}
3824
3825static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index)
3826{
3827 struct get_set_mib m;
3828 m.type = type;
3829 m.size = 1;
3830 m.index = index;
3831
3832 atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
3833 return atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE));
3834}
3835
3836static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data)
3837{
3838 struct get_set_mib m;
3839 m.type = type;
3840 m.size = 1;
3841 m.index = index;
3842 m.data[0] = data;
3843
3844 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
3845}
3846
3847static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, u16 data)
3848{
3849 struct get_set_mib m;
3850 m.type = type;
3851 m.size = 2;
3852 m.index = index;
3853 m.data[0] = data;
3854 m.data[1] = data >> 8;
3855
3856 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2);
3857}
3858
3859static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len)
3860{
3861 struct get_set_mib m;
3862 m.type = type;
3863 m.size = data_len;
3864 m.index = index;
3865
3866 if (data_len > MIB_MAX_DATA_BYTES)
3867 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
3868
3869 memcpy(m.data, data, data_len);
3870 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
3871}
3872
3873static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len)
3874{
3875 struct get_set_mib m;
3876 m.type = type;
3877 m.size = data_len;
3878 m.index = index;
3879
3880 if (data_len > MIB_MAX_DATA_BYTES)
3881 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
3882
3883 atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
3884 atmel_copy_to_host(priv->dev, data,
3885 atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len);
3886}
3887
3888static void atmel_writeAR(struct net_device *dev, u16 data)
3889{
3890 int i;
3891 outw(data, dev->base_addr + AR);
3892 /* Address register appears to need some convincing..... */
3893 for (i = 0; data != inw(dev->base_addr + AR) && i<10; i++)
3894 outw(data, dev->base_addr + AR);
3895}
3896
3897static void atmel_copy_to_card(struct net_device *dev, u16 dest, unsigned char *src, u16 len)
3898{
3899 int i;
3900 atmel_writeAR(dev, dest);
3901 if (dest % 2) {
3902 atmel_write8(dev, DR, *src);
3903 src++; len--;
3904 }
3905 for (i = len; i > 1 ; i -= 2) {
3906 u8 lb = *src++;
3907 u8 hb = *src++;
3908 atmel_write16(dev, DR, lb | (hb << 8));
3909 }
3910 if (i)
3911 atmel_write8(dev, DR, *src);
3912}
3913
3914static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, u16 src, u16 len)
3915{
3916 int i;
3917 atmel_writeAR(dev, src);
3918 if (src % 2) {
3919 *dest = atmel_read8(dev, DR);
3920 dest++; len--;
3921 }
3922 for (i = len; i > 1 ; i -= 2) {
3923 u16 hw = atmel_read16(dev, DR);
3924 *dest++ = hw;
3925 *dest++ = hw >> 8;
3926 }
3927 if (i)
3928 *dest = atmel_read8(dev, DR);
3929}
3930
3931static void atmel_set_gcr(struct net_device *dev, u16 mask)
3932{
3933 outw(inw(dev->base_addr + GCR) | mask, dev->base_addr + GCR);
3934}
3935
3936static void atmel_clear_gcr(struct net_device *dev, u16 mask)
3937{
3938 outw(inw(dev->base_addr + GCR) & ~mask, dev->base_addr + GCR);
3939}
3940
3941static int atmel_lock_mac(struct atmel_private *priv)
3942{
3943 int i, j = 20;
3944 retry:
3945 for (i = 5000; i; i--) {
3946 if (!atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET)))
3947 break;
3948 udelay(20);
3949 }
3950
3951 if (!i) return 0; /* timed out */
3952
3953 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
3954 if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
3955 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
3956 if (!j--) return 0; /* timed out */
3957 goto retry;
3958 }
3959
3960 return 1;
3961}
3962
3963static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
3964{
3965 atmel_writeAR(priv->dev, pos);
3966 atmel_write16(priv->dev, DR, data); /* card is little-endian */
3967 atmel_write16(priv->dev, DR, data >> 16);
3968}
3969
3970/***************************************************************************/
3971/* There follows the source form of the MAC address reading firmware */
3972/***************************************************************************/
3973#if 0
3974
3975/* Copyright 2003 Matthew T. Russotto */
3976/* But derived from the Atmel 76C502 firmware written by Atmel and */
3977/* included in "atmel wireless lan drivers" package */
3978/**
3979 This file is part of net.russotto.AtmelMACFW, hereto referred to
3980 as AtmelMACFW
3981
3982 AtmelMACFW is free software; you can redistribute it and/or modify
3983 it under the terms of the GNU General Public License version 2
3984 as published by the Free Software Foundation.
3985
3986 AtmelMACFW is distributed in the hope that it will be useful,
3987 but WITHOUT ANY WARRANTY; without even the implied warranty of
3988 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3989 GNU General Public License for more details.
3990
3991 You should have received a copy of the GNU General Public License
3992 along with AtmelMACFW; if not, write to the Free Software
3993 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3994
3995****************************************************************************/
3996/* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E */
3997/* It will probably work on the 76C504 and 76C502 RFMD_3COM */
3998/* It only works on SPI EEPROM versions of the card. */
3999
4000/* This firmware initializes the SPI controller and clock, reads the MAC */
4001/* address from the EEPROM into SRAM, and puts the SRAM offset of the MAC */
4002/* address in MR2, and sets MR3 to 0x10 to indicate it is done */
4003/* It also puts a complete copy of the EEPROM in SRAM with the offset in */
4004/* MR4, for investigational purposes (maybe we can determine chip type */
4005/* from that?) */
4006
4007 .org 0
4008 .set MRBASE, 0x8000000
4009 .set CPSR_INITIAL, 0xD3 /* IRQ/FIQ disabled, ARM mode, Supervisor state */
4010 .set CPSR_USER, 0xD1 /* IRQ/FIQ disabled, ARM mode, USER state */
4011 .set SRAM_BASE, 0x02000000
4012 .set SP_BASE, 0x0F300000
4013 .set UNK_BASE, 0x0F000000 /* Some internal device, but which one? */
4014 .set SPI_CGEN_BASE, 0x0E000000 /* Some internal device, but which one? */
4015 .set UNK3_BASE, 0x02014000 /* Some internal device, but which one? */
4016 .set STACK_BASE, 0x5600
4017 .set SP_SR, 0x10
4018 .set SP_TDRE, 2 /* status register bit -- TDR empty */
4019 .set SP_RDRF, 1 /* status register bit -- RDR full */
4020 .set SP_SWRST, 0x80
4021 .set SP_SPIEN, 0x1
4022 .set SP_CR, 0 /* control register */
4023 .set SP_MR, 4 /* mode register */
4024 .set SP_RDR, 0x08 /* Read Data Register */
4025 .set SP_TDR, 0x0C /* Transmit Data Register */
4026 .set SP_CSR0, 0x30 /* chip select registers */
4027 .set SP_CSR1, 0x34
4028 .set SP_CSR2, 0x38
4029 .set SP_CSR3, 0x3C
4030 .set NVRAM_CMD_RDSR, 5 /* read status register */
4031 .set NVRAM_CMD_READ, 3 /* read data */
4032 .set NVRAM_SR_RDY, 1 /* RDY bit. This bit is inverted */
4033 .set SPI_8CLOCKS, 0xFF /* Writing this to the TDR doesn't do anything to the
4034 serial output, since SO is normally high. But it
4035 does cause 8 clock cycles and thus 8 bits to be
4036 clocked in to the chip. See Atmel's SPI
4037 controller (e.g. AT91M55800) timing and 4K
4038 SPI EEPROM manuals */
4039
4040 .set NVRAM_SCRATCH, 0x02000100 /* arbitrary area for scratchpad memory */
4041 .set NVRAM_IMAGE, 0x02000200
4042 .set NVRAM_LENGTH, 0x0200
4043 .set MAC_ADDRESS_MIB, SRAM_BASE
4044 .set MAC_ADDRESS_LENGTH, 6
4045 .set MAC_BOOT_FLAG, 0x10
4046 .set MR1, 0
4047 .set MR2, 4
4048 .set MR3, 8
4049 .set MR4, 0xC
4050RESET_VECTOR:
4051 b RESET_HANDLER
4052UNDEF_VECTOR:
4053 b HALT1
4054SWI_VECTOR:
4055 b HALT1
4056IABORT_VECTOR:
4057 b HALT1
4058DABORT_VECTOR:
4059RESERVED_VECTOR:
4060 b HALT1
4061IRQ_VECTOR:
4062 b HALT1
4063FIQ_VECTOR:
4064 b HALT1
4065HALT1: b HALT1
4066RESET_HANDLER:
4067 mov r0, #CPSR_INITIAL
4068 msr CPSR_c, r0 /* This is probably unnecessary */
4069
4070/* I'm guessing this is initializing clock generator electronics for SPI */
4071 ldr r0, =SPI_CGEN_BASE
4072 mov r1, #0
4073 mov r1, r1, lsl #3
4074 orr r1,r1, #0
4075 str r1, [r0]
4076 ldr r1, [r0, #28]
4077 bic r1, r1, #16
4078 str r1, [r0, #28]
4079 mov r1, #1
4080 str r1, [r0, #8]
4081
4082 ldr r0, =MRBASE
4083 mov r1, #0
4084 strh r1, [r0, #MR1]
4085 strh r1, [r0, #MR2]
4086 strh r1, [r0, #MR3]
4087 strh r1, [r0, #MR4]
4088
4089 mov sp, #STACK_BASE
4090 bl SP_INIT
4091 mov r0, #10
4092 bl DELAY9
4093 bl GET_MAC_ADDR
4094 bl GET_WHOLE_NVRAM
4095 ldr r0, =MRBASE
4096 ldr r1, =MAC_ADDRESS_MIB
4097 strh r1, [r0, #MR2]
4098 ldr r1, =NVRAM_IMAGE
4099 strh r1, [r0, #MR4]
4100 mov r1, #MAC_BOOT_FLAG
4101 strh r1, [r0, #MR3]
4102HALT2: b HALT2
4103.func Get_Whole_NVRAM, GET_WHOLE_NVRAM
4104GET_WHOLE_NVRAM:
4105 stmdb sp!, {lr}
4106 mov r2, #0 /* 0th bytes of NVRAM */
4107 mov r3, #NVRAM_LENGTH
4108 mov r1, #0 /* not used in routine */
4109 ldr r0, =NVRAM_IMAGE
4110 bl NVRAM_XFER
4111 ldmia sp!, {lr}
4112 bx lr
4113.endfunc
4114
4115.func Get_MAC_Addr, GET_MAC_ADDR
4116GET_MAC_ADDR:
4117 stmdb sp!, {lr}
4118 mov r2, #0x120 /* address of MAC Address within NVRAM */
4119 mov r3, #MAC_ADDRESS_LENGTH
4120 mov r1, #0 /* not used in routine */
4121 ldr r0, =MAC_ADDRESS_MIB
4122 bl NVRAM_XFER
4123 ldmia sp!, {lr}
4124 bx lr
4125.endfunc
4126.ltorg
4127.func Delay9, DELAY9
4128DELAY9:
4129 adds r0, r0, r0, LSL #3 /* r0 = r0 * 9 */
4130DELAYLOOP:
4131 beq DELAY9_done
4132 subs r0, r0, #1
4133 b DELAYLOOP
4134DELAY9_done:
4135 bx lr
4136.endfunc
4137
4138.func SP_Init, SP_INIT
4139SP_INIT:
4140 mov r1, #SP_SWRST
4141 ldr r0, =SP_BASE
4142 str r1, [r0, #SP_CR] /* reset the SPI */
4143 mov r1, #0
4144 str r1, [r0, #SP_CR] /* release SPI from reset state */
4145 mov r1, #SP_SPIEN
4146 str r1, [r0, #SP_MR] /* set the SPI to MASTER mode*/
4147 str r1, [r0, #SP_CR] /* enable the SPI */
4148
4149/* My guess would be this turns on the SPI clock */
4150 ldr r3, =SPI_CGEN_BASE
4151 ldr r1, [r3, #28]
4152 orr r1, r1, #0x2000
4153 str r1, [r3, #28]
4154
4155 ldr r1, =0x2000c01
4156 str r1, [r0, #SP_CSR0]
4157 ldr r1, =0x2000201
4158 str r1, [r0, #SP_CSR1]
4159 str r1, [r0, #SP_CSR2]
4160 str r1, [r0, #SP_CSR3]
4161 ldr r1, [r0, #SP_SR]
4162 ldr r0, [r0, #SP_RDR]
4163 bx lr
4164.endfunc
4165.func NVRAM_Init, NVRAM_INIT
4166NVRAM_INIT:
4167 ldr r1, =SP_BASE
4168 ldr r0, [r1, #SP_RDR]
4169 mov r0, #NVRAM_CMD_RDSR
4170 str r0, [r1, #SP_TDR]
4171SP_loop1:
4172 ldr r0, [r1, #SP_SR]
4173 tst r0, #SP_TDRE
4174 beq SP_loop1
4175
4176 mov r0, #SPI_8CLOCKS
4177 str r0, [r1, #SP_TDR]
4178SP_loop2:
4179 ldr r0, [r1, #SP_SR]
4180 tst r0, #SP_TDRE
4181 beq SP_loop2
4182
4183 ldr r0, [r1, #SP_RDR]
4184SP_loop3:
4185 ldr r0, [r1, #SP_SR]
4186 tst r0, #SP_RDRF
4187 beq SP_loop3
4188
4189 ldr r0, [r1, #SP_RDR]
4190 and r0, r0, #255
4191 bx lr
4192.endfunc
4193
4194.func NVRAM_Xfer, NVRAM_XFER
4195 /* r0 = dest address */
4196 /* r1 = not used */
4197 /* r2 = src address within NVRAM */
4198 /* r3 = length */
4199NVRAM_XFER:
4200 stmdb sp!, {r4, r5, lr}
4201 mov r5, r0 /* save r0 (dest address) */
4202 mov r4, r3 /* save r3 (length) */
4203 mov r0, r2, LSR #5 /* SPI memories put A8 in the command field */
4204 and r0, r0, #8
4205 add r0, r0, #NVRAM_CMD_READ
4206 ldr r1, =NVRAM_SCRATCH
4207 strb r0, [r1, #0] /* save command in NVRAM_SCRATCH[0] */
4208 strb r2, [r1, #1] /* save low byte of source address in NVRAM_SCRATCH[1] */
4209_local1:
4210 bl NVRAM_INIT
4211 tst r0, #NVRAM_SR_RDY
4212 bne _local1
4213 mov r0, #20
4214 bl DELAY9
4215 mov r2, r4 /* length */
4216 mov r1, r5 /* dest address */
4217 mov r0, #2 /* bytes to transfer in command */
4218 bl NVRAM_XFER2
4219 ldmia sp!, {r4, r5, lr}
4220 bx lr
4221.endfunc
4222
4223.func NVRAM_Xfer2, NVRAM_XFER2
4224NVRAM_XFER2:
4225 stmdb sp!, {r4, r5, r6, lr}
4226 ldr r4, =SP_BASE
4227 mov r3, #0
4228 cmp r0, #0
4229 bls _local2
4230 ldr r5, =NVRAM_SCRATCH
4231_local4:
4232 ldrb r6, [r5, r3]
4233 str r6, [r4, #SP_TDR]
4234_local3:
4235 ldr r6, [r4, #SP_SR]
4236 tst r6, #SP_TDRE
4237 beq _local3
4238 add r3, r3, #1
4239 cmp r3, r0 /* r0 is # of bytes to send out (command+addr) */
4240 blo _local4
4241_local2:
4242 mov r3, #SPI_8CLOCKS
4243 str r3, [r4, #SP_TDR]
4244 ldr r0, [r4, #SP_RDR]
4245_local5:
4246 ldr r0, [r4, #SP_SR]
4247 tst r0, #SP_RDRF
4248 beq _local5
4249 ldr r0, [r4, #SP_RDR] /* what's this byte? It's the byte read while writing the TDR -- nonsense, because the NVRAM doesn't read and write at the same time */
4250 mov r0, #0
4251 cmp r2, #0 /* r2 is # of bytes to copy in */
4252 bls _local6
4253_local7:
4254 ldr r5, [r4, #SP_SR]
4255 tst r5, #SP_TDRE
4256 beq _local7
4257 str r3, [r4, #SP_TDR] /* r3 has SPI_8CLOCKS */
4258_local8:
4259 ldr r5, [r4, #SP_SR]
4260 tst r5, #SP_RDRF
4261 beq _local8
4262 ldr r5, [r4, #SP_RDR] /* but didn't we read this byte above? */
4263 strb r5, [r1], #1 /* postindexed */
4264 add r0, r0, #1
4265 cmp r0, r2
4266 blo _local7 /* since we don't send another address, the NVRAM must be capable of sequential reads */
4267_local6:
4268 mov r0, #200
4269 bl DELAY9
4270 ldmia sp!, {r4, r5, r6, lr}
4271 bx lr
4272#endif
diff --git a/drivers/net/wireless/atmel.h b/drivers/net/wireless/atmel.h
new file mode 100644
index 000000000000..825000edfc2c
--- /dev/null
+++ b/drivers/net/wireless/atmel.h
@@ -0,0 +1,43 @@
1/*** -*- linux-c -*- **********************************************************
2
3 Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
4
5 Copyright 2005 Dan Williams and Red Hat, Inc.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This software is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Atmel wireless lan drivers; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21******************************************************************************/
22
23#ifndef _ATMEL_H
24#define _ATMEL_H
25
26typedef enum {
27 ATMEL_FW_TYPE_NONE = 0,
28 ATMEL_FW_TYPE_502,
29 ATMEL_FW_TYPE_502D,
30 ATMEL_FW_TYPE_502E,
31 ATMEL_FW_TYPE_502_3COM,
32 ATMEL_FW_TYPE_504,
33 ATMEL_FW_TYPE_504_2958,
34 ATMEL_FW_TYPE_504A_2958,
35 ATMEL_FW_TYPE_506
36} AtmelFWType;
37
38struct net_device *init_atmel_card(unsigned short, int, const AtmelFWType, struct device *,
39 int (*present_func)(void *), void * );
40void stop_atmel_card( struct net_device *, int );
41int atmel_open( struct net_device * );
42
43#endif
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
new file mode 100644
index 000000000000..a91b507e0a7a
--- /dev/null
+++ b/drivers/net/wireless/atmel_cs.c
@@ -0,0 +1,708 @@
1/*** -*- linux-c -*- **********************************************************
2
3 Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
4
5 Copyright 2000-2001 ATMEL Corporation.
6 Copyright 2003 Simon Kelley.
7
8 This code was developed from version 2.1.1 of the Atmel drivers,
9 released by Atmel corp. under the GPL in December 2002. It also
10 includes code from the Linux aironet drivers (C) Benjamin Reed,
11 and the Linux PCMCIA package, (C) David Hinds.
12
13 For all queries about this code, please contact the current author,
14 Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
15
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 2 of the License, or
19 (at your option) any later version.
20
21 This software is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with Atmel wireless lan drivers; if not, write to the Free Software
28 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29
30******************************************************************************/
31
32#include <linux/config.h>
33#ifdef __IN_PCMCIA_PACKAGE__
34#include <pcmcia/k_compat.h>
35#endif
36#include <linux/init.h>
37#include <linux/kernel.h>
38#include <linux/module.h>
39#include <linux/ptrace.h>
40#include <linux/slab.h>
41#include <linux/string.h>
42#include <linux/netdevice.h>
43#include <linux/moduleparam.h>
44#include <linux/device.h>
45
46#include <pcmcia/version.h>
47#include <pcmcia/cs_types.h>
48#include <pcmcia/cs.h>
49#include <pcmcia/cistpl.h>
50#include <pcmcia/cisreg.h>
51#include <pcmcia/ds.h>
52#include <pcmcia/ciscode.h>
53
54#include <asm/io.h>
55#include <asm/system.h>
56#include <linux/wireless.h>
57
58#include "atmel.h"
59
60/*
61 All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
62 you do not define PCMCIA_DEBUG at all, all the debug code will be
63 left out. If you compile with PCMCIA_DEBUG=0, the debug code will
64 be present but disabled -- but it can then be enabled for specific
65 modules at load time with a 'pc_debug=#' option to insmod.
66*/
67#ifdef PCMCIA_DEBUG
68static int pc_debug = PCMCIA_DEBUG;
69module_param(pc_debug, int, 0);
70static char *version = "$Revision: 1.2 $";
71#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
72#else
73#define DEBUG(n, args...)
74#endif
75
76/*====================================================================*/
77
78MODULE_AUTHOR("Simon Kelley");
79MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
80MODULE_LICENSE("GPL");
81MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
82
83/*====================================================================*/
84
85/*
86 The event() function is this driver's Card Services event handler.
87 It will be called by Card Services when an appropriate card status
88 event is received. The config() and release() entry points are
89 used to configure or release a socket, in response to card
90 insertion and ejection events. They are invoked from the atmel_cs
91 event handler.
92*/
93
94static void atmel_config(dev_link_t *link);
95static void atmel_release(dev_link_t *link);
96static int atmel_event(event_t event, int priority,
97 event_callback_args_t *args);
98
99/*
100 The attach() and detach() entry points are used to create and destroy
101 "instances" of the driver, where each instance represents everything
102 needed to manage one actual PCMCIA card.
103*/
104
105static dev_link_t *atmel_attach(void);
106static void atmel_detach(dev_link_t *);
107
108/*
109 You'll also need to prototype all the functions that will actually
110 be used to talk to your device. See 'pcmem_cs' for a good example
111 of a fully self-sufficient driver; the other drivers rely more or
112 less on other parts of the kernel.
113*/
114
115/*
116 The dev_info variable is the "key" that is used to match up this
117 device driver with appropriate cards, through the card configuration
118 database.
119*/
120
121static dev_info_t dev_info = "atmel_cs";
122
123/*
124 A linked list of "instances" of the atmelnet device. Each actual
125 PCMCIA card corresponds to one device instance, and is described
126 by one dev_link_t structure (defined in ds.h).
127
128 You may not want to use a linked list for this -- for example, the
129 memory card driver uses an array of dev_link_t pointers, where minor
130 device numbers are used to derive the corresponding array index.
131*/
132
133static dev_link_t *dev_list = NULL;
134
135/*
136 A dev_link_t structure has fields for most things that are needed
137 to keep track of a socket, but there will usually be some device
138 specific information that also needs to be kept track of. The
139 'priv' pointer in a dev_link_t structure can be used to point to
140 a device-specific private data structure, like this.
141
142 A driver needs to provide a dev_node_t structure for each device
143 on a card. In some cases, there is only one device per card (for
144 example, ethernet cards, modems). In other cases, there may be
145 many actual or logical devices (SCSI adapters, memory cards with
146 multiple partitions). The dev_node_t structures need to be kept
147 in a linked list starting at the 'dev' field of a dev_link_t
148 structure. We allocate them in the card's private data structure,
149 because they generally shouldn't be allocated dynamically.
150
151 In this case, we also provide a flag to indicate if a device is
152 "stopped" due to a power management event, or card ejection. The
153 device IO routines can use a flag like this to throttle IO to a
154 card that is not ready to accept it.
155*/
156
157typedef struct local_info_t {
158 dev_node_t node;
159 struct net_device *eth_dev;
160} local_info_t;
161
162/*======================================================================
163
164 atmel_attach() creates an "instance" of the driver, allocating
165 local data structures for one device. The device is registered
166 with Card Services.
167
168 The dev_link structure is initialized, but we don't actually
169 configure the card at this point -- we wait until we receive a
170 card insertion event.
171
172 ======================================================================*/
173
174static dev_link_t *atmel_attach(void)
175{
176 client_reg_t client_reg;
177 dev_link_t *link;
178 local_info_t *local;
179 int ret;
180
181 DEBUG(0, "atmel_attach()\n");
182
183 /* Initialize the dev_link_t structure */
184 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
185 if (!link) {
186 printk(KERN_ERR "atmel_cs: no memory for new device\n");
187 return NULL;
188 }
189 memset(link, 0, sizeof(struct dev_link_t));
190
191 /* Interrupt setup */
192 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
193 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
194 link->irq.Handler = NULL;
195
196 /*
197 General socket configuration defaults can go here. In this
198 client, we assume very little, and rely on the CIS for almost
199 everything. In most clients, many details (i.e., number, sizes,
200 and attributes of IO windows) are fixed by the nature of the
201 device, and can be hard-wired here.
202 */
203 link->conf.Attributes = 0;
204 link->conf.Vcc = 50;
205 link->conf.IntType = INT_MEMORY_AND_IO;
206
207 /* Allocate space for private device-specific data */
208 local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
209 if (!local) {
210 printk(KERN_ERR "atmel_cs: no memory for new device\n");
211 kfree (link);
212 return NULL;
213 }
214 memset(local, 0, sizeof(local_info_t));
215 link->priv = local;
216
217 /* Register with Card Services */
218 link->next = dev_list;
219 dev_list = link;
220 client_reg.dev_info = &dev_info;
221 client_reg.EventMask =
222 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
223 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
224 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
225 client_reg.event_handler = &atmel_event;
226 client_reg.Version = 0x0210;
227 client_reg.event_callback_args.client_data = link;
228 ret = pcmcia_register_client(&link->handle, &client_reg);
229 if (ret != 0) {
230 cs_error(link->handle, RegisterClient, ret);
231 atmel_detach(link);
232 return NULL;
233 }
234
235 return link;
236} /* atmel_attach */
237
238/*======================================================================
239
240 This deletes a driver "instance". The device is de-registered
241 with Card Services. If it has been released, all local data
242 structures are freed. Otherwise, the structures will be freed
243 when the device is released.
244
245 ======================================================================*/
246
247static void atmel_detach(dev_link_t *link)
248{
249 dev_link_t **linkp;
250
251 DEBUG(0, "atmel_detach(0x%p)\n", link);
252
253 /* Locate device structure */
254 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
255 if (*linkp == link) break;
256 if (*linkp == NULL)
257 return;
258
259 if (link->state & DEV_CONFIG)
260 atmel_release(link);
261
262 /* Break the link with Card Services */
263 if (link->handle)
264 pcmcia_deregister_client(link->handle);
265
266 /* Unlink device structure, free pieces */
267 *linkp = link->next;
268 if (link->priv)
269 kfree(link->priv);
270 kfree(link);
271}
272
273/*======================================================================
274
275 atmel_config() is scheduled to run after a CARD_INSERTION event
276 is received, to configure the PCMCIA socket, and to make the
277 device available to the system.
278
279 ======================================================================*/
280
281#define CS_CHECK(fn, ret) \
282do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
283
284/* Call-back function to interrogate PCMCIA-specific information
285 about the current existance of the card */
286static int card_present(void *arg)
287{
288 dev_link_t *link = (dev_link_t *)arg;
289 if (link->state & DEV_SUSPEND)
290 return 0;
291 else if (link->state & DEV_PRESENT)
292 return 1;
293
294 return 0;
295}
296
297/* list of cards we know about and their firmware requirements.
298 Go either by Manfid or version strings.
299 Cards not in this list will need a firmware parameter to the module
300 in all probability. Note that the SMC 2632 V2 and V3 have the same
301 manfids, so we ignore those and use the version1 strings. */
302
303static struct {
304 int manf, card;
305 char *ver1;
306 AtmelFWType firmware;
307 char *name;
308} card_table[] = {
309 { 0, 0, "WLAN/802.11b PC CARD", ATMEL_FW_TYPE_502D, "Actiontec 802CAT1" },
310 { 0, 0, "ATMEL/AT76C502AR", ATMEL_FW_TYPE_502, "NoName-RFMD" },
311 { 0, 0, "ATMEL/AT76C502AR_D", ATMEL_FW_TYPE_502D, "NoName-revD" },
312 { 0, 0, "ATMEL/AT76C502AR_E", ATMEL_FW_TYPE_502E, "NoName-revE" },
313 { 0, 0, "ATMEL/AT76C504", ATMEL_FW_TYPE_504, "NoName-504" },
314 { 0, 0, "ATMEL/AT76C504A", ATMEL_FW_TYPE_504A_2958, "NoName-504a-2958" },
315 { 0, 0, "ATMEL/AT76C504_R", ATMEL_FW_TYPE_504_2958, "NoName-504-2958" },
316 { MANFID_3COM, 0x0620, NULL, ATMEL_FW_TYPE_502_3COM, "3com 3CRWE62092B" },
317 { MANFID_3COM, 0x0696, NULL, ATMEL_FW_TYPE_502_3COM, "3com 3CRSHPW196" },
318 { 0, 0, "SMC/2632W-V2", ATMEL_FW_TYPE_502, "SMC 2632W-V2" },
319 { 0, 0, "SMC/2632W", ATMEL_FW_TYPE_502D, "SMC 2632W-V3" },
320 { 0xd601, 0x0007, NULL, ATMEL_FW_TYPE_502, "Sitecom WLAN-011" },
321 { 0x01bf, 0x3302, NULL, ATMEL_FW_TYPE_502E, "Belkin F5D6020-V2" },
322 { 0, 0, "BT/Voyager 1020 Laptop Adapter", ATMEL_FW_TYPE_502, "BT Voyager 1020" },
323 { 0, 0, "IEEE 802.11b/Wireless LAN PC Card", ATMEL_FW_TYPE_502, "Siemens Gigaset PC Card II" },
324 { 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", ATMEL_FW_TYPE_502E, "CNet CNWLC-811ARL" },
325 { 0, 0, "Wireless/PC_CARD", ATMEL_FW_TYPE_502D, "Planet WL-3552" },
326 { 0, 0, "OEM/11Mbps Wireless LAN PC Card V-3", ATMEL_FW_TYPE_502, "OEM 11Mbps WLAN PCMCIA Card" },
327 { 0, 0, "11WAVE/11WP611AL-E", ATMEL_FW_TYPE_502E, "11WAVE WaveBuddy" },
328 { 0, 0, "LG/LW2100N", ATMEL_FW_TYPE_502E, "LG LW2100N 11Mbps WLAN PCMCIA Card" },
329};
330
331static void atmel_config(dev_link_t *link)
332{
333 client_handle_t handle;
334 tuple_t tuple;
335 cisparse_t parse;
336 local_info_t *dev;
337 int last_fn, last_ret;
338 u_char buf[64];
339 int card_index = -1, done = 0;
340
341 handle = link->handle;
342 dev = link->priv;
343
344 DEBUG(0, "atmel_config(0x%p)\n", link);
345
346 tuple.Attributes = 0;
347 tuple.TupleData = buf;
348 tuple.TupleDataMax = sizeof(buf);
349 tuple.TupleOffset = 0;
350
351 tuple.DesiredTuple = CISTPL_MANFID;
352 if (pcmcia_get_first_tuple(handle, &tuple) == 0) {
353 int i;
354 cistpl_manfid_t *manfid;
355 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
356 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
357 manfid = &(parse.manfid);
358 for (i = 0; i < sizeof(card_table)/sizeof(card_table[0]); i++) {
359 if (!card_table[i].ver1 &&
360 manfid->manf == card_table[i].manf &&
361 manfid->card == card_table[i].card) {
362 card_index = i;
363 done = 1;
364 }
365 }
366 }
367
368 tuple.DesiredTuple = CISTPL_VERS_1;
369 if (!done && (pcmcia_get_first_tuple(handle, &tuple) == 0)) {
370 int i, j, k;
371 cistpl_vers_1_t *ver1;
372 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
373 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
374 ver1 = &(parse.version_1);
375
376 for (i = 0; i < sizeof(card_table)/sizeof(card_table[0]); i++) {
377 for (j = 0; j < ver1->ns; j++) {
378 char *p = card_table[i].ver1;
379 char *q = &ver1->str[ver1->ofs[j]];
380 if (!p)
381 goto mismatch;
382 for (k = 0; k < j; k++) {
383 while ((*p != '\0') && (*p != '/')) p++;
384 if (*p == '\0') {
385 if (*q != '\0')
386 goto mismatch;
387 } else {
388 p++;
389 }
390 }
391 while((*q != '\0') && (*p != '\0') &&
392 (*p != '/') && (*p == *q)) p++, q++;
393 if (((*p != '\0') && *p != '/') || *q != '\0')
394 goto mismatch;
395 }
396 card_index = i;
397 break; /* done */
398
399 mismatch:
400 j = 0; /* dummy stmt to shut up compiler */
401 }
402 }
403
404 /*
405 This reads the card's CONFIG tuple to find its configuration
406 registers.
407 */
408 tuple.DesiredTuple = CISTPL_CONFIG;
409 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
410 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
411 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
412 link->conf.ConfigBase = parse.config.base;
413 link->conf.Present = parse.config.rmask[0];
414
415 /* Configure card */
416 link->state |= DEV_CONFIG;
417
418 /*
419 In this loop, we scan the CIS for configuration table entries,
420 each of which describes a valid card configuration, including
421 voltage, IO window, memory window, and interrupt settings.
422
423 We make no assumptions about the card to be configured: we use
424 just the information available in the CIS. In an ideal world,
425 this would work for any PCMCIA card, but it requires a complete
426 and accurate CIS. In practice, a driver usually "knows" most of
427 these things without consulting the CIS, and most client drivers
428 will only use the CIS to fill in implementation-defined details.
429 */
430 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
431 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
432 while (1) {
433 cistpl_cftable_entry_t dflt = { 0 };
434 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
435 if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
436 pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
437 goto next_entry;
438
439 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
440 if (cfg->index == 0) goto next_entry;
441 link->conf.ConfigIndex = cfg->index;
442
443 /* Does this card need audio output? */
444 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
445 link->conf.Attributes |= CONF_ENABLE_SPKR;
446 link->conf.Status = CCSR_AUDIO_ENA;
447 }
448
449 /* Use power settings for Vcc and Vpp if present */
450 /* Note that the CIS values need to be rescaled */
451 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM))
452 link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
453 else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM))
454 link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
455
456 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
457 link->conf.Vpp1 = link->conf.Vpp2 =
458 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
459 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
460 link->conf.Vpp1 = link->conf.Vpp2 =
461 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
462
463 /* Do we need to allocate an interrupt? */
464 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
465 link->conf.Attributes |= CONF_ENABLE_IRQ;
466
467 /* IO window settings */
468 link->io.NumPorts1 = link->io.NumPorts2 = 0;
469 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
470 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
471 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
472 if (!(io->flags & CISTPL_IO_8BIT))
473 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
474 if (!(io->flags & CISTPL_IO_16BIT))
475 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
476 link->io.BasePort1 = io->win[0].base;
477 link->io.NumPorts1 = io->win[0].len;
478 if (io->nwin > 1) {
479 link->io.Attributes2 = link->io.Attributes1;
480 link->io.BasePort2 = io->win[1].base;
481 link->io.NumPorts2 = io->win[1].len;
482 }
483 }
484
485 /* This reserves IO space but doesn't actually enable it */
486 if (pcmcia_request_io(link->handle, &link->io) != 0)
487 goto next_entry;
488
489 /* If we got this far, we're cool! */
490 break;
491
492 next_entry:
493 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
494 }
495
496 /*
497 Allocate an interrupt line. Note that this does not assign a
498 handler to the interrupt, unless the 'Handler' member of the
499 irq structure is initialized.
500 */
501 if (link->conf.Attributes & CONF_ENABLE_IRQ)
502 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
503
504 /*
505 This actually configures the PCMCIA socket -- setting up
506 the I/O windows and the interrupt mapping, and putting the
507 card and host interface into "Memory and IO" mode.
508 */
509 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
510
511 if (link->irq.AssignedIRQ == 0) {
512 printk(KERN_ALERT
513 "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
514 goto cs_failed;
515 }
516
517 ((local_info_t*)link->priv)->eth_dev =
518 init_atmel_card(link->irq.AssignedIRQ,
519 link->io.BasePort1,
520 card_index == -1 ? ATMEL_FW_TYPE_NONE : card_table[card_index].firmware,
521 &handle_to_dev(handle),
522 card_present,
523 link);
524 if (!((local_info_t*)link->priv)->eth_dev)
525 goto cs_failed;
526
527 /*
528 At this point, the dev_node_t structure(s) need to be
529 initialized and arranged in a linked list at link->dev.
530 */
531 strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
532 dev->node.major = dev->node.minor = 0;
533 link->dev = &dev->node;
534
535 /* Finally, report what we've done */
536 printk(KERN_INFO "%s: %s%sindex 0x%02x: Vcc %d.%d",
537 dev->node.dev_name,
538 card_index == -1 ? "" : card_table[card_index].name,
539 card_index == -1 ? "" : " ",
540 link->conf.ConfigIndex,
541 link->conf.Vcc/10, link->conf.Vcc%10);
542 if (link->conf.Vpp1)
543 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
544 if (link->conf.Attributes & CONF_ENABLE_IRQ)
545 printk(", irq %d", link->irq.AssignedIRQ);
546 if (link->io.NumPorts1)
547 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
548 link->io.BasePort1+link->io.NumPorts1-1);
549 if (link->io.NumPorts2)
550 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
551 link->io.BasePort2+link->io.NumPorts2-1);
552 printk("\n");
553
554 link->state &= ~DEV_CONFIG_PENDING;
555 return;
556
557 cs_failed:
558 cs_error(link->handle, last_fn, last_ret);
559 atmel_release(link);
560}
561
562/*======================================================================
563
564 After a card is removed, atmel_release() will unregister the
565 device, and release the PCMCIA configuration. If the device is
566 still open, this will be postponed until it is closed.
567
568 ======================================================================*/
569
570static void atmel_release(dev_link_t *link)
571{
572 struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
573
574 DEBUG(0, "atmel_release(0x%p)\n", link);
575
576 /* Unlink the device chain */
577 link->dev = NULL;
578
579 if (dev)
580 stop_atmel_card(dev, 0);
581 ((local_info_t*)link->priv)->eth_dev = NULL;
582
583 /* Don't bother checking to see if these succeed or not */
584 pcmcia_release_configuration(link->handle);
585 if (link->io.NumPorts1)
586 pcmcia_release_io(link->handle, &link->io);
587 if (link->irq.AssignedIRQ)
588 pcmcia_release_irq(link->handle, &link->irq);
589 link->state &= ~DEV_CONFIG;
590}
591
592/*======================================================================
593
594 The card status event handler. Mostly, this schedules other
595 stuff to run after an event is received.
596
597 When a CARD_REMOVAL event is received, we immediately set a
598 private flag to block future accesses to this device. All the
599 functions that actually access the device should check this flag
600 to make sure the card is still present.
601
602 ======================================================================*/
603
604static int atmel_event(event_t event, int priority,
605 event_callback_args_t *args)
606{
607 dev_link_t *link = args->client_data;
608 local_info_t *local = link->priv;
609
610 DEBUG(1, "atmel_event(0x%06x)\n", event);
611
612 switch (event) {
613 case CS_EVENT_CARD_REMOVAL:
614 link->state &= ~DEV_PRESENT;
615 if (link->state & DEV_CONFIG) {
616 netif_device_detach(local->eth_dev);
617 atmel_release(link);
618 }
619 break;
620 case CS_EVENT_CARD_INSERTION:
621 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
622 atmel_config(link);
623 break;
624 case CS_EVENT_PM_SUSPEND:
625 link->state |= DEV_SUSPEND;
626 /* Fall through... */
627 case CS_EVENT_RESET_PHYSICAL:
628 if (link->state & DEV_CONFIG) {
629 netif_device_detach(local->eth_dev);
630 pcmcia_release_configuration(link->handle);
631 }
632 break;
633 case CS_EVENT_PM_RESUME:
634 link->state &= ~DEV_SUSPEND;
635 /* Fall through... */
636 case CS_EVENT_CARD_RESET:
637 if (link->state & DEV_CONFIG) {
638 pcmcia_request_configuration(link->handle, &link->conf);
639 atmel_open(local->eth_dev);
640 netif_device_attach(local->eth_dev);
641 }
642 break;
643 }
644 return 0;
645} /* atmel_event */
646
647/*====================================================================*/
648static struct pcmcia_driver atmel_driver = {
649 .owner = THIS_MODULE,
650 .drv = {
651 .name = "atmel_cs",
652 },
653 .attach = atmel_attach,
654 .detach = atmel_detach,
655};
656
657static int atmel_cs_init(void)
658{
659 return pcmcia_register_driver(&atmel_driver);
660}
661
662static void atmel_cs_cleanup(void)
663{
664 pcmcia_unregister_driver(&atmel_driver);
665 BUG_ON(dev_list != NULL);
666}
667
668/*
669 This program is free software; you can redistribute it and/or
670 modify it under the terms of the GNU General Public License
671 as published by the Free Software Foundation; either version 2
672 of the License, or (at your option) any later version.
673
674 This program is distributed in the hope that it will be useful,
675 but WITHOUT ANY WARRANTY; without even the implied warranty of
676 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
677 GNU General Public License for more details.
678
679 In addition:
680
681 Redistribution and use in source and binary forms, with or without
682 modification, are permitted provided that the following conditions
683 are met:
684
685 1. Redistributions of source code must retain the above copyright
686 notice, this list of conditions and the following disclaimer.
687 2. Redistributions in binary form must reproduce the above copyright
688 notice, this list of conditions and the following disclaimer in the
689 documentation and/or other materials provided with the distribution.
690 3. The name of the author may not be used to endorse or promote
691 products derived from this software without specific prior written
692 permission.
693
694 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
695 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
696 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
697 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
698 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
699 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
700 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
701 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
702 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
703 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
704 POSSIBILITY OF SUCH DAMAGE.
705*/
706
707module_init(atmel_cs_init);
708module_exit(atmel_cs_cleanup);
diff --git a/drivers/net/wireless/atmel_pci.c b/drivers/net/wireless/atmel_pci.c
new file mode 100644
index 000000000000..2eb00a957bbe
--- /dev/null
+++ b/drivers/net/wireless/atmel_pci.c
@@ -0,0 +1,89 @@
1/*** -*- linux-c -*- **********************************************************
2
3 Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
4
5 Copyright 2004 Simon Kelley.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This software is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Atmel wireless lan drivers; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21******************************************************************************/
22#include <linux/config.h>
23#include <linux/pci.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/netdevice.h>
28#include "atmel.h"
29
30MODULE_AUTHOR("Simon Kelley");
31MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
32MODULE_LICENSE("GPL");
33MODULE_SUPPORTED_DEVICE("Atmel at76c506 PCI wireless cards");
34
35static struct pci_device_id card_ids[] = {
36 { 0x1114, 0x0506, PCI_ANY_ID, PCI_ANY_ID },
37 { 0, }
38};
39
40MODULE_DEVICE_TABLE(pci, card_ids);
41
42static int atmel_pci_probe(struct pci_dev *, const struct pci_device_id *);
43static void atmel_pci_remove(struct pci_dev *);
44
45static struct pci_driver atmel_driver = {
46 .name = "atmel",
47 .id_table = card_ids,
48 .probe = atmel_pci_probe,
49 .remove = __devexit_p(atmel_pci_remove),
50};
51
52
53static int __devinit atmel_pci_probe(struct pci_dev *pdev,
54 const struct pci_device_id *pent)
55{
56 struct net_device *dev;
57
58 if (pci_enable_device(pdev))
59 return -ENODEV;
60
61 pci_set_master(pdev);
62
63 dev = init_atmel_card(pdev->irq, pdev->resource[1].start,
64 ATMEL_FW_TYPE_506,
65 &pdev->dev, NULL, NULL);
66 if (!dev)
67 return -ENODEV;
68
69 pci_set_drvdata(pdev, dev);
70 return 0;
71}
72
73static void __devexit atmel_pci_remove(struct pci_dev *pdev)
74{
75 stop_atmel_card(pci_get_drvdata(pdev), 1);
76}
77
78static int __init atmel_init_module(void)
79{
80 return pci_module_init(&atmel_driver);
81}
82
83static void __exit atmel_cleanup_module(void)
84{
85 pci_unregister_driver(&atmel_driver);
86}
87
88module_init(atmel_init_module);
89module_exit(atmel_cleanup_module);
diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
new file mode 100644
index 000000000000..21c3d0d227e6
--- /dev/null
+++ b/drivers/net/wireless/hermes.c
@@ -0,0 +1,554 @@
1/* hermes.c
2 *
3 * Driver core for the "Hermes" wireless MAC controller, as used in
4 * the Lucent Orinoco and Cabletron RoamAbout cards. It should also
5 * work on the hfa3841 and hfa3842 MAC controller chips used in the
6 * Prism II chipsets.
7 *
8 * This is not a complete driver, just low-level access routines for
9 * the MAC controller itself.
10 *
11 * Based on the prism2 driver from Absolute Value Systems' linux-wlan
12 * project, the Linux wvlan_cs driver, Lucent's HCF-Light
13 * (wvlan_hcf.c) library, and the NetBSD wireless driver (in no
14 * particular order).
15 *
16 * Copyright (C) 2000, David Gibson, Linuxcare Australia.
17 * (C) Copyright David Gibson, IBM Corp. 2001-2003.
18 *
19 * The contents of this file are subject to the Mozilla Public License
20 * Version 1.1 (the "License"); you may not use this file except in
21 * compliance with the License. You may obtain a copy of the License
22 * at http://www.mozilla.org/MPL/
23 *
24 * Software distributed under the License is distributed on an "AS IS"
25 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
26 * the License for the specific language governing rights and
27 * limitations under the License.
28 *
29 * Alternatively, the contents of this file may be used under the
30 * terms of the GNU General Public License version 2 (the "GPL"), in
31 * which case the provisions of the GPL are applicable instead of the
32 * above. If you wish to allow the use of your version of this file
33 * only under the terms of the GPL and not to allow others to use your
34 * version of this file under the MPL, indicate your decision by
35 * deleting the provisions above and replace them with the notice and
36 * other provisions required by the GPL. If you do not delete the
37 * provisions above, a recipient may use your version of this file
38 * under either the MPL or the GPL.
39 */
40
41#include <linux/config.h>
42
43#include <linux/module.h>
44#include <linux/types.h>
45#include <linux/threads.h>
46#include <linux/smp.h>
47#include <asm/io.h>
48#include <linux/delay.h>
49#include <linux/init.h>
50#include <linux/kernel.h>
51#include <linux/net.h>
52#include <asm/errno.h>
53
54#include "hermes.h"
55
56MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller");
57MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>"
58 " & David Gibson <hermes@gibson.dropbear.id.au>");
59MODULE_LICENSE("Dual MPL/GPL");
60
61/* These are maximum timeouts. Most often, card wil react much faster */
62#define CMD_BUSY_TIMEOUT (100) /* In iterations of ~1us */
63#define CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */
64#define CMD_COMPL_TIMEOUT (20000) /* in iterations of ~10us */
65#define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */
66
67/*
68 * Debugging helpers
69 */
70
71#define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ %p: " , hw->iobase); \
72 printk(stuff);} while (0)
73
74#undef HERMES_DEBUG
75#ifdef HERMES_DEBUG
76#include <stdarg.h>
77
78#define DEBUG(lvl, stuff...) if ( (lvl) <= HERMES_DEBUG) DMSG(stuff)
79
80#else /* ! HERMES_DEBUG */
81
82#define DEBUG(lvl, stuff...) do { } while (0)
83
84#endif /* ! HERMES_DEBUG */
85
86
87/*
88 * Internal functions
89 */
90
91/* Issue a command to the chip. Waiting for it to complete is the caller's
92 problem.
93
94 Returns -EBUSY if the command register is busy, 0 on success.
95
96 Callable from any context.
97*/
98static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0)
99{
100 int k = CMD_BUSY_TIMEOUT;
101 u16 reg;
102
103 /* First wait for the command register to unbusy */
104 reg = hermes_read_regn(hw, CMD);
105 while ( (reg & HERMES_CMD_BUSY) && k ) {
106 k--;
107 udelay(1);
108 reg = hermes_read_regn(hw, CMD);
109 }
110 if (reg & HERMES_CMD_BUSY) {
111 return -EBUSY;
112 }
113
114 hermes_write_regn(hw, PARAM2, 0);
115 hermes_write_regn(hw, PARAM1, 0);
116 hermes_write_regn(hw, PARAM0, param0);
117 hermes_write_regn(hw, CMD, cmd);
118
119 return 0;
120}
121
122/*
123 * Function definitions
124 */
125
126void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing)
127{
128 hw->iobase = address;
129 hw->reg_spacing = reg_spacing;
130 hw->inten = 0x0;
131
132#ifdef HERMES_DEBUG_BUFFER
133 hw->dbufp = 0;
134 memset(&hw->dbuf, 0xff, sizeof(hw->dbuf));
135 memset(&hw->profile, 0, sizeof(hw->profile));
136#endif
137}
138
139int hermes_init(hermes_t *hw)
140{
141 u16 status, reg;
142 int err = 0;
143 int k;
144
145 /* We don't want to be interrupted while resetting the chipset */
146 hw->inten = 0x0;
147 hermes_write_regn(hw, INTEN, 0);
148 hermes_write_regn(hw, EVACK, 0xffff);
149
150 /* Normally it's a "can't happen" for the command register to
151 be busy when we go to issue a command because we are
152 serializing all commands. However we want to have some
153 chance of resetting the card even if it gets into a stupid
154 state, so we actually wait to see if the command register
155 will unbusy itself here. */
156 k = CMD_BUSY_TIMEOUT;
157 reg = hermes_read_regn(hw, CMD);
158 while (k && (reg & HERMES_CMD_BUSY)) {
159 if (reg == 0xffff) /* Special case - the card has probably been removed,
160 so don't wait for the timeout */
161 return -ENODEV;
162
163 k--;
164 udelay(1);
165 reg = hermes_read_regn(hw, CMD);
166 }
167
168 /* No need to explicitly handle the timeout - if we've timed
169 out hermes_issue_cmd() will probably return -EBUSY below */
170
171 /* According to the documentation, EVSTAT may contain
172 obsolete event occurrence information. We have to acknowledge
173 it by writing EVACK. */
174 reg = hermes_read_regn(hw, EVSTAT);
175 hermes_write_regn(hw, EVACK, reg);
176
177 /* We don't use hermes_docmd_wait here, because the reset wipes
178 the magic constant in SWSUPPORT0 away, and it gets confused */
179 err = hermes_issue_cmd(hw, HERMES_CMD_INIT, 0);
180 if (err)
181 return err;
182
183 reg = hermes_read_regn(hw, EVSTAT);
184 k = CMD_INIT_TIMEOUT;
185 while ( (! (reg & HERMES_EV_CMD)) && k) {
186 k--;
187 udelay(10);
188 reg = hermes_read_regn(hw, EVSTAT);
189 }
190
191 hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC);
192
193 if (! hermes_present(hw)) {
194 DEBUG(0, "hermes @ 0x%x: Card removed during reset.\n",
195 hw->iobase);
196 err = -ENODEV;
197 goto out;
198 }
199
200 if (! (reg & HERMES_EV_CMD)) {
201 printk(KERN_ERR "hermes @ %p: "
202 "Timeout waiting for card to reset (reg=0x%04x)!\n",
203 hw->iobase, reg);
204 err = -ETIMEDOUT;
205 goto out;
206 }
207
208 status = hermes_read_regn(hw, STATUS);
209
210 hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
211
212 if (status & HERMES_STATUS_RESULT)
213 err = -EIO;
214
215 out:
216 return err;
217}
218
219/* Issue a command to the chip, and (busy!) wait for it to
220 * complete.
221 *
222 * Returns: < 0 on internal error, 0 on success, > 0 on error returned by the firmware
223 *
224 * Callable from any context, but locking is your problem. */
225int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
226 struct hermes_response *resp)
227{
228 int err;
229 int k;
230 u16 reg;
231 u16 status;
232
233 err = hermes_issue_cmd(hw, cmd, parm0);
234 if (err) {
235 if (! hermes_present(hw)) {
236 if (net_ratelimit())
237 printk(KERN_WARNING "hermes @ %p: "
238 "Card removed while issuing command "
239 "0x%04x.\n", hw->iobase, cmd);
240 err = -ENODEV;
241 } else
242 if (net_ratelimit())
243 printk(KERN_ERR "hermes @ %p: "
244 "Error %d issuing command 0x%04x.\n",
245 hw->iobase, err, cmd);
246 goto out;
247 }
248
249 reg = hermes_read_regn(hw, EVSTAT);
250 k = CMD_COMPL_TIMEOUT;
251 while ( (! (reg & HERMES_EV_CMD)) && k) {
252 k--;
253 udelay(10);
254 reg = hermes_read_regn(hw, EVSTAT);
255 }
256
257 if (! hermes_present(hw)) {
258 printk(KERN_WARNING "hermes @ %p: Card removed "
259 "while waiting for command 0x%04x completion.\n",
260 hw->iobase, cmd);
261 err = -ENODEV;
262 goto out;
263 }
264
265 if (! (reg & HERMES_EV_CMD)) {
266 printk(KERN_ERR "hermes @ %p: Timeout waiting for "
267 "command 0x%04x completion.\n", hw->iobase, cmd);
268 err = -ETIMEDOUT;
269 goto out;
270 }
271
272 status = hermes_read_regn(hw, STATUS);
273 if (resp) {
274 resp->status = status;
275 resp->resp0 = hermes_read_regn(hw, RESP0);
276 resp->resp1 = hermes_read_regn(hw, RESP1);
277 resp->resp2 = hermes_read_regn(hw, RESP2);
278 }
279
280 hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
281
282 if (status & HERMES_STATUS_RESULT)
283 err = -EIO;
284
285 out:
286 return err;
287}
288
289int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
290{
291 int err = 0;
292 int k;
293 u16 reg;
294
295 if ( (size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX) )
296 return -EINVAL;
297
298 err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL);
299 if (err) {
300 return err;
301 }
302
303 reg = hermes_read_regn(hw, EVSTAT);
304 k = ALLOC_COMPL_TIMEOUT;
305 while ( (! (reg & HERMES_EV_ALLOC)) && k) {
306 k--;
307 udelay(10);
308 reg = hermes_read_regn(hw, EVSTAT);
309 }
310
311 if (! hermes_present(hw)) {
312 printk(KERN_WARNING "hermes @ %p: "
313 "Card removed waiting for frame allocation.\n",
314 hw->iobase);
315 return -ENODEV;
316 }
317
318 if (! (reg & HERMES_EV_ALLOC)) {
319 printk(KERN_ERR "hermes @ %p: "
320 "Timeout waiting for frame allocation\n",
321 hw->iobase);
322 return -ETIMEDOUT;
323 }
324
325 *fid = hermes_read_regn(hw, ALLOCFID);
326 hermes_write_regn(hw, EVACK, HERMES_EV_ALLOC);
327
328 return 0;
329}
330
331
332/* Set up a BAP to read a particular chunk of data from card's internal buffer.
333 *
334 * Returns: < 0 on internal failure (errno), 0 on success, >0 on error
335 * from firmware
336 *
337 * Callable from any context */
338static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
339{
340 int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
341 int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
342 int k;
343 u16 reg;
344
345 /* Paranoia.. */
346 if ( (offset > HERMES_BAP_OFFSET_MAX) || (offset % 2) )
347 return -EINVAL;
348
349 k = HERMES_BAP_BUSY_TIMEOUT;
350 reg = hermes_read_reg(hw, oreg);
351 while ((reg & HERMES_OFFSET_BUSY) && k) {
352 k--;
353 udelay(1);
354 reg = hermes_read_reg(hw, oreg);
355 }
356
357#ifdef HERMES_DEBUG_BUFFER
358 hw->profile[HERMES_BAP_BUSY_TIMEOUT - k]++;
359
360 if (k < HERMES_BAP_BUSY_TIMEOUT) {
361 struct hermes_debug_entry *e =
362 &hw->dbuf[(hw->dbufp++) % HERMES_DEBUG_BUFSIZE];
363 e->bap = bap;
364 e->id = id;
365 e->offset = offset;
366 e->cycles = HERMES_BAP_BUSY_TIMEOUT - k;
367 }
368#endif
369
370 if (reg & HERMES_OFFSET_BUSY)
371 return -ETIMEDOUT;
372
373 /* Now we actually set up the transfer */
374 hermes_write_reg(hw, sreg, id);
375 hermes_write_reg(hw, oreg, offset);
376
377 /* Wait for the BAP to be ready */
378 k = HERMES_BAP_BUSY_TIMEOUT;
379 reg = hermes_read_reg(hw, oreg);
380 while ( (reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
381 k--;
382 udelay(1);
383 reg = hermes_read_reg(hw, oreg);
384 }
385
386 if (reg != offset) {
387 printk(KERN_ERR "hermes @ %p: BAP%d offset %s: "
388 "reg=0x%x id=0x%x offset=0x%x\n", hw->iobase, bap,
389 (reg & HERMES_OFFSET_BUSY) ? "timeout" : "error",
390 reg, id, offset);
391
392 if (reg & HERMES_OFFSET_BUSY) {
393 return -ETIMEDOUT;
394 }
395
396 return -EIO; /* error or wrong offset */
397 }
398
399 return 0;
400}
401
402/* Read a block of data from the chip's buffer, via the
403 * BAP. Synchronization/serialization is the caller's problem. len
404 * must be even.
405 *
406 * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
407 */
408int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len,
409 u16 id, u16 offset)
410{
411 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
412 int err = 0;
413
414 if ( (len < 0) || (len % 2) )
415 return -EINVAL;
416
417 err = hermes_bap_seek(hw, bap, id, offset);
418 if (err)
419 goto out;
420
421 /* Actually do the transfer */
422 hermes_read_words(hw, dreg, buf, len/2);
423
424 out:
425 return err;
426}
427
428/* Write a block of data to the chip's buffer, via the
429 * BAP. Synchronization/serialization is the caller's problem. len
430 * must be even.
431 *
432 * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
433 */
434int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
435 u16 id, u16 offset)
436{
437 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
438 int err = 0;
439
440 if ( (len < 0) || (len % 2) )
441 return -EINVAL;
442
443 err = hermes_bap_seek(hw, bap, id, offset);
444 if (err)
445 goto out;
446
447 /* Actually do the transfer */
448 hermes_write_words(hw, dreg, buf, len/2);
449
450 out:
451 return err;
452}
453
454/* Read a Length-Type-Value record from the card.
455 *
456 * If length is NULL, we ignore the length read from the card, and
457 * read the entire buffer regardless. This is useful because some of
458 * the configuration records appear to have incorrect lengths in
459 * practice.
460 *
461 * Callable from user or bh context. */
462int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
463 u16 *length, void *buf)
464{
465 int err = 0;
466 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
467 u16 rlength, rtype;
468 unsigned nwords;
469
470 if ( (bufsize < 0) || (bufsize % 2) )
471 return -EINVAL;
472
473 err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, NULL);
474 if (err)
475 return err;
476
477 err = hermes_bap_seek(hw, bap, rid, 0);
478 if (err)
479 return err;
480
481 rlength = hermes_read_reg(hw, dreg);
482
483 if (! rlength)
484 return -ENODATA;
485
486 rtype = hermes_read_reg(hw, dreg);
487
488 if (length)
489 *length = rlength;
490
491 if (rtype != rid)
492 printk(KERN_WARNING "hermes @ %p: %s(): "
493 "rid (0x%04x) does not match type (0x%04x)\n",
494 hw->iobase, __FUNCTION__, rid, rtype);
495 if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize)
496 printk(KERN_WARNING "hermes @ %p: "
497 "Truncating LTV record from %d to %d bytes. "
498 "(rid=0x%04x, len=0x%04x)\n", hw->iobase,
499 HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);
500
501 nwords = min((unsigned)rlength - 1, bufsize / 2);
502 hermes_read_words(hw, dreg, buf, nwords);
503
504 return 0;
505}
506
507int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
508 u16 length, const void *value)
509{
510 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
511 int err = 0;
512 unsigned count;
513
514 if (length == 0)
515 return -EINVAL;
516
517 err = hermes_bap_seek(hw, bap, rid, 0);
518 if (err)
519 return err;
520
521 hermes_write_reg(hw, dreg, length);
522 hermes_write_reg(hw, dreg, rid);
523
524 count = length - 1;
525
526 hermes_write_words(hw, dreg, value, count);
527
528 err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE,
529 rid, NULL);
530
531 return err;
532}
533
534EXPORT_SYMBOL(hermes_struct_init);
535EXPORT_SYMBOL(hermes_init);
536EXPORT_SYMBOL(hermes_docmd_wait);
537EXPORT_SYMBOL(hermes_allocate);
538
539EXPORT_SYMBOL(hermes_bap_pread);
540EXPORT_SYMBOL(hermes_bap_pwrite);
541EXPORT_SYMBOL(hermes_read_ltv);
542EXPORT_SYMBOL(hermes_write_ltv);
543
544static int __init init_hermes(void)
545{
546 return 0;
547}
548
549static void __exit exit_hermes(void)
550{
551}
552
553module_init(init_hermes);
554module_exit(exit_hermes);
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
new file mode 100644
index 000000000000..8c9e874c9118
--- /dev/null
+++ b/drivers/net/wireless/hermes.h
@@ -0,0 +1,481 @@
1/* hermes.h
2 *
3 * Driver core for the "Hermes" wireless MAC controller, as used in
4 * the Lucent Orinoco and Cabletron RoamAbout cards. It should also
5 * work on the hfa3841 and hfa3842 MAC controller chips used in the
6 * Prism I & II chipsets.
7 *
8 * This is not a complete driver, just low-level access routines for
9 * the MAC controller itself.
10 *
11 * Based on the prism2 driver from Absolute Value Systems' linux-wlan
12 * project, the Linux wvlan_cs driver, Lucent's HCF-Light
13 * (wvlan_hcf.c) library, and the NetBSD wireless driver.
14 *
15 * Copyright (C) 2000, David Gibson, Linuxcare Australia.
16 * (C) Copyright David Gibson, IBM Corp. 2001-2003.
17 *
18 * Portions taken from hfa384x.h, Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
19 *
20 * This file distributed under the GPL, version 2.
21 */
22
23#ifndef _HERMES_H
24#define _HERMES_H
25
26/* Notes on locking:
27 *
28 * As a module of low level hardware access routines, there is no
29 * locking. Users of this module should ensure that they serialize
30 * access to the hermes_t structure, and to the hardware
31*/
32
33#include <linux/delay.h>
34#include <linux/if_ether.h>
35#include <asm/byteorder.h>
36
37/*
38 * Limits and constants
39 */
40#define HERMES_ALLOC_LEN_MIN (4)
41#define HERMES_ALLOC_LEN_MAX (2400)
42#define HERMES_LTV_LEN_MAX (34)
43#define HERMES_BAP_DATALEN_MAX (4096)
44#define HERMES_BAP_OFFSET_MAX (4096)
45#define HERMES_PORTID_MAX (7)
46#define HERMES_NUMPORTS_MAX (HERMES_PORTID_MAX+1)
47#define HERMES_PDR_LEN_MAX (260) /* in bytes, from EK */
48#define HERMES_PDA_RECS_MAX (200) /* a guess */
49#define HERMES_PDA_LEN_MAX (1024) /* in bytes, from EK */
50#define HERMES_SCANRESULT_MAX (35)
51#define HERMES_CHINFORESULT_MAX (8)
52#define HERMES_MAX_MULTICAST (16)
53#define HERMES_MAGIC (0x7d1f)
54
55/*
56 * Hermes register offsets
57 */
58#define HERMES_CMD (0x00)
59#define HERMES_PARAM0 (0x02)
60#define HERMES_PARAM1 (0x04)
61#define HERMES_PARAM2 (0x06)
62#define HERMES_STATUS (0x08)
63#define HERMES_RESP0 (0x0A)
64#define HERMES_RESP1 (0x0C)
65#define HERMES_RESP2 (0x0E)
66#define HERMES_INFOFID (0x10)
67#define HERMES_RXFID (0x20)
68#define HERMES_ALLOCFID (0x22)
69#define HERMES_TXCOMPLFID (0x24)
70#define HERMES_SELECT0 (0x18)
71#define HERMES_OFFSET0 (0x1C)
72#define HERMES_DATA0 (0x36)
73#define HERMES_SELECT1 (0x1A)
74#define HERMES_OFFSET1 (0x1E)
75#define HERMES_DATA1 (0x38)
76#define HERMES_EVSTAT (0x30)
77#define HERMES_INTEN (0x32)
78#define HERMES_EVACK (0x34)
79#define HERMES_CONTROL (0x14)
80#define HERMES_SWSUPPORT0 (0x28)
81#define HERMES_SWSUPPORT1 (0x2A)
82#define HERMES_SWSUPPORT2 (0x2C)
83#define HERMES_AUXPAGE (0x3A)
84#define HERMES_AUXOFFSET (0x3C)
85#define HERMES_AUXDATA (0x3E)
86
87/*
88 * CMD register bitmasks
89 */
90#define HERMES_CMD_BUSY (0x8000)
91#define HERMES_CMD_AINFO (0x7f00)
92#define HERMES_CMD_MACPORT (0x0700)
93#define HERMES_CMD_RECL (0x0100)
94#define HERMES_CMD_WRITE (0x0100)
95#define HERMES_CMD_PROGMODE (0x0300)
96#define HERMES_CMD_CMDCODE (0x003f)
97
98/*
99 * STATUS register bitmasks
100 */
101#define HERMES_STATUS_RESULT (0x7f00)
102#define HERMES_STATUS_CMDCODE (0x003f)
103
104/*
105 * OFFSET register bitmasks
106 */
107#define HERMES_OFFSET_BUSY (0x8000)
108#define HERMES_OFFSET_ERR (0x4000)
109#define HERMES_OFFSET_DATAOFF (0x0ffe)
110
111/*
112 * Event register bitmasks (INTEN, EVSTAT, EVACK)
113 */
114#define HERMES_EV_TICK (0x8000)
115#define HERMES_EV_WTERR (0x4000)
116#define HERMES_EV_INFDROP (0x2000)
117#define HERMES_EV_INFO (0x0080)
118#define HERMES_EV_DTIM (0x0020)
119#define HERMES_EV_CMD (0x0010)
120#define HERMES_EV_ALLOC (0x0008)
121#define HERMES_EV_TXEXC (0x0004)
122#define HERMES_EV_TX (0x0002)
123#define HERMES_EV_RX (0x0001)
124
125/*
126 * Command codes
127 */
128/*--- Controller Commands ----------------------------*/
129#define HERMES_CMD_INIT (0x0000)
130#define HERMES_CMD_ENABLE (0x0001)
131#define HERMES_CMD_DISABLE (0x0002)
132#define HERMES_CMD_DIAG (0x0003)
133
134/*--- Buffer Mgmt Commands ---------------------------*/
135#define HERMES_CMD_ALLOC (0x000A)
136#define HERMES_CMD_TX (0x000B)
137
138/*--- Regulate Commands ------------------------------*/
139#define HERMES_CMD_NOTIFY (0x0010)
140#define HERMES_CMD_INQUIRE (0x0011)
141
142/*--- Configure Commands -----------------------------*/
143#define HERMES_CMD_ACCESS (0x0021)
144#define HERMES_CMD_DOWNLD (0x0022)
145
146/*--- Serial I/O Commands ----------------------------*/
147#define HERMES_CMD_READMIF (0x0030)
148#define HERMES_CMD_WRITEMIF (0x0031)
149
150/*--- Debugging Commands -----------------------------*/
151#define HERMES_CMD_TEST (0x0038)
152
153
154/* Test command arguments */
155#define HERMES_TEST_SET_CHANNEL 0x0800
156#define HERMES_TEST_MONITOR 0x0b00
157#define HERMES_TEST_STOP 0x0f00
158
159/* Authentication algorithms */
160#define HERMES_AUTH_OPEN 1
161#define HERMES_AUTH_SHARED_KEY 2
162
163/* WEP settings */
164#define HERMES_WEP_PRIVACY_INVOKED 0x0001
165#define HERMES_WEP_EXCL_UNENCRYPTED 0x0002
166#define HERMES_WEP_HOST_ENCRYPT 0x0010
167#define HERMES_WEP_HOST_DECRYPT 0x0080
168
169/* Symbol hostscan options */
170#define HERMES_HOSTSCAN_SYMBOL_5SEC 0x0001
171#define HERMES_HOSTSCAN_SYMBOL_ONCE 0x0002
172#define HERMES_HOSTSCAN_SYMBOL_PASSIVE 0x0040
173#define HERMES_HOSTSCAN_SYMBOL_BCAST 0x0080
174
175/*
176 * Frame structures and constants
177 */
178
179#define HERMES_DESCRIPTOR_OFFSET 0
180#define HERMES_802_11_OFFSET (14)
181#define HERMES_802_3_OFFSET (14+32)
182#define HERMES_802_2_OFFSET (14+32+14)
183
184#define HERMES_RXSTAT_ERR (0x0003)
185#define HERMES_RXSTAT_BADCRC (0x0001)
186#define HERMES_RXSTAT_UNDECRYPTABLE (0x0002)
187#define HERMES_RXSTAT_MACPORT (0x0700)
188#define HERMES_RXSTAT_PCF (0x1000) /* Frame was received in CF period */
189#define HERMES_RXSTAT_MSGTYPE (0xE000)
190#define HERMES_RXSTAT_1042 (0x2000) /* RFC-1042 frame */
191#define HERMES_RXSTAT_TUNNEL (0x4000) /* bridge-tunnel encoded frame */
192#define HERMES_RXSTAT_WMP (0x6000) /* Wavelan-II Management Protocol frame */
193
194struct hermes_tx_descriptor {
195 u16 status;
196 u16 reserved1;
197 u16 reserved2;
198 u32 sw_support;
199 u8 retry_count;
200 u8 tx_rate;
201 u16 tx_control;
202} __attribute__ ((packed));
203
204#define HERMES_TXSTAT_RETRYERR (0x0001)
205#define HERMES_TXSTAT_AGEDERR (0x0002)
206#define HERMES_TXSTAT_DISCON (0x0004)
207#define HERMES_TXSTAT_FORMERR (0x0008)
208
209#define HERMES_TXCTRL_TX_OK (0x0002) /* ?? interrupt on Tx complete */
210#define HERMES_TXCTRL_TX_EX (0x0004) /* ?? interrupt on Tx exception */
211#define HERMES_TXCTRL_802_11 (0x0008) /* We supply 802.11 header */
212#define HERMES_TXCTRL_ALT_RTRY (0x0020)
213
214/* Inquiry constants and data types */
215
216#define HERMES_INQ_TALLIES (0xF100)
217#define HERMES_INQ_SCAN (0xF101)
218#define HERMES_INQ_CHANNELINFO (0xF102)
219#define HERMES_INQ_HOSTSCAN (0xF103)
220#define HERMES_INQ_HOSTSCAN_SYMBOL (0xF104)
221#define HERMES_INQ_LINKSTATUS (0xF200)
222#define HERMES_INQ_SEC_STAT_AGERE (0xF202)
223
224struct hermes_tallies_frame {
225 u16 TxUnicastFrames;
226 u16 TxMulticastFrames;
227 u16 TxFragments;
228 u16 TxUnicastOctets;
229 u16 TxMulticastOctets;
230 u16 TxDeferredTransmissions;
231 u16 TxSingleRetryFrames;
232 u16 TxMultipleRetryFrames;
233 u16 TxRetryLimitExceeded;
234 u16 TxDiscards;
235 u16 RxUnicastFrames;
236 u16 RxMulticastFrames;
237 u16 RxFragments;
238 u16 RxUnicastOctets;
239 u16 RxMulticastOctets;
240 u16 RxFCSErrors;
241 u16 RxDiscards_NoBuffer;
242 u16 TxDiscardsWrongSA;
243 u16 RxWEPUndecryptable;
244 u16 RxMsgInMsgFragments;
245 u16 RxMsgInBadMsgFragments;
246 /* Those last are probably not available in very old firmwares */
247 u16 RxDiscards_WEPICVError;
248 u16 RxDiscards_WEPExcluded;
249} __attribute__ ((packed));
250
251/* Grabbed from wlan-ng - Thanks Mark... - Jean II
252 * This is the result of a scan inquiry command */
253/* Structure describing info about an Access Point */
254struct prism2_scan_apinfo {
255 u16 channel; /* Channel where the AP sits */
256 u16 noise; /* Noise level */
257 u16 level; /* Signal level */
258 u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
259 u16 beacon_interv; /* Beacon interval */
260 u16 capabilities; /* Capabilities */
261 u16 essid_len; /* ESSID length */
262 u8 essid[32]; /* ESSID of the network */
263 u8 rates[10]; /* Bit rate supported */
264 u16 proberesp_rate; /* Data rate of the response frame */
265 u16 atim; /* ATIM window time, Kus (hostscan only) */
266} __attribute__ ((packed));
267
268/* Same stuff for the Lucent/Agere card.
269 * Thanks to h1kari <h1kari AT dachb0den.com> - Jean II */
270struct agere_scan_apinfo {
271 u16 channel; /* Channel where the AP sits */
272 u16 noise; /* Noise level */
273 u16 level; /* Signal level */
274 u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
275 u16 beacon_interv; /* Beacon interval */
276 u16 capabilities; /* Capabilities */
277 /* bits: 0-ess, 1-ibss, 4-privacy [wep] */
278 u16 essid_len; /* ESSID length */
279 u8 essid[32]; /* ESSID of the network */
280} __attribute__ ((packed));
281
282/* Moustafa: Scan structure for Symbol cards */
283struct symbol_scan_apinfo {
284 u8 channel; /* Channel where the AP sits */
285 u8 unknown1; /* 8 in 2.9x and 3.9x f/w, 0 otherwise */
286 u16 noise; /* Noise level */
287 u16 level; /* Signal level */
288 u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */
289 u16 beacon_interv; /* Beacon interval */
290 u16 capabilities; /* Capabilities */
291 /* bits: 0-ess, 1-ibss, 4-privacy [wep] */
292 u16 essid_len; /* ESSID length */
293 u8 essid[32]; /* ESSID of the network */
294 u16 rates[5]; /* Bit rate supported */
295 u16 basic_rates; /* Basic rates bitmask */
296 u8 unknown2[6]; /* Always FF:FF:FF:FF:00:00 */
297 u8 unknown3[8]; /* Always 0, appeared in f/w 3.91-68 */
298} __attribute__ ((packed));
299
300union hermes_scan_info {
301 struct agere_scan_apinfo a;
302 struct prism2_scan_apinfo p;
303 struct symbol_scan_apinfo s;
304};
305
306#define HERMES_LINKSTATUS_NOT_CONNECTED (0x0000)
307#define HERMES_LINKSTATUS_CONNECTED (0x0001)
308#define HERMES_LINKSTATUS_DISCONNECTED (0x0002)
309#define HERMES_LINKSTATUS_AP_CHANGE (0x0003)
310#define HERMES_LINKSTATUS_AP_OUT_OF_RANGE (0x0004)
311#define HERMES_LINKSTATUS_AP_IN_RANGE (0x0005)
312#define HERMES_LINKSTATUS_ASSOC_FAILED (0x0006)
313
314struct hermes_linkstatus {
315 u16 linkstatus; /* Link status */
316} __attribute__ ((packed));
317
318struct hermes_response {
319 u16 status, resp0, resp1, resp2;
320};
321
322/* "ID" structure - used for ESSID and station nickname */
323struct hermes_idstring {
324 u16 len;
325 u16 val[16];
326} __attribute__ ((packed));
327
328struct hermes_multicast {
329 u8 addr[HERMES_MAX_MULTICAST][ETH_ALEN];
330} __attribute__ ((packed));
331
332// #define HERMES_DEBUG_BUFFER 1
333#define HERMES_DEBUG_BUFSIZE 4096
334struct hermes_debug_entry {
335 int bap;
336 u16 id, offset;
337 int cycles;
338};
339
340#ifdef __KERNEL__
341
342/* Timeouts */
343#define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */
344
345/* Basic control structure */
346typedef struct hermes {
347 void __iomem *iobase;
348 int reg_spacing;
349#define HERMES_16BIT_REGSPACING 0
350#define HERMES_32BIT_REGSPACING 1
351
352 u16 inten; /* Which interrupts should be enabled? */
353
354#ifdef HERMES_DEBUG_BUFFER
355 struct hermes_debug_entry dbuf[HERMES_DEBUG_BUFSIZE];
356 unsigned long dbufp;
357 unsigned long profile[HERMES_BAP_BUSY_TIMEOUT+1];
358#endif
359} hermes_t;
360
361/* Register access convenience macros */
362#define hermes_read_reg(hw, off) \
363 (ioread16((hw)->iobase + ( (off) << (hw)->reg_spacing )))
364#define hermes_write_reg(hw, off, val) \
365 (iowrite16((val), (hw)->iobase + ((off) << (hw)->reg_spacing)))
366#define hermes_read_regn(hw, name) hermes_read_reg((hw), HERMES_##name)
367#define hermes_write_regn(hw, name, val) hermes_write_reg((hw), HERMES_##name, (val))
368
369/* Function prototypes */
370void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing);
371int hermes_init(hermes_t *hw);
372int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
373 struct hermes_response *resp);
374int hermes_allocate(hermes_t *hw, u16 size, u16 *fid);
375
376int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len,
377 u16 id, u16 offset);
378int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
379 u16 id, u16 offset);
380int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen,
381 u16 *length, void *buf);
382int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
383 u16 length, const void *value);
384
385/* Inline functions */
386
387static inline int hermes_present(hermes_t *hw)
388{
389 return hermes_read_regn(hw, SWSUPPORT0) == HERMES_MAGIC;
390}
391
392static inline void hermes_set_irqmask(hermes_t *hw, u16 events)
393{
394 hw->inten = events;
395 hermes_write_regn(hw, INTEN, events);
396}
397
398static inline int hermes_enable_port(hermes_t *hw, int port)
399{
400 return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8),
401 0, NULL);
402}
403
404static inline int hermes_disable_port(hermes_t *hw, int port)
405{
406 return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8),
407 0, NULL);
408}
409
410/* Initiate an INQUIRE command (tallies or scan). The result will come as an
411 * information frame in __orinoco_ev_info() */
412static inline int hermes_inquire(hermes_t *hw, u16 rid)
413{
414 return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
415}
416
417#define HERMES_BYTES_TO_RECLEN(n) ( (((n)+1)/2) + 1 )
418#define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 )
419
420/* Note that for the next two, the count is in 16-bit words, not bytes */
421static inline void hermes_read_words(struct hermes *hw, int off, void *buf, unsigned count)
422{
423 off = off << hw->reg_spacing;
424 ioread16_rep(hw->iobase + off, buf, count);
425}
426
427static inline void hermes_write_words(struct hermes *hw, int off, const void *buf, unsigned count)
428{
429 off = off << hw->reg_spacing;
430 iowrite16_rep(hw->iobase + off, buf, count);
431}
432
433static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count)
434{
435 unsigned i;
436
437 off = off << hw->reg_spacing;
438
439 for (i = 0; i < count; i++)
440 iowrite16(0, hw->iobase + off);
441}
442
443#define HERMES_READ_RECORD(hw, bap, rid, buf) \
444 (hermes_read_ltv((hw),(bap),(rid), sizeof(*buf), NULL, (buf)))
445#define HERMES_WRITE_RECORD(hw, bap, rid, buf) \
446 (hermes_write_ltv((hw),(bap),(rid),HERMES_BYTES_TO_RECLEN(sizeof(*buf)),(buf)))
447
448static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
449{
450 u16 rec;
451 int err;
452
453 err = HERMES_READ_RECORD(hw, bap, rid, &rec);
454 *word = le16_to_cpu(rec);
455 return err;
456}
457
458static inline int hermes_write_wordrec(hermes_t *hw, int bap, u16 rid, u16 word)
459{
460 u16 rec = cpu_to_le16(word);
461 return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
462}
463
464#else /* ! __KERNEL__ */
465
466/* These are provided for the benefit of userspace drivers and testing programs
467 which use ioperm() or iopl() */
468
469#define hermes_read_reg(base, off) (inw((base) + (off)))
470#define hermes_write_reg(base, off, val) (outw((val), (base) + (off)))
471
472#define hermes_read_regn(base, name) (hermes_read_reg((base), HERMES_##name))
473#define hermes_write_regn(base, name, val) (hermes_write_reg((base), HERMES_##name, (val)))
474
475/* Note that for the next two, the count is in 16-bit words, not bytes */
476#define hermes_read_data(base, off, buf, count) (insw((base) + (off), (buf), (count)))
477#define hermes_write_data(base, off, buf, count) (outsw((base) + (off), (buf), (count)))
478
479#endif /* ! __KERNEL__ */
480
481#endif /* _HERMES_H */
diff --git a/drivers/net/wireless/hermes_rid.h b/drivers/net/wireless/hermes_rid.h
new file mode 100644
index 000000000000..4f46b4809e55
--- /dev/null
+++ b/drivers/net/wireless/hermes_rid.h
@@ -0,0 +1,148 @@
1#ifndef _HERMES_RID_H
2#define _HERMES_RID_H
3
4/*
5 * Configuration RIDs
6 */
7#define HERMES_RID_CNFPORTTYPE 0xFC00
8#define HERMES_RID_CNFOWNMACADDR 0xFC01
9#define HERMES_RID_CNFDESIREDSSID 0xFC02
10#define HERMES_RID_CNFOWNCHANNEL 0xFC03
11#define HERMES_RID_CNFOWNSSID 0xFC04
12#define HERMES_RID_CNFOWNATIMWINDOW 0xFC05
13#define HERMES_RID_CNFSYSTEMSCALE 0xFC06
14#define HERMES_RID_CNFMAXDATALEN 0xFC07
15#define HERMES_RID_CNFWDSADDRESS 0xFC08
16#define HERMES_RID_CNFPMENABLED 0xFC09
17#define HERMES_RID_CNFPMEPS 0xFC0A
18#define HERMES_RID_CNFMULTICASTRECEIVE 0xFC0B
19#define HERMES_RID_CNFMAXSLEEPDURATION 0xFC0C
20#define HERMES_RID_CNFPMHOLDOVERDURATION 0xFC0D
21#define HERMES_RID_CNFOWNNAME 0xFC0E
22#define HERMES_RID_CNFOWNDTIMPERIOD 0xFC10
23#define HERMES_RID_CNFWDSADDRESS1 0xFC11
24#define HERMES_RID_CNFWDSADDRESS2 0xFC12
25#define HERMES_RID_CNFWDSADDRESS3 0xFC13
26#define HERMES_RID_CNFWDSADDRESS4 0xFC14
27#define HERMES_RID_CNFWDSADDRESS5 0xFC15
28#define HERMES_RID_CNFWDSADDRESS6 0xFC16
29#define HERMES_RID_CNFMULTICASTPMBUFFERING 0xFC17
30#define HERMES_RID_CNFWEPENABLED_AGERE 0xFC20
31#define HERMES_RID_CNFAUTHENTICATION_AGERE 0xFC21
32#define HERMES_RID_CNFMANDATORYBSSID_SYMBOL 0xFC21
33#define HERMES_RID_CNFWEPDEFAULTKEYID 0xFC23
34#define HERMES_RID_CNFDEFAULTKEY0 0xFC24
35#define HERMES_RID_CNFDEFAULTKEY1 0xFC25
36#define HERMES_RID_CNFMWOROBUST_AGERE 0xFC25
37#define HERMES_RID_CNFDEFAULTKEY2 0xFC26
38#define HERMES_RID_CNFDEFAULTKEY3 0xFC27
39#define HERMES_RID_CNFWEPFLAGS_INTERSIL 0xFC28
40#define HERMES_RID_CNFWEPKEYMAPPINGTABLE 0xFC29
41#define HERMES_RID_CNFAUTHENTICATION 0xFC2A
42#define HERMES_RID_CNFMAXASSOCSTA 0xFC2B
43#define HERMES_RID_CNFKEYLENGTH_SYMBOL 0xFC2B
44#define HERMES_RID_CNFTXCONTROL 0xFC2C
45#define HERMES_RID_CNFROAMINGMODE 0xFC2D
46#define HERMES_RID_CNFHOSTAUTHENTICATION 0xFC2E
47#define HERMES_RID_CNFRCVCRCERROR 0xFC30
48#define HERMES_RID_CNFMMLIFE 0xFC31
49#define HERMES_RID_CNFALTRETRYCOUNT 0xFC32
50#define HERMES_RID_CNFBEACONINT 0xFC33
51#define HERMES_RID_CNFAPPCFINFO 0xFC34
52#define HERMES_RID_CNFSTAPCFINFO 0xFC35
53#define HERMES_RID_CNFPRIORITYQUSAGE 0xFC37
54#define HERMES_RID_CNFTIMCTRL 0xFC40
55#define HERMES_RID_CNFTHIRTY2TALLY 0xFC42
56#define HERMES_RID_CNFENHSECURITY 0xFC43
57#define HERMES_RID_CNFGROUPADDRESSES 0xFC80
58#define HERMES_RID_CNFCREATEIBSS 0xFC81
59#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD 0xFC82
60#define HERMES_RID_CNFRTSTHRESHOLD 0xFC83
61#define HERMES_RID_CNFTXRATECONTROL 0xFC84
62#define HERMES_RID_CNFPROMISCUOUSMODE 0xFC85
63#define HERMES_RID_CNFBASICRATES_SYMBOL 0xFC8A
64#define HERMES_RID_CNFPREAMBLE_SYMBOL 0xFC8C
65#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD0 0xFC90
66#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD1 0xFC91
67#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD2 0xFC92
68#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD3 0xFC93
69#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD4 0xFC94
70#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD5 0xFC95
71#define HERMES_RID_CNFFRAGMENTATIONTHRESHOLD6 0xFC96
72#define HERMES_RID_CNFRTSTHRESHOLD0 0xFC97
73#define HERMES_RID_CNFRTSTHRESHOLD1 0xFC98
74#define HERMES_RID_CNFRTSTHRESHOLD2 0xFC99
75#define HERMES_RID_CNFRTSTHRESHOLD3 0xFC9A
76#define HERMES_RID_CNFRTSTHRESHOLD4 0xFC9B
77#define HERMES_RID_CNFRTSTHRESHOLD5 0xFC9C
78#define HERMES_RID_CNFRTSTHRESHOLD6 0xFC9D
79#define HERMES_RID_CNFHOSTSCAN_SYMBOL 0xFCAB
80#define HERMES_RID_CNFSHORTPREAMBLE 0xFCB0
81#define HERMES_RID_CNFWEPKEYS_AGERE 0xFCB0
82#define HERMES_RID_CNFEXCLUDELONGPREAMBLE 0xFCB1
83#define HERMES_RID_CNFTXKEY_AGERE 0xFCB1
84#define HERMES_RID_CNFAUTHENTICATIONRSPTO 0xFCB2
85#define HERMES_RID_CNFSCANSSID_AGERE 0xFCB2
86#define HERMES_RID_CNFBASICRATES 0xFCB3
87#define HERMES_RID_CNFSUPPORTEDRATES 0xFCB4
88#define HERMES_RID_CNFTICKTIME 0xFCE0
89#define HERMES_RID_CNFSCANREQUEST 0xFCE1
90#define HERMES_RID_CNFJOINREQUEST 0xFCE2
91#define HERMES_RID_CNFAUTHENTICATESTATION 0xFCE3
92#define HERMES_RID_CNFCHANNELINFOREQUEST 0xFCE4
93#define HERMES_RID_CNFHOSTSCAN 0xFCE5
94
95/*
96 * Information RIDs
97 */
98#define HERMES_RID_MAXLOADTIME 0xFD00
99#define HERMES_RID_DOWNLOADBUFFER 0xFD01
100#define HERMES_RID_PRIID 0xFD02
101#define HERMES_RID_PRISUPRANGE 0xFD03
102#define HERMES_RID_CFIACTRANGES 0xFD04
103#define HERMES_RID_NICSERNUM 0xFD0A
104#define HERMES_RID_NICID 0xFD0B
105#define HERMES_RID_MFISUPRANGE 0xFD0C
106#define HERMES_RID_CFISUPRANGE 0xFD0D
107#define HERMES_RID_CHANNELLIST 0xFD10
108#define HERMES_RID_REGULATORYDOMAINS 0xFD11
109#define HERMES_RID_TEMPTYPE 0xFD12
110#define HERMES_RID_CIS 0xFD13
111#define HERMES_RID_STAID 0xFD20
112#define HERMES_RID_STASUPRANGE 0xFD21
113#define HERMES_RID_MFIACTRANGES 0xFD22
114#define HERMES_RID_CFIACTRANGES2 0xFD23
115#define HERMES_RID_SECONDARYVERSION_SYMBOL 0xFD24
116#define HERMES_RID_PORTSTATUS 0xFD40
117#define HERMES_RID_CURRENTSSID 0xFD41
118#define HERMES_RID_CURRENTBSSID 0xFD42
119#define HERMES_RID_COMMSQUALITY 0xFD43
120#define HERMES_RID_CURRENTTXRATE 0xFD44
121#define HERMES_RID_CURRENTBEACONINTERVAL 0xFD45
122#define HERMES_RID_CURRENTSCALETHRESHOLDS 0xFD46
123#define HERMES_RID_PROTOCOLRSPTIME 0xFD47
124#define HERMES_RID_SHORTRETRYLIMIT 0xFD48
125#define HERMES_RID_LONGRETRYLIMIT 0xFD49
126#define HERMES_RID_MAXTRANSMITLIFETIME 0xFD4A
127#define HERMES_RID_MAXRECEIVELIFETIME 0xFD4B
128#define HERMES_RID_CFPOLLABLE 0xFD4C
129#define HERMES_RID_AUTHENTICATIONALGORITHMS 0xFD4D
130#define HERMES_RID_PRIVACYOPTIONIMPLEMENTED 0xFD4F
131#define HERMES_RID_DBMCOMMSQUALITY_INTERSIL 0xFD51
132#define HERMES_RID_CURRENTTXRATE1 0xFD80
133#define HERMES_RID_CURRENTTXRATE2 0xFD81
134#define HERMES_RID_CURRENTTXRATE3 0xFD82
135#define HERMES_RID_CURRENTTXRATE4 0xFD83
136#define HERMES_RID_CURRENTTXRATE5 0xFD84
137#define HERMES_RID_CURRENTTXRATE6 0xFD85
138#define HERMES_RID_OWNMACADDR 0xFD86
139#define HERMES_RID_SCANRESULTSTABLE 0xFD88
140#define HERMES_RID_PHYTYPE 0xFDC0
141#define HERMES_RID_CURRENTCHANNEL 0xFDC1
142#define HERMES_RID_CURRENTPOWERSTATE 0xFDC2
143#define HERMES_RID_CCAMODE 0xFDC3
144#define HERMES_RID_SUPPORTEDDATARATES 0xFDC6
145#define HERMES_RID_BUILDSEQ 0xFFFE
146#define HERMES_RID_FWID 0xFFFF
147
148#endif
diff --git a/drivers/net/wireless/i82586.h b/drivers/net/wireless/i82586.h
new file mode 100644
index 000000000000..5f65b250646f
--- /dev/null
+++ b/drivers/net/wireless/i82586.h
@@ -0,0 +1,413 @@
1/*
2 * Intel 82586 IEEE 802.3 Ethernet LAN Coprocessor.
3 *
4 * See:
5 * Intel Microcommunications 1991
6 * p1-1 to p1-37
7 * Intel order No. 231658
8 * ISBN 1-55512-119-5
9 *
10 * Unfortunately, the above chapter mentions neither
11 * the System Configuration Pointer (SCP) nor the
12 * Intermediate System Configuration Pointer (ISCP),
13 * so we probably need to look elsewhere for the
14 * whole story -- some recommend the "Intel LAN
15 * Components manual" but I have neither a copy
16 * nor a full reference. But "elsewhere" may be
17 * in the same publication...
18 * The description of a later device, the
19 * "82596CA High-Performance 32-Bit Local Area Network
20 * Coprocessor", (ibid. p1-38 to p1-109) does mention
21 * the SCP and ISCP and also has an i82586 compatibility
22 * mode. Even more useful is "AP-235 An 82586 Data Link
23 * Driver" (ibid. p1-337 to p1-417).
24 */
25
26#define I82586_MEMZ (64 * 1024)
27
28#define I82586_SCP_ADDR (I82586_MEMZ - sizeof(scp_t))
29
30#define ADDR_LEN 6
31#define I82586NULL 0xFFFF
32
33#define toff(t,p,f) (unsigned short)((void *)(&((t *)((void *)0 + (p)))->f) - (void *)0)
34
35/*
36 * System Configuration Pointer (SCP).
37 */
38typedef struct scp_t scp_t;
39struct scp_t
40{
41 unsigned short scp_sysbus; /* 82586 bus width: */
42#define SCP_SY_16BBUS (0x0 << 0) /* 16 bits */
43#define SCP_SY_8BBUS (0x1 << 0) /* 8 bits. */
44 unsigned short scp_junk[2]; /* Unused */
45 unsigned short scp_iscpl; /* lower 16 bits of ISCP_ADDR */
46 unsigned short scp_iscph; /* upper 16 bits of ISCP_ADDR */
47};
48
49/*
50 * Intermediate System Configuration Pointer (ISCP).
51 */
52typedef struct iscp_t iscp_t;
53struct iscp_t
54{
55 unsigned short iscp_busy; /* set by CPU before first CA, */
56 /* cleared by 82586 after read. */
57 unsigned short iscp_offset; /* offset of SCB */
58 unsigned short iscp_basel; /* base of SCB */
59 unsigned short iscp_baseh; /* " */
60};
61
62/*
63 * System Control Block (SCB).
64 * The 82586 writes its status to scb_status and then
65 * raises an interrupt to alert the CPU.
66 * The CPU writes a command to scb_command and
67 * then issues a Channel Attention (CA) to alert the 82586.
68 */
69typedef struct scb_t scb_t;
70struct scb_t
71{
72 unsigned short scb_status; /* Status of 82586 */
73#define SCB_ST_INT (0xF << 12) /* Some of: */
74#define SCB_ST_CX (0x1 << 15) /* Cmd completed */
75#define SCB_ST_FR (0x1 << 14) /* Frame received */
76#define SCB_ST_CNA (0x1 << 13) /* Cmd unit not active */
77#define SCB_ST_RNR (0x1 << 12) /* Rcv unit not ready */
78#define SCB_ST_JUNK0 (0x1 << 11) /* 0 */
79#define SCB_ST_CUS (0x7 << 8) /* Cmd unit status */
80#define SCB_ST_CUS_IDLE (0 << 8) /* Idle */
81#define SCB_ST_CUS_SUSP (1 << 8) /* Suspended */
82#define SCB_ST_CUS_ACTV (2 << 8) /* Active */
83#define SCB_ST_JUNK1 (0x1 << 7) /* 0 */
84#define SCB_ST_RUS (0x7 << 4) /* Rcv unit status */
85#define SCB_ST_RUS_IDLE (0 << 4) /* Idle */
86#define SCB_ST_RUS_SUSP (1 << 4) /* Suspended */
87#define SCB_ST_RUS_NRES (2 << 4) /* No resources */
88#define SCB_ST_RUS_RDY (4 << 4) /* Ready */
89 unsigned short scb_command; /* Next command */
90#define SCB_CMD_ACK_CX (0x1 << 15) /* Ack cmd completion */
91#define SCB_CMD_ACK_FR (0x1 << 14) /* Ack frame received */
92#define SCB_CMD_ACK_CNA (0x1 << 13) /* Ack CU not active */
93#define SCB_CMD_ACK_RNR (0x1 << 12) /* Ack RU not ready */
94#define SCB_CMD_JUNKX (0x1 << 11) /* Unused */
95#define SCB_CMD_CUC (0x7 << 8) /* Command Unit command */
96#define SCB_CMD_CUC_NOP (0 << 8) /* Nop */
97#define SCB_CMD_CUC_GO (1 << 8) /* Start cbl_offset */
98#define SCB_CMD_CUC_RES (2 << 8) /* Resume execution */
99#define SCB_CMD_CUC_SUS (3 << 8) /* Suspend " */
100#define SCB_CMD_CUC_ABT (4 << 8) /* Abort " */
101#define SCB_CMD_RESET (0x1 << 7) /* Reset chip (hardware) */
102#define SCB_CMD_RUC (0x7 << 4) /* Receive Unit command */
103#define SCB_CMD_RUC_NOP (0 << 4) /* Nop */
104#define SCB_CMD_RUC_GO (1 << 4) /* Start rfa_offset */
105#define SCB_CMD_RUC_RES (2 << 4) /* Resume reception */
106#define SCB_CMD_RUC_SUS (3 << 4) /* Suspend " */
107#define SCB_CMD_RUC_ABT (4 << 4) /* Abort " */
108 unsigned short scb_cbl_offset; /* Offset of first command unit */
109 /* Action Command */
110 unsigned short scb_rfa_offset; /* Offset of first Receive */
111 /* Frame Descriptor in the */
112 /* Receive Frame Area */
113 unsigned short scb_crcerrs; /* Properly aligned frames */
114 /* received with a CRC error */
115 unsigned short scb_alnerrs; /* Misaligned frames received */
116 /* with a CRC error */
117 unsigned short scb_rscerrs; /* Frames lost due to no space */
118 unsigned short scb_ovrnerrs; /* Frames lost due to slow bus */
119};
120
121#define scboff(p,f) toff(scb_t, p, f)
122
123/*
124 * The eight Action Commands.
125 */
126typedef enum acmd_e acmd_e;
127enum acmd_e
128{
129 acmd_nop = 0, /* Do nothing */
130 acmd_ia_setup = 1, /* Load an (ethernet) address into the */
131 /* 82586 */
132 acmd_configure = 2, /* Update the 82586 operating parameters */
133 acmd_mc_setup = 3, /* Load a list of (ethernet) multicast */
134 /* addresses into the 82586 */
135 acmd_transmit = 4, /* Transmit a frame */
136 acmd_tdr = 5, /* Perform a Time Domain Reflectometer */
137 /* test on the serial link */
138 acmd_dump = 6, /* Copy 82586 registers to memory */
139 acmd_diagnose = 7, /* Run an internal self test */
140};
141
142/*
143 * Generic Action Command header.
144 */
145typedef struct ach_t ach_t;
146struct ach_t
147{
148 unsigned short ac_status; /* Command status: */
149#define AC_SFLD_C (0x1 << 15) /* Command completed */
150#define AC_SFLD_B (0x1 << 14) /* Busy executing */
151#define AC_SFLD_OK (0x1 << 13) /* Completed error free */
152#define AC_SFLD_A (0x1 << 12) /* Command aborted */
153#define AC_SFLD_FAIL (0x1 << 11) /* Selftest failed */
154#define AC_SFLD_S10 (0x1 << 10) /* No carrier sense */
155 /* during transmission */
156#define AC_SFLD_S9 (0x1 << 9) /* Tx unsuccessful: */
157 /* (stopped) lost CTS */
158#define AC_SFLD_S8 (0x1 << 8) /* Tx unsuccessful: */
159 /* (stopped) slow DMA */
160#define AC_SFLD_S7 (0x1 << 7) /* Tx deferred: */
161 /* other link traffic */
162#define AC_SFLD_S6 (0x1 << 6) /* Heart Beat: collision */
163 /* detect after last tx */
164#define AC_SFLD_S5 (0x1 << 5) /* Tx stopped: */
165 /* excessive collisions */
166#define AC_SFLD_MAXCOL (0xF << 0) /* Collision count */
167 unsigned short ac_command; /* Command specifier: */
168#define AC_CFLD_EL (0x1 << 15) /* End of command list */
169#define AC_CFLD_S (0x1 << 14) /* Suspend on completion */
170#define AC_CFLD_I (0x1 << 13) /* Interrupt on completion */
171#define AC_CFLD_CMD (0x7 << 0) /* acmd_e */
172 unsigned short ac_link; /* Next Action Command */
173};
174
175#define acoff(p,f) toff(ach_t, p, f)
176
177/*
178 * The Nop Action Command.
179 */
180typedef struct ac_nop_t ac_nop_t;
181struct ac_nop_t
182{
183 ach_t nop_h;
184};
185
186/*
187 * The IA-Setup Action Command.
188 */
189typedef struct ac_ias_t ac_ias_t;
190struct ac_ias_t
191{
192 ach_t ias_h;
193 unsigned char ias_addr[ADDR_LEN]; /* The (ethernet) address */
194};
195
196/*
197 * The Configure Action Command.
198 */
199typedef struct ac_cfg_t ac_cfg_t;
200struct ac_cfg_t
201{
202 ach_t cfg_h;
203 unsigned char cfg_byte_cnt; /* Size foll data: 4-12 */
204#define AC_CFG_BYTE_CNT(v) (((v) & 0xF) << 0)
205 unsigned char cfg_fifolim; /* FIFO threshold */
206#define AC_CFG_FIFOLIM(v) (((v) & 0xF) << 0)
207 unsigned char cfg_byte8;
208#define AC_CFG_SAV_BF(v) (((v) & 0x1) << 7) /* Save rxd bad frames */
209#define AC_CFG_SRDY(v) (((v) & 0x1) << 6) /* SRDY/ARDY pin means */
210 /* external sync. */
211 unsigned char cfg_byte9;
212#define AC_CFG_ELPBCK(v) (((v) & 0x1) << 7) /* External loopback */
213#define AC_CFG_ILPBCK(v) (((v) & 0x1) << 6) /* Internal loopback */
214#define AC_CFG_PRELEN(v) (((v) & 0x3) << 4) /* Preamble length */
215#define AC_CFG_PLEN_2 0 /* 2 bytes */
216#define AC_CFG_PLEN_4 1 /* 4 bytes */
217#define AC_CFG_PLEN_8 2 /* 8 bytes */
218#define AC_CFG_PLEN_16 3 /* 16 bytes */
219#define AC_CFG_ALOC(v) (((v) & 0x1) << 3) /* Addr/len data is */
220 /* explicit in buffers */
221#define AC_CFG_ADDRLEN(v) (((v) & 0x7) << 0) /* Bytes per address */
222 unsigned char cfg_byte10;
223#define AC_CFG_BOFMET(v) (((v) & 0x1) << 7) /* Use alternate expo. */
224 /* backoff method */
225#define AC_CFG_ACR(v) (((v) & 0x7) << 4) /* Accelerated cont. res. */
226#define AC_CFG_LINPRIO(v) (((v) & 0x7) << 0) /* Linear priority */
227 unsigned char cfg_ifs; /* Interframe spacing */
228 unsigned char cfg_slotl; /* Slot time (low byte) */
229 unsigned char cfg_byte13;
230#define AC_CFG_RETRYNUM(v) (((v) & 0xF) << 4) /* Max. collision retry */
231#define AC_CFG_SLTTMHI(v) (((v) & 0x7) << 0) /* Slot time (high bits) */
232 unsigned char cfg_byte14;
233#define AC_CFG_FLGPAD(v) (((v) & 0x1) << 7) /* Pad with HDLC flags */
234#define AC_CFG_BTSTF(v) (((v) & 0x1) << 6) /* Do HDLC bitstuffing */
235#define AC_CFG_CRC16(v) (((v) & 0x1) << 5) /* 16 bit CCITT CRC */
236#define AC_CFG_NCRC(v) (((v) & 0x1) << 4) /* Insert no CRC */
237#define AC_CFG_TNCRS(v) (((v) & 0x1) << 3) /* Tx even if no carrier */
238#define AC_CFG_MANCH(v) (((v) & 0x1) << 2) /* Manchester coding */
239#define AC_CFG_BCDIS(v) (((v) & 0x1) << 1) /* Disable broadcast */
240#define AC_CFG_PRM(v) (((v) & 0x1) << 0) /* Promiscuous mode */
241 unsigned char cfg_byte15;
242#define AC_CFG_ICDS(v) (((v) & 0x1) << 7) /* Internal collision */
243 /* detect source */
244#define AC_CFG_CDTF(v) (((v) & 0x7) << 4) /* Collision detect */
245 /* filter in bit times */
246#define AC_CFG_ICSS(v) (((v) & 0x1) << 3) /* Internal carrier */
247 /* sense source */
248#define AC_CFG_CSTF(v) (((v) & 0x7) << 0) /* Carrier sense */
249 /* filter in bit times */
250 unsigned short cfg_min_frm_len;
251#define AC_CFG_MNFRM(v) (((v) & 0xFF) << 0) /* Min. bytes/frame (<= 255) */
252};
253
254/*
255 * The MC-Setup Action Command.
256 */
257typedef struct ac_mcs_t ac_mcs_t;
258struct ac_mcs_t
259{
260 ach_t mcs_h;
261 unsigned short mcs_cnt; /* No. of bytes of MC addresses */
262#if 0
263 unsigned char mcs_data[ADDR_LEN]; /* The first MC address .. */
264 ...
265#endif
266};
267
268#define I82586_MAX_MULTICAST_ADDRESSES 128 /* Hardware hashed filter */
269
270/*
271 * The Transmit Action Command.
272 */
273typedef struct ac_tx_t ac_tx_t;
274struct ac_tx_t
275{
276 ach_t tx_h;
277 unsigned short tx_tbd_offset; /* Address of list of buffers. */
278#if 0
279Linux packets are passed down with the destination MAC address
280and length/type field already prepended to the data,
281so we do not need to insert it. Consistent with this
282we must also set the AC_CFG_ALOC(..) flag during the
283ac_cfg_t action command.
284 unsigned char tx_addr[ADDR_LEN]; /* The frame dest. address */
285 unsigned short tx_length; /* The frame length */
286#endif /* 0 */
287};
288
289/*
290 * The Time Domain Reflectometer Action Command.
291 */
292typedef struct ac_tdr_t ac_tdr_t;
293struct ac_tdr_t
294{
295 ach_t tdr_h;
296 unsigned short tdr_result; /* Result. */
297#define AC_TDR_LNK_OK (0x1 << 15) /* No link problem */
298#define AC_TDR_XCVR_PRB (0x1 << 14) /* Txcvr cable problem */
299#define AC_TDR_ET_OPN (0x1 << 13) /* Open on the link */
300#define AC_TDR_ET_SRT (0x1 << 12) /* Short on the link */
301#define AC_TDR_TIME (0x7FF << 0) /* Distance to problem */
302 /* site in transmit */
303 /* clock cycles */
304};
305
306/*
307 * The Dump Action Command.
308 */
309typedef struct ac_dmp_t ac_dmp_t;
310struct ac_dmp_t
311{
312 ach_t dmp_h;
313 unsigned short dmp_offset; /* Result. */
314};
315
316/*
317 * Size of the result of the dump command.
318 */
319#define DUMPBYTES 170
320
321/*
322 * The Diagnose Action Command.
323 */
324typedef struct ac_dgn_t ac_dgn_t;
325struct ac_dgn_t
326{
327 ach_t dgn_h;
328};
329
330/*
331 * Transmit Buffer Descriptor (TBD).
332 */
333typedef struct tbd_t tbd_t;
334struct tbd_t
335{
336 unsigned short tbd_status; /* Written by the CPU */
337#define TBD_STATUS_EOF (0x1 << 15) /* This TBD is the */
338 /* last for this frame */
339#define TBD_STATUS_ACNT (0x3FFF << 0) /* Actual count of data */
340 /* bytes in this buffer */
341 unsigned short tbd_next_bd_offset; /* Next in list */
342 unsigned short tbd_bufl; /* Buffer address (low) */
343 unsigned short tbd_bufh; /* " " (high) */
344};
345
346/*
347 * Receive Buffer Descriptor (RBD).
348 */
349typedef struct rbd_t rbd_t;
350struct rbd_t
351{
352 unsigned short rbd_status; /* Written by the 82586 */
353#define RBD_STATUS_EOF (0x1 << 15) /* This RBD is the */
354 /* last for this frame */
355#define RBD_STATUS_F (0x1 << 14) /* ACNT field is valid */
356#define RBD_STATUS_ACNT (0x3FFF << 0) /* Actual no. of data */
357 /* bytes in this buffer */
358 unsigned short rbd_next_rbd_offset; /* Next rbd in list */
359 unsigned short rbd_bufl; /* Data pointer (low) */
360 unsigned short rbd_bufh; /* " " (high) */
361 unsigned short rbd_el_size; /* EL+Data buf. size */
362#define RBD_EL (0x1 << 15) /* This BD is the */
363 /* last in the list */
364#define RBD_SIZE (0x3FFF << 0) /* No. of bytes the */
365 /* buffer can hold */
366};
367
368#define rbdoff(p,f) toff(rbd_t, p, f)
369
370/*
371 * Frame Descriptor (FD).
372 */
373typedef struct fd_t fd_t;
374struct fd_t
375{
376 unsigned short fd_status; /* Written by the 82586 */
377#define FD_STATUS_C (0x1 << 15) /* Completed storing frame */
378#define FD_STATUS_B (0x1 << 14) /* FD was consumed by RU */
379#define FD_STATUS_OK (0x1 << 13) /* Frame rxd successfully */
380#define FD_STATUS_S11 (0x1 << 11) /* CRC error */
381#define FD_STATUS_S10 (0x1 << 10) /* Alignment error */
382#define FD_STATUS_S9 (0x1 << 9) /* Ran out of resources */
383#define FD_STATUS_S8 (0x1 << 8) /* Rx DMA overrun */
384#define FD_STATUS_S7 (0x1 << 7) /* Frame too short */
385#define FD_STATUS_S6 (0x1 << 6) /* No EOF flag */
386 unsigned short fd_command; /* Command */
387#define FD_COMMAND_EL (0x1 << 15) /* Last FD in list */
388#define FD_COMMAND_S (0x1 << 14) /* Suspend RU after rx */
389 unsigned short fd_link_offset; /* Next FD */
390 unsigned short fd_rbd_offset; /* First RBD (data) */
391 /* Prepared by CPU, */
392 /* updated by 82586 */
393#if 0
394I think the rest is unused since we
395have set AC_CFG_ALOC(..). However, just
396in case, we leave the space.
397#endif /* 0 */
398 unsigned char fd_dest[ADDR_LEN]; /* Destination address */
399 /* Written by 82586 */
400 unsigned char fd_src[ADDR_LEN]; /* Source address */
401 /* Written by 82586 */
402 unsigned short fd_length; /* Frame length or type */
403 /* Written by 82586 */
404};
405
406#define fdoff(p,f) toff(fd_t, p, f)
407
408/*
409 * This software may only be used and distributed
410 * according to the terms of the GNU General Public License.
411 *
412 * For more details, see wavelan.c.
413 */
diff --git a/drivers/net/wireless/i82593.h b/drivers/net/wireless/i82593.h
new file mode 100644
index 000000000000..33acb8add4d6
--- /dev/null
+++ b/drivers/net/wireless/i82593.h
@@ -0,0 +1,224 @@
1/*
2 * Definitions for Intel 82593 CSMA/CD Core LAN Controller
3 * The definitions are taken from the 1992 users manual with Intel
4 * order number 297125-001.
5 *
6 * /usr/src/pc/RCS/i82593.h,v 1.1 1996/07/17 15:23:12 root Exp
7 *
8 * Copyright 1994, Anders Klemets <klemets@it.kth.se>
9 *
10 * This software may be freely distributed for noncommercial purposes
11 * as long as this notice is retained.
12 *
13 * HISTORY
14 * i82593.h,v
15 * Revision 1.1 1996/07/17 15:23:12 root
16 * Initial revision
17 *
18 * Revision 1.3 1995/04/05 15:13:58 adj
19 * Initial alpha release
20 *
21 * Revision 1.2 1994/06/16 23:57:31 klemets
22 * Mirrored all the fields in the configuration block.
23 *
24 * Revision 1.1 1994/06/02 20:25:34 klemets
25 * Initial revision
26 *
27 *
28 */
29#ifndef _I82593_H
30#define _I82593_H
31
32/* Intel 82593 CSMA/CD Core LAN Controller */
33
34/* Port 0 Command Register definitions */
35
36/* Execution operations */
37#define OP0_NOP 0 /* CHNL = 0 */
38#define OP0_SWIT_TO_PORT_1 0 /* CHNL = 1 */
39#define OP0_IA_SETUP 1
40#define OP0_CONFIGURE 2
41#define OP0_MC_SETUP 3
42#define OP0_TRANSMIT 4
43#define OP0_TDR 5
44#define OP0_DUMP 6
45#define OP0_DIAGNOSE 7
46#define OP0_TRANSMIT_NO_CRC 9
47#define OP0_RETRANSMIT 12
48#define OP0_ABORT 13
49/* Reception operations */
50#define OP0_RCV_ENABLE 8
51#define OP0_RCV_DISABLE 10
52#define OP0_STOP_RCV 11
53/* Status pointer control operations */
54#define OP0_FIX_PTR 15 /* CHNL = 1 */
55#define OP0_RLS_PTR 15 /* CHNL = 0 */
56#define OP0_RESET 14
57
58#define CR0_CHNL (1 << 4) /* 0=Channel 0, 1=Channel 1 */
59#define CR0_STATUS_0 0x00
60#define CR0_STATUS_1 0x20
61#define CR0_STATUS_2 0x40
62#define CR0_STATUS_3 0x60
63#define CR0_INT_ACK (1 << 7) /* 0=No ack, 1=acknowledge */
64
65/* Port 0 Status Register definitions */
66
67#define SR0_NO_RESULT 0 /* dummy */
68#define SR0_EVENT_MASK 0x0f
69#define SR0_IA_SETUP_DONE 1
70#define SR0_CONFIGURE_DONE 2
71#define SR0_MC_SETUP_DONE 3
72#define SR0_TRANSMIT_DONE 4
73#define SR0_TDR_DONE 5
74#define SR0_DUMP_DONE 6
75#define SR0_DIAGNOSE_PASSED 7
76#define SR0_TRANSMIT_NO_CRC_DONE 9
77#define SR0_RETRANSMIT_DONE 12
78#define SR0_EXECUTION_ABORTED 13
79#define SR0_END_OF_FRAME 8
80#define SR0_RECEPTION_ABORTED 10
81#define SR0_DIAGNOSE_FAILED 15
82#define SR0_STOP_REG_HIT 11
83
84#define SR0_CHNL (1 << 4)
85#define SR0_EXECUTION (1 << 5)
86#define SR0_RECEPTION (1 << 6)
87#define SR0_INTERRUPT (1 << 7)
88#define SR0_BOTH_RX_TX (SR0_EXECUTION | SR0_RECEPTION)
89
90#define SR3_EXEC_STATE_MASK 0x03
91#define SR3_EXEC_IDLE 0
92#define SR3_TX_ABORT_IN_PROGRESS 1
93#define SR3_EXEC_ACTIVE 2
94#define SR3_ABORT_IN_PROGRESS 3
95#define SR3_EXEC_CHNL (1 << 2)
96#define SR3_STP_ON_NO_RSRC (1 << 3)
97#define SR3_RCVING_NO_RSRC (1 << 4)
98#define SR3_RCV_STATE_MASK 0x60
99#define SR3_RCV_IDLE 0x00
100#define SR3_RCV_READY 0x20
101#define SR3_RCV_ACTIVE 0x40
102#define SR3_RCV_STOP_IN_PROG 0x60
103#define SR3_RCV_CHNL (1 << 7)
104
105/* Port 1 Command Register definitions */
106
107#define OP1_NOP 0
108#define OP1_SWIT_TO_PORT_0 1
109#define OP1_INT_DISABLE 2
110#define OP1_INT_ENABLE 3
111#define OP1_SET_TS 5
112#define OP1_RST_TS 7
113#define OP1_POWER_DOWN 8
114#define OP1_RESET_RING_MNGMT 11
115#define OP1_RESET 14
116#define OP1_SEL_RST 15
117
118#define CR1_STATUS_4 0x00
119#define CR1_STATUS_5 0x20
120#define CR1_STATUS_6 0x40
121#define CR1_STOP_REG_UPDATE (1 << 7)
122
123/* Receive frame status bits */
124
125#define RX_RCLD (1 << 0)
126#define RX_IA_MATCH (1 << 1)
127#define RX_NO_AD_MATCH (1 << 2)
128#define RX_NO_SFD (1 << 3)
129#define RX_SRT_FRM (1 << 7)
130#define RX_OVRRUN (1 << 8)
131#define RX_ALG_ERR (1 << 10)
132#define RX_CRC_ERR (1 << 11)
133#define RX_LEN_ERR (1 << 12)
134#define RX_RCV_OK (1 << 13)
135#define RX_TYP_LEN (1 << 15)
136
137/* Transmit status bits */
138
139#define TX_NCOL_MASK 0x0f
140#define TX_FRTL (1 << 4)
141#define TX_MAX_COL (1 << 5)
142#define TX_HRT_BEAT (1 << 6)
143#define TX_DEFER (1 << 7)
144#define TX_UND_RUN (1 << 8)
145#define TX_LOST_CTS (1 << 9)
146#define TX_LOST_CRS (1 << 10)
147#define TX_LTCOL (1 << 11)
148#define TX_OK (1 << 13)
149#define TX_COLL (1 << 15)
150
151struct i82593_conf_block {
152 u_char fifo_limit : 4,
153 forgnesi : 1,
154 fifo_32 : 1,
155 d6mod : 1,
156 throttle_enb : 1;
157 u_char throttle : 6,
158 cntrxint : 1,
159 contin : 1;
160 u_char addr_len : 3,
161 acloc : 1,
162 preamb_len : 2,
163 loopback : 2;
164 u_char lin_prio : 3,
165 tbofstop : 1,
166 exp_prio : 3,
167 bof_met : 1;
168 u_char : 4,
169 ifrm_spc : 4;
170 u_char : 5,
171 slottim_low : 3;
172 u_char slottim_hi : 3,
173 : 1,
174 max_retr : 4;
175 u_char prmisc : 1,
176 bc_dis : 1,
177 : 1,
178 crs_1 : 1,
179 nocrc_ins : 1,
180 crc_1632 : 1,
181 : 1,
182 crs_cdt : 1;
183 u_char cs_filter : 3,
184 crs_src : 1,
185 cd_filter : 3,
186 : 1;
187 u_char : 2,
188 min_fr_len : 6;
189 u_char lng_typ : 1,
190 lng_fld : 1,
191 rxcrc_xf : 1,
192 artx : 1,
193 sarec : 1,
194 tx_jabber : 1, /* why is this called max_len in the manual? */
195 hash_1 : 1,
196 lbpkpol : 1;
197 u_char : 6,
198 fdx : 1,
199 : 1;
200 u_char dummy_6 : 6, /* supposed to be ones */
201 mult_ia : 1,
202 dis_bof : 1;
203 u_char dummy_1 : 1, /* supposed to be one */
204 tx_ifs_retrig : 2,
205 mc_all : 1,
206 rcv_mon : 2,
207 frag_acpt : 1,
208 tstrttrs : 1;
209 u_char fretx : 1,
210 runt_eop : 1,
211 hw_sw_pin : 1,
212 big_endn : 1,
213 syncrqs : 1,
214 sttlen : 1,
215 tx_eop : 1,
216 rx_eop : 1;
217 u_char rbuf_size : 5,
218 rcvstop : 1,
219 : 2;
220};
221
222#define I82593_MAX_MULTICAST_ADDRESSES 128 /* Hardware hashed filter */
223
224#endif /* _I82593_H */
diff --git a/drivers/net/wireless/ieee802_11.h b/drivers/net/wireless/ieee802_11.h
new file mode 100644
index 000000000000..53dd5248f9f1
--- /dev/null
+++ b/drivers/net/wireless/ieee802_11.h
@@ -0,0 +1,78 @@
1#ifndef _IEEE802_11_H
2#define _IEEE802_11_H
3
4#define IEEE802_11_DATA_LEN 2304
5/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
6 6.2.1.1.2.
7
8 The figure in section 7.1.2 suggests a body size of up to 2312
9 bytes is allowed, which is a bit confusing, I suspect this
10 represents the 2304 bytes of real data, plus a possible 8 bytes of
11 WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
12
13
14#define IEEE802_11_HLEN 30
15#define IEEE802_11_FRAME_LEN (IEEE802_11_DATA_LEN + IEEE802_11_HLEN)
16
17struct ieee802_11_hdr {
18 u16 frame_ctl;
19 u16 duration_id;
20 u8 addr1[ETH_ALEN];
21 u8 addr2[ETH_ALEN];
22 u8 addr3[ETH_ALEN];
23 u16 seq_ctl;
24 u8 addr4[ETH_ALEN];
25} __attribute__ ((packed));
26
27/* Frame control field constants */
28#define IEEE802_11_FCTL_VERS 0x0002
29#define IEEE802_11_FCTL_FTYPE 0x000c
30#define IEEE802_11_FCTL_STYPE 0x00f0
31#define IEEE802_11_FCTL_TODS 0x0100
32#define IEEE802_11_FCTL_FROMDS 0x0200
33#define IEEE802_11_FCTL_MOREFRAGS 0x0400
34#define IEEE802_11_FCTL_RETRY 0x0800
35#define IEEE802_11_FCTL_PM 0x1000
36#define IEEE802_11_FCTL_MOREDATA 0x2000
37#define IEEE802_11_FCTL_WEP 0x4000
38#define IEEE802_11_FCTL_ORDER 0x8000
39
40#define IEEE802_11_FTYPE_MGMT 0x0000
41#define IEEE802_11_FTYPE_CTL 0x0004
42#define IEEE802_11_FTYPE_DATA 0x0008
43
44/* management */
45#define IEEE802_11_STYPE_ASSOC_REQ 0x0000
46#define IEEE802_11_STYPE_ASSOC_RESP 0x0010
47#define IEEE802_11_STYPE_REASSOC_REQ 0x0020
48#define IEEE802_11_STYPE_REASSOC_RESP 0x0030
49#define IEEE802_11_STYPE_PROBE_REQ 0x0040
50#define IEEE802_11_STYPE_PROBE_RESP 0x0050
51#define IEEE802_11_STYPE_BEACON 0x0080
52#define IEEE802_11_STYPE_ATIM 0x0090
53#define IEEE802_11_STYPE_DISASSOC 0x00A0
54#define IEEE802_11_STYPE_AUTH 0x00B0
55#define IEEE802_11_STYPE_DEAUTH 0x00C0
56
57/* control */
58#define IEEE802_11_STYPE_PSPOLL 0x00A0
59#define IEEE802_11_STYPE_RTS 0x00B0
60#define IEEE802_11_STYPE_CTS 0x00C0
61#define IEEE802_11_STYPE_ACK 0x00D0
62#define IEEE802_11_STYPE_CFEND 0x00E0
63#define IEEE802_11_STYPE_CFENDACK 0x00F0
64
65/* data */
66#define IEEE802_11_STYPE_DATA 0x0000
67#define IEEE802_11_STYPE_DATA_CFACK 0x0010
68#define IEEE802_11_STYPE_DATA_CFPOLL 0x0020
69#define IEEE802_11_STYPE_DATA_CFACKPOLL 0x0030
70#define IEEE802_11_STYPE_NULLFUNC 0x0040
71#define IEEE802_11_STYPE_CFACK 0x0050
72#define IEEE802_11_STYPE_CFPOLL 0x0060
73#define IEEE802_11_STYPE_CFACKPOLL 0x0070
74
75#define IEEE802_11_SCTL_FRAG 0x000F
76#define IEEE802_11_SCTL_SEQ 0xFFF0
77
78#endif /* _IEEE802_11_H */
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
new file mode 100644
index 000000000000..382241e7edbb
--- /dev/null
+++ b/drivers/net/wireless/netwave_cs.c
@@ -0,0 +1,1736 @@
1/*********************************************************************
2 *
3 * Filename: netwave_cs.c
4 * Version: 0.4.1
5 * Description: Netwave AirSurfer Wireless LAN PC Card driver
6 * Status: Experimental.
7 * Authors: John Markus Bjørndalen <johnm@cs.uit.no>
8 * Dag Brattli <dagb@cs.uit.no>
9 * David Hinds <dahinds@users.sourceforge.net>
10 * Created at: A long time ago!
11 * Modified at: Mon Nov 10 11:54:37 1997
12 * Modified by: Dag Brattli <dagb@cs.uit.no>
13 *
14 * Copyright (c) 1997 University of Tromsø, Norway
15 *
16 * Revision History:
17 *
18 * 08-Nov-97 15:14:47 John Markus Bjørndalen <johnm@cs.uit.no>
19 * - Fixed some bugs in netwave_rx and cleaned it up a bit.
20 * (One of the bugs would have destroyed packets when receiving
21 * multiple packets per interrupt).
22 * - Cleaned up parts of newave_hw_xmit.
23 * - A few general cleanups.
24 * 24-Oct-97 13:17:36 Dag Brattli <dagb@cs.uit.no>
25 * - Fixed netwave_rx receive function (got updated docs)
26 * Others:
27 * - Changed name from xircnw to netwave, take a look at
28 * http://www.netwave-wireless.com
29 * - Some reorganizing of the code
30 * - Removed possible race condition between interrupt handler and transmit
31 * function
32 * - Started to add wireless extensions, but still needs some coding
33 * - Added watchdog for better handling of transmission timeouts
34 * (hopefully this works better)
35 ********************************************************************/
36
37/* To have statistics (just packets sent) define this */
38#undef NETWAVE_STATS
39
40#include <linux/config.h>
41#include <linux/module.h>
42#include <linux/kernel.h>
43#include <linux/init.h>
44#include <linux/types.h>
45#include <linux/fcntl.h>
46#include <linux/interrupt.h>
47#include <linux/ptrace.h>
48#include <linux/ioport.h>
49#include <linux/in.h>
50#include <linux/slab.h>
51#include <linux/string.h>
52#include <linux/timer.h>
53#include <linux/errno.h>
54#include <linux/netdevice.h>
55#include <linux/etherdevice.h>
56#include <linux/skbuff.h>
57#include <linux/bitops.h>
58#ifdef CONFIG_NET_RADIO
59#include <linux/wireless.h>
60#if WIRELESS_EXT > 12
61#include <net/iw_handler.h>
62#endif /* WIRELESS_EXT > 12 */
63#endif
64
65#include <pcmcia/version.h>
66#include <pcmcia/cs_types.h>
67#include <pcmcia/cs.h>
68#include <pcmcia/cistpl.h>
69#include <pcmcia/cisreg.h>
70#include <pcmcia/ds.h>
71#include <pcmcia/mem_op.h>
72
73#include <asm/system.h>
74#include <asm/io.h>
75#include <asm/dma.h>
76
77#define NETWAVE_REGOFF 0x8000
78/* The Netwave IO registers, offsets to iobase */
79#define NETWAVE_REG_COR 0x0
80#define NETWAVE_REG_CCSR 0x2
81#define NETWAVE_REG_ASR 0x4
82#define NETWAVE_REG_IMR 0xa
83#define NETWAVE_REG_PMR 0xc
84#define NETWAVE_REG_IOLOW 0x6
85#define NETWAVE_REG_IOHI 0x7
86#define NETWAVE_REG_IOCONTROL 0x8
87#define NETWAVE_REG_DATA 0xf
88/* The Netwave Extended IO registers, offsets to RamBase */
89#define NETWAVE_EREG_ASCC 0x114
90#define NETWAVE_EREG_RSER 0x120
91#define NETWAVE_EREG_RSERW 0x124
92#define NETWAVE_EREG_TSER 0x130
93#define NETWAVE_EREG_TSERW 0x134
94#define NETWAVE_EREG_CB 0x100
95#define NETWAVE_EREG_SPCQ 0x154
96#define NETWAVE_EREG_SPU 0x155
97#define NETWAVE_EREG_LIF 0x14e
98#define NETWAVE_EREG_ISPLQ 0x156
99#define NETWAVE_EREG_HHC 0x158
100#define NETWAVE_EREG_NI 0x16e
101#define NETWAVE_EREG_MHS 0x16b
102#define NETWAVE_EREG_TDP 0x140
103#define NETWAVE_EREG_RDP 0x150
104#define NETWAVE_EREG_PA 0x160
105#define NETWAVE_EREG_EC 0x180
106#define NETWAVE_EREG_CRBP 0x17a
107#define NETWAVE_EREG_ARW 0x166
108
109/*
110 * Commands used in the extended command buffer
111 * NETWAVE_EREG_CB (0x100-0x10F)
112 */
113#define NETWAVE_CMD_NOP 0x00
114#define NETWAVE_CMD_SRC 0x01
115#define NETWAVE_CMD_STC 0x02
116#define NETWAVE_CMD_AMA 0x03
117#define NETWAVE_CMD_DMA 0x04
118#define NETWAVE_CMD_SAMA 0x05
119#define NETWAVE_CMD_ER 0x06
120#define NETWAVE_CMD_DR 0x07
121#define NETWAVE_CMD_TL 0x08
122#define NETWAVE_CMD_SRP 0x09
123#define NETWAVE_CMD_SSK 0x0a
124#define NETWAVE_CMD_SMD 0x0b
125#define NETWAVE_CMD_SAPD 0x0c
126#define NETWAVE_CMD_SSS 0x11
127/* End of Command marker */
128#define NETWAVE_CMD_EOC 0x00
129
130/* ASR register bits */
131#define NETWAVE_ASR_RXRDY 0x80
132#define NETWAVE_ASR_TXBA 0x01
133
134#define TX_TIMEOUT ((32*HZ)/100)
135
136static const unsigned int imrConfRFU1 = 0x10; /* RFU interrupt mask, keep high */
137static const unsigned int imrConfIENA = 0x02; /* Interrupt enable */
138
139static const unsigned int corConfIENA = 0x01; /* Interrupt enable */
140static const unsigned int corConfLVLREQ = 0x40; /* Keep high */
141
142static const unsigned int rxConfRxEna = 0x80; /* Receive Enable */
143static const unsigned int rxConfMAC = 0x20; /* MAC host receive mode*/
144static const unsigned int rxConfPro = 0x10; /* Promiscuous */
145static const unsigned int rxConfAMP = 0x08; /* Accept Multicast Packets */
146static const unsigned int rxConfBcast = 0x04; /* Accept Broadcast Packets */
147
148static const unsigned int txConfTxEna = 0x80; /* Transmit Enable */
149static const unsigned int txConfMAC = 0x20; /* Host sends MAC mode */
150static const unsigned int txConfEUD = 0x10; /* Enable Uni-Data packets */
151static const unsigned int txConfKey = 0x02; /* Scramble data packets */
152static const unsigned int txConfLoop = 0x01; /* Loopback mode */
153
154/*
155 All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
156 you do not define PCMCIA_DEBUG at all, all the debug code will be
157 left out. If you compile with PCMCIA_DEBUG=0, the debug code will
158 be present but disabled -- but it can then be enabled for specific
159 modules at load time with a 'pc_debug=#' option to insmod.
160*/
161
162#ifdef PCMCIA_DEBUG
163static int pc_debug = PCMCIA_DEBUG;
164module_param(pc_debug, int, 0);
165#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
166static char *version =
167"netwave_cs.c 0.3.0 Thu Jul 17 14:36:02 1997 (John Markus Bjørndalen)\n";
168#else
169#define DEBUG(n, args...)
170#endif
171
172static dev_info_t dev_info = "netwave_cs";
173
174/*====================================================================*/
175
176/* Parameters that can be set with 'insmod' */
177
178/* Choose the domain, default is 0x100 */
179static u_int domain = 0x100;
180
181/* Scramble key, range from 0x0 to 0xffff.
182 * 0x0 is no scrambling.
183 */
184static u_int scramble_key = 0x0;
185
186/* Shared memory speed, in ns. The documentation states that
187 * the card should not be read faster than every 400ns.
188 * This timing should be provided by the HBA. If it becomes a
189 * problem, try setting mem_speed to 400.
190 */
191static int mem_speed;
192
193module_param(domain, int, 0);
194module_param(scramble_key, int, 0);
195module_param(mem_speed, int, 0);
196
197/*====================================================================*/
198
199/* PCMCIA (Card Services) related functions */
200static void netwave_release(dev_link_t *link); /* Card removal */
201static int netwave_event(event_t event, int priority,
202 event_callback_args_t *args);
203static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card
204 insertion */
205static dev_link_t *netwave_attach(void); /* Create instance */
206static void netwave_detach(dev_link_t *); /* Destroy instance */
207
208/* Hardware configuration */
209static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase);
210static void netwave_reset(struct net_device *dev);
211
212/* Misc device stuff */
213static int netwave_open(struct net_device *dev); /* Open the device */
214static int netwave_close(struct net_device *dev); /* Close the device */
215
216/* Packet transmission and Packet reception */
217static int netwave_start_xmit( struct sk_buff *skb, struct net_device *dev);
218static int netwave_rx( struct net_device *dev);
219
220/* Interrupt routines */
221static irqreturn_t netwave_interrupt(int irq, void *dev_id, struct pt_regs *regs);
222static void netwave_watchdog(struct net_device *);
223
224/* Statistics */
225static void update_stats(struct net_device *dev);
226static struct net_device_stats *netwave_get_stats(struct net_device *dev);
227
228/* Wireless extensions */
229#ifdef WIRELESS_EXT
230static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
231#endif
232static int netwave_ioctl(struct net_device *, struct ifreq *, int);
233
234static void set_multicast_list(struct net_device *dev);
235
236/*
237 A linked list of "instances" of the skeleton device. Each actual
238 PCMCIA card corresponds to one device instance, and is described
239 by one dev_link_t structure (defined in ds.h).
240
241 You may not want to use a linked list for this -- for example, the
242 memory card driver uses an array of dev_link_t pointers, where minor
243 device numbers are used to derive the corresponding array index.
244*/
245static dev_link_t *dev_list;
246
247/*
248 A dev_link_t structure has fields for most things that are needed
249 to keep track of a socket, but there will usually be some device
250 specific information that also needs to be kept track of. The
251 'priv' pointer in a dev_link_t structure can be used to point to
252 a device-specific private data structure, like this.
253
254 A driver needs to provide a dev_node_t structure for each device
255 on a card. In some cases, there is only one device per card (for
256 example, ethernet cards, modems). In other cases, there may be
257 many actual or logical devices (SCSI adapters, memory cards with
258 multiple partitions). The dev_node_t structures need to be kept
259 in a linked list starting at the 'dev' field of a dev_link_t
260 structure. We allocate them in the card's private data structure,
261 because they generally can't be allocated dynamically.
262*/
263
264#if WIRELESS_EXT <= 12
265/* Wireless extensions backward compatibility */
266
267/* Part of iw_handler prototype we need */
268struct iw_request_info
269{
270 __u16 cmd; /* Wireless Extension command */
271 __u16 flags; /* More to come ;-) */
272};
273
274/* Wireless Extension Backward compatibility - Jean II
275 * If the new wireless device private ioctl range is not defined,
276 * default to standard device private ioctl range */
277#ifndef SIOCIWFIRSTPRIV
278#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
279#endif /* SIOCIWFIRSTPRIV */
280
281#else /* WIRELESS_EXT <= 12 */
282static const struct iw_handler_def netwave_handler_def;
283#endif /* WIRELESS_EXT <= 12 */
284
285#define SIOCGIPSNAP SIOCIWFIRSTPRIV + 1 /* Site Survey Snapshot */
286
287#define MAX_ESA 10
288
289typedef struct net_addr {
290 u_char addr48[6];
291} net_addr;
292
293struct site_survey {
294 u_short length;
295 u_char struct_revision;
296 u_char roaming_state;
297
298 u_char sp_existsFlag;
299 u_char sp_link_quality;
300 u_char sp_max_link_quality;
301 u_char linkQualityGoodFairBoundary;
302 u_char linkQualityFairPoorBoundary;
303 u_char sp_utilization;
304 u_char sp_goodness;
305 u_char sp_hotheadcount;
306 u_char roaming_condition;
307
308 net_addr sp;
309 u_char numAPs;
310 net_addr nearByAccessPoints[MAX_ESA];
311};
312
313typedef struct netwave_private {
314 dev_link_t link;
315 spinlock_t spinlock; /* Serialize access to the hardware (SMP) */
316 dev_node_t node;
317 u_char __iomem *ramBase;
318 int timeoutCounter;
319 int lastExec;
320 struct timer_list watchdog; /* To avoid blocking state */
321 struct site_survey nss;
322 struct net_device_stats stats;
323#ifdef WIRELESS_EXT
324 struct iw_statistics iw_stats; /* Wireless stats */
325#endif
326} netwave_private;
327
328#ifdef NETWAVE_STATS
329static struct net_device_stats *netwave_get_stats(struct net_device *dev);
330#endif
331
332/*
333 * The Netwave card is little-endian, so won't work for big endian
334 * systems.
335 */
336static inline unsigned short get_uint16(u_char __iomem *staddr)
337{
338 return readw(staddr); /* Return only 16 bits */
339}
340
341static inline short get_int16(u_char __iomem * staddr)
342{
343 return readw(staddr);
344}
345
346/*
347 * Wait until the WOC (Write Operation Complete) bit in the
348 * ASR (Adapter Status Register) is asserted.
349 * This should have aborted if it takes too long time.
350 */
351static inline void wait_WOC(unsigned int iobase)
352{
353 /* Spin lock */
354 while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ;
355}
356
357#ifdef WIRELESS_EXT
358static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase,
359 kio_addr_t iobase) {
360 u_short resultBuffer;
361
362 /* if time since last snapshot is > 1 sec. (100 jiffies?) then take
363 * new snapshot, else return cached data. This is the recommended rate.
364 */
365 if ( jiffies - priv->lastExec > 100) {
366 /* Take site survey snapshot */
367 /*printk( KERN_DEBUG "Taking new snapshot. %ld\n", jiffies -
368 priv->lastExec); */
369 wait_WOC(iobase);
370 writeb(NETWAVE_CMD_SSS, ramBase + NETWAVE_EREG_CB + 0);
371 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
372 wait_WOC(iobase);
373
374 /* Get result and copy to cach */
375 resultBuffer = readw(ramBase + NETWAVE_EREG_CRBP);
376 copy_from_pc( &priv->nss, ramBase+resultBuffer,
377 sizeof(struct site_survey));
378 }
379}
380#endif
381
382#ifdef WIRELESS_EXT
383/*
384 * Function netwave_get_wireless_stats (dev)
385 *
386 * Wireless extensions statistics
387 *
388 */
389static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)
390{
391 unsigned long flags;
392 kio_addr_t iobase = dev->base_addr;
393 netwave_private *priv = netdev_priv(dev);
394 u_char __iomem *ramBase = priv->ramBase;
395 struct iw_statistics* wstats;
396
397 wstats = &priv->iw_stats;
398
399 spin_lock_irqsave(&priv->spinlock, flags);
400
401 netwave_snapshot( priv, ramBase, iobase);
402
403 wstats->status = priv->nss.roaming_state;
404 wstats->qual.qual = readb( ramBase + NETWAVE_EREG_SPCQ);
405 wstats->qual.level = readb( ramBase + NETWAVE_EREG_ISPLQ);
406 wstats->qual.noise = readb( ramBase + NETWAVE_EREG_SPU) & 0x3f;
407 wstats->discard.nwid = 0L;
408 wstats->discard.code = 0L;
409 wstats->discard.misc = 0L;
410
411 spin_unlock_irqrestore(&priv->spinlock, flags);
412
413 return &priv->iw_stats;
414}
415#endif
416
417/*
418 * Function netwave_attach (void)
419 *
420 * Creates an "instance" of the driver, allocating local data
421 * structures for one device. The device is registered with Card
422 * Services.
423 *
424 * The dev_link structure is initialized, but we don't actually
425 * configure the card at this point -- we wait until we receive a
426 * card insertion event.
427 */
428static dev_link_t *netwave_attach(void)
429{
430 client_reg_t client_reg;
431 dev_link_t *link;
432 struct net_device *dev;
433 netwave_private *priv;
434 int ret;
435
436 DEBUG(0, "netwave_attach()\n");
437
438 /* Initialize the dev_link_t structure */
439 dev = alloc_etherdev(sizeof(netwave_private));
440 if (!dev)
441 return NULL;
442 priv = netdev_priv(dev);
443 link = &priv->link;
444 link->priv = dev;
445
446 /* The io structure describes IO port mapping */
447 link->io.NumPorts1 = 16;
448 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
449 /* link->io.NumPorts2 = 16;
450 link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; */
451 link->io.IOAddrLines = 5;
452
453 /* Interrupt setup */
454 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
455 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
456 link->irq.Handler = &netwave_interrupt;
457
458 /* General socket configuration */
459 link->conf.Attributes = CONF_ENABLE_IRQ;
460 link->conf.Vcc = 50;
461 link->conf.IntType = INT_MEMORY_AND_IO;
462 link->conf.ConfigIndex = 1;
463 link->conf.Present = PRESENT_OPTION;
464
465 /* Netwave private struct init. link/dev/node already taken care of,
466 * other stuff zero'd - Jean II */
467 spin_lock_init(&priv->spinlock);
468
469 /* Netwave specific entries in the device structure */
470 SET_MODULE_OWNER(dev);
471 dev->hard_start_xmit = &netwave_start_xmit;
472 dev->get_stats = &netwave_get_stats;
473 dev->set_multicast_list = &set_multicast_list;
474 /* wireless extensions */
475#ifdef WIRELESS_EXT
476 dev->get_wireless_stats = &netwave_get_wireless_stats;
477#if WIRELESS_EXT > 12
478 dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def;
479#endif /* WIRELESS_EXT > 12 */
480#endif /* WIRELESS_EXT */
481 dev->do_ioctl = &netwave_ioctl;
482
483 dev->tx_timeout = &netwave_watchdog;
484 dev->watchdog_timeo = TX_TIMEOUT;
485
486 dev->open = &netwave_open;
487 dev->stop = &netwave_close;
488 link->irq.Instance = dev;
489
490 /* Register with Card Services */
491 link->next = dev_list;
492 dev_list = link;
493 client_reg.dev_info = &dev_info;
494 client_reg.EventMask =
495 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
496 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
497 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
498 client_reg.event_handler = &netwave_event;
499 client_reg.Version = 0x0210;
500 client_reg.event_callback_args.client_data = link;
501 ret = pcmcia_register_client(&link->handle, &client_reg);
502 if (ret != 0) {
503 cs_error(link->handle, RegisterClient, ret);
504 netwave_detach(link);
505 return NULL;
506 }
507
508 return link;
509} /* netwave_attach */
510
511/*
512 * Function netwave_detach (link)
513 *
514 * This deletes a driver "instance". The device is de-registered
515 * with Card Services. If it has been released, all local data
516 * structures are freed. Otherwise, the structures will be freed
517 * when the device is released.
518 */
519static void netwave_detach(dev_link_t *link)
520{
521 struct net_device *dev = link->priv;
522 dev_link_t **linkp;
523
524 DEBUG(0, "netwave_detach(0x%p)\n", link);
525
526 /*
527 If the device is currently configured and active, we won't
528 actually delete it yet. Instead, it is marked so that when
529 the release() function is called, that will trigger a proper
530 detach().
531 */
532 if (link->state & DEV_CONFIG)
533 netwave_release(link);
534
535 /* Break the link with Card Services */
536 if (link->handle)
537 pcmcia_deregister_client(link->handle);
538
539 /* Locate device structure */
540 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
541 if (*linkp == link) break;
542 if (*linkp == NULL)
543 {
544 DEBUG(1, "netwave_cs: detach fail, '%s' not in list\n",
545 link->dev->dev_name);
546 return;
547 }
548
549 /* Unlink device structure, free pieces */
550 *linkp = link->next;
551 if (link->dev)
552 unregister_netdev(dev);
553 free_netdev(dev);
554
555} /* netwave_detach */
556
557/*
558 * Wireless Handler : get protocol name
559 */
560static int netwave_get_name(struct net_device *dev,
561 struct iw_request_info *info,
562 union iwreq_data *wrqu,
563 char *extra)
564{
565 strcpy(wrqu->name, "Netwave");
566 return 0;
567}
568
569/*
570 * Wireless Handler : set Network ID
571 */
572static int netwave_set_nwid(struct net_device *dev,
573 struct iw_request_info *info,
574 union iwreq_data *wrqu,
575 char *extra)
576{
577 unsigned long flags;
578 kio_addr_t iobase = dev->base_addr;
579 netwave_private *priv = netdev_priv(dev);
580 u_char __iomem *ramBase = priv->ramBase;
581
582 /* Disable interrupts & save flags */
583 spin_lock_irqsave(&priv->spinlock, flags);
584
585#if WIRELESS_EXT > 8
586 if(!wrqu->nwid.disabled) {
587 domain = wrqu->nwid.value;
588#else /* WIRELESS_EXT > 8 */
589 if(wrqu->nwid.on) {
590 domain = wrqu->nwid.nwid;
591#endif /* WIRELESS_EXT > 8 */
592 printk( KERN_DEBUG "Setting domain to 0x%x%02x\n",
593 (domain >> 8) & 0x01, domain & 0xff);
594 wait_WOC(iobase);
595 writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
596 writeb( domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
597 writeb((domain >>8 ) & 0x01,ramBase + NETWAVE_EREG_CB+2);
598 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
599 }
600
601 /* ReEnable interrupts & restore flags */
602 spin_unlock_irqrestore(&priv->spinlock, flags);
603
604 return 0;
605}
606
607/*
608 * Wireless Handler : get Network ID
609 */
610static int netwave_get_nwid(struct net_device *dev,
611 struct iw_request_info *info,
612 union iwreq_data *wrqu,
613 char *extra)
614{
615#if WIRELESS_EXT > 8
616 wrqu->nwid.value = domain;
617 wrqu->nwid.disabled = 0;
618 wrqu->nwid.fixed = 1;
619#else /* WIRELESS_EXT > 8 */
620 wrqu->nwid.nwid = domain;
621 wrqu->nwid.on = 1;
622#endif /* WIRELESS_EXT > 8 */
623
624 return 0;
625}
626
627/*
628 * Wireless Handler : set scramble key
629 */
630static int netwave_set_scramble(struct net_device *dev,
631 struct iw_request_info *info,
632 union iwreq_data *wrqu,
633 char *key)
634{
635 unsigned long flags;
636 kio_addr_t iobase = dev->base_addr;
637 netwave_private *priv = netdev_priv(dev);
638 u_char __iomem *ramBase = priv->ramBase;
639
640 /* Disable interrupts & save flags */
641 spin_lock_irqsave(&priv->spinlock, flags);
642
643 scramble_key = (key[0] << 8) | key[1];
644 wait_WOC(iobase);
645 writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
646 writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
647 writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
648 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
649
650 /* ReEnable interrupts & restore flags */
651 spin_unlock_irqrestore(&priv->spinlock, flags);
652
653 return 0;
654}
655
656/*
657 * Wireless Handler : get scramble key
658 */
659static int netwave_get_scramble(struct net_device *dev,
660 struct iw_request_info *info,
661 union iwreq_data *wrqu,
662 char *key)
663{
664 key[1] = scramble_key & 0xff;
665 key[0] = (scramble_key>>8) & 0xff;
666#if WIRELESS_EXT > 8
667 wrqu->encoding.flags = IW_ENCODE_ENABLED;
668 wrqu->encoding.length = 2;
669#else /* WIRELESS_EXT > 8 */
670 wrqu->encoding.method = 1;
671#endif /* WIRELESS_EXT > 8 */
672
673 return 0;
674}
675
676#if WIRELESS_EXT > 8
677/*
678 * Wireless Handler : get mode
679 */
680static int netwave_get_mode(struct net_device *dev,
681 struct iw_request_info *info,
682 union iwreq_data *wrqu,
683 char *extra)
684{
685 if(domain & 0x100)
686 wrqu->mode = IW_MODE_INFRA;
687 else
688 wrqu->mode = IW_MODE_ADHOC;
689
690 return 0;
691}
692#endif /* WIRELESS_EXT > 8 */
693
694/*
695 * Wireless Handler : get range info
696 */
697static int netwave_get_range(struct net_device *dev,
698 struct iw_request_info *info,
699 union iwreq_data *wrqu,
700 char *extra)
701{
702 struct iw_range *range = (struct iw_range *) extra;
703 int ret = 0;
704
705 /* Set the length (very important for backward compatibility) */
706 wrqu->data.length = sizeof(struct iw_range);
707
708 /* Set all the info we don't care or don't know about to zero */
709 memset(range, 0, sizeof(struct iw_range));
710
711#if WIRELESS_EXT > 10
712 /* Set the Wireless Extension versions */
713 range->we_version_compiled = WIRELESS_EXT;
714 range->we_version_source = 9; /* Nothing for us in v10 and v11 */
715#endif /* WIRELESS_EXT > 10 */
716
717 /* Set information in the range struct */
718 range->throughput = 450 * 1000; /* don't argue on this ! */
719 range->min_nwid = 0x0000;
720 range->max_nwid = 0x01FF;
721
722 range->num_channels = range->num_frequency = 0;
723
724 range->sensitivity = 0x3F;
725 range->max_qual.qual = 255;
726 range->max_qual.level = 255;
727 range->max_qual.noise = 0;
728
729#if WIRELESS_EXT > 7
730 range->num_bitrates = 1;
731 range->bitrate[0] = 1000000; /* 1 Mb/s */
732#endif /* WIRELESS_EXT > 7 */
733
734#if WIRELESS_EXT > 8
735 range->encoding_size[0] = 2; /* 16 bits scrambling */
736 range->num_encoding_sizes = 1;
737 range->max_encoding_tokens = 1; /* Only one key possible */
738#endif /* WIRELESS_EXT > 8 */
739
740 return ret;
741}
742
743/*
744 * Wireless Private Handler : get snapshot
745 */
746static int netwave_get_snap(struct net_device *dev,
747 struct iw_request_info *info,
748 union iwreq_data *wrqu,
749 char *extra)
750{
751 unsigned long flags;
752 kio_addr_t iobase = dev->base_addr;
753 netwave_private *priv = netdev_priv(dev);
754 u_char __iomem *ramBase = priv->ramBase;
755
756 /* Disable interrupts & save flags */
757 spin_lock_irqsave(&priv->spinlock, flags);
758
759 /* Take snapshot of environment */
760 netwave_snapshot( priv, ramBase, iobase);
761 wrqu->data.length = priv->nss.length;
762 memcpy(extra, (u_char *) &priv->nss, sizeof( struct site_survey));
763
764 priv->lastExec = jiffies;
765
766 /* ReEnable interrupts & restore flags */
767 spin_unlock_irqrestore(&priv->spinlock, flags);
768
769 return(0);
770}
771
772/*
773 * Structures to export the Wireless Handlers
774 * This is the stuff that are treated the wireless extensions (iwconfig)
775 */
776
777static const struct iw_priv_args netwave_private_args[] = {
778/*{ cmd, set_args, get_args, name } */
779 { SIOCGIPSNAP, 0,
780 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof(struct site_survey),
781 "getsitesurvey" },
782};
783
784#if WIRELESS_EXT > 12
785
786static const iw_handler netwave_handler[] =
787{
788 NULL, /* SIOCSIWNAME */
789 netwave_get_name, /* SIOCGIWNAME */
790 netwave_set_nwid, /* SIOCSIWNWID */
791 netwave_get_nwid, /* SIOCGIWNWID */
792 NULL, /* SIOCSIWFREQ */
793 NULL, /* SIOCGIWFREQ */
794 NULL, /* SIOCSIWMODE */
795 netwave_get_mode, /* SIOCGIWMODE */
796 NULL, /* SIOCSIWSENS */
797 NULL, /* SIOCGIWSENS */
798 NULL, /* SIOCSIWRANGE */
799 netwave_get_range, /* SIOCGIWRANGE */
800 NULL, /* SIOCSIWPRIV */
801 NULL, /* SIOCGIWPRIV */
802 NULL, /* SIOCSIWSTATS */
803 NULL, /* SIOCGIWSTATS */
804 NULL, /* SIOCSIWSPY */
805 NULL, /* SIOCGIWSPY */
806 NULL, /* -- hole -- */
807 NULL, /* -- hole -- */
808 NULL, /* SIOCSIWAP */
809 NULL, /* SIOCGIWAP */
810 NULL, /* -- hole -- */
811 NULL, /* SIOCGIWAPLIST */
812 NULL, /* -- hole -- */
813 NULL, /* -- hole -- */
814 NULL, /* SIOCSIWESSID */
815 NULL, /* SIOCGIWESSID */
816 NULL, /* SIOCSIWNICKN */
817 NULL, /* SIOCGIWNICKN */
818 NULL, /* -- hole -- */
819 NULL, /* -- hole -- */
820 NULL, /* SIOCSIWRATE */
821 NULL, /* SIOCGIWRATE */
822 NULL, /* SIOCSIWRTS */
823 NULL, /* SIOCGIWRTS */
824 NULL, /* SIOCSIWFRAG */
825 NULL, /* SIOCGIWFRAG */
826 NULL, /* SIOCSIWTXPOW */
827 NULL, /* SIOCGIWTXPOW */
828 NULL, /* SIOCSIWRETRY */
829 NULL, /* SIOCGIWRETRY */
830 netwave_set_scramble, /* SIOCSIWENCODE */
831 netwave_get_scramble, /* SIOCGIWENCODE */
832};
833
834static const iw_handler netwave_private_handler[] =
835{
836 NULL, /* SIOCIWFIRSTPRIV */
837 netwave_get_snap, /* SIOCIWFIRSTPRIV + 1 */
838};
839
840static const struct iw_handler_def netwave_handler_def =
841{
842 .num_standard = sizeof(netwave_handler)/sizeof(iw_handler),
843 .num_private = sizeof(netwave_private_handler)/sizeof(iw_handler),
844 .num_private_args = sizeof(netwave_private_args)/sizeof(struct iw_priv_args),
845 .standard = (iw_handler *) netwave_handler,
846 .private = (iw_handler *) netwave_private_handler,
847 .private_args = (struct iw_priv_args *) netwave_private_args,
848};
849#endif /* WIRELESS_EXT > 12 */
850
851/*
852 * Function netwave_ioctl (dev, rq, cmd)
853 *
854 * Perform ioctl : config & info stuff
855 * This is the stuff that are treated the wireless extensions (iwconfig)
856 *
857 */
858static int netwave_ioctl(struct net_device *dev, /* ioctl device */
859 struct ifreq *rq, /* Data passed */
860 int cmd) /* Ioctl number */
861{
862 int ret = 0;
863#ifdef WIRELESS_EXT
864#if WIRELESS_EXT <= 12
865 struct iwreq *wrq = (struct iwreq *) rq;
866#endif
867#endif
868
869 DEBUG(0, "%s: ->netwave_ioctl(cmd=0x%X)\n", dev->name, cmd);
870
871 /* Look what is the request */
872 switch(cmd) {
873 /* --------------- WIRELESS EXTENSIONS --------------- */
874#ifdef WIRELESS_EXT
875#if WIRELESS_EXT <= 12
876 case SIOCGIWNAME:
877 netwave_get_name(dev, NULL, &(wrq->u), NULL);
878 break;
879 case SIOCSIWNWID:
880 ret = netwave_set_nwid(dev, NULL, &(wrq->u), NULL);
881 break;
882 case SIOCGIWNWID:
883 ret = netwave_get_nwid(dev, NULL, &(wrq->u), NULL);
884 break;
885#if WIRELESS_EXT > 8 /* Note : The API did change... */
886 case SIOCGIWENCODE:
887 /* Get scramble key */
888 if(wrq->u.encoding.pointer != (caddr_t) 0)
889 {
890 char key[2];
891 ret = netwave_get_scramble(dev, NULL, &(wrq->u), key);
892 if(copy_to_user(wrq->u.encoding.pointer, key, 2))
893 ret = -EFAULT;
894 }
895 break;
896 case SIOCSIWENCODE:
897 /* Set scramble key */
898 if(wrq->u.encoding.pointer != (caddr_t) 0)
899 {
900 char key[2];
901 if(copy_from_user(key, wrq->u.encoding.pointer, 2))
902 {
903 ret = -EFAULT;
904 break;
905 }
906 ret = netwave_set_scramble(dev, NULL, &(wrq->u), key);
907 }
908 break;
909 case SIOCGIWMODE:
910 /* Mode of operation */
911 ret = netwave_get_mode(dev, NULL, &(wrq->u), NULL);
912 break;
913#else /* WIRELESS_EXT > 8 */
914 case SIOCGIWENCODE:
915 /* Get scramble key */
916 ret = netwave_get_scramble(dev, NULL, &(wrq->u),
917 (char *) &wrq->u.encoding.code);
918 break;
919 case SIOCSIWENCODE:
920 /* Set scramble key */
921 ret = netwave_set_scramble(dev, NULL, &(wrq->u),
922 (char *) &wrq->u.encoding.code);
923 break;
924#endif /* WIRELESS_EXT > 8 */
925 case SIOCGIWRANGE:
926 /* Basic checking... */
927 if(wrq->u.data.pointer != (caddr_t) 0) {
928 struct iw_range range;
929 ret = netwave_get_range(dev, NULL, &(wrq->u), (char *) &range);
930 if (copy_to_user(wrq->u.data.pointer, &range,
931 sizeof(struct iw_range)))
932 ret = -EFAULT;
933 }
934 break;
935 case SIOCGIWPRIV:
936 /* Basic checking... */
937 if(wrq->u.data.pointer != (caddr_t) 0) {
938 /* Set the number of ioctl available */
939 wrq->u.data.length = sizeof(netwave_private_args) / sizeof(netwave_private_args[0]);
940
941 /* Copy structure to the user buffer */
942 if(copy_to_user(wrq->u.data.pointer,
943 (u_char *) netwave_private_args,
944 sizeof(netwave_private_args)))
945 ret = -EFAULT;
946 }
947 break;
948 case SIOCGIPSNAP:
949 if(wrq->u.data.pointer != (caddr_t) 0) {
950 char buffer[sizeof( struct site_survey)];
951 ret = netwave_get_snap(dev, NULL, &(wrq->u), buffer);
952 /* Copy structure to the user buffer */
953 if(copy_to_user(wrq->u.data.pointer,
954 buffer,
955 sizeof( struct site_survey)))
956 {
957 printk(KERN_DEBUG "Bad buffer!\n");
958 break;
959 }
960 }
961 break;
962#endif /* WIRELESS_EXT <= 12 */
963#endif /* WIRELESS_EXT */
964 default:
965 ret = -EOPNOTSUPP;
966 }
967
968 return ret;
969}
970
971/*
972 * Function netwave_pcmcia_config (link)
973 *
974 * netwave_pcmcia_config() is scheduled to run after a CARD_INSERTION
975 * event is received, to configure the PCMCIA socket, and to make the
976 * device available to the system.
977 *
978 */
979
980#define CS_CHECK(fn, ret) \
981do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
982
983static void netwave_pcmcia_config(dev_link_t *link) {
984 client_handle_t handle = link->handle;
985 struct net_device *dev = link->priv;
986 netwave_private *priv = netdev_priv(dev);
987 tuple_t tuple;
988 cisparse_t parse;
989 int i, j, last_ret, last_fn;
990 u_char buf[64];
991 win_req_t req;
992 memreq_t mem;
993 u_char __iomem *ramBase = NULL;
994
995 DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link);
996
997 /*
998 This reads the card's CONFIG tuple to find its configuration
999 registers.
1000 */
1001 tuple.Attributes = 0;
1002 tuple.TupleData = (cisdata_t *) buf;
1003 tuple.TupleDataMax = 64;
1004 tuple.TupleOffset = 0;
1005 tuple.DesiredTuple = CISTPL_CONFIG;
1006 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1007 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
1008 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
1009 link->conf.ConfigBase = parse.config.base;
1010 link->conf.Present = parse.config.rmask[0];
1011
1012 /* Configure card */
1013 link->state |= DEV_CONFIG;
1014
1015 /*
1016 * Try allocating IO ports. This tries a few fixed addresses.
1017 * If you want, you can also read the card's config table to
1018 * pick addresses -- see the serial driver for an example.
1019 */
1020 for (i = j = 0x0; j < 0x400; j += 0x20) {
1021 link->io.BasePort1 = j ^ 0x300;
1022 i = pcmcia_request_io(link->handle, &link->io);
1023 if (i == CS_SUCCESS) break;
1024 }
1025 if (i != CS_SUCCESS) {
1026 cs_error(link->handle, RequestIO, i);
1027 goto failed;
1028 }
1029
1030 /*
1031 * Now allocate an interrupt line. Note that this does not
1032 * actually assign a handler to the interrupt.
1033 */
1034 CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
1035
1036 /*
1037 * This actually configures the PCMCIA socket -- setting up
1038 * the I/O windows and the interrupt mapping.
1039 */
1040 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
1041
1042 /*
1043 * Allocate a 32K memory window. Note that the dev_link_t
1044 * structure provides space for one window handle -- if your
1045 * device needs several windows, you'll need to keep track of
1046 * the handles in your private data structure, dev->priv.
1047 */
1048 DEBUG(1, "Setting mem speed of %d\n", mem_speed);
1049
1050 req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
1051 req.Base = 0; req.Size = 0x8000;
1052 req.AccessSpeed = mem_speed;
1053 CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
1054 mem.CardOffset = 0x20000; mem.Page = 0;
1055 CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
1056
1057 /* Store base address of the common window frame */
1058 ramBase = ioremap(req.Base, 0x8000);
1059 priv->ramBase = ramBase;
1060
1061 dev->irq = link->irq.AssignedIRQ;
1062 dev->base_addr = link->io.BasePort1;
1063 SET_NETDEV_DEV(dev, &handle_to_dev(handle));
1064
1065 if (register_netdev(dev) != 0) {
1066 printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
1067 goto failed;
1068 }
1069
1070 strcpy(priv->node.dev_name, dev->name);
1071 link->dev = &priv->node;
1072 link->state &= ~DEV_CONFIG_PENDING;
1073
1074 /* Reset card before reading physical address */
1075 netwave_doreset(dev->base_addr, ramBase);
1076
1077 /* Read the ethernet address and fill in the Netwave registers. */
1078 for (i = 0; i < 6; i++)
1079 dev->dev_addr[i] = readb(ramBase + NETWAVE_EREG_PA + i);
1080
1081 printk(KERN_INFO "%s: Netwave: port %#3lx, irq %d, mem %lx id "
1082 "%c%c, hw_addr ", dev->name, dev->base_addr, dev->irq,
1083 (u_long) ramBase, (int) readb(ramBase+NETWAVE_EREG_NI),
1084 (int) readb(ramBase+NETWAVE_EREG_NI+1));
1085 for (i = 0; i < 6; i++)
1086 printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
1087
1088 /* get revision words */
1089 printk(KERN_DEBUG "Netwave_reset: revision %04x %04x\n",
1090 get_uint16(ramBase + NETWAVE_EREG_ARW),
1091 get_uint16(ramBase + NETWAVE_EREG_ARW+2));
1092 return;
1093
1094cs_failed:
1095 cs_error(link->handle, last_fn, last_ret);
1096failed:
1097 netwave_release(link);
1098} /* netwave_pcmcia_config */
1099
1100/*
1101 * Function netwave_release (arg)
1102 *
1103 * After a card is removed, netwave_release() will unregister the net
1104 * device, and release the PCMCIA configuration. If the device is
1105 * still open, this will be postponed until it is closed.
1106 */
1107static void netwave_release(dev_link_t *link)
1108{
1109 struct net_device *dev = link->priv;
1110 netwave_private *priv = netdev_priv(dev);
1111
1112 DEBUG(0, "netwave_release(0x%p)\n", link);
1113
1114 /* Don't bother checking to see if these succeed or not */
1115 if (link->win) {
1116 iounmap(priv->ramBase);
1117 pcmcia_release_window(link->win);
1118 }
1119 pcmcia_release_configuration(link->handle);
1120 pcmcia_release_io(link->handle, &link->io);
1121 pcmcia_release_irq(link->handle, &link->irq);
1122
1123 link->state &= ~DEV_CONFIG;
1124}
1125
1126/*
1127 * Function netwave_event (event, priority, args)
1128 *
1129 * The card status event handler. Mostly, this schedules other
1130 * stuff to run after an event is received. A CARD_REMOVAL event
1131 * also sets some flags to discourage the net drivers from trying
1132 * to talk to the card any more.
1133 *
1134 * When a CARD_REMOVAL event is received, we immediately set a flag
1135 * to block future accesses to this device. All the functions that
1136 * actually access the device should check this flag to make sure
1137 * the card is still present.
1138 *
1139 */
1140static int netwave_event(event_t event, int priority,
1141 event_callback_args_t *args)
1142{
1143 dev_link_t *link = args->client_data;
1144 struct net_device *dev = link->priv;
1145
1146 DEBUG(1, "netwave_event(0x%06x)\n", event);
1147
1148 switch (event) {
1149 case CS_EVENT_REGISTRATION_COMPLETE:
1150 DEBUG(0, "netwave_cs: registration complete\n");
1151 break;
1152
1153 case CS_EVENT_CARD_REMOVAL:
1154 link->state &= ~DEV_PRESENT;
1155 if (link->state & DEV_CONFIG) {
1156 netif_device_detach(dev);
1157 netwave_release(link);
1158 }
1159 break;
1160 case CS_EVENT_CARD_INSERTION:
1161 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1162 netwave_pcmcia_config( link);
1163 break;
1164 case CS_EVENT_PM_SUSPEND:
1165 link->state |= DEV_SUSPEND;
1166 /* Fall through... */
1167 case CS_EVENT_RESET_PHYSICAL:
1168 if (link->state & DEV_CONFIG) {
1169 if (link->open)
1170 netif_device_detach(dev);
1171 pcmcia_release_configuration(link->handle);
1172 }
1173 break;
1174 case CS_EVENT_PM_RESUME:
1175 link->state &= ~DEV_SUSPEND;
1176 /* Fall through... */
1177 case CS_EVENT_CARD_RESET:
1178 if (link->state & DEV_CONFIG) {
1179 pcmcia_request_configuration(link->handle, &link->conf);
1180 if (link->open) {
1181 netwave_reset(dev);
1182 netif_device_attach(dev);
1183 }
1184 }
1185 break;
1186 }
1187 return 0;
1188} /* netwave_event */
1189
1190/*
1191 * Function netwave_doreset (ioBase, ramBase)
1192 *
1193 * Proper hardware reset of the card.
1194 */
1195static void netwave_doreset(kio_addr_t ioBase, u_char __iomem *ramBase)
1196{
1197 /* Reset card */
1198 wait_WOC(ioBase);
1199 outb(0x80, ioBase + NETWAVE_REG_PMR);
1200 writeb(0x08, ramBase + NETWAVE_EREG_ASCC); /* Bit 3 is WOC */
1201 outb(0x0, ioBase + NETWAVE_REG_PMR); /* release reset */
1202}
1203
1204/*
1205 * Function netwave_reset (dev)
1206 *
1207 * Reset and restore all of the netwave registers
1208 */
1209static void netwave_reset(struct net_device *dev) {
1210 /* u_char state; */
1211 netwave_private *priv = netdev_priv(dev);
1212 u_char __iomem *ramBase = priv->ramBase;
1213 kio_addr_t iobase = dev->base_addr;
1214
1215 DEBUG(0, "netwave_reset: Done with hardware reset\n");
1216
1217 priv->timeoutCounter = 0;
1218
1219 /* Reset card */
1220 netwave_doreset(iobase, ramBase);
1221 printk(KERN_DEBUG "netwave_reset: Done with hardware reset\n");
1222
1223 /* Write a NOP to check the card */
1224 wait_WOC(iobase);
1225 writeb(NETWAVE_CMD_NOP, ramBase + NETWAVE_EREG_CB + 0);
1226 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
1227
1228 /* Set receive conf */
1229 wait_WOC(iobase);
1230 writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
1231 writeb(rxConfRxEna + rxConfBcast, ramBase + NETWAVE_EREG_CB + 1);
1232 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
1233
1234 /* Set transmit conf */
1235 wait_WOC(iobase);
1236 writeb(NETWAVE_CMD_STC, ramBase + NETWAVE_EREG_CB + 0);
1237 writeb(txConfTxEna, ramBase + NETWAVE_EREG_CB + 1);
1238 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
1239
1240 /* Now set the MU Domain */
1241 printk(KERN_DEBUG "Setting domain to 0x%x%02x\n", (domain >> 8) & 0x01, domain & 0xff);
1242 wait_WOC(iobase);
1243 writeb(NETWAVE_CMD_SMD, ramBase + NETWAVE_EREG_CB + 0);
1244 writeb(domain & 0xff, ramBase + NETWAVE_EREG_CB + 1);
1245 writeb((domain>>8) & 0x01, ramBase + NETWAVE_EREG_CB + 2);
1246 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
1247
1248 /* Set scramble key */
1249 printk(KERN_DEBUG "Setting scramble key to 0x%x\n", scramble_key);
1250 wait_WOC(iobase);
1251 writeb(NETWAVE_CMD_SSK, ramBase + NETWAVE_EREG_CB + 0);
1252 writeb(scramble_key & 0xff, ramBase + NETWAVE_EREG_CB + 1);
1253 writeb((scramble_key>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
1254 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
1255
1256 /* Enable interrupts, bit 4 high to keep unused
1257 * source from interrupting us, bit 2 high to
1258 * set interrupt enable, 567 to enable TxDN,
1259 * RxErr and RxRdy
1260 */
1261 wait_WOC(iobase);
1262 outb(imrConfIENA+imrConfRFU1, iobase + NETWAVE_REG_IMR);
1263
1264 /* Hent 4 bytes fra 0x170. Skal vaere 0a,29,88,36
1265 * waitWOC
1266 * skriv 80 til d000:3688
1267 * sjekk om det ble 80
1268 */
1269
1270 /* Enable Receiver */
1271 wait_WOC(iobase);
1272 writeb(NETWAVE_CMD_ER, ramBase + NETWAVE_EREG_CB + 0);
1273 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
1274
1275 /* Set the IENA bit in COR */
1276 wait_WOC(iobase);
1277 outb(corConfIENA + corConfLVLREQ, iobase + NETWAVE_REG_COR);
1278}
1279
1280/*
1281 * Function netwave_hw_xmit (data, len, dev)
1282 */
1283static int netwave_hw_xmit(unsigned char* data, int len,
1284 struct net_device* dev) {
1285 unsigned long flags;
1286 unsigned int TxFreeList,
1287 curBuff,
1288 MaxData,
1289 DataOffset;
1290 int tmpcount;
1291
1292 netwave_private *priv = netdev_priv(dev);
1293 u_char __iomem * ramBase = priv->ramBase;
1294 kio_addr_t iobase = dev->base_addr;
1295
1296 /* Disable interrupts & save flags */
1297 spin_lock_irqsave(&priv->spinlock, flags);
1298
1299 /* Check if there are transmit buffers available */
1300 wait_WOC(iobase);
1301 if ((inb(iobase+NETWAVE_REG_ASR) & NETWAVE_ASR_TXBA) == 0) {
1302 /* No buffers available */
1303 printk(KERN_DEBUG "netwave_hw_xmit: %s - no xmit buffers available.\n",
1304 dev->name);
1305 spin_unlock_irqrestore(&priv->spinlock, flags);
1306 return 1;
1307 }
1308
1309 priv->stats.tx_bytes += len;
1310
1311 DEBUG(3, "Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
1312 readb(ramBase + NETWAVE_EREG_SPCQ),
1313 readb(ramBase + NETWAVE_EREG_SPU),
1314 readb(ramBase + NETWAVE_EREG_LIF),
1315 readb(ramBase + NETWAVE_EREG_ISPLQ));
1316
1317 /* Now try to insert it into the adapters free memory */
1318 wait_WOC(iobase);
1319 TxFreeList = get_uint16(ramBase + NETWAVE_EREG_TDP);
1320 MaxData = get_uint16(ramBase + NETWAVE_EREG_TDP+2);
1321 DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4);
1322
1323 DEBUG(3, "TxFreeList %x, MaxData %x, DataOffset %x\n",
1324 TxFreeList, MaxData, DataOffset);
1325
1326 /* Copy packet to the adapter fragment buffers */
1327 curBuff = TxFreeList;
1328 tmpcount = 0;
1329 while (tmpcount < len) {
1330 int tmplen = len - tmpcount;
1331 copy_to_pc(ramBase + curBuff + DataOffset, data + tmpcount,
1332 (tmplen < MaxData) ? tmplen : MaxData);
1333 tmpcount += MaxData;
1334
1335 /* Advance to next buffer */
1336 curBuff = get_uint16(ramBase + curBuff);
1337 }
1338
1339 /* Now issue transmit list */
1340 wait_WOC(iobase);
1341 writeb(NETWAVE_CMD_TL, ramBase + NETWAVE_EREG_CB + 0);
1342 writeb(len & 0xff, ramBase + NETWAVE_EREG_CB + 1);
1343 writeb((len>>8) & 0xff, ramBase + NETWAVE_EREG_CB + 2);
1344 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 3);
1345
1346 spin_unlock_irqrestore(&priv->spinlock, flags);
1347 return 0;
1348}
1349
1350static int netwave_start_xmit(struct sk_buff *skb, struct net_device *dev) {
1351 /* This flag indicate that the hardware can't perform a transmission.
1352 * Theoritically, NET3 check it before sending a packet to the driver,
1353 * but in fact it never do that and pool continuously.
1354 * As the watchdog will abort too long transmissions, we are quite safe...
1355 */
1356
1357 netif_stop_queue(dev);
1358
1359 {
1360 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1361 unsigned char* buf = skb->data;
1362
1363 if (netwave_hw_xmit( buf, length, dev) == 1) {
1364 /* Some error, let's make them call us another time? */
1365 netif_start_queue(dev);
1366 }
1367 dev->trans_start = jiffies;
1368 }
1369 dev_kfree_skb(skb);
1370
1371 return 0;
1372} /* netwave_start_xmit */
1373
1374/*
1375 * Function netwave_interrupt (irq, dev_id, regs)
1376 *
1377 * This function is the interrupt handler for the Netwave card. This
1378 * routine will be called whenever:
1379 * 1. A packet is received.
1380 * 2. A packet has successfully been transferred and the unit is
1381 * ready to transmit another packet.
1382 * 3. A command has completed execution.
1383 */
1384static irqreturn_t netwave_interrupt(int irq, void* dev_id, struct pt_regs *regs)
1385{
1386 kio_addr_t iobase;
1387 u_char __iomem *ramBase;
1388 struct net_device *dev = (struct net_device *)dev_id;
1389 struct netwave_private *priv = netdev_priv(dev);
1390 dev_link_t *link = &priv->link;
1391 int i;
1392
1393 if (!netif_device_present(dev))
1394 return IRQ_NONE;
1395
1396 iobase = dev->base_addr;
1397 ramBase = priv->ramBase;
1398
1399 /* Now find what caused the interrupt, check while interrupts ready */
1400 for (i = 0; i < 10; i++) {
1401 u_char status;
1402
1403 wait_WOC(iobase);
1404 if (!(inb(iobase+NETWAVE_REG_CCSR) & 0x02))
1405 break; /* None of the interrupt sources asserted (normal exit) */
1406
1407 status = inb(iobase + NETWAVE_REG_ASR);
1408
1409 if (!DEV_OK(link)) {
1410 DEBUG(1, "netwave_interrupt: Interrupt with status 0x%x "
1411 "from removed or suspended card!\n", status);
1412 break;
1413 }
1414
1415 /* RxRdy */
1416 if (status & 0x80) {
1417 netwave_rx(dev);
1418 /* wait_WOC(iobase); */
1419 /* RxRdy cannot be reset directly by the host */
1420 }
1421 /* RxErr */
1422 if (status & 0x40) {
1423 u_char rser;
1424
1425 rser = readb(ramBase + NETWAVE_EREG_RSER);
1426
1427 if (rser & 0x04) {
1428 ++priv->stats.rx_dropped;
1429 ++priv->stats.rx_crc_errors;
1430 }
1431 if (rser & 0x02)
1432 ++priv->stats.rx_frame_errors;
1433
1434 /* Clear the RxErr bit in RSER. RSER+4 is the
1435 * write part. Also clear the RxCRC (0x04) and
1436 * RxBig (0x02) bits if present */
1437 wait_WOC(iobase);
1438 writeb(0x40 | (rser & 0x06), ramBase + NETWAVE_EREG_RSER + 4);
1439
1440 /* Write bit 6 high to ASCC to clear RxErr in ASR,
1441 * WOC must be set first!
1442 */
1443 wait_WOC(iobase);
1444 writeb(0x40, ramBase + NETWAVE_EREG_ASCC);
1445
1446 /* Remember to count up priv->stats on error packets */
1447 ++priv->stats.rx_errors;
1448 }
1449 /* TxDN */
1450 if (status & 0x20) {
1451 int txStatus;
1452
1453 txStatus = readb(ramBase + NETWAVE_EREG_TSER);
1454 DEBUG(3, "Transmit done. TSER = %x id %x\n",
1455 txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1));
1456
1457 if (txStatus & 0x20) {
1458 /* Transmitting was okay, clear bits */
1459 wait_WOC(iobase);
1460 writeb(0x2f, ramBase + NETWAVE_EREG_TSER + 4);
1461 ++priv->stats.tx_packets;
1462 }
1463
1464 if (txStatus & 0xd0) {
1465 if (txStatus & 0x80) {
1466 ++priv->stats.collisions; /* Because of /proc/net/dev*/
1467 /* ++priv->stats.tx_aborted_errors; */
1468 /* printk("Collision. %ld\n", jiffies - dev->trans_start); */
1469 }
1470 if (txStatus & 0x40)
1471 ++priv->stats.tx_carrier_errors;
1472 /* 0x80 TxGU Transmit giveup - nine times and no luck
1473 * 0x40 TxNOAP No access point. Discarded packet.
1474 * 0x10 TxErr Transmit error. Always set when
1475 * TxGU and TxNOAP is set. (Those are the only ones
1476 * to set TxErr).
1477 */
1478 DEBUG(3, "netwave_interrupt: TxDN with error status %x\n",
1479 txStatus);
1480
1481 /* Clear out TxGU, TxNOAP, TxErr and TxTrys */
1482 wait_WOC(iobase);
1483 writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
1484 ++priv->stats.tx_errors;
1485 }
1486 DEBUG(3, "New status is TSER %x ASR %x\n",
1487 readb(ramBase + NETWAVE_EREG_TSER),
1488 inb(iobase + NETWAVE_REG_ASR));
1489
1490 netif_wake_queue(dev);
1491 }
1492 /* TxBA, this would trigger on all error packets received */
1493 /* if (status & 0x01) {
1494 DEBUG(4, "Transmit buffers available, %x\n", status);
1495 }
1496 */
1497 }
1498 /* Handled if we looped at least one time - Jean II */
1499 return IRQ_RETVAL(i);
1500} /* netwave_interrupt */
1501
1502/*
1503 * Function netwave_watchdog (a)
1504 *
1505 * Watchdog : when we start a transmission, we set a timer in the
1506 * kernel. If the transmission complete, this timer is disabled. If
1507 * it expire, we reset the card.
1508 *
1509 */
1510static void netwave_watchdog(struct net_device *dev) {
1511
1512 DEBUG(1, "%s: netwave_watchdog: watchdog timer expired\n", dev->name);
1513 netwave_reset(dev);
1514 dev->trans_start = jiffies;
1515 netif_wake_queue(dev);
1516} /* netwave_watchdog */
1517
1518static struct net_device_stats *netwave_get_stats(struct net_device *dev) {
1519 netwave_private *priv = netdev_priv(dev);
1520
1521 update_stats(dev);
1522
1523 DEBUG(2, "netwave: SPCQ %x SPU %x LIF %x ISPLQ %x MHS %x rxtx %x"
1524 " %x tx %x %x %x %x\n",
1525 readb(priv->ramBase + NETWAVE_EREG_SPCQ),
1526 readb(priv->ramBase + NETWAVE_EREG_SPU),
1527 readb(priv->ramBase + NETWAVE_EREG_LIF),
1528 readb(priv->ramBase + NETWAVE_EREG_ISPLQ),
1529 readb(priv->ramBase + NETWAVE_EREG_MHS),
1530 readb(priv->ramBase + NETWAVE_EREG_EC + 0xe),
1531 readb(priv->ramBase + NETWAVE_EREG_EC + 0xf),
1532 readb(priv->ramBase + NETWAVE_EREG_EC + 0x18),
1533 readb(priv->ramBase + NETWAVE_EREG_EC + 0x19),
1534 readb(priv->ramBase + NETWAVE_EREG_EC + 0x1a),
1535 readb(priv->ramBase + NETWAVE_EREG_EC + 0x1b));
1536
1537 return &priv->stats;
1538}
1539
1540static void update_stats(struct net_device *dev) {
1541 //unsigned long flags;
1542/* netwave_private *priv = netdev_priv(dev); */
1543
1544 //spin_lock_irqsave(&priv->spinlock, flags);
1545
1546/* priv->stats.rx_packets = readb(priv->ramBase + 0x18e);
1547 priv->stats.tx_packets = readb(priv->ramBase + 0x18f); */
1548
1549 //spin_unlock_irqrestore(&priv->spinlock, flags);
1550}
1551
1552static int netwave_rx(struct net_device *dev)
1553{
1554 netwave_private *priv = netdev_priv(dev);
1555 u_char __iomem *ramBase = priv->ramBase;
1556 kio_addr_t iobase = dev->base_addr;
1557 u_char rxStatus;
1558 struct sk_buff *skb = NULL;
1559 unsigned int curBuffer,
1560 rcvList;
1561 int rcvLen;
1562 int tmpcount = 0;
1563 int dataCount, dataOffset;
1564 int i;
1565 u_char *ptr;
1566
1567 DEBUG(3, "xinw_rx: Receiving ... \n");
1568
1569 /* Receive max 10 packets for now. */
1570 for (i = 0; i < 10; i++) {
1571 /* Any packets? */
1572 wait_WOC(iobase);
1573 rxStatus = readb(ramBase + NETWAVE_EREG_RSER);
1574 if ( !( rxStatus & 0x80)) /* No more packets */
1575 break;
1576
1577 /* Check if multicast/broadcast or other */
1578 /* multicast = (rxStatus & 0x20); */
1579
1580 /* The receive list pointer and length of the packet */
1581 wait_WOC(iobase);
1582 rcvLen = get_int16( ramBase + NETWAVE_EREG_RDP);
1583 rcvList = get_uint16( ramBase + NETWAVE_EREG_RDP + 2);
1584
1585 if (rcvLen < 0) {
1586 printk(KERN_DEBUG "netwave_rx: Receive packet with len %d\n",
1587 rcvLen);
1588 return 0;
1589 }
1590
1591 skb = dev_alloc_skb(rcvLen+5);
1592 if (skb == NULL) {
1593 DEBUG(1, "netwave_rx: Could not allocate an sk_buff of "
1594 "length %d\n", rcvLen);
1595 ++priv->stats.rx_dropped;
1596 /* Tell the adapter to skip the packet */
1597 wait_WOC(iobase);
1598 writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
1599 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
1600 return 0;
1601 }
1602
1603 skb_reserve( skb, 2); /* Align IP on 16 byte */
1604 skb_put( skb, rcvLen);
1605 skb->dev = dev;
1606
1607 /* Copy packet fragments to the skb data area */
1608 ptr = (u_char*) skb->data;
1609 curBuffer = rcvList;
1610 tmpcount = 0;
1611 while ( tmpcount < rcvLen) {
1612 /* Get length and offset of current buffer */
1613 dataCount = get_uint16( ramBase+curBuffer+2);
1614 dataOffset = get_uint16( ramBase+curBuffer+4);
1615
1616 copy_from_pc( ptr + tmpcount,
1617 ramBase+curBuffer+dataOffset, dataCount);
1618
1619 tmpcount += dataCount;
1620
1621 /* Point to next buffer */
1622 curBuffer = get_uint16(ramBase + curBuffer);
1623 }
1624
1625 skb->protocol = eth_type_trans(skb,dev);
1626 /* Queue packet for network layer */
1627 netif_rx(skb);
1628
1629 dev->last_rx = jiffies;
1630 priv->stats.rx_packets++;
1631 priv->stats.rx_bytes += rcvLen;
1632
1633 /* Got the packet, tell the adapter to skip it */
1634 wait_WOC(iobase);
1635 writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
1636 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
1637 DEBUG(3, "Packet reception ok\n");
1638 }
1639 return 0;
1640}
1641
1642static int netwave_open(struct net_device *dev) {
1643 netwave_private *priv = netdev_priv(dev);
1644 dev_link_t *link = &priv->link;
1645
1646 DEBUG(1, "netwave_open: starting.\n");
1647
1648 if (!DEV_OK(link))
1649 return -ENODEV;
1650
1651 link->open++;
1652
1653 netif_start_queue(dev);
1654 netwave_reset(dev);
1655
1656 return 0;
1657}
1658
1659static int netwave_close(struct net_device *dev) {
1660 netwave_private *priv = netdev_priv(dev);
1661 dev_link_t *link = &priv->link;
1662
1663 DEBUG(1, "netwave_close: finishing.\n");
1664
1665 link->open--;
1666 netif_stop_queue(dev);
1667
1668 return 0;
1669}
1670
1671static struct pcmcia_driver netwave_driver = {
1672 .owner = THIS_MODULE,
1673 .drv = {
1674 .name = "netwave_cs",
1675 },
1676 .attach = netwave_attach,
1677 .detach = netwave_detach,
1678};
1679
1680static int __init init_netwave_cs(void)
1681{
1682 return pcmcia_register_driver(&netwave_driver);
1683}
1684
1685static void __exit exit_netwave_cs(void)
1686{
1687 pcmcia_unregister_driver(&netwave_driver);
1688 BUG_ON(dev_list != NULL);
1689}
1690
1691module_init(init_netwave_cs);
1692module_exit(exit_netwave_cs);
1693
1694/* Set or clear the multicast filter for this adaptor.
1695 num_addrs == -1 Promiscuous mode, receive all packets
1696 num_addrs == 0 Normal mode, clear multicast list
1697 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
1698 best-effort filtering.
1699 */
1700static void set_multicast_list(struct net_device *dev)
1701{
1702 kio_addr_t iobase = dev->base_addr;
1703 netwave_private *priv = netdev_priv(dev);
1704 u_char __iomem * ramBase = priv->ramBase;
1705 u_char rcvMode = 0;
1706
1707#ifdef PCMCIA_DEBUG
1708 if (pc_debug > 2) {
1709 static int old;
1710 if (old != dev->mc_count) {
1711 old = dev->mc_count;
1712 DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
1713 dev->name, dev->mc_count);
1714 }
1715 }
1716#endif
1717
1718 if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) {
1719 /* Multicast Mode */
1720 rcvMode = rxConfRxEna + rxConfAMP + rxConfBcast;
1721 } else if (dev->flags & IFF_PROMISC) {
1722 /* Promiscous mode */
1723 rcvMode = rxConfRxEna + rxConfPro + rxConfAMP + rxConfBcast;
1724 } else {
1725 /* Normal mode */
1726 rcvMode = rxConfRxEna + rxConfBcast;
1727 }
1728
1729 /* printk("netwave set_multicast_list: rcvMode to %x\n", rcvMode);*/
1730 /* Now set receive mode */
1731 wait_WOC(iobase);
1732 writeb(NETWAVE_CMD_SRC, ramBase + NETWAVE_EREG_CB + 0);
1733 writeb(rcvMode, ramBase + NETWAVE_EREG_CB + 1);
1734 writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 2);
1735}
1736MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
new file mode 100644
index 000000000000..a3a32430ae9d
--- /dev/null
+++ b/drivers/net/wireless/orinoco.c
@@ -0,0 +1,4243 @@
1/* orinoco.c - (formerly known as dldwd_cs.c and orinoco_cs.c)
2 *
3 * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
4 * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
5 *
6 * Current maintainers (as of 29 September 2003) are:
7 * Pavel Roskin <proski AT gnu.org>
8 * and David Gibson <hermes AT gibson.dropbear.id.au>
9 *
10 * (C) Copyright David Gibson, IBM Corporation 2001-2003.
11 * Copyright (C) 2000 David Gibson, Linuxcare Australia.
12 * With some help from :
13 * Copyright (C) 2001 Jean Tourrilhes, HP Labs
14 * Copyright (C) 2001 Benjamin Herrenschmidt
15 *
16 * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
17 *
18 * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy
19 * AT fasta.fh-dortmund.de>
20 * http://www.stud.fh-dortmund.de/~andy/wvlan/
21 *
22 * The contents of this file are subject to the Mozilla Public License
23 * Version 1.1 (the "License"); you may not use this file except in
24 * compliance with the License. You may obtain a copy of the License
25 * at http://www.mozilla.org/MPL/
26 *
27 * Software distributed under the License is distributed on an "AS IS"
28 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
29 * the License for the specific language governing rights and
30 * limitations under the License.
31 *
32 * The initial developer of the original code is David A. Hinds
33 * <dahinds AT users.sourceforge.net>. Portions created by David
34 * A. Hinds are Copyright (C) 1999 David A. Hinds. All Rights
35 * Reserved.
36 *
37 * Alternatively, the contents of this file may be used under the
38 * terms of the GNU General Public License version 2 (the "GPL"), in
39 * which case the provisions of the GPL are applicable instead of the
40 * above. If you wish to allow the use of your version of this file
41 * only under the terms of the GPL and not to allow others to use your
42 * version of this file under the MPL, indicate your decision by
43 * deleting the provisions above and replace them with the notice and
44 * other provisions required by the GPL. If you do not delete the
45 * provisions above, a recipient may use your version of this file
46 * under either the MPL or the GPL. */
47
48/*
49 * v0.01 -> v0.02 - 21/3/2001 - Jean II
50 * o Allow to use regular ethX device name instead of dldwdX
51 * o Warning on IBSS with ESSID=any for firmware 6.06
52 * o Put proper range.throughput values (optimistic)
53 * o IWSPY support (IOCTL and stat gather in Rx path)
54 * o Allow setting frequency in Ad-Hoc mode
55 * o Disable WEP setting if !has_wep to work on old firmware
56 * o Fix txpower range
57 * o Start adding support for Samsung/Compaq firmware
58 *
59 * v0.02 -> v0.03 - 23/3/2001 - Jean II
60 * o Start adding Symbol support - need to check all that
61 * o Fix Prism2/Symbol WEP to accept 128 bits keys
62 * o Add Symbol WEP (add authentication type)
63 * o Add Prism2/Symbol rate
64 * o Add PM timeout (holdover duration)
65 * o Enable "iwconfig eth0 key off" and friends (toggle flags)
66 * o Enable "iwconfig eth0 power unicast/all" (toggle flags)
67 * o Try with an Intel card. It report firmware 1.01, behave like
68 * an antiquated firmware, however on windows it says 2.00. Yuck !
69 * o Workaround firmware bug in allocate buffer (Intel 1.01)
70 * o Finish external renaming to orinoco...
71 * o Testing with various Wavelan firmwares
72 *
73 * v0.03 -> v0.04 - 30/3/2001 - Jean II
74 * o Update to Wireless 11 -> add retry limit/lifetime support
75 * o Tested with a D-Link DWL 650 card, fill in firmware support
76 * o Warning on Vcc mismatch (D-Link 3.3v card in Lucent 5v only slot)
77 * o Fixed the Prism2 WEP bugs that I introduced in v0.03 :-(
78 * It works on D-Link *only* after a tcpdump. Weird...
79 * And still doesn't work on Intel card. Grrrr...
80 * o Update the mode after a setport3
81 * o Add preamble setting for Symbol cards (not yet enabled)
82 * o Don't complain as much about Symbol cards...
83 *
84 * v0.04 -> v0.04b - 22/4/2001 - David Gibson
85 * o Removed the 'eth' parameter - always use ethXX as the
86 * interface name instead of dldwdXX. The other was racy
87 * anyway.
88 * o Clean up RID definitions in hermes.h, other cleanups
89 *
90 * v0.04b -> v0.04c - 24/4/2001 - Jean II
91 * o Tim Hurley <timster AT seiki.bliztech.com> reported a D-Link card
92 * with vendor 02 and firmware 0.08. Added in the capabilities...
93 * o Tested Lucent firmware 7.28, everything works...
94 *
95 * v0.04c -> v0.05 - 3/5/2001 - Benjamin Herrenschmidt
96 * o Spin-off Pcmcia code. This file is renamed orinoco.c,
97 * and orinoco_cs.c now contains only the Pcmcia specific stuff
98 * o Add Airport driver support on top of orinoco.c (see airport.c)
99 *
100 * v0.05 -> v0.05a - 4/5/2001 - Jean II
101 * o Revert to old Pcmcia code to fix breakage of Ben's changes...
102 *
103 * v0.05a -> v0.05b - 4/5/2001 - Jean II
104 * o add module parameter 'ignore_cis_vcc' for D-Link @ 5V
105 * o D-Link firmware doesn't support multicast. We just print a few
106 * error messages, but otherwise everything works...
107 * o For David : set/getport3 works fine, just upgrade iwpriv...
108 *
109 * v0.05b -> v0.05c - 5/5/2001 - Benjamin Herrenschmidt
110 * o Adapt airport.c to latest changes in orinoco.c
111 * o Remove deferred power enabling code
112 *
113 * v0.05c -> v0.05d - 5/5/2001 - Jean II
114 * o Workaround to SNAP decapsulate frame from Linksys AP
115 * original patch from : Dong Liu <dliu AT research.bell-labs.com>
116 * (note : the memcmp bug was mine - fixed)
117 * o Remove set_retry stuff, no firmware support it (bloat--).
118 *
119 * v0.05d -> v0.06 - 25/5/2001 - Jean II
120 * Original patch from "Hong Lin" <alin AT redhat.com>,
121 * "Ian Kinner" <ikinner AT redhat.com>
122 * and "David Smith" <dsmith AT redhat.com>
123 * o Init of priv->tx_rate_ctrl in firmware specific section.
124 * o Prism2/Symbol rate, upto should be 0xF and not 0x15. Doh !
125 * o Spectrum card always need cor_reset (for every reset)
126 * o Fix cor_reset to not lose bit 7 in the register
127 * o flush_stale_links to remove zombie Pcmcia instances
128 * o Ack previous hermes event before reset
129 * Me (with my little hands)
130 * o Allow orinoco.c to call cor_reset via priv->card_reset_handler
131 * o Add priv->need_card_reset to toggle this feature
132 * o Fix various buglets when setting WEP in Symbol firmware
133 * Now, encryption is fully functional on Symbol cards. Youpi !
134 *
135 * v0.06 -> v0.06b - 25/5/2001 - Jean II
136 * o IBSS on Symbol use port_mode = 4. Please don't ask...
137 *
138 * v0.06b -> v0.06c - 29/5/2001 - Jean II
139 * o Show first spy address in /proc/net/wireless for IBSS mode as well
140 *
141 * v0.06c -> v0.06d - 6/7/2001 - David Gibson
142 * o Change a bunch of KERN_INFO messages to KERN_DEBUG, as per Linus'
143 * wishes to reduce the number of unnecessary messages.
144 * o Removed bogus message on CRC error.
145 * o Merged fixes for v0.08 Prism 2 firmware from William Waghorn
146 * <willwaghorn AT yahoo.co.uk>
147 * o Slight cleanup/re-arrangement of firmware detection code.
148 *
149 * v0.06d -> v0.06e - 1/8/2001 - David Gibson
150 * o Removed some redundant global initializers (orinoco_cs.c).
151 * o Added some module metadata
152 *
153 * v0.06e -> v0.06f - 14/8/2001 - David Gibson
154 * o Wording fix to license
155 * o Added a 'use_alternate_encaps' module parameter for APs which need an
156 * oui of 00:00:00. We really need a better way of handling this, but
157 * the module flag is better than nothing for now.
158 *
159 * v0.06f -> v0.07 - 20/8/2001 - David Gibson
160 * o Removed BAP error retries from hermes_bap_seek(). For Tx we now
161 * let the upper layers handle the retry, we retry explicitly in the
162 * Rx path, but don't make as much noise about it.
163 * o Firmware detection cleanups.
164 *
165 * v0.07 -> v0.07a - 1/10/3001 - Jean II
166 * o Add code to read Symbol firmware revision, inspired by latest code
167 * in Spectrum24 by Lee John Keyser-Allen - Thanks Lee !
168 * o Thanks to Jared Valentine <hidden AT xmission.com> for "providing" me
169 * a 3Com card with a recent firmware, fill out Symbol firmware
170 * capabilities of latest rev (2.20), as well as older Symbol cards.
171 * o Disable Power Management in newer Symbol firmware, the API
172 * has changed (documentation needed).
173 *
174 * v0.07a -> v0.08 - 3/10/2001 - David Gibson
175 * o Fixed a possible buffer overrun found by the Stanford checker (in
176 * dldwd_ioctl_setiwencode()). Can only be called by root anyway, so not
177 * a big problem.
178 * o Turned has_big_wep on for Intersil cards. That's not true for all of
179 * them but we should at least let the capable ones try.
180 * o Wait for BUSY to clear at the beginning of hermes_bap_seek(). I
181 * realized that my assumption that the driver's serialization
182 * would prevent the BAP being busy on entry was possibly false, because
183 * things other than seeks may make the BAP busy.
184 * o Use "alternate" (oui 00:00:00) encapsulation by default.
185 * Setting use_old_encaps will mimic the old behaviour, but I think we
186 * will be able to eliminate this.
187 * o Don't try to make __initdata const (the version string). This can't
188 * work because of the way the __initdata sectioning works.
189 * o Added MODULE_LICENSE tags.
190 * o Support for PLX (transparent PCMCIA->PCI bridge) cards.
191 * o Changed to using the new type-fascist min/max.
192 *
193 * v0.08 -> v0.08a - 9/10/2001 - David Gibson
194 * o Inserted some missing acknowledgements/info into the Changelog.
195 * o Fixed some bugs in the normalization of signal level reporting.
196 * o Fixed bad bug in WEP key handling on Intersil and Symbol firmware,
197 * which led to an instant crash on big-endian machines.
198 *
199 * v0.08a -> v0.08b - 20/11/2001 - David Gibson
200 * o Lots of cleanup and bugfixes in orinoco_plx.c
201 * o Cleanup to handling of Tx rate setting.
202 * o Removed support for old encapsulation method.
203 * o Removed old "dldwd" names.
204 * o Split RID constants into a new file hermes_rid.h
205 * o Renamed RID constants to match linux-wlan-ng and prism2.o
206 * o Bugfixes in hermes.c
207 * o Poke the PLX's INTCSR register, so it actually starts
208 * generating interrupts. These cards might actually work now.
209 * o Update to wireless extensions v12 (Jean II)
210 * o Support for tallies and inquire command (Jean II)
211 * o Airport updates for newer PPC kernels (BenH)
212 *
213 * v0.08b -> v0.09 - 21/12/2001 - David Gibson
214 * o Some new PCI IDs for PLX cards.
215 * o Removed broken attempt to do ALLMULTI reception. Just use
216 * promiscuous mode instead
217 * o Preliminary work for list-AP (Jean II)
218 * o Airport updates from (BenH)
219 * o Eliminated racy hw_ready stuff
220 * o Fixed generation of fake events in irq handler. This should
221 * finally kill the EIO problems (Jean II & dgibson)
222 * o Fixed breakage of bitrate set/get on Agere firmware (Jean II)
223 *
224 * v0.09 -> v0.09a - 2/1/2002 - David Gibson
225 * o Fixed stupid mistake in multicast list handling, triggering
226 * a BUG()
227 *
228 * v0.09a -> v0.09b - 16/1/2002 - David Gibson
229 * o Fixed even stupider mistake in new interrupt handling, which
230 * seriously broke things on big-endian machines.
231 * o Removed a bunch of redundant includes and exports.
232 * o Removed a redundant MOD_{INC,DEC}_USE_COUNT pair in airport.c
233 * o Don't attempt to do hardware level multicast reception on
234 * Intersil firmware, just go promisc instead.
235 * o Typo fixed in hermes_issue_cmd()
236 * o Eliminated WIRELESS_SPY #ifdefs
237 * o Status code reported on Tx exceptions
238 * o Moved netif_wake_queue() from ALLOC interrupts to TX and TXEXC
239 * interrupts, which should fix the timeouts we're seeing.
240 *
241 * v0.09b -> v0.10 - 25 Feb 2002 - David Gibson
242 * o Removed nested structures used for header parsing, so the
243 * driver should now work without hackery on ARM
244 * o Fix for WEP handling on Intersil (Hawk Newton)
245 * o Eliminated the /proc/hermes/ethXX/regs debugging file. It
246 * was never very useful.
247 * o Make Rx errors less noisy.
248 *
249 * v0.10 -> v0.11 - 5 Apr 2002 - David Gibson
250 * o Laid the groundwork in hermes.[ch] for devices which map
251 * into PCI memory space rather than IO space.
252 * o Fixed bug in multicast handling (cleared multicast list when
253 * leaving promiscuous mode).
254 * o Relegated Tx error messages to debug.
255 * o Cleaned up / corrected handling of allocation lengths.
256 * o Set OWNSSID in IBSS mode for WinXP interoperability (jimc).
257 * o Change to using alloc_etherdev() for structure allocations.
258 * o Check for and drop undersized packets.
259 * o Fixed a race in stopping/waking the queue. This should fix
260 * the timeout problems (Pavel Roskin)
261 * o Reverted to netif_wake_queue() on the ALLOC event.
262 * o Fixes for recent Symbol firmwares which lack AP density
263 * (Pavel Roskin).
264 *
265 * v0.11 -> v0.11a - 29 Apr 2002 - David Gibson
266 * o Handle different register spacing, necessary for Prism 2.5
267 * PCI adaptors (Steve Hill).
268 * o Cleaned up initialization of card structures in orinoco_cs
269 * and airport. Removed card->priv field.
270 * o Make response structure optional for hermes_docmd_wait()
271 * Pavel Roskin)
272 * o Added PCI id for Nortel emobility to orinoco_plx.c.
273 * o Cleanup to handling of Symbol's allocation bug. (Pavel Roskin)
274 * o Cleanups to firmware capability detection.
275 * o Arrange for orinoco_pci.c to override firmware detection.
276 * We should be able to support the PCI Intersil cards now.
277 * o Cleanup handling of reset_cor and hard_reset (Pavel Roskin).
278 * o Remove erroneous use of USER_BAP in the TxExc handler (Jouni
279 * Malinen).
280 * o Makefile changes for better integration into David Hinds
281 * pcmcia-cs package.
282 *
283 * v0.11a -> v0.11b - 1 May 2002 - David Gibson
284 * o Better error reporting in orinoco_plx_init_one()
285 * o Fixed multiple bad kfree() bugs introduced by the
286 * alloc_orinocodev() changes.
287 *
288 * v0.11b -> v0.12 - 19 Jun 2002 - David Gibson
289 * o Support changing the MAC address.
290 * o Correct display of Intersil firmware revision numbers.
291 * o Entirely revised locking scheme. Should be both simpler and
292 * better.
293 * o Merged some common code in orinoco_plx, orinoco_pci and
294 * airport by creating orinoco_default_{open,stop,reset}()
295 * which are used as the dev->open, dev->stop, priv->reset
296 * callbacks if none are specified when alloc_orinocodev() is
297 * called.
298 * o Removed orinoco_plx_interrupt() and orinoco_pci_interrupt().
299 * They didn't do anything.
300 *
301 * v0.12 -> v0.12a - 4 Jul 2002 - David Gibson
302 * o Some rearrangement of code.
303 * o Numerous fixups to locking and rest handling, particularly
304 * for PCMCIA.
305 * o This allows open and stop net_device methods to be in
306 * orinoco.c now, rather than in the init modules.
307 * o In orinoco_cs.c link->priv now points to the struct
308 * net_device not to the struct orinoco_private.
309 * o Added a check for undersized SNAP frames, which could cause
310 * crashes.
311 *
312 * v0.12a -> v0.12b - 11 Jul 2002 - David Gibson
313 * o Fix hw->num_init testing code, so num_init is actually
314 * incremented.
315 * o Fix very stupid bug in orinoco_cs which broke compile with
316 * CONFIG_SMP.
317 * o Squashed a warning.
318 *
319 * v0.12b -> v0.12c - 26 Jul 2002 - David Gibson
320 * o Change to C9X style designated initializers.
321 * o Add support for 3Com AirConnect PCI.
322 * o No longer ignore the hard_reset argument to
323 * alloc_orinocodev(). Oops.
324 *
325 * v0.12c -> v0.13beta1 - 13 Sep 2002 - David Gibson
326 * o Revert the broken 0.12* locking scheme and go to a new yet
327 * simpler scheme.
328 * o Do firmware resets only in orinoco_init() and when waking
329 * the card from hard sleep.
330 *
331 * v0.13beta1 -> v0.13 - 27 Sep 2002 - David Gibson
332 * o Re-introduced full resets (via schedule_task()) on Tx
333 * timeout.
334 *
335 * v0.13 -> v0.13a - 30 Sep 2002 - David Gibson
336 * o Minor cleanups to info frame handling. Add basic support
337 * for linkstatus info frames.
338 * o Include required kernel headers in orinoco.h, to avoid
339 * compile problems.
340 *
341 * v0.13a -> v0.13b - 10 Feb 2003 - David Gibson
342 * o Implemented hard reset for Airport cards
343 * o Experimental suspend/resume implementation for orinoco_pci
344 * o Abolished /proc debugging support, replaced with a debugging
345 * iwpriv. Now it's ugly and simple instead of ugly and complex.
346 * o Bugfix in hermes.c if the firmware returned a record length
347 * of 0, we could go clobbering memory.
348 * o Bugfix in orinoco_stop() - it used to fail if hw_unavailable
349 * was set, which was usually true on PCMCIA hot removes.
350 * o Track LINKSTATUS messages, silently drop Tx packets before
351 * we are connected (avoids confusing the firmware), and only
352 * give LINKSTATUS printk()s if the status has changed.
353 *
354 * v0.13b -> v0.13c - 11 Mar 2003 - David Gibson
355 * o Cleanup: use dev instead of priv in various places.
356 * o Bug fix: Don't ReleaseConfiguration on RESET_PHYSICAL event
357 * if we're in the middle of a (driver initiated) hard reset.
358 * o Bug fix: ETH_ZLEN is supposed to include the header
359 * (Dionysus Blazakis & Manish Karir)
360 * o Convert to using workqueues instead of taskqueues (and
361 * backwards compatibility macros for pre 2.5.41 kernels).
362 * o Drop redundant (I think...) MOD_{INC,DEC}_USE_COUNT in
363 * airport.c
364 * o New orinoco_tmd.c init module from Joerg Dorchain for
365 * TMD7160 based PCI to PCMCIA bridges (similar to
366 * orinoco_plx.c).
367 *
368 * v0.13c -> v0.13d - 22 Apr 2003 - David Gibson
369 * o Make hw_unavailable a counter, rather than just a flag, this
370 * is necessary to avoid some races (such as a card being
371 * removed in the middle of orinoco_reset().
372 * o Restore Release/RequestConfiguration in the PCMCIA event handler
373 * when dealing with a driver initiated hard reset. This is
374 * necessary to prevent hangs due to a spurious interrupt while
375 * the reset is in progress.
376 * o Clear the 802.11 header when transmitting, even though we
377 * don't use it. This fixes a long standing bug on some
378 * firmwares, which seem to get confused if that isn't done.
379 * o Be less eager to de-encapsulate SNAP frames, only do so if
380 * the OUI is 00:00:00 or 00:00:f8, leave others alone. The old
381 * behaviour broke CDP (Cisco Discovery Protocol).
382 * o Use dev instead of priv for free_irq() as well as
383 * request_irq() (oops).
384 * o Attempt to reset rather than giving up if we get too many
385 * IRQs.
386 * o Changed semantics of __orinoco_down() so it can be called
387 * safely with hw_unavailable set. It also now clears the
388 * linkstatus (since we're going to have to reassociate).
389 *
390 * v0.13d -> v0.13e - 12 May 2003 - David Gibson
391 * o Support for post-2.5.68 return values from irq handler.
392 * o Fixed bug where underlength packets would be double counted
393 * in the rx_dropped statistics.
394 * o Provided a module parameter to suppress linkstatus messages.
395 *
396 * v0.13e -> v0.14alpha1 - 30 Sep 2003 - David Gibson
397 * o Replaced priv->connected logic with netif_carrier_on/off()
398 * calls.
399 * o Remove has_ibss_any and never set the CREATEIBSS RID when
400 * the ESSID is empty. Too many firmwares break if we do.
401 * o 2.6 merges: Replace pdev->slot_name with pci_name(), remove
402 * __devinitdata from PCI ID tables, use free_netdev().
403 * o Enabled shared-key authentication for Agere firmware (from
404 * Robert J. Moore <Robert.J.Moore AT allanbank.com>
405 * o Move netif_wake_queue() (back) to the Tx completion from the
406 * ALLOC event. This seems to prevent/mitigate the rolling
407 * error -110 problems at least on some Intersil firmwares.
408 * Theoretically reduces performance, but I can't measure it.
409 * Patch from Andrew Tridgell <tridge AT samba.org>
410 *
411 * v0.14alpha1 -> v0.14alpha2 - 20 Oct 2003 - David Gibson
412 * o Correctly turn off shared-key authentication when requested
413 * (bugfix from Robert J. Moore).
414 * o Correct airport sleep interfaces for current 2.6 kernels.
415 * o Add code for key change without disabling/enabling the MAC
416 * port. This is supposed to allow 802.1x to work sanely, but
417 * doesn't seem to yet.
418 *
419 * TODO
420 * o New wireless extensions API (patch from Moustafa
421 * Youssef, updated by Jim Carter and Pavel Roskin).
422 * o Handle de-encapsulation within network layer, provide 802.11
423 * headers (patch from Thomas 'Dent' Mirlacher)
424 * o RF monitor mode support
425 * o Fix possible races in SPY handling.
426 * o Disconnect wireless extensions from fundamental configuration.
427 * o (maybe) Software WEP support (patch from Stano Meduna).
428 * o (maybe) Use multiple Tx buffers - driver handling queue
429 * rather than firmware.
430 */
431
432/* Locking and synchronization:
433 *
434 * The basic principle is that everything is serialized through a
435 * single spinlock, priv->lock. The lock is used in user, bh and irq
436 * context, so when taken outside hardirq context it should always be
437 * taken with interrupts disabled. The lock protects both the
438 * hardware and the struct orinoco_private.
439 *
440 * Another flag, priv->hw_unavailable indicates that the hardware is
441 * unavailable for an extended period of time (e.g. suspended, or in
442 * the middle of a hard reset). This flag is protected by the
443 * spinlock. All code which touches the hardware should check the
444 * flag after taking the lock, and if it is set, give up on whatever
445 * they are doing and drop the lock again. The orinoco_lock()
446 * function handles this (it unlocks and returns -EBUSY if
447 * hw_unavailable is non-zero).
448 */
449
450#define DRIVER_NAME "orinoco"
451
452#include <linux/config.h>
453
454#include <linux/module.h>
455#include <linux/kernel.h>
456#include <linux/init.h>
457#include <linux/ptrace.h>
458#include <linux/slab.h>
459#include <linux/string.h>
460#include <linux/timer.h>
461#include <linux/ioport.h>
462#include <linux/netdevice.h>
463#include <linux/if_arp.h>
464#include <linux/etherdevice.h>
465#include <linux/wireless.h>
466
467#include <asm/uaccess.h>
468#include <asm/io.h>
469#include <asm/system.h>
470
471#include "hermes.h"
472#include "hermes_rid.h"
473#include "orinoco.h"
474#include "ieee802_11.h"
475
476/********************************************************************/
477/* Module information */
478/********************************************************************/
479
480MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
481MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
482MODULE_LICENSE("Dual MPL/GPL");
483
484/* Level of debugging. Used in the macros in orinoco.h */
485#ifdef ORINOCO_DEBUG
486int orinoco_debug = ORINOCO_DEBUG;
487module_param(orinoco_debug, int, 0644);
488MODULE_PARM_DESC(orinoco_debug, "Debug level");
489EXPORT_SYMBOL(orinoco_debug);
490#endif
491
492static int suppress_linkstatus; /* = 0 */
493module_param(suppress_linkstatus, bool, 0644);
494MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
495
496/********************************************************************/
497/* Compile time configuration and compatibility stuff */
498/********************************************************************/
499
500/* We do this this way to avoid ifdefs in the actual code */
501#ifdef WIRELESS_SPY
502#define SPY_NUMBER(priv) (priv->spy_number)
503#else
504#define SPY_NUMBER(priv) 0
505#endif /* WIRELESS_SPY */
506
507/********************************************************************/
508/* Internal constants */
509/********************************************************************/
510
511#define ORINOCO_MIN_MTU 256
512#define ORINOCO_MAX_MTU (IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD)
513
514#define SYMBOL_MAX_VER_LEN (14)
515#define USER_BAP 0
516#define IRQ_BAP 1
517#define MAX_IRQLOOPS_PER_IRQ 10
518#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of
519 * how many events the
520 * device could
521 * legitimately generate */
522#define SMALL_KEY_SIZE 5
523#define LARGE_KEY_SIZE 13
524#define TX_NICBUF_SIZE_BUG 1585 /* Bug in Symbol firmware */
525
526#define DUMMY_FID 0xFFFF
527
528/*#define MAX_MULTICAST(priv) (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
529 HERMES_MAX_MULTICAST : 0)*/
530#define MAX_MULTICAST(priv) (HERMES_MAX_MULTICAST)
531
532#define ORINOCO_INTEN (HERMES_EV_RX | HERMES_EV_ALLOC \
533 | HERMES_EV_TX | HERMES_EV_TXEXC \
534 | HERMES_EV_WTERR | HERMES_EV_INFO \
535 | HERMES_EV_INFDROP )
536
537/********************************************************************/
538/* Data tables */
539/********************************************************************/
540
541/* The frequency of each channel in MHz */
542static const long channel_frequency[] = {
543 2412, 2417, 2422, 2427, 2432, 2437, 2442,
544 2447, 2452, 2457, 2462, 2467, 2472, 2484
545};
546#define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
547
548/* This tables gives the actual meanings of the bitrate IDs returned
549 * by the firmware. */
550static struct {
551 int bitrate; /* in 100s of kilobits */
552 int automatic;
553 u16 agere_txratectrl;
554 u16 intersil_txratectrl;
555} bitrate_table[] = {
556 {110, 1, 3, 15}, /* Entry 0 is the default */
557 {10, 0, 1, 1},
558 {10, 1, 1, 1},
559 {20, 0, 2, 2},
560 {20, 1, 6, 3},
561 {55, 0, 4, 4},
562 {55, 1, 7, 7},
563 {110, 0, 5, 8},
564};
565#define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
566
567/********************************************************************/
568/* Data types */
569/********************************************************************/
570
571struct header_struct {
572 /* 802.3 */
573 u8 dest[ETH_ALEN];
574 u8 src[ETH_ALEN];
575 u16 len;
576 /* 802.2 */
577 u8 dsap;
578 u8 ssap;
579 u8 ctrl;
580 /* SNAP */
581 u8 oui[3];
582 u16 ethertype;
583} __attribute__ ((packed));
584
585/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
586u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
587
588#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2)
589
590struct hermes_rx_descriptor {
591 u16 status;
592 u32 time;
593 u8 silence;
594 u8 signal;
595 u8 rate;
596 u8 rxflow;
597 u32 reserved;
598} __attribute__ ((packed));
599
600/********************************************************************/
601/* Function prototypes */
602/********************************************************************/
603
604static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
605static int __orinoco_program_rids(struct net_device *dev);
606static void __orinoco_set_multicast_list(struct net_device *dev);
607static int orinoco_debug_dump_recs(struct net_device *dev);
608
609/********************************************************************/
610/* Internal helper functions */
611/********************************************************************/
612
613static inline void set_port_type(struct orinoco_private *priv)
614{
615 switch (priv->iw_mode) {
616 case IW_MODE_INFRA:
617 priv->port_type = 1;
618 priv->createibss = 0;
619 break;
620 case IW_MODE_ADHOC:
621 if (priv->prefer_port3) {
622 priv->port_type = 3;
623 priv->createibss = 0;
624 } else {
625 priv->port_type = priv->ibss_port;
626 priv->createibss = 1;
627 }
628 break;
629 default:
630 printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
631 priv->ndev->name);
632 }
633}
634
635/********************************************************************/
636/* Device methods */
637/********************************************************************/
638
639static int orinoco_open(struct net_device *dev)
640{
641 struct orinoco_private *priv = netdev_priv(dev);
642 unsigned long flags;
643 int err;
644
645 if (orinoco_lock(priv, &flags) != 0)
646 return -EBUSY;
647
648 err = __orinoco_up(dev);
649
650 if (! err)
651 priv->open = 1;
652
653 orinoco_unlock(priv, &flags);
654
655 return err;
656}
657
658int orinoco_stop(struct net_device *dev)
659{
660 struct orinoco_private *priv = netdev_priv(dev);
661 int err = 0;
662
663 /* We mustn't use orinoco_lock() here, because we need to be
664 able to close the interface even if hw_unavailable is set
665 (e.g. as we're released after a PC Card removal) */
666 spin_lock_irq(&priv->lock);
667
668 priv->open = 0;
669
670 err = __orinoco_down(dev);
671
672 spin_unlock_irq(&priv->lock);
673
674 return err;
675}
676
677static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
678{
679 struct orinoco_private *priv = netdev_priv(dev);
680
681 return &priv->stats;
682}
683
684static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
685{
686 struct orinoco_private *priv = netdev_priv(dev);
687 hermes_t *hw = &priv->hw;
688 struct iw_statistics *wstats = &priv->wstats;
689 int err = 0;
690 unsigned long flags;
691
692 if (! netif_device_present(dev)) {
693 printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
694 dev->name);
695 return NULL; /* FIXME: Can we do better than this? */
696 }
697
698 if (orinoco_lock(priv, &flags) != 0)
699 return NULL; /* FIXME: Erg, we've been signalled, how
700 * do we propagate this back up? */
701
702 if (priv->iw_mode == IW_MODE_ADHOC) {
703 memset(&wstats->qual, 0, sizeof(wstats->qual));
704 /* If a spy address is defined, we report stats of the
705 * first spy address - Jean II */
706 if (SPY_NUMBER(priv)) {
707 wstats->qual.qual = priv->spy_stat[0].qual;
708 wstats->qual.level = priv->spy_stat[0].level;
709 wstats->qual.noise = priv->spy_stat[0].noise;
710 wstats->qual.updated = priv->spy_stat[0].updated;
711 }
712 } else {
713 struct {
714 u16 qual, signal, noise;
715 } __attribute__ ((packed)) cq;
716
717 err = HERMES_READ_RECORD(hw, USER_BAP,
718 HERMES_RID_COMMSQUALITY, &cq);
719
720 wstats->qual.qual = (int)le16_to_cpu(cq.qual);
721 wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
722 wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
723 wstats->qual.updated = 7;
724 }
725
726 /* We can't really wait for the tallies inquiry command to
727 * complete, so we just use the previous results and trigger
728 * a new tallies inquiry command for next time - Jean II */
729 /* FIXME: We're in user context (I think?), so we should just
730 wait for the tallies to come through */
731 err = hermes_inquire(hw, HERMES_INQ_TALLIES);
732
733 orinoco_unlock(priv, &flags);
734
735 if (err)
736 return NULL;
737
738 return wstats;
739}
740
741static void orinoco_set_multicast_list(struct net_device *dev)
742{
743 struct orinoco_private *priv = netdev_priv(dev);
744 unsigned long flags;
745
746 if (orinoco_lock(priv, &flags) != 0) {
747 printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
748 "called when hw_unavailable\n", dev->name);
749 return;
750 }
751
752 __orinoco_set_multicast_list(dev);
753 orinoco_unlock(priv, &flags);
754}
755
756static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
757{
758 struct orinoco_private *priv = netdev_priv(dev);
759
760 if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
761 return -EINVAL;
762
763 if ( (new_mtu + ENCAPS_OVERHEAD + IEEE802_11_HLEN) >
764 (priv->nicbuf_size - ETH_HLEN) )
765 return -EINVAL;
766
767 dev->mtu = new_mtu;
768
769 return 0;
770}
771
772/********************************************************************/
773/* Tx path */
774/********************************************************************/
775
776static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
777{
778 struct orinoco_private *priv = netdev_priv(dev);
779 struct net_device_stats *stats = &priv->stats;
780 hermes_t *hw = &priv->hw;
781 int err = 0;
782 u16 txfid = priv->txfid;
783 char *p;
784 struct ethhdr *eh;
785 int len, data_len, data_off;
786 struct hermes_tx_descriptor desc;
787 unsigned long flags;
788
789 TRACE_ENTER(dev->name);
790
791 if (! netif_running(dev)) {
792 printk(KERN_ERR "%s: Tx on stopped device!\n",
793 dev->name);
794 TRACE_EXIT(dev->name);
795 return 1;
796 }
797
798 if (netif_queue_stopped(dev)) {
799 printk(KERN_DEBUG "%s: Tx while transmitter busy!\n",
800 dev->name);
801 TRACE_EXIT(dev->name);
802 return 1;
803 }
804
805 if (orinoco_lock(priv, &flags) != 0) {
806 printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
807 dev->name);
808 TRACE_EXIT(dev->name);
809 return 1;
810 }
811
812 if (! netif_carrier_ok(dev)) {
813 /* Oops, the firmware hasn't established a connection,
814 silently drop the packet (this seems to be the
815 safest approach). */
816 stats->tx_errors++;
817 orinoco_unlock(priv, &flags);
818 dev_kfree_skb(skb);
819 TRACE_EXIT(dev->name);
820 return 0;
821 }
822
823 /* Length of the packet body */
824 /* FIXME: what if the skb is smaller than this? */
825 len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN - ETH_HLEN);
826
827 eh = (struct ethhdr *)skb->data;
828
829 memset(&desc, 0, sizeof(desc));
830 desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX);
831 err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), txfid, 0);
832 if (err) {
833 if (net_ratelimit())
834 printk(KERN_ERR "%s: Error %d writing Tx descriptor "
835 "to BAP\n", dev->name, err);
836 stats->tx_errors++;
837 goto fail;
838 }
839
840 /* Clear the 802.11 header and data length fields - some
841 * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
842 * if this isn't done. */
843 hermes_clear_words(hw, HERMES_DATA0,
844 HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
845
846 /* Encapsulate Ethernet-II frames */
847 if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
848 struct header_struct hdr;
849 data_len = len;
850 data_off = HERMES_802_3_OFFSET + sizeof(hdr);
851 p = skb->data + ETH_HLEN;
852
853 /* 802.3 header */
854 memcpy(hdr.dest, eh->h_dest, ETH_ALEN);
855 memcpy(hdr.src, eh->h_source, ETH_ALEN);
856 hdr.len = htons(data_len + ENCAPS_OVERHEAD);
857
858 /* 802.2 header */
859 memcpy(&hdr.dsap, &encaps_hdr, sizeof(encaps_hdr));
860
861 hdr.ethertype = eh->h_proto;
862 err = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
863 txfid, HERMES_802_3_OFFSET);
864 if (err) {
865 if (net_ratelimit())
866 printk(KERN_ERR "%s: Error %d writing packet "
867 "header to BAP\n", dev->name, err);
868 stats->tx_errors++;
869 goto fail;
870 }
871 } else { /* IEEE 802.3 frame */
872 data_len = len + ETH_HLEN;
873 data_off = HERMES_802_3_OFFSET;
874 p = skb->data;
875 }
876
877 /* Round up for odd length packets */
878 err = hermes_bap_pwrite(hw, USER_BAP, p, ALIGN(data_len, 2),
879 txfid, data_off);
880 if (err) {
881 printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
882 dev->name, err);
883 stats->tx_errors++;
884 goto fail;
885 }
886
887 /* Finally, we actually initiate the send */
888 netif_stop_queue(dev);
889
890 err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
891 txfid, NULL);
892 if (err) {
893 netif_start_queue(dev);
894 printk(KERN_ERR "%s: Error %d transmitting packet\n",
895 dev->name, err);
896 stats->tx_errors++;
897 goto fail;
898 }
899
900 dev->trans_start = jiffies;
901 stats->tx_bytes += data_off + data_len;
902
903 orinoco_unlock(priv, &flags);
904
905 dev_kfree_skb(skb);
906
907 TRACE_EXIT(dev->name);
908
909 return 0;
910 fail:
911 TRACE_EXIT(dev->name);
912
913 orinoco_unlock(priv, &flags);
914 return err;
915}
916
917static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
918{
919 struct orinoco_private *priv = netdev_priv(dev);
920 u16 fid = hermes_read_regn(hw, ALLOCFID);
921
922 if (fid != priv->txfid) {
923 if (fid != DUMMY_FID)
924 printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
925 dev->name, fid);
926 return;
927 }
928
929 hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
930}
931
932static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
933{
934 struct orinoco_private *priv = netdev_priv(dev);
935 struct net_device_stats *stats = &priv->stats;
936
937 stats->tx_packets++;
938
939 netif_wake_queue(dev);
940
941 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
942}
943
944static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
945{
946 struct orinoco_private *priv = netdev_priv(dev);
947 struct net_device_stats *stats = &priv->stats;
948 u16 fid = hermes_read_regn(hw, TXCOMPLFID);
949 struct hermes_tx_descriptor desc;
950 int err = 0;
951
952 if (fid == DUMMY_FID)
953 return; /* Nothing's really happened */
954
955 err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc), fid, 0);
956 if (err) {
957 printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
958 "(FID=%04X error %d)\n",
959 dev->name, fid, err);
960 } else {
961 DEBUG(1, "%s: Tx error, status %d\n",
962 dev->name, le16_to_cpu(desc.status));
963 }
964
965 stats->tx_errors++;
966
967 netif_wake_queue(dev);
968 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
969}
970
971static void orinoco_tx_timeout(struct net_device *dev)
972{
973 struct orinoco_private *priv = netdev_priv(dev);
974 struct net_device_stats *stats = &priv->stats;
975 struct hermes *hw = &priv->hw;
976
977 printk(KERN_WARNING "%s: Tx timeout! "
978 "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
979 dev->name, hermes_read_regn(hw, ALLOCFID),
980 hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
981
982 stats->tx_errors++;
983
984 schedule_work(&priv->reset_work);
985}
986
987/********************************************************************/
988/* Rx path (data frames) */
989/********************************************************************/
990
991/* Does the frame have a SNAP header indicating it should be
992 * de-encapsulated to Ethernet-II? */
993static inline int is_ethersnap(void *_hdr)
994{
995 u8 *hdr = _hdr;
996
997 /* We de-encapsulate all packets which, a) have SNAP headers
998 * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
999 * and where b) the OUI of the SNAP header is 00:00:00 or
1000 * 00:00:f8 - we need both because different APs appear to use
1001 * different OUIs for some reason */
1002 return (memcmp(hdr, &encaps_hdr, 5) == 0)
1003 && ( (hdr[5] == 0x00) || (hdr[5] == 0xf8) );
1004}
1005
1006static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
1007 int level, int noise)
1008{
1009 struct orinoco_private *priv = netdev_priv(dev);
1010 int i;
1011
1012 /* Gather wireless spy statistics: for each packet, compare the
1013 * source address with out list, and if match, get the stats... */
1014 for (i = 0; i < priv->spy_number; i++)
1015 if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {
1016 priv->spy_stat[i].level = level - 0x95;
1017 priv->spy_stat[i].noise = noise - 0x95;
1018 priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0;
1019 priv->spy_stat[i].updated = 7;
1020 }
1021}
1022
1023static void orinoco_stat_gather(struct net_device *dev,
1024 struct sk_buff *skb,
1025 struct hermes_rx_descriptor *desc)
1026{
1027 struct orinoco_private *priv = netdev_priv(dev);
1028
1029 /* Using spy support with lots of Rx packets, like in an
1030 * infrastructure (AP), will really slow down everything, because
1031 * the MAC address must be compared to each entry of the spy list.
1032 * If the user really asks for it (set some address in the
1033 * spy list), we do it, but he will pay the price.
1034 * Note that to get here, you need both WIRELESS_SPY
1035 * compiled in AND some addresses in the list !!!
1036 */
1037 /* Note : gcc will optimise the whole section away if
1038 * WIRELESS_SPY is not defined... - Jean II */
1039 if (SPY_NUMBER(priv)) {
1040 orinoco_spy_gather(dev, skb->mac.raw + ETH_ALEN,
1041 desc->signal, desc->silence);
1042 }
1043}
1044
1045static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
1046{
1047 struct orinoco_private *priv = netdev_priv(dev);
1048 struct net_device_stats *stats = &priv->stats;
1049 struct iw_statistics *wstats = &priv->wstats;
1050 struct sk_buff *skb = NULL;
1051 u16 rxfid, status;
1052 int length, data_len, data_off;
1053 char *p;
1054 struct hermes_rx_descriptor desc;
1055 struct header_struct hdr;
1056 struct ethhdr *eh;
1057 int err;
1058
1059 rxfid = hermes_read_regn(hw, RXFID);
1060
1061 err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc),
1062 rxfid, 0);
1063 if (err) {
1064 printk(KERN_ERR "%s: error %d reading Rx descriptor. "
1065 "Frame dropped.\n", dev->name, err);
1066 stats->rx_errors++;
1067 goto drop;
1068 }
1069
1070 status = le16_to_cpu(desc.status);
1071
1072 if (status & HERMES_RXSTAT_ERR) {
1073 if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
1074 wstats->discard.code++;
1075 DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
1076 dev->name);
1077 } else {
1078 stats->rx_crc_errors++;
1079 DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", dev->name);
1080 }
1081 stats->rx_errors++;
1082 goto drop;
1083 }
1084
1085 /* For now we ignore the 802.11 header completely, assuming
1086 that the card's firmware has handled anything vital */
1087
1088 err = hermes_bap_pread(hw, IRQ_BAP, &hdr, sizeof(hdr),
1089 rxfid, HERMES_802_3_OFFSET);
1090 if (err) {
1091 printk(KERN_ERR "%s: error %d reading frame header. "
1092 "Frame dropped.\n", dev->name, err);
1093 stats->rx_errors++;
1094 goto drop;
1095 }
1096
1097 length = ntohs(hdr.len);
1098
1099 /* Sanity checks */
1100 if (length < 3) { /* No for even an 802.2 LLC header */
1101 /* At least on Symbol firmware with PCF we get quite a
1102 lot of these legitimately - Poll frames with no
1103 data. */
1104 stats->rx_dropped++;
1105 goto drop;
1106 }
1107 if (length > IEEE802_11_DATA_LEN) {
1108 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
1109 dev->name, length);
1110 stats->rx_length_errors++;
1111 stats->rx_errors++;
1112 goto drop;
1113 }
1114
1115 /* We need space for the packet data itself, plus an ethernet
1116 header, plus 2 bytes so we can align the IP header on a
1117 32bit boundary, plus 1 byte so we can read in odd length
1118 packets from the card, which has an IO granularity of 16
1119 bits */
1120 skb = dev_alloc_skb(length+ETH_HLEN+2+1);
1121 if (!skb) {
1122 printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
1123 dev->name);
1124 goto drop;
1125 }
1126
1127 skb_reserve(skb, 2); /* This way the IP header is aligned */
1128
1129 /* Handle decapsulation
1130 * In most cases, the firmware tell us about SNAP frames.
1131 * For some reason, the SNAP frames sent by LinkSys APs
1132 * are not properly recognised by most firmwares.
1133 * So, check ourselves */
1134 if (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
1135 ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
1136 is_ethersnap(&hdr)) {
1137 /* These indicate a SNAP within 802.2 LLC within
1138 802.11 frame which we'll need to de-encapsulate to
1139 the original EthernetII frame. */
1140
1141 if (length < ENCAPS_OVERHEAD) { /* No room for full LLC+SNAP */
1142 stats->rx_length_errors++;
1143 goto drop;
1144 }
1145
1146 /* Remove SNAP header, reconstruct EthernetII frame */
1147 data_len = length - ENCAPS_OVERHEAD;
1148 data_off = HERMES_802_3_OFFSET + sizeof(hdr);
1149
1150 eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);
1151
1152 memcpy(eh, &hdr, 2 * ETH_ALEN);
1153 eh->h_proto = hdr.ethertype;
1154 } else {
1155 /* All other cases indicate a genuine 802.3 frame. No
1156 decapsulation needed. We just throw the whole
1157 thing in, and hope the protocol layer can deal with
1158 it as 802.3 */
1159 data_len = length;
1160 data_off = HERMES_802_3_OFFSET;
1161 /* FIXME: we re-read from the card data we already read here */
1162 }
1163
1164 p = skb_put(skb, data_len);
1165 err = hermes_bap_pread(hw, IRQ_BAP, p, ALIGN(data_len, 2),
1166 rxfid, data_off);
1167 if (err) {
1168 printk(KERN_ERR "%s: error %d reading frame. "
1169 "Frame dropped.\n", dev->name, err);
1170 stats->rx_errors++;
1171 goto drop;
1172 }
1173
1174 dev->last_rx = jiffies;
1175 skb->dev = dev;
1176 skb->protocol = eth_type_trans(skb, dev);
1177 skb->ip_summed = CHECKSUM_NONE;
1178
1179 /* Process the wireless stats if needed */
1180 orinoco_stat_gather(dev, skb, &desc);
1181
1182 /* Pass the packet to the networking stack */
1183 netif_rx(skb);
1184 stats->rx_packets++;
1185 stats->rx_bytes += length;
1186
1187 return;
1188
1189 drop:
1190 stats->rx_dropped++;
1191
1192 if (skb)
1193 dev_kfree_skb_irq(skb);
1194 return;
1195}
1196
1197/********************************************************************/
1198/* Rx path (info frames) */
1199/********************************************************************/
1200
1201static void print_linkstatus(struct net_device *dev, u16 status)
1202{
1203 char * s;
1204
1205 if (suppress_linkstatus)
1206 return;
1207
1208 switch (status) {
1209 case HERMES_LINKSTATUS_NOT_CONNECTED:
1210 s = "Not Connected";
1211 break;
1212 case HERMES_LINKSTATUS_CONNECTED:
1213 s = "Connected";
1214 break;
1215 case HERMES_LINKSTATUS_DISCONNECTED:
1216 s = "Disconnected";
1217 break;
1218 case HERMES_LINKSTATUS_AP_CHANGE:
1219 s = "AP Changed";
1220 break;
1221 case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
1222 s = "AP Out of Range";
1223 break;
1224 case HERMES_LINKSTATUS_AP_IN_RANGE:
1225 s = "AP In Range";
1226 break;
1227 case HERMES_LINKSTATUS_ASSOC_FAILED:
1228 s = "Association Failed";
1229 break;
1230 default:
1231 s = "UNKNOWN";
1232 }
1233
1234 printk(KERN_INFO "%s: New link status: %s (%04x)\n",
1235 dev->name, s, status);
1236}
1237
1238static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1239{
1240 struct orinoco_private *priv = netdev_priv(dev);
1241 u16 infofid;
1242 struct {
1243 u16 len;
1244 u16 type;
1245 } __attribute__ ((packed)) info;
1246 int len, type;
1247 int err;
1248
1249 /* This is an answer to an INQUIRE command that we did earlier,
1250 * or an information "event" generated by the card
1251 * The controller return to us a pseudo frame containing
1252 * the information in question - Jean II */
1253 infofid = hermes_read_regn(hw, INFOFID);
1254
1255 /* Read the info frame header - don't try too hard */
1256 err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
1257 infofid, 0);
1258 if (err) {
1259 printk(KERN_ERR "%s: error %d reading info frame. "
1260 "Frame dropped.\n", dev->name, err);
1261 return;
1262 }
1263
1264 len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
1265 type = le16_to_cpu(info.type);
1266
1267 switch (type) {
1268 case HERMES_INQ_TALLIES: {
1269 struct hermes_tallies_frame tallies;
1270 struct iw_statistics *wstats = &priv->wstats;
1271
1272 if (len > sizeof(tallies)) {
1273 printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
1274 dev->name, len);
1275 len = sizeof(tallies);
1276 }
1277
1278 /* Read directly the data (no seek) */
1279 hermes_read_words(hw, HERMES_DATA1, (void *) &tallies,
1280 len / 2); /* FIXME: blech! */
1281
1282 /* Increment our various counters */
1283 /* wstats->discard.nwid - no wrong BSSID stuff */
1284 wstats->discard.code +=
1285 le16_to_cpu(tallies.RxWEPUndecryptable);
1286 if (len == sizeof(tallies))
1287 wstats->discard.code +=
1288 le16_to_cpu(tallies.RxDiscards_WEPICVError) +
1289 le16_to_cpu(tallies.RxDiscards_WEPExcluded);
1290 wstats->discard.misc +=
1291 le16_to_cpu(tallies.TxDiscardsWrongSA);
1292 wstats->discard.fragment +=
1293 le16_to_cpu(tallies.RxMsgInBadMsgFragments);
1294 wstats->discard.retries +=
1295 le16_to_cpu(tallies.TxRetryLimitExceeded);
1296 /* wstats->miss.beacon - no match */
1297 }
1298 break;
1299 case HERMES_INQ_LINKSTATUS: {
1300 struct hermes_linkstatus linkstatus;
1301 u16 newstatus;
1302 int connected;
1303
1304 if (len != sizeof(linkstatus)) {
1305 printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
1306 dev->name, len);
1307 break;
1308 }
1309
1310 hermes_read_words(hw, HERMES_DATA1, (void *) &linkstatus,
1311 len / 2);
1312 newstatus = le16_to_cpu(linkstatus.linkstatus);
1313
1314 connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
1315 || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
1316 || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
1317
1318 if (connected)
1319 netif_carrier_on(dev);
1320 else
1321 netif_carrier_off(dev);
1322
1323 if (newstatus != priv->last_linkstatus)
1324 print_linkstatus(dev, newstatus);
1325
1326 priv->last_linkstatus = newstatus;
1327 }
1328 break;
1329 default:
1330 printk(KERN_DEBUG "%s: Unknown information frame received: "
1331 "type 0x%04x, length %d\n", dev->name, type, len);
1332 /* We don't actually do anything about it */
1333 break;
1334 }
1335}
1336
1337static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
1338{
1339 if (net_ratelimit())
1340 printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
1341}
1342
1343/********************************************************************/
1344/* Internal hardware control routines */
1345/********************************************************************/
1346
1347int __orinoco_up(struct net_device *dev)
1348{
1349 struct orinoco_private *priv = netdev_priv(dev);
1350 struct hermes *hw = &priv->hw;
1351 int err;
1352
1353 err = __orinoco_program_rids(dev);
1354 if (err) {
1355 printk(KERN_ERR "%s: Error %d configuring card\n",
1356 dev->name, err);
1357 return err;
1358 }
1359
1360 /* Fire things up again */
1361 hermes_set_irqmask(hw, ORINOCO_INTEN);
1362 err = hermes_enable_port(hw, 0);
1363 if (err) {
1364 printk(KERN_ERR "%s: Error %d enabling MAC port\n",
1365 dev->name, err);
1366 return err;
1367 }
1368
1369 netif_start_queue(dev);
1370
1371 return 0;
1372}
1373
1374int __orinoco_down(struct net_device *dev)
1375{
1376 struct orinoco_private *priv = netdev_priv(dev);
1377 struct hermes *hw = &priv->hw;
1378 int err;
1379
1380 netif_stop_queue(dev);
1381
1382 if (! priv->hw_unavailable) {
1383 if (! priv->broken_disableport) {
1384 err = hermes_disable_port(hw, 0);
1385 if (err) {
1386 /* Some firmwares (e.g. Intersil 1.3.x) seem
1387 * to have problems disabling the port, oh
1388 * well, too bad. */
1389 printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
1390 dev->name, err);
1391 priv->broken_disableport = 1;
1392 }
1393 }
1394 hermes_set_irqmask(hw, 0);
1395 hermes_write_regn(hw, EVACK, 0xffff);
1396 }
1397
1398 /* firmware will have to reassociate */
1399 netif_carrier_off(dev);
1400 priv->last_linkstatus = 0xffff;
1401
1402 return 0;
1403}
1404
1405int orinoco_reinit_firmware(struct net_device *dev)
1406{
1407 struct orinoco_private *priv = netdev_priv(dev);
1408 struct hermes *hw = &priv->hw;
1409 int err;
1410
1411 err = hermes_init(hw);
1412 if (err)
1413 return err;
1414
1415 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
1416 if (err == -EIO) {
1417 /* Try workaround for old Symbol firmware bug */
1418 printk(KERN_WARNING "%s: firmware ALLOC bug detected "
1419 "(old Symbol firmware?). Trying to work around... ",
1420 dev->name);
1421
1422 priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
1423 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
1424 if (err)
1425 printk("failed!\n");
1426 else
1427 printk("ok.\n");
1428 }
1429
1430 return err;
1431}
1432
1433static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
1434{
1435 hermes_t *hw = &priv->hw;
1436 int err = 0;
1437
1438 if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
1439 printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
1440 priv->ndev->name, priv->bitratemode);
1441 return -EINVAL;
1442 }
1443
1444 switch (priv->firmware_type) {
1445 case FIRMWARE_TYPE_AGERE:
1446 err = hermes_write_wordrec(hw, USER_BAP,
1447 HERMES_RID_CNFTXRATECONTROL,
1448 bitrate_table[priv->bitratemode].agere_txratectrl);
1449 break;
1450 case FIRMWARE_TYPE_INTERSIL:
1451 case FIRMWARE_TYPE_SYMBOL:
1452 err = hermes_write_wordrec(hw, USER_BAP,
1453 HERMES_RID_CNFTXRATECONTROL,
1454 bitrate_table[priv->bitratemode].intersil_txratectrl);
1455 break;
1456 default:
1457 BUG();
1458 }
1459
1460 return err;
1461}
1462
1463/* Change the WEP keys and/or the current keys. Can be called
1464 * either from __orinoco_hw_setup_wep() or directly from
1465 * orinoco_ioctl_setiwencode(). In the later case the association
1466 * with the AP is not broken (if the firmware can handle it),
1467 * which is needed for 802.1x implementations. */
1468static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
1469{
1470 hermes_t *hw = &priv->hw;
1471 int err = 0;
1472
1473 switch (priv->firmware_type) {
1474 case FIRMWARE_TYPE_AGERE:
1475 err = HERMES_WRITE_RECORD(hw, USER_BAP,
1476 HERMES_RID_CNFWEPKEYS_AGERE,
1477 &priv->keys);
1478 if (err)
1479 return err;
1480 err = hermes_write_wordrec(hw, USER_BAP,
1481 HERMES_RID_CNFTXKEY_AGERE,
1482 priv->tx_key);
1483 if (err)
1484 return err;
1485 break;
1486 case FIRMWARE_TYPE_INTERSIL:
1487 case FIRMWARE_TYPE_SYMBOL:
1488 {
1489 int keylen;
1490 int i;
1491
1492 /* Force uniform key length to work around firmware bugs */
1493 keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
1494
1495 if (keylen > LARGE_KEY_SIZE) {
1496 printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
1497 priv->ndev->name, priv->tx_key, keylen);
1498 return -E2BIG;
1499 }
1500
1501 /* Write all 4 keys */
1502 for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
1503 err = hermes_write_ltv(hw, USER_BAP,
1504 HERMES_RID_CNFDEFAULTKEY0 + i,
1505 HERMES_BYTES_TO_RECLEN(keylen),
1506 priv->keys[i].data);
1507 if (err)
1508 return err;
1509 }
1510
1511 /* Write the index of the key used in transmission */
1512 err = hermes_write_wordrec(hw, USER_BAP,
1513 HERMES_RID_CNFWEPDEFAULTKEYID,
1514 priv->tx_key);
1515 if (err)
1516 return err;
1517 }
1518 break;
1519 }
1520
1521 return 0;
1522}
1523
1524static int __orinoco_hw_setup_wep(struct orinoco_private *priv)
1525{
1526 hermes_t *hw = &priv->hw;
1527 int err = 0;
1528 int master_wep_flag;
1529 int auth_flag;
1530
1531 if (priv->wep_on)
1532 __orinoco_hw_setup_wepkeys(priv);
1533
1534 if (priv->wep_restrict)
1535 auth_flag = HERMES_AUTH_SHARED_KEY;
1536 else
1537 auth_flag = HERMES_AUTH_OPEN;
1538
1539 switch (priv->firmware_type) {
1540 case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
1541 if (priv->wep_on) {
1542 /* Enable the shared-key authentication. */
1543 err = hermes_write_wordrec(hw, USER_BAP,
1544 HERMES_RID_CNFAUTHENTICATION_AGERE,
1545 auth_flag);
1546 }
1547 err = hermes_write_wordrec(hw, USER_BAP,
1548 HERMES_RID_CNFWEPENABLED_AGERE,
1549 priv->wep_on);
1550 if (err)
1551 return err;
1552 break;
1553
1554 case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
1555 case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
1556 if (priv->wep_on) {
1557 if (priv->wep_restrict ||
1558 (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
1559 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
1560 HERMES_WEP_EXCL_UNENCRYPTED;
1561 else
1562 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
1563
1564 err = hermes_write_wordrec(hw, USER_BAP,
1565 HERMES_RID_CNFAUTHENTICATION,
1566 auth_flag);
1567 if (err)
1568 return err;
1569 } else
1570 master_wep_flag = 0;
1571
1572 if (priv->iw_mode == IW_MODE_MONITOR)
1573 master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
1574
1575 /* Master WEP setting : on/off */
1576 err = hermes_write_wordrec(hw, USER_BAP,
1577 HERMES_RID_CNFWEPFLAGS_INTERSIL,
1578 master_wep_flag);
1579 if (err)
1580 return err;
1581
1582 break;
1583 }
1584
1585 return 0;
1586}
1587
1588static int __orinoco_program_rids(struct net_device *dev)
1589{
1590 struct orinoco_private *priv = netdev_priv(dev);
1591 hermes_t *hw = &priv->hw;
1592 int err;
1593 struct hermes_idstring idbuf;
1594
1595 /* Set the MAC address */
1596 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
1597 HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
1598 if (err) {
1599 printk(KERN_ERR "%s: Error %d setting MAC address\n",
1600 dev->name, err);
1601 return err;
1602 }
1603
1604 /* Set up the link mode */
1605 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
1606 priv->port_type);
1607 if (err) {
1608 printk(KERN_ERR "%s: Error %d setting port type\n",
1609 dev->name, err);
1610 return err;
1611 }
1612 /* Set the channel/frequency */
1613 if (priv->channel == 0) {
1614 printk(KERN_DEBUG "%s: Channel is 0 in __orinoco_program_rids()\n", dev->name);
1615 if (priv->createibss)
1616 priv->channel = 10;
1617 }
1618 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFOWNCHANNEL,
1619 priv->channel);
1620 if (err) {
1621 printk(KERN_ERR "%s: Error %d setting channel\n",
1622 dev->name, err);
1623 return err;
1624 }
1625
1626 if (priv->has_ibss) {
1627 u16 createibss;
1628
1629 if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
1630 printk(KERN_WARNING "%s: This firmware requires an "
1631 "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
1632 /* With wvlan_cs, in this case, we would crash.
1633 * hopefully, this driver will behave better...
1634 * Jean II */
1635 createibss = 0;
1636 } else {
1637 createibss = priv->createibss;
1638 }
1639
1640 err = hermes_write_wordrec(hw, USER_BAP,
1641 HERMES_RID_CNFCREATEIBSS,
1642 createibss);
1643 if (err) {
1644 printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
1645 dev->name, err);
1646 return err;
1647 }
1648 }
1649
1650 /* Set the desired ESSID */
1651 idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
1652 memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
1653 /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
1654 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
1655 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
1656 &idbuf);
1657 if (err) {
1658 printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
1659 dev->name, err);
1660 return err;
1661 }
1662 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
1663 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
1664 &idbuf);
1665 if (err) {
1666 printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
1667 dev->name, err);
1668 return err;
1669 }
1670
1671 /* Set the station name */
1672 idbuf.len = cpu_to_le16(strlen(priv->nick));
1673 memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
1674 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
1675 HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
1676 &idbuf);
1677 if (err) {
1678 printk(KERN_ERR "%s: Error %d setting nickname\n",
1679 dev->name, err);
1680 return err;
1681 }
1682
1683 /* Set AP density */
1684 if (priv->has_sensitivity) {
1685 err = hermes_write_wordrec(hw, USER_BAP,
1686 HERMES_RID_CNFSYSTEMSCALE,
1687 priv->ap_density);
1688 if (err) {
1689 printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE. "
1690 "Disabling sensitivity control\n",
1691 dev->name, err);
1692
1693 priv->has_sensitivity = 0;
1694 }
1695 }
1696
1697 /* Set RTS threshold */
1698 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
1699 priv->rts_thresh);
1700 if (err) {
1701 printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
1702 dev->name, err);
1703 return err;
1704 }
1705
1706 /* Set fragmentation threshold or MWO robustness */
1707 if (priv->has_mwo)
1708 err = hermes_write_wordrec(hw, USER_BAP,
1709 HERMES_RID_CNFMWOROBUST_AGERE,
1710 priv->mwo_robust);
1711 else
1712 err = hermes_write_wordrec(hw, USER_BAP,
1713 HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
1714 priv->frag_thresh);
1715 if (err) {
1716 printk(KERN_ERR "%s: Error %d setting fragmentation\n",
1717 dev->name, err);
1718 return err;
1719 }
1720
1721 /* Set bitrate */
1722 err = __orinoco_hw_set_bitrate(priv);
1723 if (err) {
1724 printk(KERN_ERR "%s: Error %d setting bitrate\n",
1725 dev->name, err);
1726 return err;
1727 }
1728
1729 /* Set power management */
1730 if (priv->has_pm) {
1731 err = hermes_write_wordrec(hw, USER_BAP,
1732 HERMES_RID_CNFPMENABLED,
1733 priv->pm_on);
1734 if (err) {
1735 printk(KERN_ERR "%s: Error %d setting up PM\n",
1736 dev->name, err);
1737 return err;
1738 }
1739
1740 err = hermes_write_wordrec(hw, USER_BAP,
1741 HERMES_RID_CNFMULTICASTRECEIVE,
1742 priv->pm_mcast);
1743 if (err) {
1744 printk(KERN_ERR "%s: Error %d setting up PM\n",
1745 dev->name, err);
1746 return err;
1747 }
1748 err = hermes_write_wordrec(hw, USER_BAP,
1749 HERMES_RID_CNFMAXSLEEPDURATION,
1750 priv->pm_period);
1751 if (err) {
1752 printk(KERN_ERR "%s: Error %d setting up PM\n",
1753 dev->name, err);
1754 return err;
1755 }
1756 err = hermes_write_wordrec(hw, USER_BAP,
1757 HERMES_RID_CNFPMHOLDOVERDURATION,
1758 priv->pm_timeout);
1759 if (err) {
1760 printk(KERN_ERR "%s: Error %d setting up PM\n",
1761 dev->name, err);
1762 return err;
1763 }
1764 }
1765
1766 /* Set preamble - only for Symbol so far... */
1767 if (priv->has_preamble) {
1768 err = hermes_write_wordrec(hw, USER_BAP,
1769 HERMES_RID_CNFPREAMBLE_SYMBOL,
1770 priv->preamble);
1771 if (err) {
1772 printk(KERN_ERR "%s: Error %d setting preamble\n",
1773 dev->name, err);
1774 return err;
1775 }
1776 }
1777
1778 /* Set up encryption */
1779 if (priv->has_wep) {
1780 err = __orinoco_hw_setup_wep(priv);
1781 if (err) {
1782 printk(KERN_ERR "%s: Error %d activating WEP\n",
1783 dev->name, err);
1784 return err;
1785 }
1786 }
1787
1788 /* Set promiscuity / multicast*/
1789 priv->promiscuous = 0;
1790 priv->mc_count = 0;
1791 __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */
1792
1793 return 0;
1794}
1795
1796/* FIXME: return int? */
1797static void
1798__orinoco_set_multicast_list(struct net_device *dev)
1799{
1800 struct orinoco_private *priv = netdev_priv(dev);
1801 hermes_t *hw = &priv->hw;
1802 int err = 0;
1803 int promisc, mc_count;
1804
1805 /* The Hermes doesn't seem to have an allmulti mode, so we go
1806 * into promiscuous mode and let the upper levels deal. */
1807 if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
1808 (dev->mc_count > MAX_MULTICAST(priv)) ) {
1809 promisc = 1;
1810 mc_count = 0;
1811 } else {
1812 promisc = 0;
1813 mc_count = dev->mc_count;
1814 }
1815
1816 if (promisc != priv->promiscuous) {
1817 err = hermes_write_wordrec(hw, USER_BAP,
1818 HERMES_RID_CNFPROMISCUOUSMODE,
1819 promisc);
1820 if (err) {
1821 printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
1822 dev->name, err);
1823 } else
1824 priv->promiscuous = promisc;
1825 }
1826
1827 if (! promisc && (mc_count || priv->mc_count) ) {
1828 struct dev_mc_list *p = dev->mc_list;
1829 struct hermes_multicast mclist;
1830 int i;
1831
1832 for (i = 0; i < mc_count; i++) {
1833 /* paranoia: is list shorter than mc_count? */
1834 BUG_ON(! p);
1835 /* paranoia: bad address size in list? */
1836 BUG_ON(p->dmi_addrlen != ETH_ALEN);
1837
1838 memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
1839 p = p->next;
1840 }
1841
1842 if (p)
1843 printk(KERN_WARNING "%s: Multicast list is "
1844 "longer than mc_count\n", dev->name);
1845
1846 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES,
1847 HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
1848 &mclist);
1849 if (err)
1850 printk(KERN_ERR "%s: Error %d setting multicast list.\n",
1851 dev->name, err);
1852 else
1853 priv->mc_count = mc_count;
1854 }
1855
1856 /* Since we can set the promiscuous flag when it wasn't asked
1857 for, make sure the net_device knows about it. */
1858 if (priv->promiscuous)
1859 dev->flags |= IFF_PROMISC;
1860 else
1861 dev->flags &= ~IFF_PROMISC;
1862}
1863
1864static int orinoco_reconfigure(struct net_device *dev)
1865{
1866 struct orinoco_private *priv = netdev_priv(dev);
1867 struct hermes *hw = &priv->hw;
1868 unsigned long flags;
1869 int err = 0;
1870
1871 if (priv->broken_disableport) {
1872 schedule_work(&priv->reset_work);
1873 return 0;
1874 }
1875
1876 if (orinoco_lock(priv, &flags) != 0)
1877 return -EBUSY;
1878
1879 err = hermes_disable_port(hw, 0);
1880 if (err) {
1881 printk(KERN_WARNING "%s: Unable to disable port while reconfiguring card\n",
1882 dev->name);
1883 priv->broken_disableport = 1;
1884 goto out;
1885 }
1886
1887 err = __orinoco_program_rids(dev);
1888 if (err) {
1889 printk(KERN_WARNING "%s: Unable to reconfigure card\n",
1890 dev->name);
1891 goto out;
1892 }
1893
1894 err = hermes_enable_port(hw, 0);
1895 if (err) {
1896 printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
1897 dev->name);
1898 goto out;
1899 }
1900
1901 out:
1902 if (err) {
1903 printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
1904 schedule_work(&priv->reset_work);
1905 err = 0;
1906 }
1907
1908 orinoco_unlock(priv, &flags);
1909 return err;
1910
1911}
1912
1913/* This must be called from user context, without locks held - use
1914 * schedule_work() */
1915static void orinoco_reset(struct net_device *dev)
1916{
1917 struct orinoco_private *priv = netdev_priv(dev);
1918 struct hermes *hw = &priv->hw;
1919 int err = 0;
1920 unsigned long flags;
1921
1922 if (orinoco_lock(priv, &flags) != 0)
1923 /* When the hardware becomes available again, whatever
1924 * detects that is responsible for re-initializing
1925 * it. So no need for anything further */
1926 return;
1927
1928 netif_stop_queue(dev);
1929
1930 /* Shut off interrupts. Depending on what state the hardware
1931 * is in, this might not work, but we'll try anyway */
1932 hermes_set_irqmask(hw, 0);
1933 hermes_write_regn(hw, EVACK, 0xffff);
1934
1935 priv->hw_unavailable++;
1936 priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
1937 netif_carrier_off(dev);
1938
1939 orinoco_unlock(priv, &flags);
1940
1941 if (priv->hard_reset)
1942 err = (*priv->hard_reset)(priv);
1943 if (err) {
1944 printk(KERN_ERR "%s: orinoco_reset: Error %d "
1945 "performing hard reset\n", dev->name, err);
1946 /* FIXME: shutdown of some sort */
1947 return;
1948 }
1949
1950 err = orinoco_reinit_firmware(dev);
1951 if (err) {
1952 printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
1953 dev->name, err);
1954 return;
1955 }
1956
1957 spin_lock_irq(&priv->lock); /* This has to be called from user context */
1958
1959 priv->hw_unavailable--;
1960
1961 /* priv->open or priv->hw_unavailable might have changed while
1962 * we dropped the lock */
1963 if (priv->open && (! priv->hw_unavailable)) {
1964 err = __orinoco_up(dev);
1965 if (err) {
1966 printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
1967 dev->name, err);
1968 } else
1969 dev->trans_start = jiffies;
1970 }
1971
1972 spin_unlock_irq(&priv->lock);
1973
1974 return;
1975}
1976
1977/********************************************************************/
1978/* Interrupt handler */
1979/********************************************************************/
1980
1981static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
1982{
1983 printk(KERN_DEBUG "%s: TICK\n", dev->name);
1984}
1985
1986static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
1987{
1988 /* This seems to happen a fair bit under load, but ignoring it
1989 seems to work fine...*/
1990 printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
1991 dev->name);
1992}
1993
1994irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1995{
1996 struct net_device *dev = (struct net_device *)dev_id;
1997 struct orinoco_private *priv = netdev_priv(dev);
1998 hermes_t *hw = &priv->hw;
1999 int count = MAX_IRQLOOPS_PER_IRQ;
2000 u16 evstat, events;
2001 /* These are used to detect a runaway interrupt situation */
2002 /* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
2003 * we panic and shut down the hardware */
2004 static int last_irq_jiffy = 0; /* jiffies value the last time
2005 * we were called */
2006 static int loops_this_jiffy = 0;
2007 unsigned long flags;
2008
2009 if (orinoco_lock(priv, &flags) != 0) {
2010 /* If hw is unavailable - we don't know if the irq was
2011 * for us or not */
2012 return IRQ_HANDLED;
2013 }
2014
2015 evstat = hermes_read_regn(hw, EVSTAT);
2016 events = evstat & hw->inten;
2017 if (! events) {
2018 orinoco_unlock(priv, &flags);
2019 return IRQ_NONE;
2020 }
2021
2022 if (jiffies != last_irq_jiffy)
2023 loops_this_jiffy = 0;
2024 last_irq_jiffy = jiffies;
2025
2026 while (events && count--) {
2027 if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
2028 printk(KERN_WARNING "%s: IRQ handler is looping too "
2029 "much! Resetting.\n", dev->name);
2030 /* Disable interrupts for now */
2031 hermes_set_irqmask(hw, 0);
2032 schedule_work(&priv->reset_work);
2033 break;
2034 }
2035
2036 /* Check the card hasn't been removed */
2037 if (! hermes_present(hw)) {
2038 DEBUG(0, "orinoco_interrupt(): card removed\n");
2039 break;
2040 }
2041
2042 if (events & HERMES_EV_TICK)
2043 __orinoco_ev_tick(dev, hw);
2044 if (events & HERMES_EV_WTERR)
2045 __orinoco_ev_wterr(dev, hw);
2046 if (events & HERMES_EV_INFDROP)
2047 __orinoco_ev_infdrop(dev, hw);
2048 if (events & HERMES_EV_INFO)
2049 __orinoco_ev_info(dev, hw);
2050 if (events & HERMES_EV_RX)
2051 __orinoco_ev_rx(dev, hw);
2052 if (events & HERMES_EV_TXEXC)
2053 __orinoco_ev_txexc(dev, hw);
2054 if (events & HERMES_EV_TX)
2055 __orinoco_ev_tx(dev, hw);
2056 if (events & HERMES_EV_ALLOC)
2057 __orinoco_ev_alloc(dev, hw);
2058
2059 hermes_write_regn(hw, EVACK, events);
2060
2061 evstat = hermes_read_regn(hw, EVSTAT);
2062 events = evstat & hw->inten;
2063 };
2064
2065 orinoco_unlock(priv, &flags);
2066 return IRQ_HANDLED;
2067}
2068
2069/********************************************************************/
2070/* Initialization */
2071/********************************************************************/
2072
2073struct comp_id {
2074 u16 id, variant, major, minor;
2075} __attribute__ ((packed));
2076
2077static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
2078{
2079 if (nic_id->id < 0x8000)
2080 return FIRMWARE_TYPE_AGERE;
2081 else if (nic_id->id == 0x8000 && nic_id->major == 0)
2082 return FIRMWARE_TYPE_SYMBOL;
2083 else
2084 return FIRMWARE_TYPE_INTERSIL;
2085}
2086
2087/* Set priv->firmware type, determine firmware properties */
2088static int determine_firmware(struct net_device *dev)
2089{
2090 struct orinoco_private *priv = netdev_priv(dev);
2091 hermes_t *hw = &priv->hw;
2092 int err;
2093 struct comp_id nic_id, sta_id;
2094 unsigned int firmver;
2095 char tmp[SYMBOL_MAX_VER_LEN+1];
2096
2097 /* Get the hardware version */
2098 err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
2099 if (err) {
2100 printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
2101 dev->name, err);
2102 return err;
2103 }
2104
2105 le16_to_cpus(&nic_id.id);
2106 le16_to_cpus(&nic_id.variant);
2107 le16_to_cpus(&nic_id.major);
2108 le16_to_cpus(&nic_id.minor);
2109 printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
2110 dev->name, nic_id.id, nic_id.variant,
2111 nic_id.major, nic_id.minor);
2112
2113 priv->firmware_type = determine_firmware_type(&nic_id);
2114
2115 /* Get the firmware version */
2116 err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
2117 if (err) {
2118 printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
2119 dev->name, err);
2120 return err;
2121 }
2122
2123 le16_to_cpus(&sta_id.id);
2124 le16_to_cpus(&sta_id.variant);
2125 le16_to_cpus(&sta_id.major);
2126 le16_to_cpus(&sta_id.minor);
2127 printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
2128 dev->name, sta_id.id, sta_id.variant,
2129 sta_id.major, sta_id.minor);
2130
2131 switch (sta_id.id) {
2132 case 0x15:
2133 printk(KERN_ERR "%s: Primary firmware is active\n",
2134 dev->name);
2135 return -ENODEV;
2136 case 0x14b:
2137 printk(KERN_ERR "%s: Tertiary firmware is active\n",
2138 dev->name);
2139 return -ENODEV;
2140 case 0x1f: /* Intersil, Agere, Symbol Spectrum24 */
2141 case 0x21: /* Symbol Spectrum24 Trilogy */
2142 break;
2143 default:
2144 printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
2145 dev->name);
2146 break;
2147 }
2148
2149 /* Default capabilities */
2150 priv->has_sensitivity = 1;
2151 priv->has_mwo = 0;
2152 priv->has_preamble = 0;
2153 priv->has_port3 = 1;
2154 priv->has_ibss = 1;
2155 priv->has_wep = 0;
2156 priv->has_big_wep = 0;
2157
2158 /* Determine capabilities from the firmware version */
2159 switch (priv->firmware_type) {
2160 case FIRMWARE_TYPE_AGERE:
2161 /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
2162 ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
2163 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2164 "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
2165
2166 firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
2167
2168 priv->has_ibss = (firmver >= 0x60006);
2169 priv->has_wep = (firmver >= 0x40020);
2170 priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
2171 Gold cards from the others? */
2172 priv->has_mwo = (firmver >= 0x60000);
2173 priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
2174 priv->ibss_port = 1;
2175
2176 /* Tested with Agere firmware :
2177 * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
2178 * Tested CableTron firmware : 4.32 => Anton */
2179 break;
2180 case FIRMWARE_TYPE_SYMBOL:
2181 /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
2182 /* Intel MAC : 00:02:B3:* */
2183 /* 3Com MAC : 00:50:DA:* */
2184 memset(tmp, 0, sizeof(tmp));
2185 /* Get the Symbol firmware version */
2186 err = hermes_read_ltv(hw, USER_BAP,
2187 HERMES_RID_SECONDARYVERSION_SYMBOL,
2188 SYMBOL_MAX_VER_LEN, NULL, &tmp);
2189 if (err) {
2190 printk(KERN_WARNING
2191 "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",
2192 dev->name, err);
2193 firmver = 0;
2194 tmp[0] = '\0';
2195 } else {
2196 /* The firmware revision is a string, the format is
2197 * something like : "V2.20-01".
2198 * Quick and dirty parsing... - Jean II
2199 */
2200 firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12)
2201 | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4)
2202 | (tmp[7] - '0');
2203
2204 tmp[SYMBOL_MAX_VER_LEN] = '\0';
2205 }
2206
2207 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2208 "Symbol %s", tmp);
2209
2210 priv->has_ibss = (firmver >= 0x20000);
2211 priv->has_wep = (firmver >= 0x15012);
2212 priv->has_big_wep = (firmver >= 0x20000);
2213 priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) ||
2214 (firmver >= 0x29000 && firmver < 0x30000) ||
2215 firmver >= 0x31000;
2216 priv->has_preamble = (firmver >= 0x20000);
2217 priv->ibss_port = 4;
2218 /* Tested with Intel firmware : 0x20015 => Jean II */
2219 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
2220 break;
2221 case FIRMWARE_TYPE_INTERSIL:
2222 /* D-Link, Linksys, Adtron, ZoomAir, and many others...
2223 * Samsung, Compaq 100/200 and Proxim are slightly
2224 * different and less well tested */
2225 /* D-Link MAC : 00:40:05:* */
2226 /* Addtron MAC : 00:90:D1:* */
2227 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2228 "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
2229 sta_id.variant);
2230
2231 firmver = ((unsigned long)sta_id.major << 16) |
2232 ((unsigned long)sta_id.minor << 8) | sta_id.variant;
2233
2234 priv->has_ibss = (firmver >= 0x000700); /* FIXME */
2235 priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
2236 priv->has_pm = (firmver >= 0x000700);
2237
2238 if (firmver >= 0x000800)
2239 priv->ibss_port = 0;
2240 else {
2241 printk(KERN_NOTICE "%s: Intersil firmware earlier "
2242 "than v0.8.x - several features not supported\n",
2243 dev->name);
2244 priv->ibss_port = 1;
2245 }
2246 break;
2247 }
2248 printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
2249 priv->fw_name);
2250
2251 return 0;
2252}
2253
2254static int orinoco_init(struct net_device *dev)
2255{
2256 struct orinoco_private *priv = netdev_priv(dev);
2257 hermes_t *hw = &priv->hw;
2258 int err = 0;
2259 struct hermes_idstring nickbuf;
2260 u16 reclen;
2261 int len;
2262
2263 TRACE_ENTER(dev->name);
2264
2265 /* No need to lock, the hw_unavailable flag is already set in
2266 * alloc_orinocodev() */
2267 priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
2268
2269 /* Initialize the firmware */
2270 err = hermes_init(hw);
2271 if (err != 0) {
2272 printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
2273 dev->name, err);
2274 goto out;
2275 }
2276
2277 err = determine_firmware(dev);
2278 if (err != 0) {
2279 printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
2280 dev->name);
2281 goto out;
2282 }
2283
2284 if (priv->has_port3)
2285 printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
2286 if (priv->has_ibss)
2287 printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
2288 dev->name);
2289 if (priv->has_wep) {
2290 printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
2291 if (priv->has_big_wep)
2292 printk("104-bit key\n");
2293 else
2294 printk("40-bit key\n");
2295 }
2296
2297 /* Get the MAC address */
2298 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
2299 ETH_ALEN, NULL, dev->dev_addr);
2300 if (err) {
2301 printk(KERN_WARNING "%s: failed to read MAC address!\n",
2302 dev->name);
2303 goto out;
2304 }
2305
2306 printk(KERN_DEBUG "%s: MAC address %02X:%02X:%02X:%02X:%02X:%02X\n",
2307 dev->name, dev->dev_addr[0], dev->dev_addr[1],
2308 dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4],
2309 dev->dev_addr[5]);
2310
2311 /* Get the station name */
2312 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
2313 sizeof(nickbuf), &reclen, &nickbuf);
2314 if (err) {
2315 printk(KERN_ERR "%s: failed to read station name\n",
2316 dev->name);
2317 goto out;
2318 }
2319 if (nickbuf.len)
2320 len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
2321 else
2322 len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
2323 memcpy(priv->nick, &nickbuf.val, len);
2324 priv->nick[len] = '\0';
2325
2326 printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
2327
2328 /* Get allowed channels */
2329 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
2330 &priv->channel_mask);
2331 if (err) {
2332 printk(KERN_ERR "%s: failed to read channel list!\n",
2333 dev->name);
2334 goto out;
2335 }
2336
2337 /* Get initial AP density */
2338 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
2339 &priv->ap_density);
2340 if (err || priv->ap_density < 1 || priv->ap_density > 3) {
2341 priv->has_sensitivity = 0;
2342 }
2343
2344 /* Get initial RTS threshold */
2345 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
2346 &priv->rts_thresh);
2347 if (err) {
2348 printk(KERN_ERR "%s: failed to read RTS threshold!\n",
2349 dev->name);
2350 goto out;
2351 }
2352
2353 /* Get initial fragmentation settings */
2354 if (priv->has_mwo)
2355 err = hermes_read_wordrec(hw, USER_BAP,
2356 HERMES_RID_CNFMWOROBUST_AGERE,
2357 &priv->mwo_robust);
2358 else
2359 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
2360 &priv->frag_thresh);
2361 if (err) {
2362 printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
2363 dev->name);
2364 goto out;
2365 }
2366
2367 /* Power management setup */
2368 if (priv->has_pm) {
2369 priv->pm_on = 0;
2370 priv->pm_mcast = 1;
2371 err = hermes_read_wordrec(hw, USER_BAP,
2372 HERMES_RID_CNFMAXSLEEPDURATION,
2373 &priv->pm_period);
2374 if (err) {
2375 printk(KERN_ERR "%s: failed to read power management period!\n",
2376 dev->name);
2377 goto out;
2378 }
2379 err = hermes_read_wordrec(hw, USER_BAP,
2380 HERMES_RID_CNFPMHOLDOVERDURATION,
2381 &priv->pm_timeout);
2382 if (err) {
2383 printk(KERN_ERR "%s: failed to read power management timeout!\n",
2384 dev->name);
2385 goto out;
2386 }
2387 }
2388
2389 /* Preamble setup */
2390 if (priv->has_preamble) {
2391 err = hermes_read_wordrec(hw, USER_BAP,
2392 HERMES_RID_CNFPREAMBLE_SYMBOL,
2393 &priv->preamble);
2394 if (err)
2395 goto out;
2396 }
2397
2398 /* Set up the default configuration */
2399 priv->iw_mode = IW_MODE_INFRA;
2400 /* By default use IEEE/IBSS ad-hoc mode if we have it */
2401 priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
2402 set_port_type(priv);
2403 priv->channel = 10; /* default channel, more-or-less arbitrary */
2404
2405 priv->promiscuous = 0;
2406 priv->wep_on = 0;
2407 priv->tx_key = 0;
2408
2409 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
2410 if (err == -EIO) {
2411 /* Try workaround for old Symbol firmware bug */
2412 printk(KERN_WARNING "%s: firmware ALLOC bug detected "
2413 "(old Symbol firmware?). Trying to work around... ",
2414 dev->name);
2415
2416 priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
2417 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
2418 if (err)
2419 printk("failed!\n");
2420 else
2421 printk("ok.\n");
2422 }
2423 if (err) {
2424 printk("%s: Error %d allocating Tx buffer\n", dev->name, err);
2425 goto out;
2426 }
2427
2428 /* Make the hardware available, as long as it hasn't been
2429 * removed elsewhere (e.g. by PCMCIA hot unplug) */
2430 spin_lock_irq(&priv->lock);
2431 priv->hw_unavailable--;
2432 spin_unlock_irq(&priv->lock);
2433
2434 printk(KERN_DEBUG "%s: ready\n", dev->name);
2435
2436 out:
2437 TRACE_EXIT(dev->name);
2438 return err;
2439}
2440
2441struct net_device *alloc_orinocodev(int sizeof_card,
2442 int (*hard_reset)(struct orinoco_private *))
2443{
2444 struct net_device *dev;
2445 struct orinoco_private *priv;
2446
2447 dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
2448 if (! dev)
2449 return NULL;
2450 priv = netdev_priv(dev);
2451 priv->ndev = dev;
2452 if (sizeof_card)
2453 priv->card = (void *)((unsigned long)netdev_priv(dev)
2454 + sizeof(struct orinoco_private));
2455 else
2456 priv->card = NULL;
2457
2458 /* Setup / override net_device fields */
2459 dev->init = orinoco_init;
2460 dev->hard_start_xmit = orinoco_xmit;
2461 dev->tx_timeout = orinoco_tx_timeout;
2462 dev->watchdog_timeo = HZ; /* 1 second timeout */
2463 dev->get_stats = orinoco_get_stats;
2464 dev->get_wireless_stats = orinoco_get_wireless_stats;
2465 dev->do_ioctl = orinoco_ioctl;
2466 dev->change_mtu = orinoco_change_mtu;
2467 dev->set_multicast_list = orinoco_set_multicast_list;
2468 /* we use the default eth_mac_addr for setting the MAC addr */
2469
2470 /* Set up default callbacks */
2471 dev->open = orinoco_open;
2472 dev->stop = orinoco_stop;
2473 priv->hard_reset = hard_reset;
2474
2475 spin_lock_init(&priv->lock);
2476 priv->open = 0;
2477 priv->hw_unavailable = 1; /* orinoco_init() must clear this
2478 * before anything else touches the
2479 * hardware */
2480 INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev);
2481
2482 netif_carrier_off(dev);
2483 priv->last_linkstatus = 0xffff;
2484
2485 return dev;
2486
2487}
2488
2489void free_orinocodev(struct net_device *dev)
2490{
2491 free_netdev(dev);
2492}
2493
2494/********************************************************************/
2495/* Wireless extensions */
2496/********************************************************************/
2497
2498static int orinoco_hw_get_bssid(struct orinoco_private *priv,
2499 char buf[ETH_ALEN])
2500{
2501 hermes_t *hw = &priv->hw;
2502 int err = 0;
2503 unsigned long flags;
2504
2505 if (orinoco_lock(priv, &flags) != 0)
2506 return -EBUSY;
2507
2508 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
2509 ETH_ALEN, NULL, buf);
2510
2511 orinoco_unlock(priv, &flags);
2512
2513 return err;
2514}
2515
2516static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
2517 char buf[IW_ESSID_MAX_SIZE+1])
2518{
2519 hermes_t *hw = &priv->hw;
2520 int err = 0;
2521 struct hermes_idstring essidbuf;
2522 char *p = (char *)(&essidbuf.val);
2523 int len;
2524 unsigned long flags;
2525
2526 if (orinoco_lock(priv, &flags) != 0)
2527 return -EBUSY;
2528
2529 if (strlen(priv->desired_essid) > 0) {
2530 /* We read the desired SSID from the hardware rather
2531 than from priv->desired_essid, just in case the
2532 firmware is allowed to change it on us. I'm not
2533 sure about this */
2534 /* My guess is that the OWNSSID should always be whatever
2535 * we set to the card, whereas CURRENT_SSID is the one that
2536 * may change... - Jean II */
2537 u16 rid;
2538
2539 *active = 1;
2540
2541 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
2542 HERMES_RID_CNFDESIREDSSID;
2543
2544 err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
2545 NULL, &essidbuf);
2546 if (err)
2547 goto fail_unlock;
2548 } else {
2549 *active = 0;
2550
2551 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
2552 sizeof(essidbuf), NULL, &essidbuf);
2553 if (err)
2554 goto fail_unlock;
2555 }
2556
2557 len = le16_to_cpu(essidbuf.len);
2558
2559 memset(buf, 0, IW_ESSID_MAX_SIZE+1);
2560 memcpy(buf, p, len);
2561 buf[len] = '\0';
2562
2563 fail_unlock:
2564 orinoco_unlock(priv, &flags);
2565
2566 return err;
2567}
2568
2569static long orinoco_hw_get_freq(struct orinoco_private *priv)
2570{
2571
2572 hermes_t *hw = &priv->hw;
2573 int err = 0;
2574 u16 channel;
2575 long freq = 0;
2576 unsigned long flags;
2577
2578 if (orinoco_lock(priv, &flags) != 0)
2579 return -EBUSY;
2580
2581 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
2582 if (err)
2583 goto out;
2584
2585 /* Intersil firmware 1.3.5 returns 0 when the interface is down */
2586 if (channel == 0) {
2587 err = -EBUSY;
2588 goto out;
2589 }
2590
2591 if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
2592 printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
2593 priv->ndev->name, channel);
2594 err = -EBUSY;
2595 goto out;
2596
2597 }
2598 freq = channel_frequency[channel-1] * 100000;
2599
2600 out:
2601 orinoco_unlock(priv, &flags);
2602
2603 if (err > 0)
2604 err = -EBUSY;
2605 return err ? err : freq;
2606}
2607
2608static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
2609 int *numrates, s32 *rates, int max)
2610{
2611 hermes_t *hw = &priv->hw;
2612 struct hermes_idstring list;
2613 unsigned char *p = (unsigned char *)&list.val;
2614 int err = 0;
2615 int num;
2616 int i;
2617 unsigned long flags;
2618
2619 if (orinoco_lock(priv, &flags) != 0)
2620 return -EBUSY;
2621
2622 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
2623 sizeof(list), NULL, &list);
2624 orinoco_unlock(priv, &flags);
2625
2626 if (err)
2627 return err;
2628
2629 num = le16_to_cpu(list.len);
2630 *numrates = num;
2631 num = min(num, max);
2632
2633 for (i = 0; i < num; i++) {
2634 rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
2635 }
2636
2637 return 0;
2638}
2639
2640static int orinoco_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq)
2641{
2642 struct orinoco_private *priv = netdev_priv(dev);
2643 int err = 0;
2644 int mode;
2645 struct iw_range range;
2646 int numrates;
2647 int i, k;
2648 unsigned long flags;
2649
2650 TRACE_ENTER(dev->name);
2651
2652 if (!access_ok(VERIFY_WRITE, rrq->pointer, sizeof(range)))
2653 return -EFAULT;
2654
2655 rrq->length = sizeof(range);
2656
2657 if (orinoco_lock(priv, &flags) != 0)
2658 return -EBUSY;
2659
2660 mode = priv->iw_mode;
2661 orinoco_unlock(priv, &flags);
2662
2663 memset(&range, 0, sizeof(range));
2664
2665 /* Much of this shamelessly taken from wvlan_cs.c. No idea
2666 * what it all means -dgibson */
2667 range.we_version_compiled = WIRELESS_EXT;
2668 range.we_version_source = 11;
2669
2670 range.min_nwid = range.max_nwid = 0; /* We don't use nwids */
2671
2672 /* Set available channels/frequencies */
2673 range.num_channels = NUM_CHANNELS;
2674 k = 0;
2675 for (i = 0; i < NUM_CHANNELS; i++) {
2676 if (priv->channel_mask & (1 << i)) {
2677 range.freq[k].i = i + 1;
2678 range.freq[k].m = channel_frequency[i] * 100000;
2679 range.freq[k].e = 1;
2680 k++;
2681 }
2682
2683 if (k >= IW_MAX_FREQUENCIES)
2684 break;
2685 }
2686 range.num_frequency = k;
2687
2688 range.sensitivity = 3;
2689
2690 if ((mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
2691 /* Quality stats meaningless in ad-hoc mode */
2692 range.max_qual.qual = 0;
2693 range.max_qual.level = 0;
2694 range.max_qual.noise = 0;
2695 range.avg_qual.qual = 0;
2696 range.avg_qual.level = 0;
2697 range.avg_qual.noise = 0;
2698 } else {
2699 range.max_qual.qual = 0x8b - 0x2f;
2700 range.max_qual.level = 0x2f - 0x95 - 1;
2701 range.max_qual.noise = 0x2f - 0x95 - 1;
2702 /* Need to get better values */
2703 range.avg_qual.qual = 0x24;
2704 range.avg_qual.level = 0xC2;
2705 range.avg_qual.noise = 0x9E;
2706 }
2707
2708 err = orinoco_hw_get_bitratelist(priv, &numrates,
2709 range.bitrate, IW_MAX_BITRATES);
2710 if (err)
2711 return err;
2712 range.num_bitrates = numrates;
2713
2714 /* Set an indication of the max TCP throughput in bit/s that we can
2715 * expect using this interface. May be use for QoS stuff...
2716 * Jean II */
2717 if(numrates > 2)
2718 range.throughput = 5 * 1000 * 1000; /* ~5 Mb/s */
2719 else
2720 range.throughput = 1.5 * 1000 * 1000; /* ~1.5 Mb/s */
2721
2722 range.min_rts = 0;
2723 range.max_rts = 2347;
2724 range.min_frag = 256;
2725 range.max_frag = 2346;
2726
2727 if (orinoco_lock(priv, &flags) != 0)
2728 return -EBUSY;
2729 if (priv->has_wep) {
2730 range.max_encoding_tokens = ORINOCO_MAX_KEYS;
2731
2732 range.encoding_size[0] = SMALL_KEY_SIZE;
2733 range.num_encoding_sizes = 1;
2734
2735 if (priv->has_big_wep) {
2736 range.encoding_size[1] = LARGE_KEY_SIZE;
2737 range.num_encoding_sizes = 2;
2738 }
2739 } else {
2740 range.num_encoding_sizes = 0;
2741 range.max_encoding_tokens = 0;
2742 }
2743 orinoco_unlock(priv, &flags);
2744
2745 range.min_pmp = 0;
2746 range.max_pmp = 65535000;
2747 range.min_pmt = 0;
2748 range.max_pmt = 65535 * 1000; /* ??? */
2749 range.pmp_flags = IW_POWER_PERIOD;
2750 range.pmt_flags = IW_POWER_TIMEOUT;
2751 range.pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
2752
2753 range.num_txpower = 1;
2754 range.txpower[0] = 15; /* 15dBm */
2755 range.txpower_capa = IW_TXPOW_DBM;
2756
2757 range.retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
2758 range.retry_flags = IW_RETRY_LIMIT;
2759 range.r_time_flags = IW_RETRY_LIFETIME;
2760 range.min_retry = 0;
2761 range.max_retry = 65535; /* ??? */
2762 range.min_r_time = 0;
2763 range.max_r_time = 65535 * 1000; /* ??? */
2764
2765 if (copy_to_user(rrq->pointer, &range, sizeof(range)))
2766 return -EFAULT;
2767
2768 TRACE_EXIT(dev->name);
2769
2770 return 0;
2771}
2772
2773static int orinoco_ioctl_setiwencode(struct net_device *dev, struct iw_point *erq)
2774{
2775 struct orinoco_private *priv = netdev_priv(dev);
2776 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
2777 int setindex = priv->tx_key;
2778 int enable = priv->wep_on;
2779 int restricted = priv->wep_restrict;
2780 u16 xlen = 0;
2781 int err = 0;
2782 char keybuf[ORINOCO_MAX_KEY_SIZE];
2783 unsigned long flags;
2784
2785 if (! priv->has_wep)
2786 return -EOPNOTSUPP;
2787
2788 if (erq->pointer) {
2789 /* We actually have a key to set - check its length */
2790 if (erq->length > LARGE_KEY_SIZE)
2791 return -E2BIG;
2792
2793 if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
2794 return -E2BIG;
2795
2796 if (copy_from_user(keybuf, erq->pointer, erq->length))
2797 return -EFAULT;
2798 }
2799
2800 if (orinoco_lock(priv, &flags) != 0)
2801 return -EBUSY;
2802
2803 if (erq->pointer) {
2804 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
2805 index = priv->tx_key;
2806
2807 /* Adjust key length to a supported value */
2808 if (erq->length > SMALL_KEY_SIZE) {
2809 xlen = LARGE_KEY_SIZE;
2810 } else if (erq->length > 0) {
2811 xlen = SMALL_KEY_SIZE;
2812 } else
2813 xlen = 0;
2814
2815 /* Switch on WEP if off */
2816 if ((!enable) && (xlen > 0)) {
2817 setindex = index;
2818 enable = 1;
2819 }
2820 } else {
2821 /* Important note : if the user do "iwconfig eth0 enc off",
2822 * we will arrive there with an index of -1. This is valid
2823 * but need to be taken care off... Jean II */
2824 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
2825 if((index != -1) || (erq->flags == 0)) {
2826 err = -EINVAL;
2827 goto out;
2828 }
2829 } else {
2830 /* Set the index : Check that the key is valid */
2831 if(priv->keys[index].len == 0) {
2832 err = -EINVAL;
2833 goto out;
2834 }
2835 setindex = index;
2836 }
2837 }
2838
2839 if (erq->flags & IW_ENCODE_DISABLED)
2840 enable = 0;
2841 if (erq->flags & IW_ENCODE_OPEN)
2842 restricted = 0;
2843 if (erq->flags & IW_ENCODE_RESTRICTED)
2844 restricted = 1;
2845
2846 if (erq->pointer) {
2847 priv->keys[index].len = cpu_to_le16(xlen);
2848 memset(priv->keys[index].data, 0,
2849 sizeof(priv->keys[index].data));
2850 memcpy(priv->keys[index].data, keybuf, erq->length);
2851 }
2852 priv->tx_key = setindex;
2853
2854 /* Try fast key change if connected and only keys are changed */
2855 if (priv->wep_on && enable && (priv->wep_restrict == restricted) &&
2856 netif_carrier_ok(dev)) {
2857 err = __orinoco_hw_setup_wepkeys(priv);
2858 /* No need to commit if successful */
2859 goto out;
2860 }
2861
2862 priv->wep_on = enable;
2863 priv->wep_restrict = restricted;
2864
2865 out:
2866 orinoco_unlock(priv, &flags);
2867
2868 return err;
2869}
2870
2871static int orinoco_ioctl_getiwencode(struct net_device *dev, struct iw_point *erq)
2872{
2873 struct orinoco_private *priv = netdev_priv(dev);
2874 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
2875 u16 xlen = 0;
2876 char keybuf[ORINOCO_MAX_KEY_SIZE];
2877 unsigned long flags;
2878
2879 if (! priv->has_wep)
2880 return -EOPNOTSUPP;
2881
2882 if (orinoco_lock(priv, &flags) != 0)
2883 return -EBUSY;
2884
2885 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
2886 index = priv->tx_key;
2887
2888 erq->flags = 0;
2889 if (! priv->wep_on)
2890 erq->flags |= IW_ENCODE_DISABLED;
2891 erq->flags |= index + 1;
2892
2893 if (priv->wep_restrict)
2894 erq->flags |= IW_ENCODE_RESTRICTED;
2895 else
2896 erq->flags |= IW_ENCODE_OPEN;
2897
2898 xlen = le16_to_cpu(priv->keys[index].len);
2899
2900 erq->length = xlen;
2901
2902 memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
2903
2904 orinoco_unlock(priv, &flags);
2905
2906 if (erq->pointer) {
2907 if (copy_to_user(erq->pointer, keybuf, xlen))
2908 return -EFAULT;
2909 }
2910
2911 return 0;
2912}
2913
2914static int orinoco_ioctl_setessid(struct net_device *dev, struct iw_point *erq)
2915{
2916 struct orinoco_private *priv = netdev_priv(dev);
2917 char essidbuf[IW_ESSID_MAX_SIZE+1];
2918 unsigned long flags;
2919
2920 /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
2921 * anyway... - Jean II */
2922
2923 memset(&essidbuf, 0, sizeof(essidbuf));
2924
2925 if (erq->flags) {
2926 if (erq->length > IW_ESSID_MAX_SIZE)
2927 return -E2BIG;
2928
2929 if (copy_from_user(&essidbuf, erq->pointer, erq->length))
2930 return -EFAULT;
2931
2932 essidbuf[erq->length] = '\0';
2933 }
2934
2935 if (orinoco_lock(priv, &flags) != 0)
2936 return -EBUSY;
2937
2938 memcpy(priv->desired_essid, essidbuf, sizeof(priv->desired_essid));
2939
2940 orinoco_unlock(priv, &flags);
2941
2942 return 0;
2943}
2944
2945static int orinoco_ioctl_getessid(struct net_device *dev, struct iw_point *erq)
2946{
2947 struct orinoco_private *priv = netdev_priv(dev);
2948 char essidbuf[IW_ESSID_MAX_SIZE+1];
2949 int active;
2950 int err = 0;
2951 unsigned long flags;
2952
2953 TRACE_ENTER(dev->name);
2954
2955 if (netif_running(dev)) {
2956 err = orinoco_hw_get_essid(priv, &active, essidbuf);
2957 if (err)
2958 return err;
2959 } else {
2960 if (orinoco_lock(priv, &flags) != 0)
2961 return -EBUSY;
2962 memcpy(essidbuf, priv->desired_essid, sizeof(essidbuf));
2963 orinoco_unlock(priv, &flags);
2964 }
2965
2966 erq->flags = 1;
2967 erq->length = strlen(essidbuf) + 1;
2968 if (erq->pointer)
2969 if (copy_to_user(erq->pointer, essidbuf, erq->length))
2970 return -EFAULT;
2971
2972 TRACE_EXIT(dev->name);
2973
2974 return 0;
2975}
2976
2977static int orinoco_ioctl_setnick(struct net_device *dev, struct iw_point *nrq)
2978{
2979 struct orinoco_private *priv = netdev_priv(dev);
2980 char nickbuf[IW_ESSID_MAX_SIZE+1];
2981 unsigned long flags;
2982
2983 if (nrq->length > IW_ESSID_MAX_SIZE)
2984 return -E2BIG;
2985
2986 memset(nickbuf, 0, sizeof(nickbuf));
2987
2988 if (copy_from_user(nickbuf, nrq->pointer, nrq->length))
2989 return -EFAULT;
2990
2991 nickbuf[nrq->length] = '\0';
2992
2993 if (orinoco_lock(priv, &flags) != 0)
2994 return -EBUSY;
2995
2996 memcpy(priv->nick, nickbuf, sizeof(priv->nick));
2997
2998 orinoco_unlock(priv, &flags);
2999
3000 return 0;
3001}
3002
3003static int orinoco_ioctl_getnick(struct net_device *dev, struct iw_point *nrq)
3004{
3005 struct orinoco_private *priv = netdev_priv(dev);
3006 char nickbuf[IW_ESSID_MAX_SIZE+1];
3007 unsigned long flags;
3008
3009 if (orinoco_lock(priv, &flags) != 0)
3010 return -EBUSY;
3011
3012 memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
3013 orinoco_unlock(priv, &flags);
3014
3015 nrq->length = strlen(nickbuf)+1;
3016
3017 if (copy_to_user(nrq->pointer, nickbuf, sizeof(nickbuf)))
3018 return -EFAULT;
3019
3020 return 0;
3021}
3022
3023static int orinoco_ioctl_setfreq(struct net_device *dev, struct iw_freq *frq)
3024{
3025 struct orinoco_private *priv = netdev_priv(dev);
3026 int chan = -1;
3027 unsigned long flags;
3028
3029 /* We can only use this in Ad-Hoc demo mode to set the operating
3030 * frequency, or in IBSS mode to set the frequency where the IBSS
3031 * will be created - Jean II */
3032 if (priv->iw_mode != IW_MODE_ADHOC)
3033 return -EOPNOTSUPP;
3034
3035 if ( (frq->e == 0) && (frq->m <= 1000) ) {
3036 /* Setting by channel number */
3037 chan = frq->m;
3038 } else {
3039 /* Setting by frequency - search the table */
3040 int mult = 1;
3041 int i;
3042
3043 for (i = 0; i < (6 - frq->e); i++)
3044 mult *= 10;
3045
3046 for (i = 0; i < NUM_CHANNELS; i++)
3047 if (frq->m == (channel_frequency[i] * mult))
3048 chan = i+1;
3049 }
3050
3051 if ( (chan < 1) || (chan > NUM_CHANNELS) ||
3052 ! (priv->channel_mask & (1 << (chan-1)) ) )
3053 return -EINVAL;
3054
3055 if (orinoco_lock(priv, &flags) != 0)
3056 return -EBUSY;
3057 priv->channel = chan;
3058 orinoco_unlock(priv, &flags);
3059
3060 return 0;
3061}
3062
3063static int orinoco_ioctl_getsens(struct net_device *dev, struct iw_param *srq)
3064{
3065 struct orinoco_private *priv = netdev_priv(dev);
3066 hermes_t *hw = &priv->hw;
3067 u16 val;
3068 int err;
3069 unsigned long flags;
3070
3071 if (!priv->has_sensitivity)
3072 return -EOPNOTSUPP;
3073
3074 if (orinoco_lock(priv, &flags) != 0)
3075 return -EBUSY;
3076 err = hermes_read_wordrec(hw, USER_BAP,
3077 HERMES_RID_CNFSYSTEMSCALE, &val);
3078 orinoco_unlock(priv, &flags);
3079
3080 if (err)
3081 return err;
3082
3083 srq->value = val;
3084 srq->fixed = 0; /* auto */
3085
3086 return 0;
3087}
3088
3089static int orinoco_ioctl_setsens(struct net_device *dev, struct iw_param *srq)
3090{
3091 struct orinoco_private *priv = netdev_priv(dev);
3092 int val = srq->value;
3093 unsigned long flags;
3094
3095 if (!priv->has_sensitivity)
3096 return -EOPNOTSUPP;
3097
3098 if ((val < 1) || (val > 3))
3099 return -EINVAL;
3100
3101 if (orinoco_lock(priv, &flags) != 0)
3102 return -EBUSY;
3103 priv->ap_density = val;
3104 orinoco_unlock(priv, &flags);
3105
3106 return 0;
3107}
3108
3109static int orinoco_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
3110{
3111 struct orinoco_private *priv = netdev_priv(dev);
3112 int val = rrq->value;
3113 unsigned long flags;
3114
3115 if (rrq->disabled)
3116 val = 2347;
3117
3118 if ( (val < 0) || (val > 2347) )
3119 return -EINVAL;
3120
3121 if (orinoco_lock(priv, &flags) != 0)
3122 return -EBUSY;
3123
3124 priv->rts_thresh = val;
3125 orinoco_unlock(priv, &flags);
3126
3127 return 0;
3128}
3129
3130static int orinoco_ioctl_setfrag(struct net_device *dev, struct iw_param *frq)
3131{
3132 struct orinoco_private *priv = netdev_priv(dev);
3133 int err = 0;
3134 unsigned long flags;
3135
3136 if (orinoco_lock(priv, &flags) != 0)
3137 return -EBUSY;
3138
3139 if (priv->has_mwo) {
3140 if (frq->disabled)
3141 priv->mwo_robust = 0;
3142 else {
3143 if (frq->fixed)
3144 printk(KERN_WARNING "%s: Fixed fragmentation is "
3145 "not supported on this firmware. "
3146 "Using MWO robust instead.\n", dev->name);
3147 priv->mwo_robust = 1;
3148 }
3149 } else {
3150 if (frq->disabled)
3151 priv->frag_thresh = 2346;
3152 else {
3153 if ( (frq->value < 256) || (frq->value > 2346) )
3154 err = -EINVAL;
3155 else
3156 priv->frag_thresh = frq->value & ~0x1; /* must be even */
3157 }
3158 }
3159
3160 orinoco_unlock(priv, &flags);
3161
3162 return err;
3163}
3164
3165static int orinoco_ioctl_getfrag(struct net_device *dev, struct iw_param *frq)
3166{
3167 struct orinoco_private *priv = netdev_priv(dev);
3168 hermes_t *hw = &priv->hw;
3169 int err = 0;
3170 u16 val;
3171 unsigned long flags;
3172
3173 if (orinoco_lock(priv, &flags) != 0)
3174 return -EBUSY;
3175
3176 if (priv->has_mwo) {
3177 err = hermes_read_wordrec(hw, USER_BAP,
3178 HERMES_RID_CNFMWOROBUST_AGERE,
3179 &val);
3180 if (err)
3181 val = 0;
3182
3183 frq->value = val ? 2347 : 0;
3184 frq->disabled = ! val;
3185 frq->fixed = 0;
3186 } else {
3187 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
3188 &val);
3189 if (err)
3190 val = 0;
3191
3192 frq->value = val;
3193 frq->disabled = (val >= 2346);
3194 frq->fixed = 1;
3195 }
3196
3197 orinoco_unlock(priv, &flags);
3198
3199 return err;
3200}
3201
3202static int orinoco_ioctl_setrate(struct net_device *dev, struct iw_param *rrq)
3203{
3204 struct orinoco_private *priv = netdev_priv(dev);
3205 int err = 0;
3206 int ratemode = -1;
3207 int bitrate; /* 100s of kilobits */
3208 int i;
3209 unsigned long flags;
3210
3211 /* As the user space doesn't know our highest rate, it uses -1
3212 * to ask us to set the highest rate. Test it using "iwconfig
3213 * ethX rate auto" - Jean II */
3214 if (rrq->value == -1)
3215 bitrate = 110;
3216 else {
3217 if (rrq->value % 100000)
3218 return -EINVAL;
3219 bitrate = rrq->value / 100000;
3220 }
3221
3222 if ( (bitrate != 10) && (bitrate != 20) &&
3223 (bitrate != 55) && (bitrate != 110) )
3224 return -EINVAL;
3225
3226 for (i = 0; i < BITRATE_TABLE_SIZE; i++)
3227 if ( (bitrate_table[i].bitrate == bitrate) &&
3228 (bitrate_table[i].automatic == ! rrq->fixed) ) {
3229 ratemode = i;
3230 break;
3231 }
3232
3233 if (ratemode == -1)
3234 return -EINVAL;
3235
3236 if (orinoco_lock(priv, &flags) != 0)
3237 return -EBUSY;
3238 priv->bitratemode = ratemode;
3239 orinoco_unlock(priv, &flags);
3240
3241 return err;
3242}
3243
3244static int orinoco_ioctl_getrate(struct net_device *dev, struct iw_param *rrq)
3245{
3246 struct orinoco_private *priv = netdev_priv(dev);
3247 hermes_t *hw = &priv->hw;
3248 int err = 0;
3249 int ratemode;
3250 int i;
3251 u16 val;
3252 unsigned long flags;
3253
3254 if (orinoco_lock(priv, &flags) != 0)
3255 return -EBUSY;
3256
3257 ratemode = priv->bitratemode;
3258
3259 BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
3260
3261 rrq->value = bitrate_table[ratemode].bitrate * 100000;
3262 rrq->fixed = ! bitrate_table[ratemode].automatic;
3263 rrq->disabled = 0;
3264
3265 /* If the interface is running we try to find more about the
3266 current mode */
3267 if (netif_running(dev)) {
3268 err = hermes_read_wordrec(hw, USER_BAP,
3269 HERMES_RID_CURRENTTXRATE, &val);
3270 if (err)
3271 goto out;
3272
3273 switch (priv->firmware_type) {
3274 case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
3275 /* Note : in Lucent firmware, the return value of
3276 * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
3277 * and therefore is totally different from the
3278 * encoding of HERMES_RID_CNFTXRATECONTROL.
3279 * Don't forget that 6Mb/s is really 5.5Mb/s */
3280 if (val == 6)
3281 rrq->value = 5500000;
3282 else
3283 rrq->value = val * 1000000;
3284 break;
3285 case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
3286 case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
3287 for (i = 0; i < BITRATE_TABLE_SIZE; i++)
3288 if (bitrate_table[i].intersil_txratectrl == val) {
3289 ratemode = i;
3290 break;
3291 }
3292 if (i >= BITRATE_TABLE_SIZE)
3293 printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
3294 dev->name, val);
3295
3296 rrq->value = bitrate_table[ratemode].bitrate * 100000;
3297 break;
3298 default:
3299 BUG();
3300 }
3301 }
3302
3303 out:
3304 orinoco_unlock(priv, &flags);
3305
3306 return err;
3307}
3308
3309static int orinoco_ioctl_setpower(struct net_device *dev, struct iw_param *prq)
3310{
3311 struct orinoco_private *priv = netdev_priv(dev);
3312 int err = 0;
3313 unsigned long flags;
3314
3315 if (orinoco_lock(priv, &flags) != 0)
3316 return -EBUSY;
3317
3318 if (prq->disabled) {
3319 priv->pm_on = 0;
3320 } else {
3321 switch (prq->flags & IW_POWER_MODE) {
3322 case IW_POWER_UNICAST_R:
3323 priv->pm_mcast = 0;
3324 priv->pm_on = 1;
3325 break;
3326 case IW_POWER_ALL_R:
3327 priv->pm_mcast = 1;
3328 priv->pm_on = 1;
3329 break;
3330 case IW_POWER_ON:
3331 /* No flags : but we may have a value - Jean II */
3332 break;
3333 default:
3334 err = -EINVAL;
3335 }
3336 if (err)
3337 goto out;
3338
3339 if (prq->flags & IW_POWER_TIMEOUT) {
3340 priv->pm_on = 1;
3341 priv->pm_timeout = prq->value / 1000;
3342 }
3343 if (prq->flags & IW_POWER_PERIOD) {
3344 priv->pm_on = 1;
3345 priv->pm_period = prq->value / 1000;
3346 }
3347 /* It's valid to not have a value if we are just toggling
3348 * the flags... Jean II */
3349 if(!priv->pm_on) {
3350 err = -EINVAL;
3351 goto out;
3352 }
3353 }
3354
3355 out:
3356 orinoco_unlock(priv, &flags);
3357
3358 return err;
3359}
3360
3361static int orinoco_ioctl_getpower(struct net_device *dev, struct iw_param *prq)
3362{
3363 struct orinoco_private *priv = netdev_priv(dev);
3364 hermes_t *hw = &priv->hw;
3365 int err = 0;
3366 u16 enable, period, timeout, mcast;
3367 unsigned long flags;
3368
3369 if (orinoco_lock(priv, &flags) != 0)
3370 return -EBUSY;
3371
3372 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
3373 if (err)
3374 goto out;
3375
3376 err = hermes_read_wordrec(hw, USER_BAP,
3377 HERMES_RID_CNFMAXSLEEPDURATION, &period);
3378 if (err)
3379 goto out;
3380
3381 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
3382 if (err)
3383 goto out;
3384
3385 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
3386 if (err)
3387 goto out;
3388
3389 prq->disabled = !enable;
3390 /* Note : by default, display the period */
3391 if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
3392 prq->flags = IW_POWER_TIMEOUT;
3393 prq->value = timeout * 1000;
3394 } else {
3395 prq->flags = IW_POWER_PERIOD;
3396 prq->value = period * 1000;
3397 }
3398 if (mcast)
3399 prq->flags |= IW_POWER_ALL_R;
3400 else
3401 prq->flags |= IW_POWER_UNICAST_R;
3402
3403 out:
3404 orinoco_unlock(priv, &flags);
3405
3406 return err;
3407}
3408
3409static int orinoco_ioctl_getretry(struct net_device *dev, struct iw_param *rrq)
3410{
3411 struct orinoco_private *priv = netdev_priv(dev);
3412 hermes_t *hw = &priv->hw;
3413 int err = 0;
3414 u16 short_limit, long_limit, lifetime;
3415 unsigned long flags;
3416
3417 if (orinoco_lock(priv, &flags) != 0)
3418 return -EBUSY;
3419
3420 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
3421 &short_limit);
3422 if (err)
3423 goto out;
3424
3425 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
3426 &long_limit);
3427 if (err)
3428 goto out;
3429
3430 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
3431 &lifetime);
3432 if (err)
3433 goto out;
3434
3435 rrq->disabled = 0; /* Can't be disabled */
3436
3437 /* Note : by default, display the retry number */
3438 if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
3439 rrq->flags = IW_RETRY_LIFETIME;
3440 rrq->value = lifetime * 1000; /* ??? */
3441 } else {
3442 /* By default, display the min number */
3443 if ((rrq->flags & IW_RETRY_MAX)) {
3444 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
3445 rrq->value = long_limit;
3446 } else {
3447 rrq->flags = IW_RETRY_LIMIT;
3448 rrq->value = short_limit;
3449 if(short_limit != long_limit)
3450 rrq->flags |= IW_RETRY_MIN;
3451 }
3452 }
3453
3454 out:
3455 orinoco_unlock(priv, &flags);
3456
3457 return err;
3458}
3459
3460static int orinoco_ioctl_setibssport(struct net_device *dev, struct iwreq *wrq)
3461{
3462 struct orinoco_private *priv = netdev_priv(dev);
3463 int val = *( (int *) wrq->u.name );
3464 unsigned long flags;
3465
3466 if (orinoco_lock(priv, &flags) != 0)
3467 return -EBUSY;
3468
3469 priv->ibss_port = val ;
3470
3471 /* Actually update the mode we are using */
3472 set_port_type(priv);
3473
3474 orinoco_unlock(priv, &flags);
3475 return 0;
3476}
3477
3478static int orinoco_ioctl_getibssport(struct net_device *dev, struct iwreq *wrq)
3479{
3480 struct orinoco_private *priv = netdev_priv(dev);
3481 int *val = (int *)wrq->u.name;
3482 unsigned long flags;
3483
3484 if (orinoco_lock(priv, &flags) != 0)
3485 return -EBUSY;
3486
3487 *val = priv->ibss_port;
3488 orinoco_unlock(priv, &flags);
3489
3490 return 0;
3491}
3492
3493static int orinoco_ioctl_setport3(struct net_device *dev, struct iwreq *wrq)
3494{
3495 struct orinoco_private *priv = netdev_priv(dev);
3496 int val = *( (int *) wrq->u.name );
3497 int err = 0;
3498 unsigned long flags;
3499
3500 if (orinoco_lock(priv, &flags) != 0)
3501 return -EBUSY;
3502
3503 switch (val) {
3504 case 0: /* Try to do IEEE ad-hoc mode */
3505 if (! priv->has_ibss) {
3506 err = -EINVAL;
3507 break;
3508 }
3509 priv->prefer_port3 = 0;
3510
3511 break;
3512
3513 case 1: /* Try to do Lucent proprietary ad-hoc mode */
3514 if (! priv->has_port3) {
3515 err = -EINVAL;
3516 break;
3517 }
3518 priv->prefer_port3 = 1;
3519 break;
3520
3521 default:
3522 err = -EINVAL;
3523 }
3524
3525 if (! err)
3526 /* Actually update the mode we are using */
3527 set_port_type(priv);
3528
3529 orinoco_unlock(priv, &flags);
3530
3531 return err;
3532}
3533
3534static int orinoco_ioctl_getport3(struct net_device *dev, struct iwreq *wrq)
3535{
3536 struct orinoco_private *priv = netdev_priv(dev);
3537 int *val = (int *)wrq->u.name;
3538 unsigned long flags;
3539
3540 if (orinoco_lock(priv, &flags) != 0)
3541 return -EBUSY;
3542
3543 *val = priv->prefer_port3;
3544 orinoco_unlock(priv, &flags);
3545 return 0;
3546}
3547
3548/* Spy is used for link quality/strength measurements in Ad-Hoc mode
3549 * Jean II */
3550static int orinoco_ioctl_setspy(struct net_device *dev, struct iw_point *srq)
3551{
3552 struct orinoco_private *priv = netdev_priv(dev);
3553 struct sockaddr address[IW_MAX_SPY];
3554 int number = srq->length;
3555 int i;
3556 int err = 0;
3557 unsigned long flags;
3558
3559 /* Check the number of addresses */
3560 if (number > IW_MAX_SPY)
3561 return -E2BIG;
3562
3563 /* Get the data in the driver */
3564 if (srq->pointer) {
3565 if (copy_from_user(address, srq->pointer,
3566 sizeof(struct sockaddr) * number))
3567 return -EFAULT;
3568 }
3569
3570 /* Make sure nobody mess with the structure while we do */
3571 if (orinoco_lock(priv, &flags) != 0)
3572 return -EBUSY;
3573
3574 /* orinoco_lock() doesn't disable interrupts, so make sure the
3575 * interrupt rx path don't get confused while we copy */
3576 priv->spy_number = 0;
3577
3578 if (number > 0) {
3579 /* Extract the addresses */
3580 for (i = 0; i < number; i++)
3581 memcpy(priv->spy_address[i], address[i].sa_data,
3582 ETH_ALEN);
3583 /* Reset stats */
3584 memset(priv->spy_stat, 0,
3585 sizeof(struct iw_quality) * IW_MAX_SPY);
3586 /* Set number of addresses */
3587 priv->spy_number = number;
3588 }
3589
3590 /* Now, let the others play */
3591 orinoco_unlock(priv, &flags);
3592
3593 return err;
3594}
3595
3596static int orinoco_ioctl_getspy(struct net_device *dev, struct iw_point *srq)
3597{
3598 struct orinoco_private *priv = netdev_priv(dev);
3599 struct sockaddr address[IW_MAX_SPY];
3600 struct iw_quality spy_stat[IW_MAX_SPY];
3601 int number;
3602 int i;
3603 unsigned long flags;
3604
3605 if (orinoco_lock(priv, &flags) != 0)
3606 return -EBUSY;
3607
3608 number = priv->spy_number;
3609 if ((number > 0) && (srq->pointer)) {
3610 /* Create address struct */
3611 for (i = 0; i < number; i++) {
3612 memcpy(address[i].sa_data, priv->spy_address[i],
3613 ETH_ALEN);
3614 address[i].sa_family = AF_UNIX;
3615 }
3616 /* Copy stats */
3617 /* In theory, we should disable irqs while copying the stats
3618 * because the rx path might update it in the middle...
3619 * Bah, who care ? - Jean II */
3620 memcpy(&spy_stat, priv->spy_stat,
3621 sizeof(struct iw_quality) * IW_MAX_SPY);
3622 for (i=0; i < number; i++)
3623 priv->spy_stat[i].updated = 0;
3624 }
3625
3626 orinoco_unlock(priv, &flags);
3627
3628 /* Push stuff to user space */
3629 srq->length = number;
3630 if(copy_to_user(srq->pointer, address,
3631 sizeof(struct sockaddr) * number))
3632 return -EFAULT;
3633 if(copy_to_user(srq->pointer + (sizeof(struct sockaddr)*number),
3634 &spy_stat, sizeof(struct iw_quality) * number))
3635 return -EFAULT;
3636
3637 return 0;
3638}
3639
3640static int
3641orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3642{
3643 struct orinoco_private *priv = netdev_priv(dev);
3644 struct iwreq *wrq = (struct iwreq *)rq;
3645 int err = 0;
3646 int tmp;
3647 int changed = 0;
3648 unsigned long flags;
3649
3650 TRACE_ENTER(dev->name);
3651
3652 /* In theory, we could allow most of the the SET stuff to be
3653 * done. In practice, the lapse of time at startup when the
3654 * card is not ready is very short, so why bother... Note
3655 * that netif_device_present is different from up/down
3656 * (ifconfig), when the device is not yet up, it is usually
3657 * already ready... Jean II */
3658 if (! netif_device_present(dev))
3659 return -ENODEV;
3660
3661 switch (cmd) {
3662 case SIOCGIWNAME:
3663 strcpy(wrq->u.name, "IEEE 802.11-DS");
3664 break;
3665
3666 case SIOCGIWAP:
3667 wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
3668 err = orinoco_hw_get_bssid(priv, wrq->u.ap_addr.sa_data);
3669 break;
3670
3671 case SIOCGIWRANGE:
3672 err = orinoco_ioctl_getiwrange(dev, &wrq->u.data);
3673 break;
3674
3675 case SIOCSIWMODE:
3676 if (orinoco_lock(priv, &flags) != 0)
3677 return -EBUSY;
3678 switch (wrq->u.mode) {
3679 case IW_MODE_ADHOC:
3680 if (! (priv->has_ibss || priv->has_port3) )
3681 err = -EINVAL;
3682 else {
3683 priv->iw_mode = IW_MODE_ADHOC;
3684 changed = 1;
3685 }
3686 break;
3687
3688 case IW_MODE_INFRA:
3689 priv->iw_mode = IW_MODE_INFRA;
3690 changed = 1;
3691 break;
3692
3693 default:
3694 err = -EINVAL;
3695 break;
3696 }
3697 set_port_type(priv);
3698 orinoco_unlock(priv, &flags);
3699 break;
3700
3701 case SIOCGIWMODE:
3702 if (orinoco_lock(priv, &flags) != 0)
3703 return -EBUSY;
3704 wrq->u.mode = priv->iw_mode;
3705 orinoco_unlock(priv, &flags);
3706 break;
3707
3708 case SIOCSIWENCODE:
3709 err = orinoco_ioctl_setiwencode(dev, &wrq->u.encoding);
3710 if (! err)
3711 changed = 1;
3712 break;
3713
3714 case SIOCGIWENCODE:
3715 if (! capable(CAP_NET_ADMIN)) {
3716 err = -EPERM;
3717 break;
3718 }
3719
3720 err = orinoco_ioctl_getiwencode(dev, &wrq->u.encoding);
3721 break;
3722
3723 case SIOCSIWESSID:
3724 err = orinoco_ioctl_setessid(dev, &wrq->u.essid);
3725 if (! err)
3726 changed = 1;
3727 break;
3728
3729 case SIOCGIWESSID:
3730 err = orinoco_ioctl_getessid(dev, &wrq->u.essid);
3731 break;
3732
3733 case SIOCSIWNICKN:
3734 err = orinoco_ioctl_setnick(dev, &wrq->u.data);
3735 if (! err)
3736 changed = 1;
3737 break;
3738
3739 case SIOCGIWNICKN:
3740 err = orinoco_ioctl_getnick(dev, &wrq->u.data);
3741 break;
3742
3743 case SIOCGIWFREQ:
3744 tmp = orinoco_hw_get_freq(priv);
3745 if (tmp < 0) {
3746 err = tmp;
3747 } else {
3748 wrq->u.freq.m = tmp;
3749 wrq->u.freq.e = 1;
3750 }
3751 break;
3752
3753 case SIOCSIWFREQ:
3754 err = orinoco_ioctl_setfreq(dev, &wrq->u.freq);
3755 if (! err)
3756 changed = 1;
3757 break;
3758
3759 case SIOCGIWSENS:
3760 err = orinoco_ioctl_getsens(dev, &wrq->u.sens);
3761 break;
3762
3763 case SIOCSIWSENS:
3764 err = orinoco_ioctl_setsens(dev, &wrq->u.sens);
3765 if (! err)
3766 changed = 1;
3767 break;
3768
3769 case SIOCGIWRTS:
3770 wrq->u.rts.value = priv->rts_thresh;
3771 wrq->u.rts.disabled = (wrq->u.rts.value == 2347);
3772 wrq->u.rts.fixed = 1;
3773 break;
3774
3775 case SIOCSIWRTS:
3776 err = orinoco_ioctl_setrts(dev, &wrq->u.rts);
3777 if (! err)
3778 changed = 1;
3779 break;
3780
3781 case SIOCSIWFRAG:
3782 err = orinoco_ioctl_setfrag(dev, &wrq->u.frag);
3783 if (! err)
3784 changed = 1;
3785 break;
3786
3787 case SIOCGIWFRAG:
3788 err = orinoco_ioctl_getfrag(dev, &wrq->u.frag);
3789 break;
3790
3791 case SIOCSIWRATE:
3792 err = orinoco_ioctl_setrate(dev, &wrq->u.bitrate);
3793 if (! err)
3794 changed = 1;
3795 break;
3796
3797 case SIOCGIWRATE:
3798 err = orinoco_ioctl_getrate(dev, &wrq->u.bitrate);
3799 break;
3800
3801 case SIOCSIWPOWER:
3802 err = orinoco_ioctl_setpower(dev, &wrq->u.power);
3803 if (! err)
3804 changed = 1;
3805 break;
3806
3807 case SIOCGIWPOWER:
3808 err = orinoco_ioctl_getpower(dev, &wrq->u.power);
3809 break;
3810
3811 case SIOCGIWTXPOW:
3812 /* The card only supports one tx power, so this is easy */
3813 wrq->u.txpower.value = 15; /* dBm */
3814 wrq->u.txpower.fixed = 1;
3815 wrq->u.txpower.disabled = 0;
3816 wrq->u.txpower.flags = IW_TXPOW_DBM;
3817 break;
3818
3819 case SIOCSIWRETRY:
3820 err = -EOPNOTSUPP;
3821 break;
3822
3823 case SIOCGIWRETRY:
3824 err = orinoco_ioctl_getretry(dev, &wrq->u.retry);
3825 break;
3826
3827 case SIOCSIWSPY:
3828 err = orinoco_ioctl_setspy(dev, &wrq->u.data);
3829 break;
3830
3831 case SIOCGIWSPY:
3832 err = orinoco_ioctl_getspy(dev, &wrq->u.data);
3833 break;
3834
3835 case SIOCGIWPRIV:
3836 if (wrq->u.data.pointer) {
3837 struct iw_priv_args privtab[] = {
3838 { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
3839 { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
3840 { SIOCIWFIRSTPRIV + 0x2,
3841 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3842 0, "set_port3" },
3843 { SIOCIWFIRSTPRIV + 0x3, 0,
3844 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3845 "get_port3" },
3846 { SIOCIWFIRSTPRIV + 0x4,
3847 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3848 0, "set_preamble" },
3849 { SIOCIWFIRSTPRIV + 0x5, 0,
3850 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3851 "get_preamble" },
3852 { SIOCIWFIRSTPRIV + 0x6,
3853 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3854 0, "set_ibssport" },
3855 { SIOCIWFIRSTPRIV + 0x7, 0,
3856 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3857 "get_ibssport" },
3858 { SIOCIWLASTPRIV, 0, 0, "dump_recs" },
3859 };
3860
3861 wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
3862 if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
3863 err = -EFAULT;
3864 }
3865 break;
3866
3867 case SIOCIWFIRSTPRIV + 0x0: /* force_reset */
3868 case SIOCIWFIRSTPRIV + 0x1: /* card_reset */
3869 if (! capable(CAP_NET_ADMIN)) {
3870 err = -EPERM;
3871 break;
3872 }
3873
3874 printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
3875
3876 schedule_work(&priv->reset_work);
3877 break;
3878
3879 case SIOCIWFIRSTPRIV + 0x2: /* set_port3 */
3880 if (! capable(CAP_NET_ADMIN)) {
3881 err = -EPERM;
3882 break;
3883 }
3884
3885 err = orinoco_ioctl_setport3(dev, wrq);
3886 if (! err)
3887 changed = 1;
3888 break;
3889
3890 case SIOCIWFIRSTPRIV + 0x3: /* get_port3 */
3891 err = orinoco_ioctl_getport3(dev, wrq);
3892 break;
3893
3894 case SIOCIWFIRSTPRIV + 0x4: /* set_preamble */
3895 if (! capable(CAP_NET_ADMIN)) {
3896 err = -EPERM;
3897 break;
3898 }
3899
3900 /* 802.11b has recently defined some short preamble.
3901 * Basically, the Phy header has been reduced in size.
3902 * This increase performance, especially at high rates
3903 * (the preamble is transmitted at 1Mb/s), unfortunately
3904 * this give compatibility troubles... - Jean II */
3905 if(priv->has_preamble) {
3906 int val = *( (int *) wrq->u.name );
3907
3908 if (orinoco_lock(priv, &flags) != 0)
3909 return -EBUSY;
3910 if (val)
3911 priv->preamble = 1;
3912 else
3913 priv->preamble = 0;
3914 orinoco_unlock(priv, &flags);
3915 changed = 1;
3916 } else
3917 err = -EOPNOTSUPP;
3918 break;
3919
3920 case SIOCIWFIRSTPRIV + 0x5: /* get_preamble */
3921 if(priv->has_preamble) {
3922 int *val = (int *)wrq->u.name;
3923
3924 if (orinoco_lock(priv, &flags) != 0)
3925 return -EBUSY;
3926 *val = priv->preamble;
3927 orinoco_unlock(priv, &flags);
3928 } else
3929 err = -EOPNOTSUPP;
3930 break;
3931 case SIOCIWFIRSTPRIV + 0x6: /* set_ibssport */
3932 if (! capable(CAP_NET_ADMIN)) {
3933 err = -EPERM;
3934 break;
3935 }
3936
3937 err = orinoco_ioctl_setibssport(dev, wrq);
3938 if (! err)
3939 changed = 1;
3940 break;
3941
3942 case SIOCIWFIRSTPRIV + 0x7: /* get_ibssport */
3943 err = orinoco_ioctl_getibssport(dev, wrq);
3944 break;
3945
3946 case SIOCIWLASTPRIV:
3947 err = orinoco_debug_dump_recs(dev);
3948 if (err)
3949 printk(KERN_ERR "%s: Unable to dump records (%d)\n",
3950 dev->name, err);
3951 break;
3952
3953
3954 default:
3955 err = -EOPNOTSUPP;
3956 }
3957
3958 if (! err && changed && netif_running(dev)) {
3959 err = orinoco_reconfigure(dev);
3960 }
3961
3962 TRACE_EXIT(dev->name);
3963
3964 return err;
3965}
3966
3967struct {
3968 u16 rid;
3969 char *name;
3970 int displaytype;
3971#define DISPLAY_WORDS 0
3972#define DISPLAY_BYTES 1
3973#define DISPLAY_STRING 2
3974#define DISPLAY_XSTRING 3
3975} record_table[] = {
3976#define DEBUG_REC(name,type) { HERMES_RID_##name, #name, DISPLAY_##type }
3977 DEBUG_REC(CNFPORTTYPE,WORDS),
3978 DEBUG_REC(CNFOWNMACADDR,BYTES),
3979 DEBUG_REC(CNFDESIREDSSID,STRING),
3980 DEBUG_REC(CNFOWNCHANNEL,WORDS),
3981 DEBUG_REC(CNFOWNSSID,STRING),
3982 DEBUG_REC(CNFOWNATIMWINDOW,WORDS),
3983 DEBUG_REC(CNFSYSTEMSCALE,WORDS),
3984 DEBUG_REC(CNFMAXDATALEN,WORDS),
3985 DEBUG_REC(CNFPMENABLED,WORDS),
3986 DEBUG_REC(CNFPMEPS,WORDS),
3987 DEBUG_REC(CNFMULTICASTRECEIVE,WORDS),
3988 DEBUG_REC(CNFMAXSLEEPDURATION,WORDS),
3989 DEBUG_REC(CNFPMHOLDOVERDURATION,WORDS),
3990 DEBUG_REC(CNFOWNNAME,STRING),
3991 DEBUG_REC(CNFOWNDTIMPERIOD,WORDS),
3992 DEBUG_REC(CNFMULTICASTPMBUFFERING,WORDS),
3993 DEBUG_REC(CNFWEPENABLED_AGERE,WORDS),
3994 DEBUG_REC(CNFMANDATORYBSSID_SYMBOL,WORDS),
3995 DEBUG_REC(CNFWEPDEFAULTKEYID,WORDS),
3996 DEBUG_REC(CNFDEFAULTKEY0,BYTES),
3997 DEBUG_REC(CNFDEFAULTKEY1,BYTES),
3998 DEBUG_REC(CNFMWOROBUST_AGERE,WORDS),
3999 DEBUG_REC(CNFDEFAULTKEY2,BYTES),
4000 DEBUG_REC(CNFDEFAULTKEY3,BYTES),
4001 DEBUG_REC(CNFWEPFLAGS_INTERSIL,WORDS),
4002 DEBUG_REC(CNFWEPKEYMAPPINGTABLE,WORDS),
4003 DEBUG_REC(CNFAUTHENTICATION,WORDS),
4004 DEBUG_REC(CNFMAXASSOCSTA,WORDS),
4005 DEBUG_REC(CNFKEYLENGTH_SYMBOL,WORDS),
4006 DEBUG_REC(CNFTXCONTROL,WORDS),
4007 DEBUG_REC(CNFROAMINGMODE,WORDS),
4008 DEBUG_REC(CNFHOSTAUTHENTICATION,WORDS),
4009 DEBUG_REC(CNFRCVCRCERROR,WORDS),
4010 DEBUG_REC(CNFMMLIFE,WORDS),
4011 DEBUG_REC(CNFALTRETRYCOUNT,WORDS),
4012 DEBUG_REC(CNFBEACONINT,WORDS),
4013 DEBUG_REC(CNFAPPCFINFO,WORDS),
4014 DEBUG_REC(CNFSTAPCFINFO,WORDS),
4015 DEBUG_REC(CNFPRIORITYQUSAGE,WORDS),
4016 DEBUG_REC(CNFTIMCTRL,WORDS),
4017 DEBUG_REC(CNFTHIRTY2TALLY,WORDS),
4018 DEBUG_REC(CNFENHSECURITY,WORDS),
4019 DEBUG_REC(CNFGROUPADDRESSES,BYTES),
4020 DEBUG_REC(CNFCREATEIBSS,WORDS),
4021 DEBUG_REC(CNFFRAGMENTATIONTHRESHOLD,WORDS),
4022 DEBUG_REC(CNFRTSTHRESHOLD,WORDS),
4023 DEBUG_REC(CNFTXRATECONTROL,WORDS),
4024 DEBUG_REC(CNFPROMISCUOUSMODE,WORDS),
4025 DEBUG_REC(CNFBASICRATES_SYMBOL,WORDS),
4026 DEBUG_REC(CNFPREAMBLE_SYMBOL,WORDS),
4027 DEBUG_REC(CNFSHORTPREAMBLE,WORDS),
4028 DEBUG_REC(CNFWEPKEYS_AGERE,BYTES),
4029 DEBUG_REC(CNFEXCLUDELONGPREAMBLE,WORDS),
4030 DEBUG_REC(CNFTXKEY_AGERE,WORDS),
4031 DEBUG_REC(CNFAUTHENTICATIONRSPTO,WORDS),
4032 DEBUG_REC(CNFBASICRATES,WORDS),
4033 DEBUG_REC(CNFSUPPORTEDRATES,WORDS),
4034 DEBUG_REC(CNFTICKTIME,WORDS),
4035 DEBUG_REC(CNFSCANREQUEST,WORDS),
4036 DEBUG_REC(CNFJOINREQUEST,WORDS),
4037 DEBUG_REC(CNFAUTHENTICATESTATION,WORDS),
4038 DEBUG_REC(CNFCHANNELINFOREQUEST,WORDS),
4039 DEBUG_REC(MAXLOADTIME,WORDS),
4040 DEBUG_REC(DOWNLOADBUFFER,WORDS),
4041 DEBUG_REC(PRIID,WORDS),
4042 DEBUG_REC(PRISUPRANGE,WORDS),
4043 DEBUG_REC(CFIACTRANGES,WORDS),
4044 DEBUG_REC(NICSERNUM,XSTRING),
4045 DEBUG_REC(NICID,WORDS),
4046 DEBUG_REC(MFISUPRANGE,WORDS),
4047 DEBUG_REC(CFISUPRANGE,WORDS),
4048 DEBUG_REC(CHANNELLIST,WORDS),
4049 DEBUG_REC(REGULATORYDOMAINS,WORDS),
4050 DEBUG_REC(TEMPTYPE,WORDS),
4051/* DEBUG_REC(CIS,BYTES), */
4052 DEBUG_REC(STAID,WORDS),
4053 DEBUG_REC(CURRENTSSID,STRING),
4054 DEBUG_REC(CURRENTBSSID,BYTES),
4055 DEBUG_REC(COMMSQUALITY,WORDS),
4056 DEBUG_REC(CURRENTTXRATE,WORDS),
4057 DEBUG_REC(CURRENTBEACONINTERVAL,WORDS),
4058 DEBUG_REC(CURRENTSCALETHRESHOLDS,WORDS),
4059 DEBUG_REC(PROTOCOLRSPTIME,WORDS),
4060 DEBUG_REC(SHORTRETRYLIMIT,WORDS),
4061 DEBUG_REC(LONGRETRYLIMIT,WORDS),
4062 DEBUG_REC(MAXTRANSMITLIFETIME,WORDS),
4063 DEBUG_REC(MAXRECEIVELIFETIME,WORDS),
4064 DEBUG_REC(CFPOLLABLE,WORDS),
4065 DEBUG_REC(AUTHENTICATIONALGORITHMS,WORDS),
4066 DEBUG_REC(PRIVACYOPTIONIMPLEMENTED,WORDS),
4067 DEBUG_REC(OWNMACADDR,BYTES),
4068 DEBUG_REC(SCANRESULTSTABLE,WORDS),
4069 DEBUG_REC(PHYTYPE,WORDS),
4070 DEBUG_REC(CURRENTCHANNEL,WORDS),
4071 DEBUG_REC(CURRENTPOWERSTATE,WORDS),
4072 DEBUG_REC(CCAMODE,WORDS),
4073 DEBUG_REC(SUPPORTEDDATARATES,WORDS),
4074 DEBUG_REC(BUILDSEQ,BYTES),
4075 DEBUG_REC(FWID,XSTRING)
4076#undef DEBUG_REC
4077};
4078
4079#define DEBUG_LTV_SIZE 128
4080
4081static int orinoco_debug_dump_recs(struct net_device *dev)
4082{
4083 struct orinoco_private *priv = netdev_priv(dev);
4084 hermes_t *hw = &priv->hw;
4085 u8 *val8;
4086 u16 *val16;
4087 int i,j;
4088 u16 length;
4089 int err;
4090
4091 /* I'm not sure: we might have a lock here, so we'd better go
4092 atomic, just in case. */
4093 val8 = kmalloc(DEBUG_LTV_SIZE + 2, GFP_ATOMIC);
4094 if (! val8)
4095 return -ENOMEM;
4096 val16 = (u16 *)val8;
4097
4098 for (i = 0; i < ARRAY_SIZE(record_table); i++) {
4099 u16 rid = record_table[i].rid;
4100 int len;
4101
4102 memset(val8, 0, DEBUG_LTV_SIZE + 2);
4103
4104 err = hermes_read_ltv(hw, USER_BAP, rid, DEBUG_LTV_SIZE,
4105 &length, val8);
4106 if (err) {
4107 DEBUG(0, "Error %d reading RID 0x%04x\n", err, rid);
4108 continue;
4109 }
4110 val16 = (u16 *)val8;
4111 if (length == 0)
4112 continue;
4113
4114 printk(KERN_DEBUG "%-15s (0x%04x): length=%d (%d bytes)\tvalue=",
4115 record_table[i].name,
4116 rid, length, (length-1)*2);
4117 len = min(((int)length-1)*2, DEBUG_LTV_SIZE);
4118
4119 switch (record_table[i].displaytype) {
4120 case DISPLAY_WORDS:
4121 for (j = 0; j < len / 2; j++)
4122 printk("%04X-", le16_to_cpu(val16[j]));
4123 break;
4124
4125 case DISPLAY_BYTES:
4126 default:
4127 for (j = 0; j < len; j++)
4128 printk("%02X:", val8[j]);
4129 break;
4130
4131 case DISPLAY_STRING:
4132 len = min(len, le16_to_cpu(val16[0])+2);
4133 val8[len] = '\0';
4134 printk("\"%s\"", (char *)&val16[1]);
4135 break;
4136
4137 case DISPLAY_XSTRING:
4138 printk("'%s'", (char *)val8);
4139 }
4140
4141 printk("\n");
4142 }
4143
4144 kfree(val8);
4145
4146 return 0;
4147}
4148
4149/********************************************************************/
4150/* Debugging */
4151/********************************************************************/
4152
4153#if 0
4154static void show_rx_frame(struct orinoco_rxframe_hdr *frame)
4155{
4156 printk(KERN_DEBUG "RX descriptor:\n");
4157 printk(KERN_DEBUG " status = 0x%04x\n", frame->desc.status);
4158 printk(KERN_DEBUG " time = 0x%08x\n", frame->desc.time);
4159 printk(KERN_DEBUG " silence = 0x%02x\n", frame->desc.silence);
4160 printk(KERN_DEBUG " signal = 0x%02x\n", frame->desc.signal);
4161 printk(KERN_DEBUG " rate = 0x%02x\n", frame->desc.rate);
4162 printk(KERN_DEBUG " rxflow = 0x%02x\n", frame->desc.rxflow);
4163 printk(KERN_DEBUG " reserved = 0x%08x\n", frame->desc.reserved);
4164
4165 printk(KERN_DEBUG "IEEE 802.11 header:\n");
4166 printk(KERN_DEBUG " frame_ctl = 0x%04x\n",
4167 frame->p80211.frame_ctl);
4168 printk(KERN_DEBUG " duration_id = 0x%04x\n",
4169 frame->p80211.duration_id);
4170 printk(KERN_DEBUG " addr1 = %02x:%02x:%02x:%02x:%02x:%02x\n",
4171 frame->p80211.addr1[0], frame->p80211.addr1[1],
4172 frame->p80211.addr1[2], frame->p80211.addr1[3],
4173 frame->p80211.addr1[4], frame->p80211.addr1[5]);
4174 printk(KERN_DEBUG " addr2 = %02x:%02x:%02x:%02x:%02x:%02x\n",
4175 frame->p80211.addr2[0], frame->p80211.addr2[1],
4176 frame->p80211.addr2[2], frame->p80211.addr2[3],
4177 frame->p80211.addr2[4], frame->p80211.addr2[5]);
4178 printk(KERN_DEBUG " addr3 = %02x:%02x:%02x:%02x:%02x:%02x\n",
4179 frame->p80211.addr3[0], frame->p80211.addr3[1],
4180 frame->p80211.addr3[2], frame->p80211.addr3[3],
4181 frame->p80211.addr3[4], frame->p80211.addr3[5]);
4182 printk(KERN_DEBUG " seq_ctl = 0x%04x\n",
4183 frame->p80211.seq_ctl);
4184 printk(KERN_DEBUG " addr4 = %02x:%02x:%02x:%02x:%02x:%02x\n",
4185 frame->p80211.addr4[0], frame->p80211.addr4[1],
4186 frame->p80211.addr4[2], frame->p80211.addr4[3],
4187 frame->p80211.addr4[4], frame->p80211.addr4[5]);
4188 printk(KERN_DEBUG " data_len = 0x%04x\n",
4189 frame->p80211.data_len);
4190
4191 printk(KERN_DEBUG "IEEE 802.3 header:\n");
4192 printk(KERN_DEBUG " dest = %02x:%02x:%02x:%02x:%02x:%02x\n",
4193 frame->p8023.h_dest[0], frame->p8023.h_dest[1],
4194 frame->p8023.h_dest[2], frame->p8023.h_dest[3],
4195 frame->p8023.h_dest[4], frame->p8023.h_dest[5]);
4196 printk(KERN_DEBUG " src = %02x:%02x:%02x:%02x:%02x:%02x\n",
4197 frame->p8023.h_source[0], frame->p8023.h_source[1],
4198 frame->p8023.h_source[2], frame->p8023.h_source[3],
4199 frame->p8023.h_source[4], frame->p8023.h_source[5]);
4200 printk(KERN_DEBUG " len = 0x%04x\n", frame->p8023.h_proto);
4201
4202 printk(KERN_DEBUG "IEEE 802.2 LLC/SNAP header:\n");
4203 printk(KERN_DEBUG " DSAP = 0x%02x\n", frame->p8022.dsap);
4204 printk(KERN_DEBUG " SSAP = 0x%02x\n", frame->p8022.ssap);
4205 printk(KERN_DEBUG " ctrl = 0x%02x\n", frame->p8022.ctrl);
4206 printk(KERN_DEBUG " OUI = %02x:%02x:%02x\n",
4207 frame->p8022.oui[0], frame->p8022.oui[1], frame->p8022.oui[2]);
4208 printk(KERN_DEBUG " ethertype = 0x%04x\n", frame->ethertype);
4209}
4210#endif /* 0 */
4211
4212/********************************************************************/
4213/* Module initialization */
4214/********************************************************************/
4215
4216EXPORT_SYMBOL(alloc_orinocodev);
4217EXPORT_SYMBOL(free_orinocodev);
4218
4219EXPORT_SYMBOL(__orinoco_up);
4220EXPORT_SYMBOL(__orinoco_down);
4221EXPORT_SYMBOL(orinoco_stop);
4222EXPORT_SYMBOL(orinoco_reinit_firmware);
4223
4224EXPORT_SYMBOL(orinoco_interrupt);
4225
4226/* Can't be declared "const" or the whole __initdata section will
4227 * become const */
4228static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
4229 " (David Gibson <hermes@gibson.dropbear.id.au>, "
4230 "Pavel Roskin <proski@gnu.org>, et al)";
4231
4232static int __init init_orinoco(void)
4233{
4234 printk(KERN_DEBUG "%s\n", version);
4235 return 0;
4236}
4237
4238static void __exit exit_orinoco(void)
4239{
4240}
4241
4242module_init(init_orinoco);
4243module_exit(exit_orinoco);
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
new file mode 100644
index 000000000000..13e42c2afb27
--- /dev/null
+++ b/drivers/net/wireless/orinoco.h
@@ -0,0 +1,153 @@
1/* orinoco.h
2 *
3 * Common definitions to all pieces of the various orinoco
4 * drivers
5 */
6
7#ifndef _ORINOCO_H
8#define _ORINOCO_H
9
10#define DRIVER_VERSION "0.14alpha2"
11
12#include <linux/types.h>
13#include <linux/spinlock.h>
14#include <linux/netdevice.h>
15#include <linux/wireless.h>
16#include <linux/version.h>
17
18#include "hermes.h"
19
20/* To enable debug messages */
21//#define ORINOCO_DEBUG 3
22
23#define WIRELESS_SPY // enable iwspy support
24
25#define ORINOCO_MAX_KEY_SIZE 14
26#define ORINOCO_MAX_KEYS 4
27
28struct orinoco_key {
29 u16 len; /* always stored as little-endian */
30 char data[ORINOCO_MAX_KEY_SIZE];
31} __attribute__ ((packed));
32
33typedef enum {
34 FIRMWARE_TYPE_AGERE,
35 FIRMWARE_TYPE_INTERSIL,
36 FIRMWARE_TYPE_SYMBOL
37} fwtype_t;
38
39struct orinoco_private {
40 void *card; /* Pointer to card dependent structure */
41 int (*hard_reset)(struct orinoco_private *);
42
43 /* Synchronisation stuff */
44 spinlock_t lock;
45 int hw_unavailable;
46 struct work_struct reset_work;
47
48 /* driver state */
49 int open;
50 u16 last_linkstatus;
51
52 /* Net device stuff */
53 struct net_device *ndev;
54 struct net_device_stats stats;
55 struct iw_statistics wstats;
56
57 /* Hardware control variables */
58 hermes_t hw;
59 u16 txfid;
60
61 /* Capabilities of the hardware/firmware */
62 fwtype_t firmware_type;
63 char fw_name[32];
64 int ibss_port;
65 int nicbuf_size;
66 u16 channel_mask;
67
68 /* Boolean capabilities */
69 unsigned int has_ibss:1;
70 unsigned int has_port3:1;
71 unsigned int has_wep:1;
72 unsigned int has_big_wep:1;
73 unsigned int has_mwo:1;
74 unsigned int has_pm:1;
75 unsigned int has_preamble:1;
76 unsigned int has_sensitivity:1;
77 unsigned int broken_disableport:1;
78
79 /* Configuration paramaters */
80 u32 iw_mode;
81 int prefer_port3;
82 u16 wep_on, wep_restrict, tx_key;
83 struct orinoco_key keys[ORINOCO_MAX_KEYS];
84 int bitratemode;
85 char nick[IW_ESSID_MAX_SIZE+1];
86 char desired_essid[IW_ESSID_MAX_SIZE+1];
87 u16 frag_thresh, mwo_robust;
88 u16 channel;
89 u16 ap_density, rts_thresh;
90 u16 pm_on, pm_mcast, pm_period, pm_timeout;
91 u16 preamble;
92#ifdef WIRELESS_SPY
93 int spy_number;
94 u_char spy_address[IW_MAX_SPY][ETH_ALEN];
95 struct iw_quality spy_stat[IW_MAX_SPY];
96#endif
97
98 /* Configuration dependent variables */
99 int port_type, createibss;
100 int promiscuous, mc_count;
101};
102
103#ifdef ORINOCO_DEBUG
104extern int orinoco_debug;
105#define DEBUG(n, args...) do { if (orinoco_debug>(n)) printk(KERN_DEBUG args); } while(0)
106#else
107#define DEBUG(n, args...) do { } while (0)
108#endif /* ORINOCO_DEBUG */
109
110#define TRACE_ENTER(devname) DEBUG(2, "%s: -> %s()\n", devname, __FUNCTION__);
111#define TRACE_EXIT(devname) DEBUG(2, "%s: <- %s()\n", devname, __FUNCTION__);
112
113/********************************************************************/
114/* Exported prototypes */
115/********************************************************************/
116
117extern struct net_device *alloc_orinocodev(int sizeof_card,
118 int (*hard_reset)(struct orinoco_private *));
119extern void free_orinocodev(struct net_device *dev);
120extern int __orinoco_up(struct net_device *dev);
121extern int __orinoco_down(struct net_device *dev);
122extern int orinoco_stop(struct net_device *dev);
123extern int orinoco_reinit_firmware(struct net_device *dev);
124extern irqreturn_t orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);
125
126/********************************************************************/
127/* Locking and synchronization functions */
128/********************************************************************/
129
130/* These functions *must* be inline or they will break horribly on
131 * SPARC, due to its weird semantics for save/restore flags. extern
132 * inline should prevent the kernel from linking or module from
133 * loading if they are not inlined. */
134extern inline int orinoco_lock(struct orinoco_private *priv,
135 unsigned long *flags)
136{
137 spin_lock_irqsave(&priv->lock, *flags);
138 if (priv->hw_unavailable) {
139 DEBUG(1, "orinoco_lock() called with hw_unavailable (dev=%p)\n",
140 priv->ndev);
141 spin_unlock_irqrestore(&priv->lock, *flags);
142 return -EBUSY;
143 }
144 return 0;
145}
146
147extern inline void orinoco_unlock(struct orinoco_private *priv,
148 unsigned long *flags)
149{
150 spin_unlock_irqrestore(&priv->lock, *flags);
151}
152
153#endif /* _ORINOCO_H */
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
new file mode 100644
index 000000000000..74a8227256aa
--- /dev/null
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -0,0 +1,636 @@
1/* orinoco_cs.c (formerly known as dldwd_cs.c)
2 *
3 * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
4 * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
5 * EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and others).
6 * It should also be usable on various Prism II based cards such as the
7 * Linksys, D-Link and Farallon Skyline. It should also work on Symbol
8 * cards such as the 3Com AirConnect and Ericsson WLAN.
9 *
10 * Copyright notice & release notes in file orinoco.c
11 */
12
13#define DRIVER_NAME "orinoco_cs"
14#define PFX DRIVER_NAME ": "
15
16#include <linux/config.h>
17#ifdef __IN_PCMCIA_PACKAGE__
18#include <pcmcia/k_compat.h>
19#endif /* __IN_PCMCIA_PACKAGE__ */
20
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/sched.h>
25#include <linux/ptrace.h>
26#include <linux/slab.h>
27#include <linux/string.h>
28#include <linux/ioport.h>
29#include <linux/netdevice.h>
30#include <linux/if_arp.h>
31#include <linux/etherdevice.h>
32#include <linux/wireless.h>
33
34#include <pcmcia/version.h>
35#include <pcmcia/cs_types.h>
36#include <pcmcia/cs.h>
37#include <pcmcia/cistpl.h>
38#include <pcmcia/cisreg.h>
39#include <pcmcia/ds.h>
40
41#include <asm/uaccess.h>
42#include <asm/io.h>
43#include <asm/system.h>
44
45#include "orinoco.h"
46
47/********************************************************************/
48/* Module stuff */
49/********************************************************************/
50
51MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
52MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards");
53MODULE_LICENSE("Dual MPL/GPL");
54
55/* Module parameters */
56
57/* Some D-Link cards have buggy CIS. They do work at 5v properly, but
58 * don't have any CIS entry for it. This workaround it... */
59static int ignore_cis_vcc; /* = 0 */
60module_param(ignore_cis_vcc, int, 0);
61MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
62
63/********************************************************************/
64/* Magic constants */
65/********************************************************************/
66
67/*
68 * The dev_info variable is the "key" that is used to match up this
69 * device driver with appropriate cards, through the card
70 * configuration database.
71 */
72static dev_info_t dev_info = DRIVER_NAME;
73
74/********************************************************************/
75/* Data structures */
76/********************************************************************/
77
78/* PCMCIA specific device information (goes in the card field of
79 * struct orinoco_private */
80struct orinoco_pccard {
81 dev_link_t link;
82 dev_node_t node;
83
84 /* Used to handle hard reset */
85 /* yuck, we need this hack to work around the insanity of the
86 * PCMCIA layer */
87 unsigned long hard_reset_in_progress;
88};
89
90/*
91 * A linked list of "instances" of the device. Each actual PCMCIA
92 * card corresponds to one device instance, and is described by one
93 * dev_link_t structure (defined in ds.h).
94 */
95static dev_link_t *dev_list; /* = NULL */
96
97/********************************************************************/
98/* Function prototypes */
99/********************************************************************/
100
101/* device methods */
102static int orinoco_cs_hard_reset(struct orinoco_private *priv);
103
104/* PCMCIA gumpf */
105static void orinoco_cs_config(dev_link_t * link);
106static void orinoco_cs_release(dev_link_t * link);
107static int orinoco_cs_event(event_t event, int priority,
108 event_callback_args_t * args);
109
110static dev_link_t *orinoco_cs_attach(void);
111static void orinoco_cs_detach(dev_link_t *);
112
113/********************************************************************/
114/* Device methods */
115/********************************************************************/
116
117static int
118orinoco_cs_hard_reset(struct orinoco_private *priv)
119{
120 struct orinoco_pccard *card = priv->card;
121 dev_link_t *link = &card->link;
122 int err;
123
124 /* We need atomic ops here, because we're not holding the lock */
125 set_bit(0, &card->hard_reset_in_progress);
126
127 err = pcmcia_reset_card(link->handle, NULL);
128 if (err)
129 return err;
130
131 msleep(100);
132 clear_bit(0, &card->hard_reset_in_progress);
133
134 return 0;
135}
136
137/********************************************************************/
138/* PCMCIA stuff */
139/********************************************************************/
140
141/*
142 * This creates an "instance" of the driver, allocating local data
143 * structures for one device. The device is registered with Card
144 * Services.
145 *
146 * The dev_link structure is initialized, but we don't actually
147 * configure the card at this point -- we wait until we receive a card
148 * insertion event. */
149static dev_link_t *
150orinoco_cs_attach(void)
151{
152 struct net_device *dev;
153 struct orinoco_private *priv;
154 struct orinoco_pccard *card;
155 dev_link_t *link;
156 client_reg_t client_reg;
157 int ret;
158
159 dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
160 if (! dev)
161 return NULL;
162 priv = netdev_priv(dev);
163 card = priv->card;
164
165 /* Link both structures together */
166 link = &card->link;
167 link->priv = dev;
168
169 /* Interrupt setup */
170 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
171 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
172 link->irq.Handler = orinoco_interrupt;
173 link->irq.Instance = dev;
174
175 /* General socket configuration defaults can go here. In this
176 * client, we assume very little, and rely on the CIS for
177 * almost everything. In most clients, many details (i.e.,
178 * number, sizes, and attributes of IO windows) are fixed by
179 * the nature of the device, and can be hard-wired here. */
180 link->conf.Attributes = 0;
181 link->conf.IntType = INT_MEMORY_AND_IO;
182
183 /* Register with Card Services */
184 /* FIXME: need a lock? */
185 link->next = dev_list;
186 dev_list = link;
187
188 client_reg.dev_info = &dev_info;
189 client_reg.EventMask =
190 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
191 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
192 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
193 client_reg.event_handler = &orinoco_cs_event;
194 client_reg.Version = 0x0210; /* FIXME: what does this mean? */
195 client_reg.event_callback_args.client_data = link;
196
197 ret = pcmcia_register_client(&link->handle, &client_reg);
198 if (ret != CS_SUCCESS) {
199 cs_error(link->handle, RegisterClient, ret);
200 orinoco_cs_detach(link);
201 return NULL;
202 }
203
204 return link;
205} /* orinoco_cs_attach */
206
207/*
208 * This deletes a driver "instance". The device is de-registered with
209 * Card Services. If it has been released, all local data structures
210 * are freed. Otherwise, the structures will be freed when the device
211 * is released.
212 */
213static void orinoco_cs_detach(dev_link_t *link)
214{
215 dev_link_t **linkp;
216 struct net_device *dev = link->priv;
217
218 /* Locate device structure */
219 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
220 if (*linkp == link)
221 break;
222
223 BUG_ON(*linkp == NULL);
224
225 if (link->state & DEV_CONFIG)
226 orinoco_cs_release(link);
227
228 /* Break the link with Card Services */
229 if (link->handle)
230 pcmcia_deregister_client(link->handle);
231
232 /* Unlink device structure, and free it */
233 *linkp = link->next;
234 DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
235 if (link->dev) {
236 DEBUG(0, PFX "About to unregister net device %p\n",
237 dev);
238 unregister_netdev(dev);
239 }
240 free_orinocodev(dev);
241} /* orinoco_cs_detach */
242
243/*
244 * orinoco_cs_config() is scheduled to run after a CARD_INSERTION
245 * event is received, to configure the PCMCIA socket, and to make the
246 * device available to the system.
247 */
248
249#define CS_CHECK(fn, ret) do { \
250 last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \
251 } while (0)
252
253static void
254orinoco_cs_config(dev_link_t *link)
255{
256 struct net_device *dev = link->priv;
257 client_handle_t handle = link->handle;
258 struct orinoco_private *priv = netdev_priv(dev);
259 struct orinoco_pccard *card = priv->card;
260 hermes_t *hw = &priv->hw;
261 int last_fn, last_ret;
262 u_char buf[64];
263 config_info_t conf;
264 cisinfo_t info;
265 tuple_t tuple;
266 cisparse_t parse;
267 void __iomem *mem;
268
269 CS_CHECK(ValidateCIS, pcmcia_validate_cis(handle, &info));
270
271 /*
272 * This reads the card's CONFIG tuple to find its
273 * configuration registers.
274 */
275 tuple.DesiredTuple = CISTPL_CONFIG;
276 tuple.Attributes = 0;
277 tuple.TupleData = buf;
278 tuple.TupleDataMax = sizeof(buf);
279 tuple.TupleOffset = 0;
280 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
281 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
282 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
283 link->conf.ConfigBase = parse.config.base;
284 link->conf.Present = parse.config.rmask[0];
285
286 /* Configure card */
287 link->state |= DEV_CONFIG;
288
289 /* Look up the current Vcc */
290 CS_CHECK(GetConfigurationInfo,
291 pcmcia_get_configuration_info(handle, &conf));
292 link->conf.Vcc = conf.Vcc;
293
294 /*
295 * In this loop, we scan the CIS for configuration table
296 * entries, each of which describes a valid card
297 * configuration, including voltage, IO window, memory window,
298 * and interrupt settings.
299 *
300 * We make no assumptions about the card to be configured: we
301 * use just the information available in the CIS. In an ideal
302 * world, this would work for any PCMCIA card, but it requires
303 * a complete and accurate CIS. In practice, a driver usually
304 * "knows" most of these things without consulting the CIS,
305 * and most client drivers will only use the CIS to fill in
306 * implementation-defined details.
307 */
308 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
309 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
310 while (1) {
311 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
312 cistpl_cftable_entry_t dflt = { .index = 0 };
313
314 if ( (pcmcia_get_tuple_data(handle, &tuple) != 0)
315 || (pcmcia_parse_tuple(handle, &tuple, &parse) != 0))
316 goto next_entry;
317
318 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
319 dflt = *cfg;
320 if (cfg->index == 0)
321 goto next_entry;
322 link->conf.ConfigIndex = cfg->index;
323
324 /* Does this card need audio output? */
325 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
326 link->conf.Attributes |= CONF_ENABLE_SPKR;
327 link->conf.Status = CCSR_AUDIO_ENA;
328 }
329
330 /* Use power settings for Vcc and Vpp if present */
331 /* Note that the CIS values need to be rescaled */
332 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
333 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
334 DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
335 if (!ignore_cis_vcc)
336 goto next_entry;
337 }
338 } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
339 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
340 DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
341 if(!ignore_cis_vcc)
342 goto next_entry;
343 }
344 }
345
346 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
347 link->conf.Vpp1 = link->conf.Vpp2 =
348 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
349 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
350 link->conf.Vpp1 = link->conf.Vpp2 =
351 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
352
353 /* Do we need to allocate an interrupt? */
354 link->conf.Attributes |= CONF_ENABLE_IRQ;
355
356 /* IO window settings */
357 link->io.NumPorts1 = link->io.NumPorts2 = 0;
358 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
359 cistpl_io_t *io =
360 (cfg->io.nwin) ? &cfg->io : &dflt.io;
361 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
362 if (!(io->flags & CISTPL_IO_8BIT))
363 link->io.Attributes1 =
364 IO_DATA_PATH_WIDTH_16;
365 if (!(io->flags & CISTPL_IO_16BIT))
366 link->io.Attributes1 =
367 IO_DATA_PATH_WIDTH_8;
368 link->io.IOAddrLines =
369 io->flags & CISTPL_IO_LINES_MASK;
370 link->io.BasePort1 = io->win[0].base;
371 link->io.NumPorts1 = io->win[0].len;
372 if (io->nwin > 1) {
373 link->io.Attributes2 =
374 link->io.Attributes1;
375 link->io.BasePort2 = io->win[1].base;
376 link->io.NumPorts2 = io->win[1].len;
377 }
378
379 /* This reserves IO space but doesn't actually enable it */
380 if (pcmcia_request_io(link->handle, &link->io) != 0)
381 goto next_entry;
382 }
383
384
385 /* If we got this far, we're cool! */
386
387 break;
388
389 next_entry:
390 if (link->io.NumPorts1)
391 pcmcia_release_io(link->handle, &link->io);
392 last_ret = pcmcia_get_next_tuple(handle, &tuple);
393 if (last_ret == CS_NO_MORE_ITEMS) {
394 printk(KERN_ERR PFX "GetNextTuple(): No matching "
395 "CIS configuration. Maybe you need the "
396 "ignore_cis_vcc=1 parameter.\n");
397 goto cs_failed;
398 }
399 }
400
401 /*
402 * Allocate an interrupt line. Note that this does not assign
403 * a handler to the interrupt, unless the 'Handler' member of
404 * the irq structure is initialized.
405 */
406 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
407
408 /* We initialize the hermes structure before completing PCMCIA
409 * configuration just in case the interrupt handler gets
410 * called. */
411 mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
412 if (!mem)
413 goto cs_failed;
414
415 hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
416
417 /*
418 * This actually configures the PCMCIA socket -- setting up
419 * the I/O windows and the interrupt mapping, and putting the
420 * card and host interface into "Memory and IO" mode.
421 */
422 CS_CHECK(RequestConfiguration,
423 pcmcia_request_configuration(link->handle, &link->conf));
424
425 /* Ok, we have the configuration, prepare to register the netdev */
426 dev->base_addr = link->io.BasePort1;
427 dev->irq = link->irq.AssignedIRQ;
428 SET_MODULE_OWNER(dev);
429 card->node.major = card->node.minor = 0;
430
431 SET_NETDEV_DEV(dev, &handle_to_dev(handle));
432 /* Tell the stack we exist */
433 if (register_netdev(dev) != 0) {
434 printk(KERN_ERR PFX "register_netdev() failed\n");
435 goto failed;
436 }
437
438 /* At this point, the dev_node_t structure(s) needs to be
439 * initialized and arranged in a linked list at link->dev. */
440 strcpy(card->node.dev_name, dev->name);
441 link->dev = &card->node; /* link->dev being non-NULL is also
442 used to indicate that the
443 net_device has been registered */
444 link->state &= ~DEV_CONFIG_PENDING;
445
446 /* Finally, report what we've done */
447 printk(KERN_DEBUG "%s: index 0x%02x: Vcc %d.%d",
448 dev->name, link->conf.ConfigIndex,
449 link->conf.Vcc / 10, link->conf.Vcc % 10);
450 if (link->conf.Vpp1)
451 printk(", Vpp %d.%d", link->conf.Vpp1 / 10,
452 link->conf.Vpp1 % 10);
453 printk(", irq %d", link->irq.AssignedIRQ);
454 if (link->io.NumPorts1)
455 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
456 link->io.BasePort1 + link->io.NumPorts1 - 1);
457 if (link->io.NumPorts2)
458 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
459 link->io.BasePort2 + link->io.NumPorts2 - 1);
460 printk("\n");
461
462 return;
463
464 cs_failed:
465 cs_error(link->handle, last_fn, last_ret);
466
467 failed:
468 orinoco_cs_release(link);
469} /* orinoco_cs_config */
470
471/*
472 * After a card is removed, orinoco_cs_release() will unregister the
473 * device, and release the PCMCIA configuration. If the device is
474 * still open, this will be postponed until it is closed.
475 */
476static void
477orinoco_cs_release(dev_link_t *link)
478{
479 struct net_device *dev = link->priv;
480 struct orinoco_private *priv = netdev_priv(dev);
481 unsigned long flags;
482
483 /* We're committed to taking the device away now, so mark the
484 * hardware as unavailable */
485 spin_lock_irqsave(&priv->lock, flags);
486 priv->hw_unavailable++;
487 spin_unlock_irqrestore(&priv->lock, flags);
488
489 /* Don't bother checking to see if these succeed or not */
490 pcmcia_release_configuration(link->handle);
491 if (link->io.NumPorts1)
492 pcmcia_release_io(link->handle, &link->io);
493 if (link->irq.AssignedIRQ)
494 pcmcia_release_irq(link->handle, &link->irq);
495 link->state &= ~DEV_CONFIG;
496 if (priv->hw.iobase)
497 ioport_unmap(priv->hw.iobase);
498} /* orinoco_cs_release */
499
500/*
501 * The card status event handler. Mostly, this schedules other stuff
502 * to run after an event is received.
503 */
504static int
505orinoco_cs_event(event_t event, int priority,
506 event_callback_args_t * args)
507{
508 dev_link_t *link = args->client_data;
509 struct net_device *dev = link->priv;
510 struct orinoco_private *priv = netdev_priv(dev);
511 struct orinoco_pccard *card = priv->card;
512 int err = 0;
513 unsigned long flags;
514
515 switch (event) {
516 case CS_EVENT_CARD_REMOVAL:
517 link->state &= ~DEV_PRESENT;
518 if (link->state & DEV_CONFIG) {
519 unsigned long flags;
520
521 spin_lock_irqsave(&priv->lock, flags);
522 netif_device_detach(dev);
523 priv->hw_unavailable++;
524 spin_unlock_irqrestore(&priv->lock, flags);
525 }
526 break;
527
528 case CS_EVENT_CARD_INSERTION:
529 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
530 orinoco_cs_config(link);
531 break;
532
533 case CS_EVENT_PM_SUSPEND:
534 link->state |= DEV_SUSPEND;
535 /* Fall through... */
536 case CS_EVENT_RESET_PHYSICAL:
537 /* Mark the device as stopped, to block IO until later */
538 if (link->state & DEV_CONFIG) {
539 /* This is probably racy, but I can't think of
540 a better way, short of rewriting the PCMCIA
541 layer to not suck :-( */
542 if (! test_bit(0, &card->hard_reset_in_progress)) {
543 spin_lock_irqsave(&priv->lock, flags);
544
545 err = __orinoco_down(dev);
546 if (err)
547 printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
548 dev->name,
549 event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
550 err);
551
552 netif_device_detach(dev);
553 priv->hw_unavailable++;
554
555 spin_unlock_irqrestore(&priv->lock, flags);
556 }
557
558 pcmcia_release_configuration(link->handle);
559 }
560 break;
561
562 case CS_EVENT_PM_RESUME:
563 link->state &= ~DEV_SUSPEND;
564 /* Fall through... */
565 case CS_EVENT_CARD_RESET:
566 if (link->state & DEV_CONFIG) {
567 /* FIXME: should we double check that this is
568 * the same card as we had before */
569 pcmcia_request_configuration(link->handle, &link->conf);
570
571 if (! test_bit(0, &card->hard_reset_in_progress)) {
572 err = orinoco_reinit_firmware(dev);
573 if (err) {
574 printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
575 dev->name, err);
576 break;
577 }
578
579 spin_lock_irqsave(&priv->lock, flags);
580
581 netif_device_attach(dev);
582 priv->hw_unavailable--;
583
584 if (priv->open && ! priv->hw_unavailable) {
585 err = __orinoco_up(dev);
586 if (err)
587 printk(KERN_ERR "%s: Error %d restarting card\n",
588 dev->name, err);
589
590 }
591
592 spin_unlock_irqrestore(&priv->lock, flags);
593 }
594 }
595 break;
596 }
597
598 return err;
599} /* orinoco_cs_event */
600
601/********************************************************************/
602/* Module initialization */
603/********************************************************************/
604
605/* Can't be declared "const" or the whole __initdata section will
606 * become const */
607static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
608 " (David Gibson <hermes@gibson.dropbear.id.au>, "
609 "Pavel Roskin <proski@gnu.org>, et al)";
610
611static struct pcmcia_driver orinoco_driver = {
612 .owner = THIS_MODULE,
613 .drv = {
614 .name = DRIVER_NAME,
615 },
616 .attach = orinoco_cs_attach,
617 .detach = orinoco_cs_detach,
618};
619
620static int __init
621init_orinoco_cs(void)
622{
623 printk(KERN_DEBUG "%s\n", version);
624
625 return pcmcia_register_driver(&orinoco_driver);
626}
627
628static void __exit
629exit_orinoco_cs(void)
630{
631 pcmcia_unregister_driver(&orinoco_driver);
632 BUG_ON(dev_list != NULL);
633}
634
635module_init(init_orinoco_cs);
636module_exit(exit_orinoco_cs);
diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c
new file mode 100644
index 000000000000..ff30d37e12e2
--- /dev/null
+++ b/drivers/net/wireless/orinoco_pci.c
@@ -0,0 +1,417 @@
1/* orinoco_pci.c
2 *
3 * Driver for Prism II devices that have a direct PCI interface
4 * (i.e., not in a Pcmcia or PLX bridge)
5 *
6 * Specifically here we're talking about the Linksys WMP11
7 *
8 * Current maintainers (as of 29 September 2003) are:
9 * Pavel Roskin <proski AT gnu.org>
10 * and David Gibson <hermes AT gibson.dropbear.id.au>
11 *
12 * Some of this code is borrowed from orinoco_plx.c
13 * Copyright (C) 2001 Daniel Barlow <dan AT telent.net>
14 * Some of this code is "inspired" by linux-wlan-ng-0.1.10, but nothing
15 * has been copied from it. linux-wlan-ng-0.1.10 is originally :
16 * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
17 * This file originally written by:
18 * Copyright (C) 2001 Jean Tourrilhes <jt AT hpl.hp.com>
19 * And is now maintained by:
20 * (C) Copyright David Gibson, IBM Corp. 2002-2003.
21 *
22 * The contents of this file are subject to the Mozilla Public License
23 * Version 1.1 (the "License"); you may not use this file except in
24 * compliance with the License. You may obtain a copy of the License
25 * at http://www.mozilla.org/MPL/
26 *
27 * Software distributed under the License is distributed on an "AS IS"
28 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
29 * the License for the specific language governing rights and
30 * limitations under the License.
31 *
32 * Alternatively, the contents of this file may be used under the
33 * terms of the GNU General Public License version 2 (the "GPL"), in
34 * which case the provisions of the GPL are applicable instead of the
35 * above. If you wish to allow the use of your version of this file
36 * only under the terms of the GPL and not to allow others to use your
37 * version of this file under the MPL, indicate your decision by
38 * deleting the provisions above and replace them with the notice and
39 * other provisions required by the GPL. If you do not delete the
40 * provisions above, a recipient may use your version of this file
41 * under either the MPL or the GPL.
42 */
43
44/*
45 * Theory of operation...
46 * -------------------
47 * Maybe you had a look in orinoco_plx. Well, this is totally different...
48 *
49 * The card contains only one PCI region, which contains all the usual
50 * hermes registers.
51 *
52 * The driver will memory map this region in normal memory. Because
53 * the hermes registers are mapped in normal memory and not in ISA I/O
54 * post space, we can't use the usual inw/outw macros and we need to
55 * use readw/writew.
56 * This slight difference force us to compile our own version of
57 * hermes.c with the register access macro changed. That's a bit
58 * hackish but works fine.
59 *
60 * Note that the PCI region is pretty big (4K). That's much more than
61 * the usual set of hermes register (0x0 -> 0x3E). I've got a strong
62 * suspicion that the whole memory space of the adapter is in fact in
63 * this region. Accessing directly the adapter memory instead of going
64 * through the usual register would speed up significantely the
65 * operations...
66 *
67 * Finally, the card looks like this :
68-----------------------
69 Bus 0, device 14, function 0:
70 Network controller: PCI device 1260:3873 (Harris Semiconductor) (rev 1).
71 IRQ 11.
72 Master Capable. Latency=248.
73 Prefetchable 32 bit memory at 0xffbcc000 [0xffbccfff].
74-----------------------
7500:0e.0 Network controller: Harris Semiconductor: Unknown device 3873 (rev 01)
76 Subsystem: Unknown device 1737:3874
77 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
78 Status: Cap+ 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
79 Latency: 248 set, cache line size 08
80 Interrupt: pin A routed to IRQ 11
81 Region 0: Memory at ffbcc000 (32-bit, prefetchable) [size=4K]
82 Capabilities: [dc] Power Management version 2
83 Flags: PMEClk- AuxPwr- DSI- D1+ D2+ PME+
84 Status: D0 PME-Enable- DSel=0 DScale=0 PME-
85-----------------------
86 *
87 * That's all..
88 *
89 * Jean II
90 */
91
92#define DRIVER_NAME "orinoco_pci"
93#define PFX DRIVER_NAME ": "
94
95#include <linux/config.h>
96
97#include <linux/module.h>
98#include <linux/kernel.h>
99#include <linux/init.h>
100#include <linux/sched.h>
101#include <linux/ptrace.h>
102#include <linux/slab.h>
103#include <linux/string.h>
104#include <linux/timer.h>
105#include <linux/ioport.h>
106#include <linux/netdevice.h>
107#include <linux/if_arp.h>
108#include <linux/etherdevice.h>
109#include <linux/list.h>
110#include <linux/pci.h>
111#include <linux/fcntl.h>
112
113#include <asm/uaccess.h>
114#include <asm/io.h>
115#include <asm/system.h>
116
117#include "hermes.h"
118#include "orinoco.h"
119
120/* All the magic there is from wlan-ng */
121/* Magic offset of the reset register of the PCI card */
122#define HERMES_PCI_COR (0x26)
123/* Magic bitmask to reset the card */
124#define HERMES_PCI_COR_MASK (0x0080)
125/* Magic timeouts for doing the reset.
126 * Those times are straight from wlan-ng, and it is claimed that they
127 * are necessary. Alan will kill me. Take your time and grab a coffee. */
128#define HERMES_PCI_COR_ONT (250) /* ms */
129#define HERMES_PCI_COR_OFFT (500) /* ms */
130#define HERMES_PCI_COR_BUSYT (500) /* ms */
131
132/* Orinoco PCI specific data */
133struct orinoco_pci_card {
134 void __iomem *pci_ioaddr;
135};
136
137/*
138 * Do a soft reset of the PCI card using the Configuration Option Register
139 * We need this to get going...
140 * This is the part of the code that is strongly inspired from wlan-ng
141 *
142 * Note : This code is done with irq enabled. This mean that many
143 * interrupts will occur while we are there. This is why we use the
144 * jiffies to regulate time instead of a straight mdelay(). Usually we
145 * need only around 245 iteration of the loop to do 250 ms delay.
146 *
147 * Note bis : Don't try to access HERMES_CMD during the reset phase.
148 * It just won't work !
149 */
150static int
151orinoco_pci_cor_reset(struct orinoco_private *priv)
152{
153 hermes_t *hw = &priv->hw;
154 unsigned long timeout;
155 u16 reg;
156
157 /* Assert the reset until the card notice */
158 hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK);
159 mdelay(HERMES_PCI_COR_ONT);
160
161 /* Give time for the card to recover from this hard effort */
162 hermes_write_regn(hw, PCI_COR, 0x0000);
163 mdelay(HERMES_PCI_COR_OFFT);
164
165 /* The card is ready when it's no longer busy */
166 timeout = jiffies + (HERMES_PCI_COR_BUSYT * HZ / 1000);
167 reg = hermes_read_regn(hw, CMD);
168 while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
169 mdelay(1);
170 reg = hermes_read_regn(hw, CMD);
171 }
172
173 /* Still busy? */
174 if (reg & HERMES_CMD_BUSY) {
175 printk(KERN_ERR PFX "Busy timeout\n");
176 return -ETIMEDOUT;
177 }
178
179 return 0;
180}
181
182/*
183 * Initialise a card. Mostly similar to PLX code.
184 */
185static int orinoco_pci_init_one(struct pci_dev *pdev,
186 const struct pci_device_id *ent)
187{
188 int err = 0;
189 unsigned long pci_iorange;
190 u16 __iomem *pci_ioaddr = NULL;
191 unsigned long pci_iolen;
192 struct orinoco_private *priv = NULL;
193 struct orinoco_pci_card *card;
194 struct net_device *dev = NULL;
195
196 err = pci_enable_device(pdev);
197 if (err) {
198 printk(KERN_ERR PFX "Cannot enable PCI device\n");
199 return err;
200 }
201
202 err = pci_request_regions(pdev, DRIVER_NAME);
203 if (err != 0) {
204 printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
205 goto fail_resources;
206 }
207
208 /* Resource 0 is mapped to the hermes registers */
209 pci_iorange = pci_resource_start(pdev, 0);
210 pci_iolen = pci_resource_len(pdev, 0);
211 pci_ioaddr = ioremap(pci_iorange, pci_iolen);
212 if (!pci_iorange) {
213 printk(KERN_ERR PFX "Cannot remap hardware registers\n");
214 goto fail_map;
215 }
216
217 /* Allocate network device */
218 dev = alloc_orinocodev(sizeof(*card), orinoco_pci_cor_reset);
219 if (! dev) {
220 err = -ENOMEM;
221 goto fail_alloc;
222 }
223
224 priv = netdev_priv(dev);
225 card = priv->card;
226 card->pci_ioaddr = pci_ioaddr;
227 dev->mem_start = pci_iorange;
228 dev->mem_end = pci_iorange + pci_iolen - 1;
229 SET_MODULE_OWNER(dev);
230 SET_NETDEV_DEV(dev, &pdev->dev);
231
232 hermes_struct_init(&priv->hw, pci_ioaddr, HERMES_32BIT_REGSPACING);
233
234 printk(KERN_DEBUG PFX "Detected device %s, mem:0x%lx-0x%lx, irq %d\n",
235 pci_name(pdev), dev->mem_start, dev->mem_end, pdev->irq);
236
237 err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
238 dev->name, dev);
239 if (err) {
240 printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
241 err = -EBUSY;
242 goto fail_irq;
243 }
244 dev->irq = pdev->irq;
245
246 /* Perform a COR reset to start the card */
247 err = orinoco_pci_cor_reset(priv);
248 if (err) {
249 printk(KERN_ERR PFX "Initial reset failed\n");
250 goto fail;
251 }
252
253 err = register_netdev(dev);
254 if (err) {
255 printk(KERN_ERR PFX "Failed to register net device\n");
256 goto fail;
257 }
258
259 pci_set_drvdata(pdev, dev);
260
261 return 0;
262
263 fail:
264 free_irq(pdev->irq, dev);
265
266 fail_irq:
267 pci_set_drvdata(pdev, NULL);
268 free_orinocodev(dev);
269
270 fail_alloc:
271 iounmap(pci_ioaddr);
272
273 fail_map:
274 pci_release_regions(pdev);
275
276 fail_resources:
277 pci_disable_device(pdev);
278
279 return err;
280}
281
282static void __devexit orinoco_pci_remove_one(struct pci_dev *pdev)
283{
284 struct net_device *dev = pci_get_drvdata(pdev);
285 struct orinoco_private *priv = netdev_priv(dev);
286 struct orinoco_pci_card *card = priv->card;
287
288 unregister_netdev(dev);
289 free_irq(dev->irq, dev);
290 pci_set_drvdata(pdev, NULL);
291 free_orinocodev(dev);
292 iounmap(card->pci_ioaddr);
293 pci_release_regions(pdev);
294 pci_disable_device(pdev);
295}
296
297static int orinoco_pci_suspend(struct pci_dev *pdev, u32 state)
298{
299 struct net_device *dev = pci_get_drvdata(pdev);
300 struct orinoco_private *priv = netdev_priv(dev);
301 unsigned long flags;
302 int err;
303
304 printk(KERN_DEBUG "%s: Orinoco-PCI entering sleep mode (state=%d)\n",
305 dev->name, state);
306
307 err = orinoco_lock(priv, &flags);
308 if (err) {
309 printk(KERN_ERR "%s: hw_unavailable on orinoco_pci_suspend\n",
310 dev->name);
311 return err;
312 }
313
314 err = __orinoco_down(dev);
315 if (err)
316 printk(KERN_WARNING "%s: orinoco_pci_suspend(): Error %d downing interface\n",
317 dev->name, err);
318
319 netif_device_detach(dev);
320
321 priv->hw_unavailable++;
322
323 orinoco_unlock(priv, &flags);
324
325 pci_save_state(pdev);
326 pci_set_power_state(pdev, 3);
327
328 return 0;
329}
330
331static int orinoco_pci_resume(struct pci_dev *pdev)
332{
333 struct net_device *dev = pci_get_drvdata(pdev);
334 struct orinoco_private *priv = netdev_priv(dev);
335 unsigned long flags;
336 int err;
337
338 printk(KERN_DEBUG "%s: Orinoco-PCI waking up\n", dev->name);
339
340 pci_set_power_state(pdev, 0);
341 pci_restore_state(pdev);
342
343 err = orinoco_reinit_firmware(dev);
344 if (err) {
345 printk(KERN_ERR "%s: Error %d re-initializing firmware on orinoco_pci_resume()\n",
346 dev->name, err);
347 return err;
348 }
349
350 spin_lock_irqsave(&priv->lock, flags);
351
352 netif_device_attach(dev);
353
354 priv->hw_unavailable--;
355
356 if (priv->open && (! priv->hw_unavailable)) {
357 err = __orinoco_up(dev);
358 if (err)
359 printk(KERN_ERR "%s: Error %d restarting card on orinoco_pci_resume()\n",
360 dev->name, err);
361 }
362
363 spin_unlock_irqrestore(&priv->lock, flags);
364
365 return 0;
366}
367
368static struct pci_device_id orinoco_pci_pci_id_table[] = {
369 /* Intersil Prism 3 */
370 {0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID,},
371 /* Intersil Prism 2.5 */
372 {0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID,},
373 /* Samsung MagicLAN SWL-2210P */
374 {0x167d, 0xa000, PCI_ANY_ID, PCI_ANY_ID,},
375 {0,},
376};
377
378MODULE_DEVICE_TABLE(pci, orinoco_pci_pci_id_table);
379
380static struct pci_driver orinoco_pci_driver = {
381 .name = DRIVER_NAME,
382 .id_table = orinoco_pci_pci_id_table,
383 .probe = orinoco_pci_init_one,
384 .remove = __devexit_p(orinoco_pci_remove_one),
385 .suspend = orinoco_pci_suspend,
386 .resume = orinoco_pci_resume,
387};
388
389static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
390 " (Pavel Roskin <proski@gnu.org>,"
391 " David Gibson <hermes@gibson.dropbear.id.au> &"
392 " Jean Tourrilhes <jt@hpl.hp.com>)";
393MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
394MODULE_DESCRIPTION("Driver for wireless LAN cards using direct PCI interface");
395MODULE_LICENSE("Dual MPL/GPL");
396
397static int __init orinoco_pci_init(void)
398{
399 printk(KERN_DEBUG "%s\n", version);
400 return pci_module_init(&orinoco_pci_driver);
401}
402
403static void __exit orinoco_pci_exit(void)
404{
405 pci_unregister_driver(&orinoco_pci_driver);
406}
407
408module_init(orinoco_pci_init);
409module_exit(orinoco_pci_exit);
410
411/*
412 * Local variables:
413 * c-indent-level: 8
414 * c-basic-offset: 8
415 * tab-width: 8
416 * End:
417 */
diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c
new file mode 100644
index 000000000000..7ab05b89fb3f
--- /dev/null
+++ b/drivers/net/wireless/orinoco_plx.c
@@ -0,0 +1,419 @@
1/* orinoco_plx.c
2 *
3 * Driver for Prism II devices which would usually be driven by orinoco_cs,
4 * but are connected to the PCI bus by a PLX9052.
5 *
6 * Current maintainers (as of 29 September 2003) are:
7 * Pavel Roskin <proski AT gnu.org>
8 * and David Gibson <hermes AT gibson.dropbear.id.au>
9 *
10 * (C) Copyright David Gibson, IBM Corp. 2001-2003.
11 * Copyright (C) 2001 Daniel Barlow
12 *
13 * The contents of this file are subject to the Mozilla Public License
14 * Version 1.1 (the "License"); you may not use this file except in
15 * compliance with the License. You may obtain a copy of the License
16 * at http://www.mozilla.org/MPL/
17 *
18 * Software distributed under the License is distributed on an "AS IS"
19 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
20 * the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * Alternatively, the contents of this file may be used under the
24 * terms of the GNU General Public License version 2 (the "GPL"), in
25 * which case the provisions of the GPL are applicable instead of the
26 * above. If you wish to allow the use of your version of this file
27 * only under the terms of the GPL and not to allow others to use your
28 * version of this file under the MPL, indicate your decision by
29 * deleting the provisions above and replace them with the notice and
30 * other provisions required by the GPL. If you do not delete the
31 * provisions above, a recipient may use your version of this file
32 * under either the MPL or the GPL.
33
34 * Caution: this is experimental and probably buggy. For success and
35 * failure reports for different cards and adaptors, see
36 * orinoco_plx_pci_id_table near the end of the file. If you have a
37 * card we don't have the PCI id for, and looks like it should work,
38 * drop me mail with the id and "it works"/"it doesn't work".
39 *
40 * Note: if everything gets detected fine but it doesn't actually send
41 * or receive packets, your first port of call should probably be to
42 * try newer firmware in the card. Especially if you're doing Ad-Hoc
43 * modes.
44 *
45 * The actual driving is done by orinoco.c, this is just resource
46 * allocation stuff. The explanation below is courtesy of Ryan Niemi
47 * on the linux-wlan-ng list at
48 * http://archives.neohapsis.com/archives/dev/linux-wlan/2001-q1/0026.html
49 *
50 * The PLX9052-based cards (WL11000 and several others) are a
51 * different beast than the usual PCMCIA-based PRISM2 configuration
52 * expected by wlan-ng. Here's the general details on how the WL11000
53 * PCI adapter works:
54 *
55 * - Two PCI I/O address spaces, one 0x80 long which contains the
56 * PLX9052 registers, and one that's 0x40 long mapped to the PCMCIA
57 * slot I/O address space.
58 *
59 * - One PCI memory address space, mapped to the PCMCIA memory space
60 * (containing the CIS).
61 *
62 * After identifying the I/O and memory space, you can read through
63 * the memory space to confirm the CIS's device ID or manufacturer ID
64 * to make sure it's the expected card. qKeep in mind that the PCMCIA
65 * spec specifies the CIS as the lower 8 bits of each word read from
66 * the CIS, so to read the bytes of the CIS, read every other byte
67 * (0,2,4,...). Passing that test, you need to enable the I/O address
68 * space on the PCMCIA card via the PCMCIA COR register. This is the
69 * first byte following the CIS. In my case (which may not have any
70 * relation to what's on the PRISM2 cards), COR was at offset 0x800
71 * within the PCI memory space. Write 0x41 to the COR register to
72 * enable I/O mode and to select level triggered interrupts. To
73 * confirm you actually succeeded, read the COR register back and make
74 * sure it actually got set to 0x41, incase you have an unexpected
75 * card inserted.
76 *
77 * Following that, you can treat the second PCI I/O address space (the
78 * one that's not 0x80 in length) as the PCMCIA I/O space.
79 *
80 * Note that in the Eumitcom's source for their drivers, they register
81 * the interrupt as edge triggered when registering it with the
82 * Windows kernel. I don't recall how to register edge triggered on
83 * Linux (if it can be done at all). But in some experimentation, I
84 * don't see much operational difference between using either
85 * interrupt mode. Don't mess with the interrupt mode in the COR
86 * register though, as the PLX9052 wants level triggers with the way
87 * the serial EEPROM configures it on the WL11000.
88 *
89 * There's some other little quirks related to timing that I bumped
90 * into, but I don't recall right now. Also, there's two variants of
91 * the WL11000 I've seen, revision A1 and T2. These seem to differ
92 * slightly in the timings configured in the wait-state generator in
93 * the PLX9052. There have also been some comments from Eumitcom that
94 * cards shouldn't be hot swapped, apparently due to risk of cooking
95 * the PLX9052. I'm unsure why they believe this, as I can't see
96 * anything in the design that would really cause a problem, except
97 * for crashing drivers not written to expect it. And having developed
98 * drivers for the WL11000, I'd say it's quite tricky to write code
99 * that will successfully deal with a hot unplug. Very odd things
100 * happen on the I/O side of things. But anyway, be warned. Despite
101 * that, I've hot-swapped a number of times during debugging and
102 * driver development for various reasons (stuck WAIT# line after the
103 * radio card's firmware locks up).
104 *
105 * Hope this is enough info for someone to add PLX9052 support to the
106 * wlan-ng card. In the case of the WL11000, the PCI ID's are
107 * 0x1639/0x0200, with matching subsystem ID's. Other PLX9052-based
108 * manufacturers other than Eumitcom (or on cards other than the
109 * WL11000) may have different PCI ID's.
110 *
111 * If anyone needs any more specific info, let me know. I haven't had
112 * time to implement support myself yet, and with the way things are
113 * going, might not have time for a while..
114 */
115
116#define DRIVER_NAME "orinoco_plx"
117#define PFX DRIVER_NAME ": "
118
119#include <linux/config.h>
120
121#include <linux/module.h>
122#include <linux/kernel.h>
123#include <linux/init.h>
124#include <linux/sched.h>
125#include <linux/ptrace.h>
126#include <linux/slab.h>
127#include <linux/string.h>
128#include <linux/timer.h>
129#include <linux/ioport.h>
130#include <asm/uaccess.h>
131#include <asm/io.h>
132#include <asm/system.h>
133#include <linux/netdevice.h>
134#include <linux/if_arp.h>
135#include <linux/etherdevice.h>
136#include <linux/list.h>
137#include <linux/pci.h>
138#include <linux/fcntl.h>
139
140#include <pcmcia/cisreg.h>
141
142#include "hermes.h"
143#include "orinoco.h"
144
145#define COR_OFFSET (0x3e0) /* COR attribute offset of Prism2 PC card */
146#define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
147#define COR_RESET (0x80) /* reset bit in the COR register */
148#define PLX_RESET_TIME (500) /* milliseconds */
149
150#define PLX_INTCSR 0x4c /* Interrupt Control & Status Register */
151#define PLX_INTCSR_INTEN (1<<6) /* Interrupt Enable bit */
152
153static const u8 cis_magic[] = {
154 0x01, 0x03, 0x00, 0x00, 0xff, 0x17, 0x04, 0x67
155};
156
157/* Orinoco PLX specific data */
158struct orinoco_plx_card {
159 void __iomem *attr_mem;
160};
161
162/*
163 * Do a soft reset of the card using the Configuration Option Register
164 */
165static int orinoco_plx_cor_reset(struct orinoco_private *priv)
166{
167 hermes_t *hw = &priv->hw;
168 struct orinoco_plx_card *card = priv->card;
169 u8 __iomem *attr_mem = card->attr_mem;
170 unsigned long timeout;
171 u16 reg;
172
173 writeb(COR_VALUE | COR_RESET, attr_mem + COR_OFFSET);
174 mdelay(1);
175
176 writeb(COR_VALUE, attr_mem + COR_OFFSET);
177 mdelay(1);
178
179 /* Just in case, wait more until the card is no longer busy */
180 timeout = jiffies + (PLX_RESET_TIME * HZ / 1000);
181 reg = hermes_read_regn(hw, CMD);
182 while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
183 mdelay(1);
184 reg = hermes_read_regn(hw, CMD);
185 }
186
187 /* Did we timeout ? */
188 if (reg & HERMES_CMD_BUSY) {
189 printk(KERN_ERR PFX "Busy timeout\n");
190 return -ETIMEDOUT;
191 }
192
193 return 0;
194}
195
196
197static int orinoco_plx_init_one(struct pci_dev *pdev,
198 const struct pci_device_id *ent)
199{
200 int err = 0;
201 u8 __iomem *attr_mem = NULL;
202 u32 csr_reg, plx_addr;
203 struct orinoco_private *priv = NULL;
204 struct orinoco_plx_card *card;
205 unsigned long pccard_ioaddr = 0;
206 unsigned long pccard_iolen = 0;
207 struct net_device *dev = NULL;
208 void __iomem *mem;
209 int i;
210
211 err = pci_enable_device(pdev);
212 if (err) {
213 printk(KERN_ERR PFX "Cannot enable PCI device\n");
214 return err;
215 }
216
217 err = pci_request_regions(pdev, DRIVER_NAME);
218 if (err != 0) {
219 printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
220 goto fail_resources;
221 }
222
223 /* Resource 1 is mapped to PLX-specific registers */
224 plx_addr = pci_resource_start(pdev, 1);
225
226 /* Resource 2 is mapped to the PCMCIA attribute memory */
227 attr_mem = ioremap(pci_resource_start(pdev, 2),
228 pci_resource_len(pdev, 2));
229 if (!attr_mem) {
230 printk(KERN_ERR PFX "Cannot remap PCMCIA space\n");
231 goto fail_map_attr;
232 }
233
234 /* Resource 3 is mapped to the PCMCIA I/O address space */
235 pccard_ioaddr = pci_resource_start(pdev, 3);
236 pccard_iolen = pci_resource_len(pdev, 3);
237
238 mem = pci_iomap(pdev, 3, 0);
239 if (!mem) {
240 err = -ENOMEM;
241 goto fail_map_io;
242 }
243
244 /* Allocate network device */
245 dev = alloc_orinocodev(sizeof(*card), orinoco_plx_cor_reset);
246 if (!dev) {
247 printk(KERN_ERR PFX "Cannot allocate network device\n");
248 err = -ENOMEM;
249 goto fail_alloc;
250 }
251
252 priv = netdev_priv(dev);
253 card = priv->card;
254 card->attr_mem = attr_mem;
255 dev->base_addr = pccard_ioaddr;
256 SET_MODULE_OWNER(dev);
257 SET_NETDEV_DEV(dev, &pdev->dev);
258
259 hermes_struct_init(&priv->hw, mem, HERMES_16BIT_REGSPACING);
260
261 printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 PLX device "
262 "at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq,
263 pccard_ioaddr);
264
265 err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
266 dev->name, dev);
267 if (err) {
268 printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
269 err = -EBUSY;
270 goto fail_irq;
271 }
272 dev->irq = pdev->irq;
273
274 /* bjoern: We need to tell the card to enable interrupts, in
275 case the serial eprom didn't do this already. See the
276 PLX9052 data book, p8-1 and 8-24 for reference. */
277 csr_reg = inl(plx_addr + PLX_INTCSR);
278 if (!(csr_reg & PLX_INTCSR_INTEN)) {
279 csr_reg |= PLX_INTCSR_INTEN;
280 outl(csr_reg, plx_addr + PLX_INTCSR);
281 csr_reg = inl(plx_addr + PLX_INTCSR);
282 if (!(csr_reg & PLX_INTCSR_INTEN)) {
283 printk(KERN_ERR PFX "Cannot enable interrupts\n");
284 goto fail;
285 }
286 }
287
288 err = orinoco_plx_cor_reset(priv);
289 if (err) {
290 printk(KERN_ERR PFX "Initial reset failed\n");
291 goto fail;
292 }
293
294 printk(KERN_DEBUG PFX "CIS: ");
295 for (i = 0; i < 16; i++) {
296 printk("%02X:", readb(attr_mem + 2*i));
297 }
298 printk("\n");
299
300 /* Verify whether a supported PC card is present */
301 /* FIXME: we probably need to be smarted about this */
302 for (i = 0; i < sizeof(cis_magic); i++) {
303 if (cis_magic[i] != readb(attr_mem +2*i)) {
304 printk(KERN_ERR PFX "The CIS value of Prism2 PC "
305 "card is unexpected\n");
306 err = -EIO;
307 goto fail;
308 }
309 }
310
311 err = register_netdev(dev);
312 if (err) {
313 printk(KERN_ERR PFX "Cannot register network device\n");
314 goto fail;
315 }
316
317 pci_set_drvdata(pdev, dev);
318
319 return 0;
320
321 fail:
322 free_irq(pdev->irq, dev);
323
324 fail_irq:
325 pci_set_drvdata(pdev, NULL);
326 free_orinocodev(dev);
327
328 fail_alloc:
329 pci_iounmap(pdev, mem);
330
331 fail_map_io:
332 iounmap(attr_mem);
333
334 fail_map_attr:
335 pci_release_regions(pdev);
336
337 fail_resources:
338 pci_disable_device(pdev);
339
340 return err;
341}
342
343static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
344{
345 struct net_device *dev = pci_get_drvdata(pdev);
346 struct orinoco_private *priv = netdev_priv(dev);
347 struct orinoco_plx_card *card = priv->card;
348 u8 __iomem *attr_mem = card->attr_mem;
349
350 BUG_ON(! dev);
351
352 unregister_netdev(dev);
353 free_irq(dev->irq, dev);
354 pci_set_drvdata(pdev, NULL);
355 free_orinocodev(dev);
356 pci_iounmap(pdev, priv->hw.iobase);
357 iounmap(attr_mem);
358 pci_release_regions(pdev);
359 pci_disable_device(pdev);
360}
361
362
363static struct pci_device_id orinoco_plx_pci_id_table[] = {
364 {0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,}, /* Siemens SpeedStream SS1023 */
365 {0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,}, /* Netgear MA301 */
366 {0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,}, /* Correga - does this work? */
367 {0x1638, 0x1100, PCI_ANY_ID, PCI_ANY_ID,}, /* SMC EZConnect SMC2602W,
368 Eumitcom PCI WL11000,
369 Addtron AWA-100 */
370 {0x16ab, 0x1100, PCI_ANY_ID, PCI_ANY_ID,}, /* Global Sun Tech GL24110P */
371 {0x16ab, 0x1101, PCI_ANY_ID, PCI_ANY_ID,}, /* Reported working, but unknown */
372 {0x16ab, 0x1102, PCI_ANY_ID, PCI_ANY_ID,}, /* Linksys WDT11 */
373 {0x16ec, 0x3685, PCI_ANY_ID, PCI_ANY_ID,}, /* USR 2415 */
374 {0xec80, 0xec00, PCI_ANY_ID, PCI_ANY_ID,}, /* Belkin F5D6000 tested by
375 Brendan W. McAdams <rit AT jacked-in.org> */
376 {0x10b7, 0x7770, PCI_ANY_ID, PCI_ANY_ID,}, /* 3Com AirConnect PCI tested by
377 Damien Persohn <damien AT persohn.net> */
378 {0,},
379};
380
381MODULE_DEVICE_TABLE(pci, orinoco_plx_pci_id_table);
382
383static struct pci_driver orinoco_plx_driver = {
384 .name = DRIVER_NAME,
385 .id_table = orinoco_plx_pci_id_table,
386 .probe = orinoco_plx_init_one,
387 .remove = __devexit_p(orinoco_plx_remove_one),
388};
389
390static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
391 " (Pavel Roskin <proski@gnu.org>,"
392 " David Gibson <hermes@gibson.dropbear.id.au>,"
393 " Daniel Barlow <dan@telent.net>)";
394MODULE_AUTHOR("Daniel Barlow <dan@telent.net>");
395MODULE_DESCRIPTION("Driver for wireless LAN cards using the PLX9052 PCI bridge");
396MODULE_LICENSE("Dual MPL/GPL");
397
398static int __init orinoco_plx_init(void)
399{
400 printk(KERN_DEBUG "%s\n", version);
401 return pci_module_init(&orinoco_plx_driver);
402}
403
404static void __exit orinoco_plx_exit(void)
405{
406 pci_unregister_driver(&orinoco_plx_driver);
407 ssleep(1);
408}
409
410module_init(orinoco_plx_init);
411module_exit(orinoco_plx_exit);
412
413/*
414 * Local variables:
415 * c-indent-level: 8
416 * c-basic-offset: 8
417 * tab-width: 8
418 * End:
419 */
diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c
new file mode 100644
index 000000000000..85893f42445b
--- /dev/null
+++ b/drivers/net/wireless/orinoco_tmd.c
@@ -0,0 +1,276 @@
1/* orinoco_tmd.c
2 *
3 * Driver for Prism II devices which would usually be driven by orinoco_cs,
4 * but are connected to the PCI bus by a TMD7160.
5 *
6 * Copyright (C) 2003 Joerg Dorchain <joerg AT dorchain.net>
7 * based heavily upon orinoco_plx.c Copyright (C) 2001 Daniel Barlow
8 *
9 * The contents of this file are subject to the Mozilla Public License
10 * Version 1.1 (the "License"); you may not use this file except in
11 * compliance with the License. You may obtain a copy of the License
12 * at http://www.mozilla.org/MPL/
13 *
14 * Software distributed under the License is distributed on an "AS IS"
15 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
16 * the License for the specific language governing rights and
17 * limitations under the License.
18 *
19 * Alternatively, the contents of this file may be used under the
20 * terms of the GNU General Public License version 2 (the "GPL"), in
21 * which case the provisions of the GPL are applicable instead of the
22 * above. If you wish to allow the use of your version of this file
23 * only under the terms of the GPL and not to allow others to use your
24 * version of this file under the MPL, indicate your decision by
25 * deleting the provisions above and replace them with the notice and
26 * other provisions required by the GPL. If you do not delete the
27 * provisions above, a recipient may use your version of this file
28 * under either the MPL or the GPL.
29
30 * Caution: this is experimental and probably buggy. For success and
31 * failure reports for different cards and adaptors, see
32 * orinoco_tmd_pci_id_table near the end of the file. If you have a
33 * card we don't have the PCI id for, and looks like it should work,
34 * drop me mail with the id and "it works"/"it doesn't work".
35 *
36 * Note: if everything gets detected fine but it doesn't actually send
37 * or receive packets, your first port of call should probably be to
38 * try newer firmware in the card. Especially if you're doing Ad-Hoc
39 * modes
40 *
41 * The actual driving is done by orinoco.c, this is just resource
42 * allocation stuff.
43 *
44 * This driver is modeled after the orinoco_plx driver. The main
45 * difference is that the TMD chip has only IO port ranges and no
46 * memory space, i.e. no access to the CIS. Compared to the PLX chip,
47 * the io range functionalities are exchanged.
48 *
49 * Pheecom sells cards with the TMD chip as "ASIC version"
50 */
51
52#define DRIVER_NAME "orinoco_tmd"
53#define PFX DRIVER_NAME ": "
54
55#include <linux/config.h>
56
57#include <linux/module.h>
58#include <linux/kernel.h>
59#include <linux/init.h>
60#include <linux/sched.h>
61#include <linux/ptrace.h>
62#include <linux/slab.h>
63#include <linux/string.h>
64#include <linux/timer.h>
65#include <linux/ioport.h>
66#include <asm/uaccess.h>
67#include <asm/io.h>
68#include <asm/system.h>
69#include <linux/netdevice.h>
70#include <linux/if_arp.h>
71#include <linux/etherdevice.h>
72#include <linux/list.h>
73#include <linux/pci.h>
74#include <linux/fcntl.h>
75
76#include <pcmcia/cisreg.h>
77
78#include "hermes.h"
79#include "orinoco.h"
80
81#define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
82#define COR_RESET (0x80) /* reset bit in the COR register */
83#define TMD_RESET_TIME (500) /* milliseconds */
84
85/* Orinoco TMD specific data */
86struct orinoco_tmd_card {
87 u32 tmd_io;
88};
89
90
91/*
92 * Do a soft reset of the card using the Configuration Option Register
93 */
94static int orinoco_tmd_cor_reset(struct orinoco_private *priv)
95{
96 hermes_t *hw = &priv->hw;
97 struct orinoco_tmd_card *card = priv->card;
98 u32 addr = card->tmd_io;
99 unsigned long timeout;
100 u16 reg;
101
102 outb(COR_VALUE | COR_RESET, addr);
103 mdelay(1);
104
105 outb(COR_VALUE, addr);
106 mdelay(1);
107
108 /* Just in case, wait more until the card is no longer busy */
109 timeout = jiffies + (TMD_RESET_TIME * HZ / 1000);
110 reg = hermes_read_regn(hw, CMD);
111 while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
112 mdelay(1);
113 reg = hermes_read_regn(hw, CMD);
114 }
115
116 /* Did we timeout ? */
117 if (reg & HERMES_CMD_BUSY) {
118 printk(KERN_ERR PFX "Busy timeout\n");
119 return -ETIMEDOUT;
120 }
121
122 return 0;
123}
124
125
126static int orinoco_tmd_init_one(struct pci_dev *pdev,
127 const struct pci_device_id *ent)
128{
129 int err = 0;
130 struct orinoco_private *priv = NULL;
131 struct orinoco_tmd_card *card;
132 struct net_device *dev = NULL;
133 void __iomem *mem;
134
135 err = pci_enable_device(pdev);
136 if (err) {
137 printk(KERN_ERR PFX "Cannot enable PCI device\n");
138 return err;
139 }
140
141 err = pci_request_regions(pdev, DRIVER_NAME);
142 if (err != 0) {
143 printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
144 goto fail_resources;
145 }
146
147 mem = pci_iomap(pdev, 2, 0);
148 if (! mem) {
149 err = -ENOMEM;
150 goto fail_iomap;
151 }
152
153 /* Allocate network device */
154 dev = alloc_orinocodev(sizeof(*card), orinoco_tmd_cor_reset);
155 if (! dev) {
156 printk(KERN_ERR PFX "Cannot allocate network device\n");
157 err = -ENOMEM;
158 goto fail_alloc;
159 }
160
161 priv = netdev_priv(dev);
162 card = priv->card;
163 card->tmd_io = pci_resource_start(pdev, 1);
164 dev->base_addr = pci_resource_start(pdev, 2);
165 SET_MODULE_OWNER(dev);
166 SET_NETDEV_DEV(dev, &pdev->dev);
167
168 hermes_struct_init(&priv->hw, mem, HERMES_16BIT_REGSPACING);
169
170 printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 TMD device "
171 "at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq,
172 dev->base_addr);
173
174 err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
175 dev->name, dev);
176 if (err) {
177 printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
178 err = -EBUSY;
179 goto fail_irq;
180 }
181 dev->irq = pdev->irq;
182
183 err = orinoco_tmd_cor_reset(priv);
184 if (err) {
185 printk(KERN_ERR PFX "Initial reset failed\n");
186 goto fail;
187 }
188
189 err = register_netdev(dev);
190 if (err) {
191 printk(KERN_ERR PFX "Cannot register network device\n");
192 goto fail;
193 }
194
195 pci_set_drvdata(pdev, dev);
196
197 return 0;
198
199 fail:
200 free_irq(pdev->irq, dev);
201
202 fail_irq:
203 pci_set_drvdata(pdev, NULL);
204 free_orinocodev(dev);
205
206 fail_alloc:
207 pci_iounmap(pdev, mem);
208
209 fail_iomap:
210 pci_release_regions(pdev);
211
212 fail_resources:
213 pci_disable_device(pdev);
214
215 return err;
216}
217
218static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev)
219{
220 struct net_device *dev = pci_get_drvdata(pdev);
221 struct orinoco_private *priv = dev->priv;
222
223 BUG_ON(! dev);
224
225 unregister_netdev(dev);
226 free_irq(dev->irq, dev);
227 pci_set_drvdata(pdev, NULL);
228 free_orinocodev(dev);
229 pci_iounmap(pdev, priv->hw.iobase);
230 pci_release_regions(pdev);
231 pci_disable_device(pdev);
232}
233
234
235static struct pci_device_id orinoco_tmd_pci_id_table[] = {
236 {0x15e8, 0x0131, PCI_ANY_ID, PCI_ANY_ID,}, /* NDC and OEMs, e.g. pheecom */
237 {0,},
238};
239
240MODULE_DEVICE_TABLE(pci, orinoco_tmd_pci_id_table);
241
242static struct pci_driver orinoco_tmd_driver = {
243 .name = DRIVER_NAME,
244 .id_table = orinoco_tmd_pci_id_table,
245 .probe = orinoco_tmd_init_one,
246 .remove = __devexit_p(orinoco_tmd_remove_one),
247};
248
249static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
250 " (Joerg Dorchain <joerg@dorchain.net>)";
251MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
252MODULE_DESCRIPTION("Driver for wireless LAN cards using the TMD7160 PCI bridge");
253MODULE_LICENSE("Dual MPL/GPL");
254
255static int __init orinoco_tmd_init(void)
256{
257 printk(KERN_DEBUG "%s\n", version);
258 return pci_module_init(&orinoco_tmd_driver);
259}
260
261static void __exit orinoco_tmd_exit(void)
262{
263 pci_unregister_driver(&orinoco_tmd_driver);
264 ssleep(1);
265}
266
267module_init(orinoco_tmd_init);
268module_exit(orinoco_tmd_exit);
269
270/*
271 * Local variables:
272 * c-indent-level: 8
273 * c-basic-offset: 8
274 * tab-width: 8
275 * End:
276 */
diff --git a/drivers/net/wireless/prism54/Makefile b/drivers/net/wireless/prism54/Makefile
new file mode 100644
index 000000000000..fad305c76737
--- /dev/null
+++ b/drivers/net/wireless/prism54/Makefile
@@ -0,0 +1,8 @@
1# $Id: Makefile.k26,v 1.7 2004/01/30 16:24:00 ajfa Exp $
2
3prism54-objs := islpci_eth.o islpci_mgt.o \
4 isl_38xx.o isl_ioctl.o islpci_dev.o \
5 islpci_hotplug.o oid_mgt.o
6
7obj-$(CONFIG_PRISM54) += prism54.o
8
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
new file mode 100644
index 000000000000..4481ec18c5a0
--- /dev/null
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -0,0 +1,260 @@
1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc.
4 * Copyright (C) 2003-2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>_
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <linux/version.h>
22#include <linux/module.h>
23#include <linux/types.h>
24#include <linux/delay.h>
25
26#include <asm/uaccess.h>
27#include <asm/io.h>
28
29#include "prismcompat.h"
30#include "isl_38xx.h"
31#include "islpci_dev.h"
32#include "islpci_mgt.h"
33
34/******************************************************************************
35 Device Interface & Control functions
36******************************************************************************/
37
38/**
39 * isl38xx_disable_interrupts - disable all interrupts
40 * @device: pci memory base address
41 *
42 * Instructs the device to disable all interrupt reporting by asserting
43 * the IRQ line. New events may still show up in the interrupt identification
44 * register located at offset %ISL38XX_INT_IDENT_REG.
45 */
46void
47isl38xx_disable_interrupts(void __iomem *device)
48{
49 isl38xx_w32_flush(device, 0x00000000, ISL38XX_INT_EN_REG);
50 udelay(ISL38XX_WRITEIO_DELAY);
51}
52
53void
54isl38xx_handle_sleep_request(isl38xx_control_block *control_block,
55 int *powerstate, void __iomem *device_base)
56{
57 /* device requests to go into sleep mode
58 * check whether the transmit queues for data and management are empty */
59 if (isl38xx_in_queue(control_block, ISL38XX_CB_TX_DATA_LQ))
60 /* data tx queue not empty */
61 return;
62
63 if (isl38xx_in_queue(control_block, ISL38XX_CB_TX_MGMTQ))
64 /* management tx queue not empty */
65 return;
66
67 /* check also whether received frames are pending */
68 if (isl38xx_in_queue(control_block, ISL38XX_CB_RX_DATA_LQ))
69 /* data rx queue not empty */
70 return;
71
72 if (isl38xx_in_queue(control_block, ISL38XX_CB_RX_MGMTQ))
73 /* management rx queue not empty */
74 return;
75
76#if VERBOSE > SHOW_ERROR_MESSAGES
77 DEBUG(SHOW_TRACING, "Device going to sleep mode\n");
78#endif
79
80 /* all queues are empty, allow the device to go into sleep mode */
81 *powerstate = ISL38XX_PSM_POWERSAVE_STATE;
82
83 /* assert the Sleep interrupt in the Device Interrupt Register */
84 isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_SLEEP,
85 ISL38XX_DEV_INT_REG);
86 udelay(ISL38XX_WRITEIO_DELAY);
87}
88
89void
90isl38xx_handle_wakeup(isl38xx_control_block *control_block,
91 int *powerstate, void __iomem *device_base)
92{
93 /* device is in active state, update the powerstate flag */
94 *powerstate = ISL38XX_PSM_ACTIVE_STATE;
95
96 /* now check whether there are frames pending for the card */
97 if (!isl38xx_in_queue(control_block, ISL38XX_CB_TX_DATA_LQ)
98 && !isl38xx_in_queue(control_block, ISL38XX_CB_TX_MGMTQ))
99 return;
100
101#if VERBOSE > SHOW_ERROR_MESSAGES
102 DEBUG(SHOW_ANYTHING, "Wake up handler trigger the device\n");
103#endif
104
105 /* either data or management transmit queue has a frame pending
106 * trigger the device by setting the Update bit in the Device Int reg */
107 isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE,
108 ISL38XX_DEV_INT_REG);
109 udelay(ISL38XX_WRITEIO_DELAY);
110}
111
112void
113isl38xx_trigger_device(int asleep, void __iomem *device_base)
114{
115 struct timeval current_time;
116 u32 reg, counter = 0;
117
118#if VERBOSE > SHOW_ERROR_MESSAGES
119 DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n");
120#endif
121
122 /* check whether the device is in power save mode */
123 if (asleep) {
124 /* device is in powersave, trigger the device for wakeup */
125#if VERBOSE > SHOW_ERROR_MESSAGES
126 do_gettimeofday(&current_time);
127 DEBUG(SHOW_TRACING, "%08li.%08li Device wakeup triggered\n",
128 current_time.tv_sec, (long)current_time.tv_usec);
129#endif
130
131 DEBUG(SHOW_TRACING, "%08li.%08li Device register read %08x\n",
132 current_time.tv_sec, (long)current_time.tv_usec,
133 readl(device_base + ISL38XX_CTRL_STAT_REG));
134 udelay(ISL38XX_WRITEIO_DELAY);
135
136 reg = readl(device_base + ISL38XX_INT_IDENT_REG);
137 if (reg == 0xabadface) {
138#if VERBOSE > SHOW_ERROR_MESSAGES
139 do_gettimeofday(&current_time);
140 DEBUG(SHOW_TRACING,
141 "%08li.%08li Device register abadface\n",
142 current_time.tv_sec, (long)current_time.tv_usec);
143#endif
144 /* read the Device Status Register until Sleepmode bit is set */
145 while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG),
146 (reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) {
147 udelay(ISL38XX_WRITEIO_DELAY);
148 counter++;
149 }
150
151 DEBUG(SHOW_TRACING,
152 "%08li.%08li Device register read %08x\n",
153 current_time.tv_sec, (long)current_time.tv_usec,
154 readl(device_base + ISL38XX_CTRL_STAT_REG));
155 udelay(ISL38XX_WRITEIO_DELAY);
156
157#if VERBOSE > SHOW_ERROR_MESSAGES
158 do_gettimeofday(&current_time);
159 DEBUG(SHOW_TRACING,
160 "%08li.%08li Device asleep counter %i\n",
161 current_time.tv_sec, (long)current_time.tv_usec,
162 counter);
163#endif
164 }
165 /* assert the Wakeup interrupt in the Device Interrupt Register */
166 isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_WAKEUP,
167 ISL38XX_DEV_INT_REG);
168 udelay(ISL38XX_WRITEIO_DELAY);
169
170 /* perform another read on the Device Status Register */
171 reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
172 udelay(ISL38XX_WRITEIO_DELAY);
173
174#if VERBOSE > SHOW_ERROR_MESSAGES
175 do_gettimeofday(&current_time);
176 DEBUG(SHOW_TRACING, "%08li.%08li Device register read %08x\n",
177 current_time.tv_sec, (long)current_time.tv_usec, reg);
178#endif
179 } else {
180 /* device is (still) awake */
181#if VERBOSE > SHOW_ERROR_MESSAGES
182 DEBUG(SHOW_TRACING, "Device is in active state\n");
183#endif
184 /* trigger the device by setting the Update bit in the Device Int reg */
185
186 isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE,
187 ISL38XX_DEV_INT_REG);
188 udelay(ISL38XX_WRITEIO_DELAY);
189 }
190}
191
192void
193isl38xx_interface_reset(void __iomem *device_base, dma_addr_t host_address)
194{
195#if VERBOSE > SHOW_ERROR_MESSAGES
196 DEBUG(SHOW_FUNCTION_CALLS, "isl38xx_interface_reset\n");
197#endif
198
199 /* load the address of the control block in the device */
200 isl38xx_w32_flush(device_base, host_address, ISL38XX_CTRL_BLK_BASE_REG);
201 udelay(ISL38XX_WRITEIO_DELAY);
202
203 /* set the reset bit in the Device Interrupt Register */
204 isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_RESET, ISL38XX_DEV_INT_REG);
205 udelay(ISL38XX_WRITEIO_DELAY);
206
207 /* enable the interrupt for detecting initialization */
208
209 /* Note: Do not enable other interrupts here. We want the
210 * device to have come up first 100% before allowing any other
211 * interrupts. */
212 isl38xx_w32_flush(device_base, ISL38XX_INT_IDENT_INIT, ISL38XX_INT_EN_REG);
213 udelay(ISL38XX_WRITEIO_DELAY); /* allow complete full reset */
214}
215
216void
217isl38xx_enable_common_interrupts(void __iomem *device_base) {
218 u32 reg;
219 reg = ( ISL38XX_INT_IDENT_UPDATE |
220 ISL38XX_INT_IDENT_SLEEP | ISL38XX_INT_IDENT_WAKEUP);
221 isl38xx_w32_flush(device_base, reg, ISL38XX_INT_EN_REG);
222 udelay(ISL38XX_WRITEIO_DELAY);
223}
224
225int
226isl38xx_in_queue(isl38xx_control_block *cb, int queue)
227{
228 const s32 delta = (le32_to_cpu(cb->driver_curr_frag[queue]) -
229 le32_to_cpu(cb->device_curr_frag[queue]));
230
231 /* determine the amount of fragments in the queue depending on the type
232 * of the queue, either transmit or receive */
233
234 BUG_ON(delta < 0); /* driver ptr must be ahead of device ptr */
235
236 switch (queue) {
237 /* send queues */
238 case ISL38XX_CB_TX_MGMTQ:
239 BUG_ON(delta > ISL38XX_CB_MGMT_QSIZE);
240 case ISL38XX_CB_TX_DATA_LQ:
241 case ISL38XX_CB_TX_DATA_HQ:
242 BUG_ON(delta > ISL38XX_CB_TX_QSIZE);
243 return delta;
244 break;
245
246 /* receive queues */
247 case ISL38XX_CB_RX_MGMTQ:
248 BUG_ON(delta > ISL38XX_CB_MGMT_QSIZE);
249 return ISL38XX_CB_MGMT_QSIZE - delta;
250 break;
251
252 case ISL38XX_CB_RX_DATA_LQ:
253 case ISL38XX_CB_RX_DATA_HQ:
254 BUG_ON(delta > ISL38XX_CB_RX_QSIZE);
255 return ISL38XX_CB_RX_QSIZE - delta;
256 break;
257 }
258 BUG();
259 return 0;
260}
diff --git a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h
new file mode 100644
index 000000000000..e83e4912ab66
--- /dev/null
+++ b/drivers/net/wireless/prism54/isl_38xx.h
@@ -0,0 +1,173 @@
1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19
20#ifndef _ISL_38XX_H
21#define _ISL_38XX_H
22
23#include <linux/version.h>
24#include <asm/io.h>
25#include <asm/byteorder.h>
26
27#define ISL38XX_CB_RX_QSIZE 8
28#define ISL38XX_CB_TX_QSIZE 32
29
30/* ISL38XX Access Point Specific definitions */
31#define ISL38XX_MAX_WDS_LINKS 8
32
33/* ISL38xx Client Specific definitions */
34#define ISL38XX_PSM_ACTIVE_STATE 0
35#define ISL38XX_PSM_POWERSAVE_STATE 1
36
37/* ISL38XX Host Interface Definitions */
38#define ISL38XX_PCI_MEM_SIZE 0x02000
39#define ISL38XX_MEMORY_WINDOW_SIZE 0x01000
40#define ISL38XX_DEV_FIRMWARE_ADDRES 0x20000
41#define ISL38XX_WRITEIO_DELAY 10 /* in us */
42#define ISL38XX_RESET_DELAY 50 /* in ms */
43#define ISL38XX_WAIT_CYCLE 10 /* in 10ms */
44#define ISL38XX_MAX_WAIT_CYCLES 10
45
46/* PCI Memory Area */
47#define ISL38XX_HARDWARE_REG 0x0000
48#define ISL38XX_CARDBUS_CIS 0x0800
49#define ISL38XX_DIRECT_MEM_WIN 0x1000
50
51/* Hardware registers */
52#define ISL38XX_DEV_INT_REG 0x0000
53#define ISL38XX_INT_IDENT_REG 0x0010
54#define ISL38XX_INT_ACK_REG 0x0014
55#define ISL38XX_INT_EN_REG 0x0018
56#define ISL38XX_GEN_PURP_COM_REG_1 0x0020
57#define ISL38XX_GEN_PURP_COM_REG_2 0x0024
58#define ISL38XX_CTRL_BLK_BASE_REG ISL38XX_GEN_PURP_COM_REG_1
59#define ISL38XX_DIR_MEM_BASE_REG 0x0030
60#define ISL38XX_CTRL_STAT_REG 0x0078
61
62/* High end mobos queue up pci writes, the following
63 * is used to "read" from after a write to force flush */
64#define ISL38XX_PCI_POSTING_FLUSH ISL38XX_INT_EN_REG
65
66/**
67 * isl38xx_w32_flush - PCI iomem write helper
68 * @base: (host) memory base address of the device
69 * @val: 32bit value (host order) to write
70 * @offset: byte offset into @base to write value to
71 *
72 * This helper takes care of writing a 32bit datum to the
73 * specified offset into the device's pci memory space, and making sure
74 * the pci memory buffers get flushed by performing one harmless read
75 * from the %ISL38XX_PCI_POSTING_FLUSH offset.
76 */
77static inline void
78isl38xx_w32_flush(void __iomem *base, u32 val, unsigned long offset)
79{
80 writel(val, base + offset);
81 (void) readl(base + ISL38XX_PCI_POSTING_FLUSH);
82}
83
84/* Device Interrupt register bits */
85#define ISL38XX_DEV_INT_RESET 0x0001
86#define ISL38XX_DEV_INT_UPDATE 0x0002
87#define ISL38XX_DEV_INT_WAKEUP 0x0008
88#define ISL38XX_DEV_INT_SLEEP 0x0010
89
90/* Interrupt Identification/Acknowledge/Enable register bits */
91#define ISL38XX_INT_IDENT_UPDATE 0x0002
92#define ISL38XX_INT_IDENT_INIT 0x0004
93#define ISL38XX_INT_IDENT_WAKEUP 0x0008
94#define ISL38XX_INT_IDENT_SLEEP 0x0010
95#define ISL38XX_INT_SOURCES 0x001E
96
97/* Control/Status register bits */
98/* Looks like there are other meaningful bits
99 0x20004400 seen in normal operation,
100 0x200044db at 'timeout waiting for mgmt response'
101*/
102#define ISL38XX_CTRL_STAT_SLEEPMODE 0x00000200
103#define ISL38XX_CTRL_STAT_CLKRUN 0x00800000
104#define ISL38XX_CTRL_STAT_RESET 0x10000000
105#define ISL38XX_CTRL_STAT_RAMBOOT 0x20000000
106#define ISL38XX_CTRL_STAT_STARTHALTED 0x40000000
107#define ISL38XX_CTRL_STAT_HOST_OVERRIDE 0x80000000
108
109/* Control Block definitions */
110#define ISL38XX_CB_RX_DATA_LQ 0
111#define ISL38XX_CB_TX_DATA_LQ 1
112#define ISL38XX_CB_RX_DATA_HQ 2
113#define ISL38XX_CB_TX_DATA_HQ 3
114#define ISL38XX_CB_RX_MGMTQ 4
115#define ISL38XX_CB_TX_MGMTQ 5
116#define ISL38XX_CB_QCOUNT 6
117#define ISL38XX_CB_MGMT_QSIZE 4
118#define ISL38XX_MIN_QTHRESHOLD 4 /* fragments */
119
120/* Memory Manager definitions */
121#define MGMT_FRAME_SIZE 1500 /* >= size struct obj_bsslist */
122#define MGMT_TX_FRAME_COUNT 24 /* max 4 + spare 4 + 8 init */
123#define MGMT_RX_FRAME_COUNT 24 /* 4*4 + spare 8 */
124#define MGMT_FRAME_COUNT (MGMT_TX_FRAME_COUNT + MGMT_RX_FRAME_COUNT)
125#define CONTROL_BLOCK_SIZE 1024 /* should be enough */
126#define PSM_FRAME_SIZE 1536
127#define PSM_MINIMAL_STATION_COUNT 64
128#define PSM_FRAME_COUNT PSM_MINIMAL_STATION_COUNT
129#define PSM_BUFFER_SIZE PSM_FRAME_SIZE * PSM_FRAME_COUNT
130#define MAX_TRAP_RX_QUEUE 4
131#define HOST_MEM_BLOCK CONTROL_BLOCK_SIZE + PSM_BUFFER_SIZE
132
133/* Fragment package definitions */
134#define FRAGMENT_FLAG_MF 0x0001
135#define MAX_FRAGMENT_SIZE 1536
136
137/* In monitor mode frames have a header. I don't know exactly how big those
138 * frame can be but I've never seen any frame bigger than 1584... :
139 */
140#define MAX_FRAGMENT_SIZE_RX 1600
141
142typedef struct {
143 u32 address; /* physical address on host */
144 u16 size; /* packet size */
145 u16 flags; /* set of bit-wise flags */
146} isl38xx_fragment;
147
148struct isl38xx_cb {
149 u32 driver_curr_frag[ISL38XX_CB_QCOUNT];
150 u32 device_curr_frag[ISL38XX_CB_QCOUNT];
151 isl38xx_fragment rx_data_low[ISL38XX_CB_RX_QSIZE];
152 isl38xx_fragment tx_data_low[ISL38XX_CB_TX_QSIZE];
153 isl38xx_fragment rx_data_high[ISL38XX_CB_RX_QSIZE];
154 isl38xx_fragment tx_data_high[ISL38XX_CB_TX_QSIZE];
155 isl38xx_fragment rx_data_mgmt[ISL38XX_CB_MGMT_QSIZE];
156 isl38xx_fragment tx_data_mgmt[ISL38XX_CB_MGMT_QSIZE];
157};
158
159typedef struct isl38xx_cb isl38xx_control_block;
160
161/* determine number of entries currently in queue */
162int isl38xx_in_queue(isl38xx_control_block *cb, int queue);
163
164void isl38xx_disable_interrupts(void __iomem *);
165void isl38xx_enable_common_interrupts(void __iomem *);
166
167void isl38xx_handle_sleep_request(isl38xx_control_block *, int *,
168 void __iomem *);
169void isl38xx_handle_wakeup(isl38xx_control_block *, int *, void __iomem *);
170void isl38xx_trigger_device(int, void __iomem *);
171void isl38xx_interface_reset(void __iomem *, dma_addr_t);
172
173#endif /* _ISL_38XX_H */
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
new file mode 100644
index 000000000000..0f29a9c7bc2c
--- /dev/null
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -0,0 +1,2750 @@
1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc.
4 * (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
5 * (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
6 * (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <linux/version.h>
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/if_arp.h>
27#include <linux/pci.h>
28
29#include <asm/uaccess.h>
30
31#include "prismcompat.h"
32#include "isl_ioctl.h"
33#include "islpci_mgt.h"
34#include "isl_oid.h" /* additional types and defs for isl38xx fw */
35#include "oid_mgt.h"
36
37#include <net/iw_handler.h> /* New driver API */
38
39
40static void prism54_wpa_ie_add(islpci_private *priv, u8 *bssid,
41 u8 *wpa_ie, size_t wpa_ie_len);
42static size_t prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie);
43static int prism54_set_wpa(struct net_device *, struct iw_request_info *,
44 __u32 *, char *);
45
46
47/**
48 * prism54_mib_mode_helper - MIB change mode helper function
49 * @mib: the &struct islpci_mib object to modify
50 * @iw_mode: new mode (%IW_MODE_*)
51 *
52 * This is a helper function, hence it does not lock. Make sure
53 * caller deals with locking *if* necessary. This function sets the
54 * mode-dependent mib values and does the mapping of the Linux
55 * Wireless API modes to Device firmware modes. It also checks for
56 * correct valid Linux wireless modes.
57 */
58static int
59prism54_mib_mode_helper(islpci_private *priv, u32 iw_mode)
60{
61 u32 config = INL_CONFIG_MANUALRUN;
62 u32 mode, bsstype;
63
64 /* For now, just catch early the Repeater and Secondary modes here */
65 if (iw_mode == IW_MODE_REPEAT || iw_mode == IW_MODE_SECOND) {
66 printk(KERN_DEBUG
67 "%s(): Sorry, Repeater mode and Secondary mode "
68 "are not yet supported by this driver.\n", __FUNCTION__);
69 return -EINVAL;
70 }
71
72 priv->iw_mode = iw_mode;
73
74 switch (iw_mode) {
75 case IW_MODE_AUTO:
76 mode = INL_MODE_CLIENT;
77 bsstype = DOT11_BSSTYPE_ANY;
78 break;
79 case IW_MODE_ADHOC:
80 mode = INL_MODE_CLIENT;
81 bsstype = DOT11_BSSTYPE_IBSS;
82 break;
83 case IW_MODE_INFRA:
84 mode = INL_MODE_CLIENT;
85 bsstype = DOT11_BSSTYPE_INFRA;
86 break;
87 case IW_MODE_MASTER:
88 mode = INL_MODE_AP;
89 bsstype = DOT11_BSSTYPE_INFRA;
90 break;
91 case IW_MODE_MONITOR:
92 mode = INL_MODE_PROMISCUOUS;
93 bsstype = DOT11_BSSTYPE_ANY;
94 config |= INL_CONFIG_RXANNEX;
95 break;
96 default:
97 return -EINVAL;
98 }
99
100 if (init_wds)
101 config |= INL_CONFIG_WDS;
102 mgt_set(priv, DOT11_OID_BSSTYPE, &bsstype);
103 mgt_set(priv, OID_INL_CONFIG, &config);
104 mgt_set(priv, OID_INL_MODE, &mode);
105
106 return 0;
107}
108
109/**
110 * prism54_mib_init - fill MIB cache with defaults
111 *
112 * this function initializes the struct given as @mib with defaults,
113 * of which many are retrieved from the global module parameter
114 * variables.
115 */
116
117void
118prism54_mib_init(islpci_private *priv)
119{
120 u32 channel, authen, wep, filter, dot1x, mlme, conformance, power, mode;
121 struct obj_buffer psm_buffer = {
122 .size = PSM_BUFFER_SIZE,
123 .addr = priv->device_psm_buffer
124 };
125
126 channel = CARD_DEFAULT_CHANNEL;
127 authen = CARD_DEFAULT_AUTHEN;
128 wep = CARD_DEFAULT_WEP;
129 filter = CARD_DEFAULT_FILTER; /* (0) Do not filter un-encrypted data */
130 dot1x = CARD_DEFAULT_DOT1X;
131 mlme = CARD_DEFAULT_MLME_MODE;
132 conformance = CARD_DEFAULT_CONFORMANCE;
133 power = 127;
134 mode = CARD_DEFAULT_IW_MODE;
135
136 mgt_set(priv, DOT11_OID_CHANNEL, &channel);
137 mgt_set(priv, DOT11_OID_AUTHENABLE, &authen);
138 mgt_set(priv, DOT11_OID_PRIVACYINVOKED, &wep);
139 mgt_set(priv, DOT11_OID_PSMBUFFER, &psm_buffer);
140 mgt_set(priv, DOT11_OID_EXUNENCRYPTED, &filter);
141 mgt_set(priv, DOT11_OID_DOT1XENABLE, &dot1x);
142 mgt_set(priv, DOT11_OID_MLMEAUTOLEVEL, &mlme);
143 mgt_set(priv, OID_INL_DOT11D_CONFORMANCE, &conformance);
144 mgt_set(priv, OID_INL_OUTPUTPOWER, &power);
145
146 /* This sets all of the mode-dependent values */
147 prism54_mib_mode_helper(priv, mode);
148}
149
150/* this will be executed outside of atomic context thanks to
151 * schedule_work(), thus we can as well use sleeping semaphore
152 * locking */
153void
154prism54_update_stats(islpci_private *priv)
155{
156 char *data;
157 int j;
158 struct obj_bss bss, *bss2;
159 union oid_res_t r;
160
161 if (down_interruptible(&priv->stats_sem))
162 return;
163
164/* Noise floor.
165 * I'm not sure if the unit is dBm.
166 * Note : If we are not connected, this value seems to be irrelevant. */
167
168 mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
169 priv->local_iwstatistics.qual.noise = r.u;
170
171/* Get the rssi of the link. To do this we need to retrieve a bss. */
172
173 /* First get the MAC address of the AP we are associated with. */
174 mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r);
175 data = r.ptr;
176
177 /* copy this MAC to the bss */
178 memcpy(bss.address, data, 6);
179 kfree(data);
180
181 /* now ask for the corresponding bss */
182 j = mgt_get_request(priv, DOT11_OID_BSSFIND, 0, (void *) &bss, &r);
183 bss2 = r.ptr;
184 /* report the rssi and use it to calculate
185 * link quality through a signal-noise
186 * ratio */
187 priv->local_iwstatistics.qual.level = bss2->rssi;
188 priv->local_iwstatistics.qual.qual =
189 bss2->rssi - priv->iwstatistics.qual.noise;
190
191 kfree(bss2);
192
193 /* report that the stats are new */
194 priv->local_iwstatistics.qual.updated = 0x7;
195
196/* Rx : unable to decrypt the MPDU */
197 mgt_get_request(priv, DOT11_OID_PRIVRXFAILED, 0, NULL, &r);
198 priv->local_iwstatistics.discard.code = r.u;
199
200/* Tx : Max MAC retries num reached */
201 mgt_get_request(priv, DOT11_OID_MPDUTXFAILED, 0, NULL, &r);
202 priv->local_iwstatistics.discard.retries = r.u;
203
204 up(&priv->stats_sem);
205
206 return;
207}
208
209struct iw_statistics *
210prism54_get_wireless_stats(struct net_device *ndev)
211{
212 islpci_private *priv = netdev_priv(ndev);
213
214 /* If the stats are being updated return old data */
215 if (down_trylock(&priv->stats_sem) == 0) {
216 memcpy(&priv->iwstatistics, &priv->local_iwstatistics,
217 sizeof (struct iw_statistics));
218 /* They won't be marked updated for the next time */
219 priv->local_iwstatistics.qual.updated = 0;
220 up(&priv->stats_sem);
221 } else
222 priv->iwstatistics.qual.updated = 0;
223
224 /* Update our wireless stats, but do not schedule to often
225 * (max 1 HZ) */
226 if ((priv->stats_timestamp == 0) ||
227 time_after(jiffies, priv->stats_timestamp + 1 * HZ)) {
228 schedule_work(&priv->stats_work);
229 priv->stats_timestamp = jiffies;
230 }
231
232 return &priv->iwstatistics;
233}
234
235static int
236prism54_commit(struct net_device *ndev, struct iw_request_info *info,
237 char *cwrq, char *extra)
238{
239 islpci_private *priv = netdev_priv(ndev);
240
241 /* simply re-set the last set SSID, this should commit most stuff */
242
243 /* Commit in Monitor mode is not necessary, also setting essid
244 * in Monitor mode does not make sense and isn't allowed for this
245 * device's firmware */
246 if (priv->iw_mode != IW_MODE_MONITOR)
247 return mgt_set_request(priv, DOT11_OID_SSID, 0, NULL);
248 return 0;
249}
250
251static int
252prism54_get_name(struct net_device *ndev, struct iw_request_info *info,
253 char *cwrq, char *extra)
254{
255 islpci_private *priv = netdev_priv(ndev);
256 char *capabilities;
257 union oid_res_t r;
258 int rvalue;
259
260 if (islpci_get_state(priv) < PRV_STATE_INIT) {
261 strncpy(cwrq, "NOT READY!", IFNAMSIZ);
262 return 0;
263 }
264 rvalue = mgt_get_request(priv, OID_INL_PHYCAPABILITIES, 0, NULL, &r);
265
266 switch (r.u) {
267 case INL_PHYCAP_5000MHZ:
268 capabilities = "IEEE 802.11a/b/g";
269 break;
270 case INL_PHYCAP_FAA:
271 capabilities = "IEEE 802.11b/g - FAA Support";
272 break;
273 case INL_PHYCAP_2400MHZ:
274 default:
275 capabilities = "IEEE 802.11b/g"; /* Default */
276 break;
277 }
278 strncpy(cwrq, capabilities, IFNAMSIZ);
279 return rvalue;
280}
281
282static int
283prism54_set_freq(struct net_device *ndev, struct iw_request_info *info,
284 struct iw_freq *fwrq, char *extra)
285{
286 islpci_private *priv = netdev_priv(ndev);
287 int rvalue;
288 u32 c;
289
290 if (fwrq->m < 1000)
291 /* we have a channel number */
292 c = fwrq->m;
293 else
294 c = (fwrq->e == 1) ? channel_of_freq(fwrq->m / 100000) : 0;
295
296 rvalue = c ? mgt_set_request(priv, DOT11_OID_CHANNEL, 0, &c) : -EINVAL;
297
298 /* Call commit handler */
299 return (rvalue ? rvalue : -EINPROGRESS);
300}
301
302static int
303prism54_get_freq(struct net_device *ndev, struct iw_request_info *info,
304 struct iw_freq *fwrq, char *extra)
305{
306 islpci_private *priv = netdev_priv(ndev);
307 union oid_res_t r;
308 int rvalue;
309
310 rvalue = mgt_get_request(priv, DOT11_OID_CHANNEL, 0, NULL, &r);
311 fwrq->i = r.u;
312 rvalue |= mgt_get_request(priv, DOT11_OID_FREQUENCY, 0, NULL, &r);
313 fwrq->m = r.u;
314 fwrq->e = 3;
315
316 return rvalue;
317}
318
319static int
320prism54_set_mode(struct net_device *ndev, struct iw_request_info *info,
321 __u32 * uwrq, char *extra)
322{
323 islpci_private *priv = netdev_priv(ndev);
324 u32 mlmeautolevel = CARD_DEFAULT_MLME_MODE;
325
326 /* Let's see if the user passed a valid Linux Wireless mode */
327 if (*uwrq > IW_MODE_MONITOR || *uwrq < IW_MODE_AUTO) {
328 printk(KERN_DEBUG
329 "%s: %s() You passed a non-valid init_mode.\n",
330 priv->ndev->name, __FUNCTION__);
331 return -EINVAL;
332 }
333
334 down_write(&priv->mib_sem);
335
336 if (prism54_mib_mode_helper(priv, *uwrq)) {
337 up_write(&priv->mib_sem);
338 return -EOPNOTSUPP;
339 }
340
341 /* the ACL code needs an intermediate mlmeautolevel. The wpa stuff an
342 * extended one.
343 */
344 if ((*uwrq == IW_MODE_MASTER) && (priv->acl.policy != MAC_POLICY_OPEN))
345 mlmeautolevel = DOT11_MLME_INTERMEDIATE;
346 if (priv->wpa)
347 mlmeautolevel = DOT11_MLME_EXTENDED;
348
349 mgt_set(priv, DOT11_OID_MLMEAUTOLEVEL, &mlmeautolevel);
350
351 if (mgt_commit(priv)) {
352 up_write(&priv->mib_sem);
353 return -EIO;
354 }
355 priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR)
356 ? priv->monitor_type : ARPHRD_ETHER;
357 up_write(&priv->mib_sem);
358
359 return 0;
360}
361
362/* Use mib cache */
363static int
364prism54_get_mode(struct net_device *ndev, struct iw_request_info *info,
365 __u32 * uwrq, char *extra)
366{
367 islpci_private *priv = netdev_priv(ndev);
368
369 BUG_ON((priv->iw_mode < IW_MODE_AUTO) || (priv->iw_mode >
370 IW_MODE_MONITOR));
371 *uwrq = priv->iw_mode;
372
373 return 0;
374}
375
376/* we use DOT11_OID_EDTHRESHOLD. From what I guess the card will not try to
377 * emit data if (sensitivity > rssi - noise) (in dBm).
378 * prism54_set_sens does not seem to work.
379 */
380
381static int
382prism54_set_sens(struct net_device *ndev, struct iw_request_info *info,
383 struct iw_param *vwrq, char *extra)
384{
385 islpci_private *priv = netdev_priv(ndev);
386 u32 sens;
387
388 /* by default the card sets this to 20. */
389 sens = vwrq->disabled ? 20 : vwrq->value;
390
391 return mgt_set_request(priv, DOT11_OID_EDTHRESHOLD, 0, &sens);
392}
393
394static int
395prism54_get_sens(struct net_device *ndev, struct iw_request_info *info,
396 struct iw_param *vwrq, char *extra)
397{
398 islpci_private *priv = netdev_priv(ndev);
399 union oid_res_t r;
400 int rvalue;
401
402 rvalue = mgt_get_request(priv, DOT11_OID_EDTHRESHOLD, 0, NULL, &r);
403
404 vwrq->value = r.u;
405 vwrq->disabled = (vwrq->value == 0);
406 vwrq->fixed = 1;
407
408 return rvalue;
409}
410
411static int
412prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
413 struct iw_point *dwrq, char *extra)
414{
415 struct iw_range *range = (struct iw_range *) extra;
416 islpci_private *priv = netdev_priv(ndev);
417 u8 *data;
418 int i, m, rvalue;
419 struct obj_frequencies *freq;
420 union oid_res_t r;
421
422 memset(range, 0, sizeof (struct iw_range));
423 dwrq->length = sizeof (struct iw_range);
424
425 /* set the wireless extension version number */
426 range->we_version_source = SUPPORTED_WIRELESS_EXT;
427 range->we_version_compiled = WIRELESS_EXT;
428
429 /* Now the encoding capabilities */
430 range->num_encoding_sizes = 3;
431 /* 64(40) bits WEP */
432 range->encoding_size[0] = 5;
433 /* 128(104) bits WEP */
434 range->encoding_size[1] = 13;
435 /* 256 bits for WPA-PSK */
436 range->encoding_size[2] = 32;
437 /* 4 keys are allowed */
438 range->max_encoding_tokens = 4;
439
440 /* we don't know the quality range... */
441 range->max_qual.level = 0;
442 range->max_qual.noise = 0;
443 range->max_qual.qual = 0;
444 /* these value describe an average quality. Needs more tweaking... */
445 range->avg_qual.level = -80; /* -80 dBm */
446 range->avg_qual.noise = 0; /* don't know what to put here */
447 range->avg_qual.qual = 0;
448
449 range->sensitivity = 200;
450
451 /* retry limit capabilities */
452 range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
453 range->retry_flags = IW_RETRY_LIMIT;
454 range->r_time_flags = IW_RETRY_LIFETIME;
455
456 /* I don't know the range. Put stupid things here */
457 range->min_retry = 1;
458 range->max_retry = 65535;
459 range->min_r_time = 1024;
460 range->max_r_time = 65535 * 1024;
461
462 /* txpower is supported in dBm's */
463 range->txpower_capa = IW_TXPOW_DBM;
464
465#if WIRELESS_EXT > 16
466 /* Event capability (kernel + driver) */
467 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
468 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
469 IW_EVENT_CAPA_MASK(SIOCGIWAP));
470 range->event_capa[1] = IW_EVENT_CAPA_K_1;
471 range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM);
472#endif /* WIRELESS_EXT > 16 */
473
474 if (islpci_get_state(priv) < PRV_STATE_INIT)
475 return 0;
476
477 /* Request the device for the supported frequencies
478 * not really relevant since some devices will report the 5 GHz band
479 * frequencies even if they don't support them.
480 */
481 rvalue =
482 mgt_get_request(priv, DOT11_OID_SUPPORTEDFREQUENCIES, 0, NULL, &r);
483 freq = r.ptr;
484
485 range->num_channels = freq->nr;
486 range->num_frequency = freq->nr;
487
488 m = min(IW_MAX_FREQUENCIES, (int) freq->nr);
489 for (i = 0; i < m; i++) {
490 range->freq[i].m = freq->mhz[i];
491 range->freq[i].e = 6;
492 range->freq[i].i = channel_of_freq(freq->mhz[i]);
493 }
494 kfree(freq);
495
496 rvalue |= mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r);
497 data = r.ptr;
498
499 /* We got an array of char. It is NULL terminated. */
500 i = 0;
501 while ((i < IW_MAX_BITRATES) && (*data != 0)) {
502 /* the result must be in bps. The card gives us 500Kbps */
503 range->bitrate[i] = *data * 500000;
504 i++;
505 data++;
506 }
507 range->num_bitrates = i;
508 kfree(r.ptr);
509
510 return rvalue;
511}
512
513/* Set AP address*/
514
515static int
516prism54_set_wap(struct net_device *ndev, struct iw_request_info *info,
517 struct sockaddr *awrq, char *extra)
518{
519 islpci_private *priv = netdev_priv(ndev);
520 char bssid[6];
521 int rvalue;
522
523 if (awrq->sa_family != ARPHRD_ETHER)
524 return -EINVAL;
525
526 /* prepare the structure for the set object */
527 memcpy(&bssid[0], awrq->sa_data, 6);
528
529 /* set the bssid -- does this make sense when in AP mode? */
530 rvalue = mgt_set_request(priv, DOT11_OID_BSSID, 0, &bssid);
531
532 return (rvalue ? rvalue : -EINPROGRESS); /* Call commit handler */
533}
534
535/* get AP address*/
536
537static int
538prism54_get_wap(struct net_device *ndev, struct iw_request_info *info,
539 struct sockaddr *awrq, char *extra)
540{
541 islpci_private *priv = netdev_priv(ndev);
542 union oid_res_t r;
543 int rvalue;
544
545 rvalue = mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r);
546 memcpy(awrq->sa_data, r.ptr, 6);
547 awrq->sa_family = ARPHRD_ETHER;
548 kfree(r.ptr);
549
550 return rvalue;
551}
552
553static int
554prism54_set_scan(struct net_device *dev, struct iw_request_info *info,
555 struct iw_param *vwrq, char *extra)
556{
557 /* hehe the device does this automagicaly */
558 return 0;
559}
560
561/* a little helper that will translate our data into a card independent
562 * format that the Wireless Tools will understand. This was inspired by
563 * the "Aironet driver for 4500 and 4800 series cards" (GPL)
564 */
565
566static char *
567prism54_translate_bss(struct net_device *ndev, char *current_ev,
568 char *end_buf, struct obj_bss *bss, char noise)
569{
570 struct iw_event iwe; /* Temporary buffer */
571 short cap;
572 islpci_private *priv = netdev_priv(ndev);
573
574 /* The first entry must be the MAC address */
575 memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
576 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
577 iwe.cmd = SIOCGIWAP;
578 current_ev =
579 iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
580
581 /* The following entries will be displayed in the same order we give them */
582
583 /* The ESSID. */
584 iwe.u.data.length = bss->ssid.length;
585 iwe.u.data.flags = 1;
586 iwe.cmd = SIOCGIWESSID;
587 current_ev = iwe_stream_add_point(current_ev, end_buf,
588 &iwe, bss->ssid.octets);
589
590 /* Capabilities */
591#define CAP_ESS 0x01
592#define CAP_IBSS 0x02
593#define CAP_CRYPT 0x10
594
595 /* Mode */
596 cap = bss->capinfo;
597 iwe.u.mode = 0;
598 if (cap & CAP_ESS)
599 iwe.u.mode = IW_MODE_MASTER;
600 else if (cap & CAP_IBSS)
601 iwe.u.mode = IW_MODE_ADHOC;
602 iwe.cmd = SIOCGIWMODE;
603 if (iwe.u.mode)
604 current_ev =
605 iwe_stream_add_event(current_ev, end_buf, &iwe,
606 IW_EV_UINT_LEN);
607
608 /* Encryption capability */
609 if (cap & CAP_CRYPT)
610 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
611 else
612 iwe.u.data.flags = IW_ENCODE_DISABLED;
613 iwe.u.data.length = 0;
614 iwe.cmd = SIOCGIWENCODE;
615 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL);
616
617 /* Add frequency. (short) bss->channel is the frequency in MHz */
618 iwe.u.freq.m = bss->channel;
619 iwe.u.freq.e = 6;
620 iwe.cmd = SIOCGIWFREQ;
621 current_ev =
622 iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
623
624 /* Add quality statistics */
625 iwe.u.qual.level = bss->rssi;
626 iwe.u.qual.noise = noise;
627 /* do a simple SNR for quality */
628 iwe.u.qual.qual = bss->rssi - noise;
629 iwe.cmd = IWEVQUAL;
630 current_ev =
631 iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
632
633 if (priv->wpa) {
634 u8 wpa_ie[MAX_WPA_IE_LEN];
635 char *buf, *p;
636 size_t wpa_ie_len;
637 int i;
638
639 wpa_ie_len = prism54_wpa_ie_get(priv, bss->address, wpa_ie);
640 if (wpa_ie_len > 0 &&
641 (buf = kmalloc(wpa_ie_len * 2 + 10, GFP_ATOMIC))) {
642 p = buf;
643 p += sprintf(p, "wpa_ie=");
644 for (i = 0; i < wpa_ie_len; i++) {
645 p += sprintf(p, "%02x", wpa_ie[i]);
646 }
647 memset(&iwe, 0, sizeof (iwe));
648 iwe.cmd = IWEVCUSTOM;
649 iwe.u.data.length = strlen(buf);
650 current_ev = iwe_stream_add_point(current_ev, end_buf,
651 &iwe, buf);
652 kfree(buf);
653 }
654 }
655 return current_ev;
656}
657
658static int
659prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
660 struct iw_point *dwrq, char *extra)
661{
662 islpci_private *priv = netdev_priv(ndev);
663 int i, rvalue;
664 struct obj_bsslist *bsslist;
665 u32 noise = 0;
666 char *current_ev = extra;
667 union oid_res_t r;
668
669 if (islpci_get_state(priv) < PRV_STATE_INIT) {
670 /* device is not ready, fail gently */
671 dwrq->length = 0;
672 return 0;
673 }
674
675 /* first get the noise value. We will use it to report the link quality */
676 rvalue = mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
677 noise = r.u;
678
679 /* Ask the device for a list of known bss.
680 * The old API, using SIOCGIWAPLIST, had a hard limit of IW_MAX_AP=64.
681 * The new API, using SIOCGIWSCAN, is only limited by the buffer size.
682 * WE-14->WE-16, the buffer is limited to IW_SCAN_MAX_DATA bytes.
683 * Starting with WE-17, the buffer can be as big as needed.
684 * But the device won't repport anything if you change the value
685 * of IWMAX_BSS=24. */
686
687 rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
688 bsslist = r.ptr;
689
690 /* ok now, scan the list and translate its info */
691 for (i = 0; i < (int) bsslist->nr; i++) {
692 current_ev = prism54_translate_bss(ndev, current_ev,
693 extra + dwrq->length,
694 &(bsslist->bsslist[i]),
695 noise);
696#if WIRELESS_EXT > 16
697 /* Check if there is space for one more entry */
698 if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
699 /* Ask user space to try again with a bigger buffer */
700 rvalue = -E2BIG;
701 break;
702 }
703#endif /* WIRELESS_EXT > 16 */
704 }
705
706 kfree(bsslist);
707 dwrq->length = (current_ev - extra);
708 dwrq->flags = 0; /* todo */
709
710 return rvalue;
711}
712
713static int
714prism54_set_essid(struct net_device *ndev, struct iw_request_info *info,
715 struct iw_point *dwrq, char *extra)
716{
717 islpci_private *priv = netdev_priv(ndev);
718 struct obj_ssid essid;
719
720 memset(essid.octets, 0, 33);
721
722 /* Check if we were asked for `any' */
723 if (dwrq->flags && dwrq->length) {
724 if (dwrq->length > min(33, IW_ESSID_MAX_SIZE + 1))
725 return -E2BIG;
726 essid.length = dwrq->length - 1;
727 memcpy(essid.octets, extra, dwrq->length);
728 } else
729 essid.length = 0;
730
731 if (priv->iw_mode != IW_MODE_MONITOR)
732 return mgt_set_request(priv, DOT11_OID_SSID, 0, &essid);
733
734 /* If in monitor mode, just save to mib */
735 mgt_set(priv, DOT11_OID_SSID, &essid);
736 return 0;
737
738}
739
740static int
741prism54_get_essid(struct net_device *ndev, struct iw_request_info *info,
742 struct iw_point *dwrq, char *extra)
743{
744 islpci_private *priv = netdev_priv(ndev);
745 struct obj_ssid *essid;
746 union oid_res_t r;
747 int rvalue;
748
749 rvalue = mgt_get_request(priv, DOT11_OID_SSID, 0, NULL, &r);
750 essid = r.ptr;
751
752 if (essid->length) {
753 dwrq->flags = 1; /* set ESSID to ON for Wireless Extensions */
754 /* if it is to big, trunk it */
755 dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length + 1);
756 } else {
757 dwrq->flags = 0;
758 dwrq->length = 0;
759 }
760 essid->octets[essid->length] = '\0';
761 memcpy(extra, essid->octets, dwrq->length);
762 kfree(essid);
763
764 return rvalue;
765}
766
767/* Provides no functionality, just completes the ioctl. In essence this is a
768 * just a cosmetic ioctl.
769 */
770static int
771prism54_set_nick(struct net_device *ndev, struct iw_request_info *info,
772 struct iw_point *dwrq, char *extra)
773{
774 islpci_private *priv = netdev_priv(ndev);
775
776 if (dwrq->length > IW_ESSID_MAX_SIZE)
777 return -E2BIG;
778
779 down_write(&priv->mib_sem);
780 memset(priv->nickname, 0, sizeof (priv->nickname));
781 memcpy(priv->nickname, extra, dwrq->length);
782 up_write(&priv->mib_sem);
783
784 return 0;
785}
786
787static int
788prism54_get_nick(struct net_device *ndev, struct iw_request_info *info,
789 struct iw_point *dwrq, char *extra)
790{
791 islpci_private *priv = netdev_priv(ndev);
792
793 dwrq->length = 0;
794
795 down_read(&priv->mib_sem);
796 dwrq->length = strlen(priv->nickname) + 1;
797 memcpy(extra, priv->nickname, dwrq->length);
798 up_read(&priv->mib_sem);
799
800 return 0;
801}
802
803/* Set the allowed Bitrates */
804
805static int
806prism54_set_rate(struct net_device *ndev,
807 struct iw_request_info *info,
808 struct iw_param *vwrq, char *extra)
809{
810
811 islpci_private *priv = netdev_priv(ndev);
812 u32 rate, profile;
813 char *data;
814 int ret, i;
815 union oid_res_t r;
816
817 if (vwrq->value == -1) {
818 /* auto mode. No limit. */
819 profile = 1;
820 return mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
821 }
822
823 ret = mgt_get_request(priv, DOT11_OID_SUPPORTEDRATES, 0, NULL, &r);
824 if (ret) {
825 kfree(r.ptr);
826 return ret;
827 }
828
829 rate = (u32) (vwrq->value / 500000);
830 data = r.ptr;
831 i = 0;
832
833 while (data[i]) {
834 if (rate && (data[i] == rate)) {
835 break;
836 }
837 if (vwrq->value == i) {
838 break;
839 }
840 data[i] |= 0x80;
841 i++;
842 }
843
844 if (!data[i]) {
845 kfree(r.ptr);
846 return -EINVAL;
847 }
848
849 data[i] |= 0x80;
850 data[i + 1] = 0;
851
852 /* Now, check if we want a fixed or auto value */
853 if (vwrq->fixed) {
854 data[0] = data[i];
855 data[1] = 0;
856 }
857
858/*
859 i = 0;
860 printk("prism54 rate: ");
861 while(data[i]) {
862 printk("%u ", data[i]);
863 i++;
864 }
865 printk("0\n");
866*/
867 profile = -1;
868 ret = mgt_set_request(priv, DOT11_OID_PROFILES, 0, &profile);
869 ret |= mgt_set_request(priv, DOT11_OID_EXTENDEDRATES, 0, data);
870 ret |= mgt_set_request(priv, DOT11_OID_RATES, 0, data);
871
872 kfree(r.ptr);
873
874 return ret;
875}
876
877/* Get the current bit rate */
878static int
879prism54_get_rate(struct net_device *ndev,
880 struct iw_request_info *info,
881 struct iw_param *vwrq, char *extra)
882{
883 islpci_private *priv = netdev_priv(ndev);
884 int rvalue;
885 char *data;
886 union oid_res_t r;
887
888 /* Get the current bit rate */
889 if ((rvalue = mgt_get_request(priv, GEN_OID_LINKSTATE, 0, NULL, &r)))
890 return rvalue;
891 vwrq->value = r.u * 500000;
892
893 /* request the device for the enabled rates */
894 rvalue = mgt_get_request(priv, DOT11_OID_RATES, 0, NULL, &r);
895 if (rvalue) {
896 kfree(r.ptr);
897 return rvalue;
898 }
899 data = r.ptr;
900 vwrq->fixed = (data[0] != 0) && (data[1] == 0);
901 kfree(r.ptr);
902
903 return 0;
904}
905
906static int
907prism54_set_rts(struct net_device *ndev, struct iw_request_info *info,
908 struct iw_param *vwrq, char *extra)
909{
910 islpci_private *priv = netdev_priv(ndev);
911
912 return mgt_set_request(priv, DOT11_OID_RTSTHRESH, 0, &vwrq->value);
913}
914
915static int
916prism54_get_rts(struct net_device *ndev, struct iw_request_info *info,
917 struct iw_param *vwrq, char *extra)
918{
919 islpci_private *priv = netdev_priv(ndev);
920 union oid_res_t r;
921 int rvalue;
922
923 /* get the rts threshold */
924 rvalue = mgt_get_request(priv, DOT11_OID_RTSTHRESH, 0, NULL, &r);
925 vwrq->value = r.u;
926
927 return rvalue;
928}
929
930static int
931prism54_set_frag(struct net_device *ndev, struct iw_request_info *info,
932 struct iw_param *vwrq, char *extra)
933{
934 islpci_private *priv = netdev_priv(ndev);
935
936 return mgt_set_request(priv, DOT11_OID_FRAGTHRESH, 0, &vwrq->value);
937}
938
939static int
940prism54_get_frag(struct net_device *ndev, struct iw_request_info *info,
941 struct iw_param *vwrq, char *extra)
942{
943 islpci_private *priv = netdev_priv(ndev);
944 union oid_res_t r;
945 int rvalue;
946
947 rvalue = mgt_get_request(priv, DOT11_OID_FRAGTHRESH, 0, NULL, &r);
948 vwrq->value = r.u;
949
950 return rvalue;
951}
952
953/* Here we have (min,max) = max retries for (small frames, big frames). Where
954 * big frame <=> bigger than the rts threshold
955 * small frame <=> smaller than the rts threshold
956 * This is not really the behavior expected by the wireless tool but it seems
957 * to be a common behavior in other drivers.
958 */
959
960static int
961prism54_set_retry(struct net_device *ndev, struct iw_request_info *info,
962 struct iw_param *vwrq, char *extra)
963{
964 islpci_private *priv = netdev_priv(ndev);
965 u32 slimit = 0, llimit = 0; /* short and long limit */
966 u32 lifetime = 0;
967 int rvalue = 0;
968
969 if (vwrq->disabled)
970 /* we cannot disable this feature */
971 return -EINVAL;
972
973 if (vwrq->flags & IW_RETRY_LIMIT) {
974 if (vwrq->flags & IW_RETRY_MIN)
975 slimit = vwrq->value;
976 else if (vwrq->flags & IW_RETRY_MAX)
977 llimit = vwrq->value;
978 else {
979 /* we are asked to set both */
980 slimit = vwrq->value;
981 llimit = vwrq->value;
982 }
983 }
984 if (vwrq->flags & IW_RETRY_LIFETIME)
985 /* Wireless tools use us unit while the device uses 1024 us unit */
986 lifetime = vwrq->value / 1024;
987
988 /* now set what is requested */
989 if (slimit)
990 rvalue =
991 mgt_set_request(priv, DOT11_OID_SHORTRETRIES, 0, &slimit);
992 if (llimit)
993 rvalue |=
994 mgt_set_request(priv, DOT11_OID_LONGRETRIES, 0, &llimit);
995 if (lifetime)
996 rvalue |=
997 mgt_set_request(priv, DOT11_OID_MAXTXLIFETIME, 0,
998 &lifetime);
999 return rvalue;
1000}
1001
1002static int
1003prism54_get_retry(struct net_device *ndev, struct iw_request_info *info,
1004 struct iw_param *vwrq, char *extra)
1005{
1006 islpci_private *priv = netdev_priv(ndev);
1007 union oid_res_t r;
1008 int rvalue = 0;
1009 vwrq->disabled = 0; /* It cannot be disabled */
1010
1011 if ((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1012 /* we are asked for the life time */
1013 rvalue =
1014 mgt_get_request(priv, DOT11_OID_MAXTXLIFETIME, 0, NULL, &r);
1015 vwrq->value = r.u * 1024;
1016 vwrq->flags = IW_RETRY_LIFETIME;
1017 } else if ((vwrq->flags & IW_RETRY_MAX)) {
1018 /* we are asked for the long retry limit */
1019 rvalue |=
1020 mgt_get_request(priv, DOT11_OID_LONGRETRIES, 0, NULL, &r);
1021 vwrq->value = r.u;
1022 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
1023 } else {
1024 /* default. get the short retry limit */
1025 rvalue |=
1026 mgt_get_request(priv, DOT11_OID_SHORTRETRIES, 0, NULL, &r);
1027 vwrq->value = r.u;
1028 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
1029 }
1030
1031 return rvalue;
1032}
1033
1034static int
1035prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
1036 struct iw_point *dwrq, char *extra)
1037{
1038 islpci_private *priv = netdev_priv(ndev);
1039 int rvalue = 0, force = 0;
1040 int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
1041 union oid_res_t r;
1042
1043 /* with the new API, it's impossible to get a NULL pointer.
1044 * New version of iwconfig set the IW_ENCODE_NOKEY flag
1045 * when no key is given, but older versions don't. */
1046
1047 if (dwrq->length > 0) {
1048 /* we have a key to set */
1049 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1050 int current_index;
1051 struct obj_key key = { DOT11_PRIV_WEP, 0, "" };
1052
1053 /* get the current key index */
1054 rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
1055 current_index = r.u;
1056 /* Verify that the key is not marked as invalid */
1057 if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
1058 key.length = dwrq->length > sizeof (key.key) ?
1059 sizeof (key.key) : dwrq->length;
1060 memcpy(key.key, extra, key.length);
1061 if (key.length == 32)
1062 /* we want WPA-PSK */
1063 key.type = DOT11_PRIV_TKIP;
1064 if ((index < 0) || (index > 3))
1065 /* no index provided use the current one */
1066 index = current_index;
1067
1068 /* now send the key to the card */
1069 rvalue |=
1070 mgt_set_request(priv, DOT11_OID_DEFKEYX, index,
1071 &key);
1072 }
1073 /*
1074 * If a valid key is set, encryption should be enabled
1075 * (user may turn it off later).
1076 * This is also how "iwconfig ethX key on" works
1077 */
1078 if ((index == current_index) && (key.length > 0))
1079 force = 1;
1080 } else {
1081 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1082 if ((index >= 0) && (index <= 3)) {
1083 /* we want to set the key index */
1084 rvalue |=
1085 mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
1086 &index);
1087 } else {
1088 if (!dwrq->flags & IW_ENCODE_MODE) {
1089 /* we cannot do anything. Complain. */
1090 return -EINVAL;
1091 }
1092 }
1093 }
1094 /* now read the flags */
1095 if (dwrq->flags & IW_ENCODE_DISABLED) {
1096 /* Encoding disabled,
1097 * authen = DOT11_AUTH_OS;
1098 * invoke = 0;
1099 * exunencrypt = 0; */
1100 }
1101 if (dwrq->flags & IW_ENCODE_OPEN)
1102 /* Encode but accept non-encoded packets. No auth */
1103 invoke = 1;
1104 if ((dwrq->flags & IW_ENCODE_RESTRICTED) || force) {
1105 /* Refuse non-encoded packets. Auth */
1106 authen = DOT11_AUTH_BOTH;
1107 invoke = 1;
1108 exunencrypt = 1;
1109 }
1110 /* do the change if requested */
1111 if ((dwrq->flags & IW_ENCODE_MODE) || force) {
1112 rvalue |=
1113 mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
1114 rvalue |=
1115 mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
1116 rvalue |=
1117 mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
1118 &exunencrypt);
1119 }
1120 return rvalue;
1121}
1122
1123static int
1124prism54_get_encode(struct net_device *ndev, struct iw_request_info *info,
1125 struct iw_point *dwrq, char *extra)
1126{
1127 islpci_private *priv = netdev_priv(ndev);
1128 struct obj_key *key;
1129 u32 devindex, index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1130 u32 authen = 0, invoke = 0, exunencrypt = 0;
1131 int rvalue;
1132 union oid_res_t r;
1133
1134 /* first get the flags */
1135 rvalue = mgt_get_request(priv, DOT11_OID_AUTHENABLE, 0, NULL, &r);
1136 authen = r.u;
1137 rvalue |= mgt_get_request(priv, DOT11_OID_PRIVACYINVOKED, 0, NULL, &r);
1138 invoke = r.u;
1139 rvalue |= mgt_get_request(priv, DOT11_OID_EXUNENCRYPTED, 0, NULL, &r);
1140 exunencrypt = r.u;
1141
1142 if (invoke && (authen == DOT11_AUTH_BOTH) && exunencrypt)
1143 dwrq->flags = IW_ENCODE_RESTRICTED;
1144 else if ((authen == DOT11_AUTH_OS) && !exunencrypt) {
1145 if (invoke)
1146 dwrq->flags = IW_ENCODE_OPEN;
1147 else
1148 dwrq->flags = IW_ENCODE_DISABLED;
1149 } else
1150 /* The card should not work in this state */
1151 dwrq->flags = 0;
1152
1153 /* get the current device key index */
1154 rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
1155 devindex = r.u;
1156 /* Now get the key, return it */
1157 if ((index < 0) || (index > 3))
1158 /* no index provided, use the current one */
1159 index = devindex;
1160 rvalue |= mgt_get_request(priv, DOT11_OID_DEFKEYX, index, NULL, &r);
1161 key = r.ptr;
1162 dwrq->length = key->length;
1163 memcpy(extra, key->key, dwrq->length);
1164 kfree(key);
1165 /* return the used key index */
1166 dwrq->flags |= devindex + 1;
1167
1168 return rvalue;
1169}
1170
1171static int
1172prism54_get_txpower(struct net_device *ndev, struct iw_request_info *info,
1173 struct iw_param *vwrq, char *extra)
1174{
1175 islpci_private *priv = netdev_priv(ndev);
1176 union oid_res_t r;
1177 int rvalue;
1178
1179 rvalue = mgt_get_request(priv, OID_INL_OUTPUTPOWER, 0, NULL, &r);
1180 /* intersil firmware operates in 0.25 dBm (1/4 dBm) */
1181 vwrq->value = (s32) r.u / 4;
1182 vwrq->fixed = 1;
1183 /* radio is not turned of
1184 * btw: how is possible to turn off only the radio
1185 */
1186 vwrq->disabled = 0;
1187
1188 return rvalue;
1189}
1190
1191static int
1192prism54_set_txpower(struct net_device *ndev, struct iw_request_info *info,
1193 struct iw_param *vwrq, char *extra)
1194{
1195 islpci_private *priv = netdev_priv(ndev);
1196 s32 u = vwrq->value;
1197
1198 /* intersil firmware operates in 0.25 dBm (1/4) */
1199 u *= 4;
1200 if (vwrq->disabled) {
1201 /* don't know how to disable radio */
1202 printk(KERN_DEBUG
1203 "%s: %s() disabling radio is not yet supported.\n",
1204 priv->ndev->name, __FUNCTION__);
1205 return -ENOTSUPP;
1206 } else if (vwrq->fixed)
1207 /* currently only fixed value is supported */
1208 return mgt_set_request(priv, OID_INL_OUTPUTPOWER, 0, &u);
1209 else {
1210 printk(KERN_DEBUG
1211 "%s: %s() auto power will be implemented later.\n",
1212 priv->ndev->name, __FUNCTION__);
1213 return -ENOTSUPP;
1214 }
1215}
1216
1217static int
1218prism54_reset(struct net_device *ndev, struct iw_request_info *info,
1219 __u32 * uwrq, char *extra)
1220{
1221 islpci_reset(netdev_priv(ndev), 0);
1222
1223 return 0;
1224}
1225
1226static int
1227prism54_get_oid(struct net_device *ndev, struct iw_request_info *info,
1228 struct iw_point *dwrq, char *extra)
1229{
1230 union oid_res_t r;
1231 int rvalue;
1232 enum oid_num_t n = dwrq->flags;
1233
1234 rvalue = mgt_get_request((islpci_private *) ndev->priv, n, 0, NULL, &r);
1235 dwrq->length = mgt_response_to_str(n, &r, extra);
1236 if ((isl_oid[n].flags & OID_FLAG_TYPE) != OID_TYPE_U32)
1237 kfree(r.ptr);
1238 return rvalue;
1239}
1240
1241static int
1242prism54_set_u32(struct net_device *ndev, struct iw_request_info *info,
1243 __u32 * uwrq, char *extra)
1244{
1245 u32 oid = uwrq[0], u = uwrq[1];
1246
1247 return mgt_set_request((islpci_private *) ndev->priv, oid, 0, &u);
1248}
1249
1250static int
1251prism54_set_raw(struct net_device *ndev, struct iw_request_info *info,
1252 struct iw_point *dwrq, char *extra)
1253{
1254 u32 oid = dwrq->flags;
1255
1256 return mgt_set_request((islpci_private *) ndev->priv, oid, 0, extra);
1257}
1258
1259void
1260prism54_acl_init(struct islpci_acl *acl)
1261{
1262 sema_init(&acl->sem, 1);
1263 INIT_LIST_HEAD(&acl->mac_list);
1264 acl->size = 0;
1265 acl->policy = MAC_POLICY_OPEN;
1266}
1267
1268static void
1269prism54_clear_mac(struct islpci_acl *acl)
1270{
1271 struct list_head *ptr, *next;
1272 struct mac_entry *entry;
1273
1274 if (down_interruptible(&acl->sem))
1275 return;
1276
1277 if (acl->size == 0) {
1278 up(&acl->sem);
1279 return;
1280 }
1281
1282 for (ptr = acl->mac_list.next, next = ptr->next;
1283 ptr != &acl->mac_list; ptr = next, next = ptr->next) {
1284 entry = list_entry(ptr, struct mac_entry, _list);
1285 list_del(ptr);
1286 kfree(entry);
1287 }
1288 acl->size = 0;
1289 up(&acl->sem);
1290}
1291
1292void
1293prism54_acl_clean(struct islpci_acl *acl)
1294{
1295 prism54_clear_mac(acl);
1296}
1297
1298static int
1299prism54_add_mac(struct net_device *ndev, struct iw_request_info *info,
1300 struct sockaddr *awrq, char *extra)
1301{
1302 islpci_private *priv = netdev_priv(ndev);
1303 struct islpci_acl *acl = &priv->acl;
1304 struct mac_entry *entry;
1305 struct sockaddr *addr = (struct sockaddr *) extra;
1306
1307 if (addr->sa_family != ARPHRD_ETHER)
1308 return -EOPNOTSUPP;
1309
1310 entry = kmalloc(sizeof (struct mac_entry), GFP_KERNEL);
1311 if (entry == NULL)
1312 return -ENOMEM;
1313
1314 memcpy(entry->addr, addr->sa_data, ETH_ALEN);
1315
1316 if (down_interruptible(&acl->sem)) {
1317 kfree(entry);
1318 return -ERESTARTSYS;
1319 }
1320 list_add_tail(&entry->_list, &acl->mac_list);
1321 acl->size++;
1322 up(&acl->sem);
1323
1324 return 0;
1325}
1326
1327static int
1328prism54_del_mac(struct net_device *ndev, struct iw_request_info *info,
1329 struct sockaddr *awrq, char *extra)
1330{
1331 islpci_private *priv = netdev_priv(ndev);
1332 struct islpci_acl *acl = &priv->acl;
1333 struct mac_entry *entry;
1334 struct list_head *ptr;
1335 struct sockaddr *addr = (struct sockaddr *) extra;
1336
1337 if (addr->sa_family != ARPHRD_ETHER)
1338 return -EOPNOTSUPP;
1339
1340 if (down_interruptible(&acl->sem))
1341 return -ERESTARTSYS;
1342 for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {
1343 entry = list_entry(ptr, struct mac_entry, _list);
1344
1345 if (memcmp(entry->addr, addr->sa_data, ETH_ALEN) == 0) {
1346 list_del(ptr);
1347 acl->size--;
1348 kfree(entry);
1349 up(&acl->sem);
1350 return 0;
1351 }
1352 }
1353 up(&acl->sem);
1354 return -EINVAL;
1355}
1356
1357static int
1358prism54_get_mac(struct net_device *ndev, struct iw_request_info *info,
1359 struct iw_point *dwrq, char *extra)
1360{
1361 islpci_private *priv = netdev_priv(ndev);
1362 struct islpci_acl *acl = &priv->acl;
1363 struct mac_entry *entry;
1364 struct list_head *ptr;
1365 struct sockaddr *dst = (struct sockaddr *) extra;
1366
1367 dwrq->length = 0;
1368
1369 if (down_interruptible(&acl->sem))
1370 return -ERESTARTSYS;
1371
1372 for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {
1373 entry = list_entry(ptr, struct mac_entry, _list);
1374
1375 memcpy(dst->sa_data, entry->addr, ETH_ALEN);
1376 dst->sa_family = ARPHRD_ETHER;
1377 dwrq->length++;
1378 dst++;
1379 }
1380 up(&acl->sem);
1381 return 0;
1382}
1383
1384/* Setting policy also clears the MAC acl, even if we don't change the defaut
1385 * policy
1386 */
1387
1388static int
1389prism54_set_policy(struct net_device *ndev, struct iw_request_info *info,
1390 __u32 * uwrq, char *extra)
1391{
1392 islpci_private *priv = netdev_priv(ndev);
1393 struct islpci_acl *acl = &priv->acl;
1394 u32 mlmeautolevel;
1395
1396 prism54_clear_mac(acl);
1397
1398 if ((*uwrq < MAC_POLICY_OPEN) || (*uwrq > MAC_POLICY_REJECT))
1399 return -EINVAL;
1400
1401 down_write(&priv->mib_sem);
1402
1403 acl->policy = *uwrq;
1404
1405 /* the ACL code needs an intermediate mlmeautolevel */
1406 if ((priv->iw_mode == IW_MODE_MASTER) &&
1407 (acl->policy != MAC_POLICY_OPEN))
1408 mlmeautolevel = DOT11_MLME_INTERMEDIATE;
1409 else
1410 mlmeautolevel = CARD_DEFAULT_MLME_MODE;
1411 if (priv->wpa)
1412 mlmeautolevel = DOT11_MLME_EXTENDED;
1413 mgt_set(priv, DOT11_OID_MLMEAUTOLEVEL, &mlmeautolevel);
1414 /* restart the card with our new policy */
1415 if (mgt_commit(priv)) {
1416 up_write(&priv->mib_sem);
1417 return -EIO;
1418 }
1419 up_write(&priv->mib_sem);
1420
1421 return 0;
1422}
1423
1424static int
1425prism54_get_policy(struct net_device *ndev, struct iw_request_info *info,
1426 __u32 * uwrq, char *extra)
1427{
1428 islpci_private *priv = netdev_priv(ndev);
1429 struct islpci_acl *acl = &priv->acl;
1430
1431 *uwrq = acl->policy;
1432
1433 return 0;
1434}
1435
1436/* Return 1 only if client should be accepted. */
1437
1438static int
1439prism54_mac_accept(struct islpci_acl *acl, char *mac)
1440{
1441 struct list_head *ptr;
1442 struct mac_entry *entry;
1443 int res = 0;
1444
1445 if (down_interruptible(&acl->sem))
1446 return -ERESTARTSYS;
1447
1448 if (acl->policy == MAC_POLICY_OPEN) {
1449 up(&acl->sem);
1450 return 1;
1451 }
1452
1453 for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {
1454 entry = list_entry(ptr, struct mac_entry, _list);
1455 if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
1456 res = 1;
1457 break;
1458 }
1459 }
1460 res = (acl->policy == MAC_POLICY_ACCEPT) ? !res : res;
1461 up(&acl->sem);
1462
1463 return res;
1464}
1465
1466static int
1467prism54_kick_all(struct net_device *ndev, struct iw_request_info *info,
1468 struct iw_point *dwrq, char *extra)
1469{
1470 struct obj_mlme *mlme;
1471 int rvalue;
1472
1473 mlme = kmalloc(sizeof (struct obj_mlme), GFP_KERNEL);
1474 if (mlme == NULL)
1475 return -ENOMEM;
1476
1477 /* Tell the card to kick every client */
1478 mlme->id = 0;
1479 rvalue =
1480 mgt_set_request(netdev_priv(ndev), DOT11_OID_DISASSOCIATE, 0, mlme);
1481 kfree(mlme);
1482
1483 return rvalue;
1484}
1485
1486static int
1487prism54_kick_mac(struct net_device *ndev, struct iw_request_info *info,
1488 struct sockaddr *awrq, char *extra)
1489{
1490 struct obj_mlme *mlme;
1491 struct sockaddr *addr = (struct sockaddr *) extra;
1492 int rvalue;
1493
1494 if (addr->sa_family != ARPHRD_ETHER)
1495 return -EOPNOTSUPP;
1496
1497 mlme = kmalloc(sizeof (struct obj_mlme), GFP_KERNEL);
1498 if (mlme == NULL)
1499 return -ENOMEM;
1500
1501 /* Tell the card to only kick the corresponding bastard */
1502 memcpy(mlme->address, addr->sa_data, ETH_ALEN);
1503 mlme->id = -1;
1504 rvalue =
1505 mgt_set_request(netdev_priv(ndev), DOT11_OID_DISASSOCIATE, 0, mlme);
1506
1507 kfree(mlme);
1508
1509 return rvalue;
1510}
1511
1512/* Translate a TRAP oid into a wireless event. Called in islpci_mgt_receive. */
1513
1514static void
1515format_event(islpci_private *priv, char *dest, const char *str,
1516 const struct obj_mlme *mlme, u16 *length, int error)
1517{
1518 const u8 *a = mlme->address;
1519 int n = snprintf(dest, IW_CUSTOM_MAX,
1520 "%s %s %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X %s (%2.2X)",
1521 str,
1522 ((priv->iw_mode == IW_MODE_MASTER) ? "from" : "to"),
1523 a[0], a[1], a[2], a[3], a[4], a[5],
1524 (error ? (mlme->code ? " : REJECTED " : " : ACCEPTED ")
1525 : ""), mlme->code);
1526 BUG_ON(n > IW_CUSTOM_MAX);
1527 *length = n;
1528}
1529
1530static void
1531send_formatted_event(islpci_private *priv, const char *str,
1532 const struct obj_mlme *mlme, int error)
1533{
1534 union iwreq_data wrqu;
1535 char *memptr;
1536
1537 memptr = kmalloc(IW_CUSTOM_MAX, GFP_KERNEL);
1538 if (!memptr)
1539 return;
1540 wrqu.data.pointer = memptr;
1541 wrqu.data.length = 0;
1542 format_event(priv, memptr, str, mlme, &wrqu.data.length,
1543 error);
1544 wireless_send_event(priv->ndev, IWEVCUSTOM, &wrqu, memptr);
1545 kfree(memptr);
1546}
1547
1548static void
1549send_simple_event(islpci_private *priv, const char *str)
1550{
1551 union iwreq_data wrqu;
1552 char *memptr;
1553 int n = strlen(str);
1554
1555 memptr = kmalloc(IW_CUSTOM_MAX, GFP_KERNEL);
1556 if (!memptr)
1557 return;
1558 BUG_ON(n > IW_CUSTOM_MAX);
1559 wrqu.data.pointer = memptr;
1560 wrqu.data.length = n;
1561 strcpy(memptr, str);
1562 wireless_send_event(priv->ndev, IWEVCUSTOM, &wrqu, memptr);
1563 kfree(memptr);
1564}
1565
1566static void
1567link_changed(struct net_device *ndev, u32 bitrate)
1568{
1569 islpci_private *priv = netdev_priv(ndev);
1570
1571 if (bitrate) {
1572 if (priv->iw_mode == IW_MODE_INFRA) {
1573 union iwreq_data uwrq;
1574 prism54_get_wap(ndev, NULL, (struct sockaddr *) &uwrq,
1575 NULL);
1576 wireless_send_event(ndev, SIOCGIWAP, &uwrq, NULL);
1577 } else
1578 send_simple_event(netdev_priv(ndev),
1579 "Link established");
1580 } else
1581 send_simple_event(netdev_priv(ndev), "Link lost");
1582}
1583
1584/* Beacon/ProbeResp payload header */
1585struct ieee80211_beacon_phdr {
1586 u8 timestamp[8];
1587 u16 beacon_int;
1588 u16 capab_info;
1589} __attribute__ ((packed));
1590
1591#define WLAN_EID_GENERIC 0xdd
1592static u8 wpa_oid[4] = { 0x00, 0x50, 0xf2, 1 };
1593
1594#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
1595#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
1596
1597static void
1598prism54_wpa_ie_add(islpci_private *priv, u8 *bssid,
1599 u8 *wpa_ie, size_t wpa_ie_len)
1600{
1601 struct list_head *ptr;
1602 struct islpci_bss_wpa_ie *bss = NULL;
1603
1604 if (wpa_ie_len > MAX_WPA_IE_LEN)
1605 wpa_ie_len = MAX_WPA_IE_LEN;
1606
1607 if (down_interruptible(&priv->wpa_sem))
1608 return;
1609
1610 /* try to use existing entry */
1611 list_for_each(ptr, &priv->bss_wpa_list) {
1612 bss = list_entry(ptr, struct islpci_bss_wpa_ie, list);
1613 if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) {
1614 list_move(&bss->list, &priv->bss_wpa_list);
1615 break;
1616 }
1617 bss = NULL;
1618 }
1619
1620 if (bss == NULL) {
1621 /* add a new BSS entry; if max number of entries is already
1622 * reached, replace the least recently updated */
1623 if (priv->num_bss_wpa >= MAX_BSS_WPA_IE_COUNT) {
1624 bss = list_entry(priv->bss_wpa_list.prev,
1625 struct islpci_bss_wpa_ie, list);
1626 list_del(&bss->list);
1627 } else {
1628 bss = kmalloc(sizeof (*bss), GFP_ATOMIC);
1629 if (bss != NULL) {
1630 priv->num_bss_wpa++;
1631 memset(bss, 0, sizeof (*bss));
1632 }
1633 }
1634 if (bss != NULL) {
1635 memcpy(bss->bssid, bssid, ETH_ALEN);
1636 list_add(&bss->list, &priv->bss_wpa_list);
1637 }
1638 }
1639
1640 if (bss != NULL) {
1641 memcpy(bss->wpa_ie, wpa_ie, wpa_ie_len);
1642 bss->wpa_ie_len = wpa_ie_len;
1643 bss->last_update = jiffies;
1644 } else {
1645 printk(KERN_DEBUG "Failed to add BSS WPA entry for " MACSTR
1646 "\n", MAC2STR(bssid));
1647 }
1648
1649 /* expire old entries from WPA list */
1650 while (priv->num_bss_wpa > 0) {
1651 bss = list_entry(priv->bss_wpa_list.prev,
1652 struct islpci_bss_wpa_ie, list);
1653 if (!time_after(jiffies, bss->last_update + 60 * HZ))
1654 break;
1655
1656 list_del(&bss->list);
1657 priv->num_bss_wpa--;
1658 kfree(bss);
1659 }
1660
1661 up(&priv->wpa_sem);
1662}
1663
1664static size_t
1665prism54_wpa_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie)
1666{
1667 struct list_head *ptr;
1668 struct islpci_bss_wpa_ie *bss = NULL;
1669 size_t len = 0;
1670
1671 if (down_interruptible(&priv->wpa_sem))
1672 return 0;
1673
1674 list_for_each(ptr, &priv->bss_wpa_list) {
1675 bss = list_entry(ptr, struct islpci_bss_wpa_ie, list);
1676 if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0)
1677 break;
1678 bss = NULL;
1679 }
1680 if (bss) {
1681 len = bss->wpa_ie_len;
1682 memcpy(wpa_ie, bss->wpa_ie, len);
1683 }
1684 up(&priv->wpa_sem);
1685
1686 return len;
1687}
1688
1689void
1690prism54_wpa_ie_init(islpci_private *priv)
1691{
1692 INIT_LIST_HEAD(&priv->bss_wpa_list);
1693 sema_init(&priv->wpa_sem, 1);
1694}
1695
1696void
1697prism54_wpa_ie_clean(islpci_private *priv)
1698{
1699 struct list_head *ptr, *n;
1700
1701 list_for_each_safe(ptr, n, &priv->bss_wpa_list) {
1702 struct islpci_bss_wpa_ie *bss;
1703 bss = list_entry(ptr, struct islpci_bss_wpa_ie, list);
1704 kfree(bss);
1705 }
1706}
1707
1708static void
1709prism54_process_bss_data(islpci_private *priv, u32 oid, u8 *addr,
1710 u8 *payload, size_t len)
1711{
1712 struct ieee80211_beacon_phdr *hdr;
1713 u8 *pos, *end;
1714
1715 if (!priv->wpa)
1716 return;
1717
1718 hdr = (struct ieee80211_beacon_phdr *) payload;
1719 pos = (u8 *) (hdr + 1);
1720 end = payload + len;
1721 while (pos < end) {
1722 if (pos + 2 + pos[1] > end) {
1723 printk(KERN_DEBUG "Parsing Beacon/ProbeResp failed "
1724 "for " MACSTR "\n", MAC2STR(addr));
1725 return;
1726 }
1727 if (pos[0] == WLAN_EID_GENERIC && pos[1] >= 4 &&
1728 memcmp(pos + 2, wpa_oid, 4) == 0) {
1729 prism54_wpa_ie_add(priv, addr, pos, pos[1] + 2);
1730 return;
1731 }
1732 pos += 2 + pos[1];
1733 }
1734}
1735
1736static void
1737handle_request(islpci_private *priv, struct obj_mlme *mlme, enum oid_num_t oid)
1738{
1739 if (((mlme->state == DOT11_STATE_AUTHING) ||
1740 (mlme->state == DOT11_STATE_ASSOCING))
1741 && mgt_mlme_answer(priv)) {
1742 /* Someone is requesting auth and we must respond. Just send back
1743 * the trap with error code set accordingly.
1744 */
1745 mlme->code = prism54_mac_accept(&priv->acl,
1746 mlme->address) ? 0 : 1;
1747 mgt_set_request(priv, oid, 0, mlme);
1748 }
1749}
1750
1751static int
1752prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid,
1753 char *data)
1754{
1755 struct obj_mlme *mlme = (struct obj_mlme *) data;
1756 struct obj_mlmeex *mlmeex = (struct obj_mlmeex *) data;
1757 struct obj_mlmeex *confirm;
1758 u8 wpa_ie[MAX_WPA_IE_LEN];
1759 int wpa_ie_len;
1760 size_t len = 0; /* u16, better? */
1761 u8 *payload = NULL, *pos = NULL;
1762 int ret;
1763
1764 /* I think all trapable objects are listed here.
1765 * Some oids have a EX version. The difference is that they are emitted
1766 * in DOT11_MLME_EXTENDED mode (set with DOT11_OID_MLMEAUTOLEVEL)
1767 * with more info.
1768 * The few events already defined by the wireless tools are not really
1769 * suited. We use the more flexible custom event facility.
1770 */
1771
1772 if (oid >= DOT11_OID_BEACON) {
1773 len = mlmeex->size;
1774 payload = pos = mlmeex->data;
1775 }
1776
1777 /* I fear prism54_process_bss_data won't work with big endian data */
1778 if ((oid == DOT11_OID_BEACON) || (oid == DOT11_OID_PROBE))
1779 prism54_process_bss_data(priv, oid, mlmeex->address,
1780 payload, len);
1781
1782 mgt_le_to_cpu(isl_oid[oid].flags & OID_FLAG_TYPE, (void *) mlme);
1783
1784 switch (oid) {
1785
1786 case GEN_OID_LINKSTATE:
1787 link_changed(priv->ndev, (u32) *data);
1788 break;
1789
1790 case DOT11_OID_MICFAILURE:
1791 send_simple_event(priv, "Mic failure");
1792 break;
1793
1794 case DOT11_OID_DEAUTHENTICATE:
1795 send_formatted_event(priv, "DeAuthenticate request", mlme, 0);
1796 break;
1797
1798 case DOT11_OID_AUTHENTICATE:
1799 handle_request(priv, mlme, oid);
1800 send_formatted_event(priv, "Authenticate request", mlme, 1);
1801 break;
1802
1803 case DOT11_OID_DISASSOCIATE:
1804 send_formatted_event(priv, "Disassociate request", mlme, 0);
1805 break;
1806
1807 case DOT11_OID_ASSOCIATE:
1808 handle_request(priv, mlme, oid);
1809 send_formatted_event(priv, "Associate request", mlme, 1);
1810 break;
1811
1812 case DOT11_OID_REASSOCIATE:
1813 handle_request(priv, mlme, oid);
1814 send_formatted_event(priv, "ReAssociate request", mlme, 1);
1815 break;
1816
1817 case DOT11_OID_BEACON:
1818 send_formatted_event(priv,
1819 "Received a beacon from an unkown AP",
1820 mlme, 0);
1821 break;
1822
1823 case DOT11_OID_PROBE:
1824 /* we received a probe from a client. */
1825 send_formatted_event(priv, "Received a probe from client", mlme,
1826 0);
1827 break;
1828
1829 /* Note : "mlme" is actually a "struct obj_mlmeex *" here, but this
1830 * is backward compatible layout-wise with "struct obj_mlme".
1831 */
1832
1833 case DOT11_OID_DEAUTHENTICATEEX:
1834 send_formatted_event(priv, "DeAuthenticate request", mlme, 0);
1835 break;
1836
1837 case DOT11_OID_AUTHENTICATEEX:
1838 handle_request(priv, mlme, oid);
1839 send_formatted_event(priv, "Authenticate request (ex)", mlme, 1);
1840
1841 if (priv->iw_mode != IW_MODE_MASTER
1842 && mlmeex->state != DOT11_STATE_AUTHING)
1843 break;
1844
1845 confirm = kmalloc(sizeof(struct obj_mlmeex) + 6, GFP_ATOMIC);
1846
1847 if (!confirm)
1848 break;
1849
1850 memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
1851 printk(KERN_DEBUG "Authenticate from: address:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
1852 mlmeex->address[0],
1853 mlmeex->address[1],
1854 mlmeex->address[2],
1855 mlmeex->address[3],
1856 mlmeex->address[4],
1857 mlmeex->address[5]
1858 );
1859 confirm->id = -1; /* or mlmeex->id ? */
1860 confirm->state = 0; /* not used */
1861 confirm->code = 0;
1862 confirm->size = 6;
1863 confirm->data[0] = 0x00;
1864 confirm->data[1] = 0x00;
1865 confirm->data[2] = 0x02;
1866 confirm->data[3] = 0x00;
1867 confirm->data[4] = 0x00;
1868 confirm->data[5] = 0x00;
1869
1870 ret = mgt_set_varlen(priv, DOT11_OID_ASSOCIATEEX, confirm, 6);
1871
1872 kfree(confirm);
1873 if (ret)
1874 return ret;
1875 break;
1876
1877 case DOT11_OID_DISASSOCIATEEX:
1878 send_formatted_event(priv, "Disassociate request (ex)", mlme, 0);
1879 break;
1880
1881 case DOT11_OID_ASSOCIATEEX:
1882 handle_request(priv, mlme, oid);
1883 send_formatted_event(priv, "Associate request (ex)", mlme, 1);
1884
1885 if (priv->iw_mode != IW_MODE_MASTER
1886 && mlmeex->state != DOT11_STATE_AUTHING)
1887 break;
1888
1889 confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
1890
1891 if (!confirm)
1892 break;
1893
1894 memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
1895
1896 confirm->id = ((struct obj_mlmeex *)mlme)->id;
1897 confirm->state = 0; /* not used */
1898 confirm->code = 0;
1899
1900 wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie);
1901
1902 if (!wpa_ie_len) {
1903 printk(KERN_DEBUG "No WPA IE found from "
1904 "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
1905 mlmeex->address[0],
1906 mlmeex->address[1],
1907 mlmeex->address[2],
1908 mlmeex->address[3],
1909 mlmeex->address[4],
1910 mlmeex->address[5]
1911 );
1912 kfree(confirm);
1913 break;
1914 }
1915
1916 confirm->size = wpa_ie_len;
1917 memcpy(&confirm->data, wpa_ie, wpa_ie_len);
1918
1919 mgt_set_varlen(priv, oid, confirm, wpa_ie_len);
1920
1921 kfree(confirm);
1922
1923 break;
1924
1925 case DOT11_OID_REASSOCIATEEX:
1926 handle_request(priv, mlme, oid);
1927 send_formatted_event(priv, "Reassociate request (ex)", mlme, 1);
1928
1929 if (priv->iw_mode != IW_MODE_MASTER
1930 && mlmeex->state != DOT11_STATE_ASSOCING)
1931 break;
1932
1933 confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
1934
1935 if (!confirm)
1936 break;
1937
1938 memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
1939
1940 confirm->id = mlmeex->id;
1941 confirm->state = 0; /* not used */
1942 confirm->code = 0;
1943
1944 wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie);
1945
1946 if (!wpa_ie_len) {
1947 printk(KERN_DEBUG "No WPA IE found from "
1948 "address:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
1949 mlmeex->address[0],
1950 mlmeex->address[1],
1951 mlmeex->address[2],
1952 mlmeex->address[3],
1953 mlmeex->address[4],
1954 mlmeex->address[5]
1955 );
1956 kfree(confirm);
1957 break;
1958 }
1959
1960 confirm->size = wpa_ie_len;
1961 memcpy(&confirm->data, wpa_ie, wpa_ie_len);
1962
1963 mgt_set_varlen(priv, oid, confirm, wpa_ie_len);
1964
1965 kfree(confirm);
1966
1967 break;
1968
1969 default:
1970 return -EINVAL;
1971 }
1972
1973 return 0;
1974}
1975
1976/*
1977 * Process a device trap. This is called via schedule_work(), outside of
1978 * interrupt context, no locks held.
1979 */
1980void
1981prism54_process_trap(void *data)
1982{
1983 struct islpci_mgmtframe *frame = data;
1984 struct net_device *ndev = frame->ndev;
1985 enum oid_num_t n = mgt_oidtonum(frame->header->oid);
1986
1987 if (n != OID_NUM_LAST)
1988 prism54_process_trap_helper(netdev_priv(ndev), n, frame->data);
1989 islpci_mgt_release(frame);
1990}
1991
1992int
1993prism54_set_mac_address(struct net_device *ndev, void *addr)
1994{
1995 islpci_private *priv = netdev_priv(ndev);
1996 int ret;
1997
1998 if (ndev->addr_len != 6)
1999 return -EINVAL;
2000 ret = mgt_set_request(priv, GEN_OID_MACADDRESS, 0,
2001 &((struct sockaddr *) addr)->sa_data);
2002 if (!ret)
2003 memcpy(priv->ndev->dev_addr,
2004 &((struct sockaddr *) addr)->sa_data, 6);
2005
2006 return ret;
2007}
2008
2009/* Note: currently, use hostapd ioctl from the Host AP driver for WPA
2010 * support. This is to be replaced with Linux wireless extensions once they
2011 * get WPA support. */
2012
2013/* Note II: please leave all this together as it will be easier to remove later,
2014 * once wireless extensions add WPA support -mcgrof */
2015
2016/* PRISM54_HOSTAPD ioctl() cmd: */
2017enum {
2018 PRISM2_SET_ENCRYPTION = 6,
2019 PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12,
2020 PRISM2_HOSTAPD_MLME = 13,
2021 PRISM2_HOSTAPD_SCAN_REQ = 14,
2022};
2023
2024#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
2025#define PRISM54_HOSTAPD SIOCIWFIRSTPRIV+25
2026#define PRISM54_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+26
2027
2028#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
2029#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
2030((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
2031
2032/* Maximum length for algorithm names (-1 for nul termination)
2033 * used in ioctl() */
2034#define HOSTAP_CRYPT_ALG_NAME_LEN 16
2035
2036struct prism2_hostapd_param {
2037 u32 cmd;
2038 u8 sta_addr[ETH_ALEN];
2039 union {
2040 struct {
2041 u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN];
2042 u32 flags;
2043 u32 err;
2044 u8 idx;
2045 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
2046 u16 key_len;
2047 u8 key[0];
2048 } crypt;
2049 struct {
2050 u8 len;
2051 u8 data[0];
2052 } generic_elem;
2053 struct {
2054#define MLME_STA_DEAUTH 0
2055#define MLME_STA_DISASSOC 1
2056 u16 cmd;
2057 u16 reason_code;
2058 } mlme;
2059 struct {
2060 u8 ssid_len;
2061 u8 ssid[32];
2062 } scan_req;
2063 } u;
2064};
2065
2066
2067static int
2068prism2_ioctl_set_encryption(struct net_device *dev,
2069 struct prism2_hostapd_param *param,
2070 int param_len)
2071{
2072 islpci_private *priv = netdev_priv(dev);
2073 int rvalue = 0, force = 0;
2074 int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
2075 union oid_res_t r;
2076
2077 /* with the new API, it's impossible to get a NULL pointer.
2078 * New version of iwconfig set the IW_ENCODE_NOKEY flag
2079 * when no key is given, but older versions don't. */
2080
2081 if (param->u.crypt.key_len > 0) {
2082 /* we have a key to set */
2083 int index = param->u.crypt.idx;
2084 int current_index;
2085 struct obj_key key = { DOT11_PRIV_TKIP, 0, "" };
2086
2087 /* get the current key index */
2088 rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
2089 current_index = r.u;
2090 /* Verify that the key is not marked as invalid */
2091 if (!(param->u.crypt.flags & IW_ENCODE_NOKEY)) {
2092 key.length = param->u.crypt.key_len > sizeof (param->u.crypt.key) ?
2093 sizeof (param->u.crypt.key) : param->u.crypt.key_len;
2094 memcpy(key.key, param->u.crypt.key, key.length);
2095 if (key.length == 32)
2096 /* we want WPA-PSK */
2097 key.type = DOT11_PRIV_TKIP;
2098 if ((index < 0) || (index > 3))
2099 /* no index provided use the current one */
2100 index = current_index;
2101
2102 /* now send the key to the card */
2103 rvalue |=
2104 mgt_set_request(priv, DOT11_OID_DEFKEYX, index,
2105 &key);
2106 }
2107 /*
2108 * If a valid key is set, encryption should be enabled
2109 * (user may turn it off later).
2110 * This is also how "iwconfig ethX key on" works
2111 */
2112 if ((index == current_index) && (key.length > 0))
2113 force = 1;
2114 } else {
2115 int index = (param->u.crypt.flags & IW_ENCODE_INDEX) - 1;
2116 if ((index >= 0) && (index <= 3)) {
2117 /* we want to set the key index */
2118 rvalue |=
2119 mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
2120 &index);
2121 } else {
2122 if (!param->u.crypt.flags & IW_ENCODE_MODE) {
2123 /* we cannot do anything. Complain. */
2124 return -EINVAL;
2125 }
2126 }
2127 }
2128 /* now read the flags */
2129 if (param->u.crypt.flags & IW_ENCODE_DISABLED) {
2130 /* Encoding disabled,
2131 * authen = DOT11_AUTH_OS;
2132 * invoke = 0;
2133 * exunencrypt = 0; */
2134 }
2135 if (param->u.crypt.flags & IW_ENCODE_OPEN)
2136 /* Encode but accept non-encoded packets. No auth */
2137 invoke = 1;
2138 if ((param->u.crypt.flags & IW_ENCODE_RESTRICTED) || force) {
2139 /* Refuse non-encoded packets. Auth */
2140 authen = DOT11_AUTH_BOTH;
2141 invoke = 1;
2142 exunencrypt = 1;
2143 }
2144 /* do the change if requested */
2145 if ((param->u.crypt.flags & IW_ENCODE_MODE) || force) {
2146 rvalue |=
2147 mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
2148 rvalue |=
2149 mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
2150 rvalue |=
2151 mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
2152 &exunencrypt);
2153 }
2154 return rvalue;
2155}
2156
2157static int
2158prism2_ioctl_set_generic_element(struct net_device *ndev,
2159 struct prism2_hostapd_param *param,
2160 int param_len)
2161{
2162 islpci_private *priv = netdev_priv(ndev);
2163 int max_len, len, alen, ret=0;
2164 struct obj_attachment *attach;
2165
2166 len = param->u.generic_elem.len;
2167 max_len = param_len - PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
2168 if (max_len < 0 || max_len < len)
2169 return -EINVAL;
2170
2171 alen = sizeof(*attach) + len;
2172 attach = kmalloc(alen, GFP_KERNEL);
2173 if (attach == NULL)
2174 return -ENOMEM;
2175
2176 memset(attach, 0, alen);
2177#define WLAN_FC_TYPE_MGMT 0
2178#define WLAN_FC_STYPE_ASSOC_REQ 0
2179#define WLAN_FC_STYPE_REASSOC_REQ 2
2180
2181 /* Note: endianness is covered by mgt_set_varlen */
2182
2183 attach->type = (WLAN_FC_TYPE_MGMT << 2) |
2184 (WLAN_FC_STYPE_ASSOC_REQ << 4);
2185 attach->id = -1;
2186 attach->size = len;
2187 memcpy(attach->data, param->u.generic_elem.data, len);
2188
2189 ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
2190
2191 if (ret == 0) {
2192 attach->type = (WLAN_FC_TYPE_MGMT << 2) |
2193 (WLAN_FC_STYPE_REASSOC_REQ << 4);
2194
2195 ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
2196
2197 if (ret == 0)
2198 printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
2199 ndev->name);
2200 }
2201
2202 kfree(attach);
2203 return ret;
2204
2205}
2206
2207static int
2208prism2_ioctl_mlme(struct net_device *dev, struct prism2_hostapd_param *param)
2209{
2210 return -EOPNOTSUPP;
2211}
2212
2213static int
2214prism2_ioctl_scan_req(struct net_device *ndev,
2215 struct prism2_hostapd_param *param)
2216{
2217 islpci_private *priv = netdev_priv(ndev);
2218 int i, rvalue;
2219 struct obj_bsslist *bsslist;
2220 u32 noise = 0;
2221 char *extra = "";
2222 char *current_ev = "foo";
2223 union oid_res_t r;
2224
2225 if (islpci_get_state(priv) < PRV_STATE_INIT) {
2226 /* device is not ready, fail gently */
2227 return 0;
2228 }
2229
2230 /* first get the noise value. We will use it to report the link quality */
2231 rvalue = mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
2232 noise = r.u;
2233
2234 /* Ask the device for a list of known bss. We can report at most
2235 * IW_MAX_AP=64 to the range struct. But the device won't repport anything
2236 * if you change the value of IWMAX_BSS=24.
2237 */
2238 rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
2239 bsslist = r.ptr;
2240
2241 /* ok now, scan the list and translate its info */
2242 for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++)
2243 current_ev = prism54_translate_bss(ndev, current_ev,
2244 extra + IW_SCAN_MAX_DATA,
2245 &(bsslist->bsslist[i]),
2246 noise);
2247 kfree(bsslist);
2248
2249 return rvalue;
2250}
2251
2252static int
2253prism54_hostapd(struct net_device *ndev, struct iw_point *p)
2254{
2255 struct prism2_hostapd_param *param;
2256 int ret = 0;
2257 u32 uwrq;
2258
2259 printk(KERN_DEBUG "prism54_hostapd - len=%d\n", p->length);
2260 if (p->length < sizeof(struct prism2_hostapd_param) ||
2261 p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
2262 return -EINVAL;
2263
2264 param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
2265 if (param == NULL)
2266 return -ENOMEM;
2267
2268 if (copy_from_user(param, p->pointer, p->length)) {
2269 kfree(param);
2270 return -EFAULT;
2271 }
2272
2273 switch (param->cmd) {
2274 case PRISM2_SET_ENCRYPTION:
2275 printk(KERN_DEBUG "%s: Caught WPA supplicant set encryption request\n",
2276 ndev->name);
2277 ret = prism2_ioctl_set_encryption(ndev, param, p->length);
2278 break;
2279 case PRISM2_HOSTAPD_SET_GENERIC_ELEMENT:
2280 printk(KERN_DEBUG "%s: Caught WPA supplicant set WPA IE request\n",
2281 ndev->name);
2282 ret = prism2_ioctl_set_generic_element(ndev, param,
2283 p->length);
2284 break;
2285 case PRISM2_HOSTAPD_MLME:
2286 printk(KERN_DEBUG "%s: Caught WPA supplicant MLME request\n",
2287 ndev->name);
2288 ret = prism2_ioctl_mlme(ndev, param);
2289 break;
2290 case PRISM2_HOSTAPD_SCAN_REQ:
2291 printk(KERN_DEBUG "%s: Caught WPA supplicant scan request\n",
2292 ndev->name);
2293 ret = prism2_ioctl_scan_req(ndev, param);
2294 break;
2295 case PRISM54_SET_WPA:
2296 printk(KERN_DEBUG "%s: Caught WPA supplicant wpa init request\n",
2297 ndev->name);
2298 uwrq = 1;
2299 ret = prism54_set_wpa(ndev, NULL, &uwrq, NULL);
2300 break;
2301 case PRISM54_DROP_UNENCRYPTED:
2302 printk(KERN_DEBUG "%s: Caught WPA drop unencrypted request\n",
2303 ndev->name);
2304#if 0
2305 uwrq = 0x01;
2306 mgt_set(priv, DOT11_OID_EXUNENCRYPTED, &uwrq);
2307 down_write(&priv->mib_sem);
2308 mgt_commit(priv);
2309 up_write(&priv->mib_sem);
2310#endif
2311 /* Not necessary, as set_wpa does it, should we just do it here though? */
2312 ret = 0;
2313 break;
2314 default:
2315 printk(KERN_DEBUG "%s: Caught a WPA supplicant request that is not supported\n",
2316 ndev->name);
2317 ret = -EOPNOTSUPP;
2318 break;
2319 }
2320
2321 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
2322 ret = -EFAULT;
2323
2324 kfree(param);
2325
2326 return ret;
2327}
2328
2329static int
2330prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info,
2331 __u32 * uwrq, char *extra)
2332{
2333 islpci_private *priv = netdev_priv(ndev);
2334 u32 mlme, authen, dot1x, filter, wep;
2335
2336 if (islpci_get_state(priv) < PRV_STATE_INIT)
2337 return 0;
2338
2339 wep = 1; /* For privacy invoked */
2340 filter = 1; /* Filter out all unencrypted frames */
2341 dot1x = 0x01; /* To enable eap filter */
2342 mlme = DOT11_MLME_EXTENDED;
2343 authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
2344
2345 down_write(&priv->mib_sem);
2346 priv->wpa = *uwrq;
2347
2348 switch (priv->wpa) {
2349 default:
2350 case 0: /* Clears/disables WPA and friends */
2351 wep = 0;
2352 filter = 0; /* Do not filter un-encrypted data */
2353 dot1x = 0;
2354 mlme = DOT11_MLME_AUTO;
2355 printk("%s: Disabling WPA\n", ndev->name);
2356 break;
2357 case 2:
2358 case 1: /* WPA */
2359 printk("%s: Enabling WPA\n", ndev->name);
2360 break;
2361 }
2362 up_write(&priv->mib_sem);
2363
2364 mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
2365 mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &wep);
2366 mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &filter);
2367 mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
2368 mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlme);
2369
2370 return 0;
2371}
2372
2373static int
2374prism54_get_wpa(struct net_device *ndev, struct iw_request_info *info,
2375 __u32 * uwrq, char *extra)
2376{
2377 islpci_private *priv = netdev_priv(ndev);
2378 *uwrq = priv->wpa;
2379 return 0;
2380}
2381
2382static int
2383prism54_set_prismhdr(struct net_device *ndev, struct iw_request_info *info,
2384 __u32 * uwrq, char *extra)
2385{
2386 islpci_private *priv = netdev_priv(ndev);
2387 priv->monitor_type =
2388 (*uwrq ? ARPHRD_IEEE80211_PRISM : ARPHRD_IEEE80211);
2389 if (priv->iw_mode == IW_MODE_MONITOR)
2390 priv->ndev->type = priv->monitor_type;
2391
2392 return 0;
2393}
2394
2395static int
2396prism54_get_prismhdr(struct net_device *ndev, struct iw_request_info *info,
2397 __u32 * uwrq, char *extra)
2398{
2399 islpci_private *priv = netdev_priv(ndev);
2400 *uwrq = (priv->monitor_type == ARPHRD_IEEE80211_PRISM);
2401 return 0;
2402}
2403
2404static int
2405prism54_debug_oid(struct net_device *ndev, struct iw_request_info *info,
2406 __u32 * uwrq, char *extra)
2407{
2408 islpci_private *priv = netdev_priv(ndev);
2409
2410 priv->priv_oid = *uwrq;
2411 printk("%s: oid 0x%08X\n", ndev->name, *uwrq);
2412
2413 return 0;
2414}
2415
2416static int
2417prism54_debug_get_oid(struct net_device *ndev, struct iw_request_info *info,
2418 struct iw_point *data, char *extra)
2419{
2420 islpci_private *priv = netdev_priv(ndev);
2421 struct islpci_mgmtframe *response;
2422 int ret = -EIO;
2423
2424 printk("%s: get_oid 0x%08X\n", ndev->name, priv->priv_oid);
2425 data->length = 0;
2426
2427 if (islpci_get_state(priv) >= PRV_STATE_INIT) {
2428 ret =
2429 islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET,
2430 priv->priv_oid, extra, 256,
2431 &response);
2432 printk("%s: ret: %i\n", ndev->name, ret);
2433 if (ret || !response
2434 || response->header->operation == PIMFOR_OP_ERROR) {
2435 if (response) {
2436 islpci_mgt_release(response);
2437 }
2438 printk("%s: EIO\n", ndev->name);
2439 ret = -EIO;
2440 }
2441 if (!ret) {
2442 data->length = response->header->length;
2443 memcpy(extra, response->data, data->length);
2444 islpci_mgt_release(response);
2445 printk("%s: len: %i\n", ndev->name, data->length);
2446 }
2447 }
2448
2449 return ret;
2450}
2451
2452static int
2453prism54_debug_set_oid(struct net_device *ndev, struct iw_request_info *info,
2454 struct iw_point *data, char *extra)
2455{
2456 islpci_private *priv = netdev_priv(ndev);
2457 struct islpci_mgmtframe *response;
2458 int ret = 0, response_op = PIMFOR_OP_ERROR;
2459
2460 printk("%s: set_oid 0x%08X\tlen: %d\n", ndev->name, priv->priv_oid,
2461 data->length);
2462
2463 if (islpci_get_state(priv) >= PRV_STATE_INIT) {
2464 ret =
2465 islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET,
2466 priv->priv_oid, extra, data->length,
2467 &response);
2468 printk("%s: ret: %i\n", ndev->name, ret);
2469 if (ret || !response
2470 || response->header->operation == PIMFOR_OP_ERROR) {
2471 if (response) {
2472 islpci_mgt_release(response);
2473 }
2474 printk("%s: EIO\n", ndev->name);
2475 ret = -EIO;
2476 }
2477 if (!ret) {
2478 response_op = response->header->operation;
2479 printk("%s: response_op: %i\n", ndev->name,
2480 response_op);
2481 islpci_mgt_release(response);
2482 }
2483 }
2484
2485 return (ret ? ret : -EINPROGRESS);
2486}
2487
2488static int
2489prism54_set_spy(struct net_device *ndev,
2490 struct iw_request_info *info,
2491 union iwreq_data *uwrq, char *extra)
2492{
2493 islpci_private *priv = netdev_priv(ndev);
2494 u32 u, oid = OID_INL_CONFIG;
2495
2496 down_write(&priv->mib_sem);
2497 mgt_get(priv, OID_INL_CONFIG, &u);
2498
2499 if ((uwrq->data.length == 0) && (priv->spy_data.spy_number > 0))
2500 /* disable spy */
2501 u &= ~INL_CONFIG_RXANNEX;
2502 else if ((uwrq->data.length > 0) && (priv->spy_data.spy_number == 0))
2503 /* enable spy */
2504 u |= INL_CONFIG_RXANNEX;
2505
2506 mgt_set(priv, OID_INL_CONFIG, &u);
2507 mgt_commit_list(priv, &oid, 1);
2508 up_write(&priv->mib_sem);
2509
2510 return iw_handler_set_spy(ndev, info, uwrq, extra);
2511}
2512
2513static const iw_handler prism54_handler[] = {
2514 (iw_handler) prism54_commit, /* SIOCSIWCOMMIT */
2515 (iw_handler) prism54_get_name, /* SIOCGIWNAME */
2516 (iw_handler) NULL, /* SIOCSIWNWID */
2517 (iw_handler) NULL, /* SIOCGIWNWID */
2518 (iw_handler) prism54_set_freq, /* SIOCSIWFREQ */
2519 (iw_handler) prism54_get_freq, /* SIOCGIWFREQ */
2520 (iw_handler) prism54_set_mode, /* SIOCSIWMODE */
2521 (iw_handler) prism54_get_mode, /* SIOCGIWMODE */
2522 (iw_handler) prism54_set_sens, /* SIOCSIWSENS */
2523 (iw_handler) prism54_get_sens, /* SIOCGIWSENS */
2524 (iw_handler) NULL, /* SIOCSIWRANGE */
2525 (iw_handler) prism54_get_range, /* SIOCGIWRANGE */
2526 (iw_handler) NULL, /* SIOCSIWPRIV */
2527 (iw_handler) NULL, /* SIOCGIWPRIV */
2528 (iw_handler) NULL, /* SIOCSIWSTATS */
2529 (iw_handler) NULL, /* SIOCGIWSTATS */
2530 prism54_set_spy, /* SIOCSIWSPY */
2531 iw_handler_get_spy, /* SIOCGIWSPY */
2532 iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
2533 iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
2534 (iw_handler) prism54_set_wap, /* SIOCSIWAP */
2535 (iw_handler) prism54_get_wap, /* SIOCGIWAP */
2536 (iw_handler) NULL, /* -- hole -- */
2537 (iw_handler) NULL, /* SIOCGIWAPLIST depreciated */
2538 (iw_handler) prism54_set_scan, /* SIOCSIWSCAN */
2539 (iw_handler) prism54_get_scan, /* SIOCGIWSCAN */
2540 (iw_handler) prism54_set_essid, /* SIOCSIWESSID */
2541 (iw_handler) prism54_get_essid, /* SIOCGIWESSID */
2542 (iw_handler) prism54_set_nick, /* SIOCSIWNICKN */
2543 (iw_handler) prism54_get_nick, /* SIOCGIWNICKN */
2544 (iw_handler) NULL, /* -- hole -- */
2545 (iw_handler) NULL, /* -- hole -- */
2546 (iw_handler) prism54_set_rate, /* SIOCSIWRATE */
2547 (iw_handler) prism54_get_rate, /* SIOCGIWRATE */
2548 (iw_handler) prism54_set_rts, /* SIOCSIWRTS */
2549 (iw_handler) prism54_get_rts, /* SIOCGIWRTS */
2550 (iw_handler) prism54_set_frag, /* SIOCSIWFRAG */
2551 (iw_handler) prism54_get_frag, /* SIOCGIWFRAG */
2552 (iw_handler) prism54_set_txpower, /* SIOCSIWTXPOW */
2553 (iw_handler) prism54_get_txpower, /* SIOCGIWTXPOW */
2554 (iw_handler) prism54_set_retry, /* SIOCSIWRETRY */
2555 (iw_handler) prism54_get_retry, /* SIOCGIWRETRY */
2556 (iw_handler) prism54_set_encode, /* SIOCSIWENCODE */
2557 (iw_handler) prism54_get_encode, /* SIOCGIWENCODE */
2558 (iw_handler) NULL, /* SIOCSIWPOWER */
2559 (iw_handler) NULL, /* SIOCGIWPOWER */
2560};
2561
2562/* The low order bit identify a SET (0) or a GET (1) ioctl. */
2563
2564#define PRISM54_RESET SIOCIWFIRSTPRIV
2565#define PRISM54_GET_POLICY SIOCIWFIRSTPRIV+1
2566#define PRISM54_SET_POLICY SIOCIWFIRSTPRIV+2
2567#define PRISM54_GET_MAC SIOCIWFIRSTPRIV+3
2568#define PRISM54_ADD_MAC SIOCIWFIRSTPRIV+4
2569
2570#define PRISM54_DEL_MAC SIOCIWFIRSTPRIV+6
2571
2572#define PRISM54_KICK_MAC SIOCIWFIRSTPRIV+8
2573
2574#define PRISM54_KICK_ALL SIOCIWFIRSTPRIV+10
2575
2576#define PRISM54_GET_WPA SIOCIWFIRSTPRIV+11
2577#define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
2578
2579#define PRISM54_DBG_OID SIOCIWFIRSTPRIV+14
2580#define PRISM54_DBG_GET_OID SIOCIWFIRSTPRIV+15
2581#define PRISM54_DBG_SET_OID SIOCIWFIRSTPRIV+16
2582
2583#define PRISM54_GET_OID SIOCIWFIRSTPRIV+17
2584#define PRISM54_SET_OID_U32 SIOCIWFIRSTPRIV+18
2585#define PRISM54_SET_OID_STR SIOCIWFIRSTPRIV+20
2586#define PRISM54_SET_OID_ADDR SIOCIWFIRSTPRIV+22
2587
2588#define PRISM54_GET_PRISMHDR SIOCIWFIRSTPRIV+23
2589#define PRISM54_SET_PRISMHDR SIOCIWFIRSTPRIV+24
2590
2591#define IWPRIV_SET_U32(n,x) { n, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x }
2592#define IWPRIV_SET_SSID(n,x) { n, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x }
2593#define IWPRIV_SET_ADDR(n,x) { n, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, "s_"x }
2594#define IWPRIV_GET(n,x) { n, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, "g_"x }
2595
2596#define IWPRIV_U32(n,x) IWPRIV_SET_U32(n,x), IWPRIV_GET(n,x)
2597#define IWPRIV_SSID(n,x) IWPRIV_SET_SSID(n,x), IWPRIV_GET(n,x)
2598#define IWPRIV_ADDR(n,x) IWPRIV_SET_ADDR(n,x), IWPRIV_GET(n,x)
2599
2600/* Note : limited to 128 private ioctls (wireless tools 26) */
2601
2602static const struct iw_priv_args prism54_private_args[] = {
2603/*{ cmd, set_args, get_args, name } */
2604 {PRISM54_RESET, 0, 0, "reset"},
2605 {PRISM54_GET_PRISMHDR, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2606 "get_prismhdr"},
2607 {PRISM54_SET_PRISMHDR, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
2608 "set_prismhdr"},
2609 {PRISM54_GET_POLICY, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2610 "getPolicy"},
2611 {PRISM54_SET_POLICY, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
2612 "setPolicy"},
2613 {PRISM54_GET_MAC, 0, IW_PRIV_TYPE_ADDR | 64, "getMac"},
2614 {PRISM54_ADD_MAC, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0,
2615 "addMac"},
2616 {PRISM54_DEL_MAC, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0,
2617 "delMac"},
2618 {PRISM54_KICK_MAC, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0,
2619 "kickMac"},
2620 {PRISM54_KICK_ALL, 0, 0, "kickAll"},
2621 {PRISM54_GET_WPA, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2622 "get_wpa"},
2623 {PRISM54_SET_WPA, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
2624 "set_wpa"},
2625 {PRISM54_DBG_OID, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
2626 "dbg_oid"},
2627 {PRISM54_DBG_GET_OID, 0, IW_PRIV_TYPE_BYTE | 256, "dbg_get_oid"},
2628 {PRISM54_DBG_SET_OID, IW_PRIV_TYPE_BYTE | 256, 0, "dbg_set_oid"},
2629 /* --- sub-ioctls handlers --- */
2630 {PRISM54_GET_OID,
2631 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | PRIV_STR_SIZE, ""},
2632 {PRISM54_SET_OID_U32,
2633 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""},
2634 {PRISM54_SET_OID_STR,
2635 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, ""},
2636 {PRISM54_SET_OID_ADDR,
2637 IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 0, ""},
2638 /* --- sub-ioctls definitions --- */
2639 IWPRIV_ADDR(GEN_OID_MACADDRESS, "addr"),
2640 IWPRIV_GET(GEN_OID_LINKSTATE, "linkstate"),
2641 IWPRIV_U32(DOT11_OID_BSSTYPE, "bsstype"),
2642 IWPRIV_ADDR(DOT11_OID_BSSID, "bssid"),
2643 IWPRIV_U32(DOT11_OID_STATE, "state"),
2644 IWPRIV_U32(DOT11_OID_AID, "aid"),
2645
2646 IWPRIV_SSID(DOT11_OID_SSIDOVERRIDE, "ssidoverride"),
2647
2648 IWPRIV_U32(DOT11_OID_MEDIUMLIMIT, "medlimit"),
2649 IWPRIV_U32(DOT11_OID_BEACONPERIOD, "beacon"),
2650 IWPRIV_U32(DOT11_OID_DTIMPERIOD, "dtimperiod"),
2651
2652 IWPRIV_U32(DOT11_OID_AUTHENABLE, "authenable"),
2653 IWPRIV_U32(DOT11_OID_PRIVACYINVOKED, "privinvok"),
2654 IWPRIV_U32(DOT11_OID_EXUNENCRYPTED, "exunencrypt"),
2655
2656 IWPRIV_U32(DOT11_OID_REKEYTHRESHOLD, "rekeythresh"),
2657
2658 IWPRIV_U32(DOT11_OID_MAXTXLIFETIME, "maxtxlife"),
2659 IWPRIV_U32(DOT11_OID_MAXRXLIFETIME, "maxrxlife"),
2660 IWPRIV_U32(DOT11_OID_ALOFT_FIXEDRATE, "fixedrate"),
2661 IWPRIV_U32(DOT11_OID_MAXFRAMEBURST, "frameburst"),
2662 IWPRIV_U32(DOT11_OID_PSM, "psm"),
2663
2664 IWPRIV_U32(DOT11_OID_BRIDGELOCAL, "bridge"),
2665 IWPRIV_U32(DOT11_OID_CLIENTS, "clients"),
2666 IWPRIV_U32(DOT11_OID_CLIENTSASSOCIATED, "clientassoc"),
2667 IWPRIV_U32(DOT11_OID_DOT1XENABLE, "dot1xenable"),
2668 IWPRIV_U32(DOT11_OID_ANTENNARX, "rxant"),
2669 IWPRIV_U32(DOT11_OID_ANTENNATX, "txant"),
2670 IWPRIV_U32(DOT11_OID_ANTENNADIVERSITY, "antdivers"),
2671 IWPRIV_U32(DOT11_OID_EDTHRESHOLD, "edthresh"),
2672 IWPRIV_U32(DOT11_OID_PREAMBLESETTINGS, "preamble"),
2673 IWPRIV_GET(DOT11_OID_RATES, "rates"),
2674 IWPRIV_U32(DOT11_OID_OUTPUTPOWER, ".11outpower"),
2675 IWPRIV_GET(DOT11_OID_SUPPORTEDRATES, "supprates"),
2676 IWPRIV_GET(DOT11_OID_SUPPORTEDFREQUENCIES, "suppfreq"),
2677
2678 IWPRIV_U32(DOT11_OID_NOISEFLOOR, "noisefloor"),
2679 IWPRIV_GET(DOT11_OID_FREQUENCYACTIVITY, "freqactivity"),
2680 IWPRIV_U32(DOT11_OID_NONERPPROTECTION, "nonerpprotec"),
2681 IWPRIV_U32(DOT11_OID_PROFILES, "profile"),
2682 IWPRIV_GET(DOT11_OID_EXTENDEDRATES, "extrates"),
2683 IWPRIV_U32(DOT11_OID_MLMEAUTOLEVEL, "mlmelevel"),
2684
2685 IWPRIV_GET(DOT11_OID_BSSS, "bsss"),
2686 IWPRIV_GET(DOT11_OID_BSSLIST, "bsslist"),
2687 IWPRIV_U32(OID_INL_MODE, "mode"),
2688 IWPRIV_U32(OID_INL_CONFIG, "config"),
2689 IWPRIV_U32(OID_INL_DOT11D_CONFORMANCE, ".11dconform"),
2690 IWPRIV_GET(OID_INL_PHYCAPABILITIES, "phycapa"),
2691 IWPRIV_U32(OID_INL_OUTPUTPOWER, "outpower"),
2692};
2693
2694static const iw_handler prism54_private_handler[] = {
2695 (iw_handler) prism54_reset,
2696 (iw_handler) prism54_get_policy,
2697 (iw_handler) prism54_set_policy,
2698 (iw_handler) prism54_get_mac,
2699 (iw_handler) prism54_add_mac,
2700 (iw_handler) NULL,
2701 (iw_handler) prism54_del_mac,
2702 (iw_handler) NULL,
2703 (iw_handler) prism54_kick_mac,
2704 (iw_handler) NULL,
2705 (iw_handler) prism54_kick_all,
2706 (iw_handler) prism54_get_wpa,
2707 (iw_handler) prism54_set_wpa,
2708 (iw_handler) NULL,
2709 (iw_handler) prism54_debug_oid,
2710 (iw_handler) prism54_debug_get_oid,
2711 (iw_handler) prism54_debug_set_oid,
2712 (iw_handler) prism54_get_oid,
2713 (iw_handler) prism54_set_u32,
2714 (iw_handler) NULL,
2715 (iw_handler) prism54_set_raw,
2716 (iw_handler) NULL,
2717 (iw_handler) prism54_set_raw,
2718 (iw_handler) prism54_get_prismhdr,
2719 (iw_handler) prism54_set_prismhdr,
2720};
2721
2722const struct iw_handler_def prism54_handler_def = {
2723 .num_standard = sizeof (prism54_handler) / sizeof (iw_handler),
2724 .num_private = sizeof (prism54_private_handler) / sizeof (iw_handler),
2725 .num_private_args =
2726 sizeof (prism54_private_args) / sizeof (struct iw_priv_args),
2727 .standard = (iw_handler *) prism54_handler,
2728 .private = (iw_handler *) prism54_private_handler,
2729 .private_args = (struct iw_priv_args *) prism54_private_args,
2730#if WIRELESS_EXT == 16
2731 .spy_offset = offsetof(islpci_private, spy_data),
2732#endif /* WIRELESS_EXT == 16 */
2733};
2734
2735/* For wpa_supplicant */
2736
2737int
2738prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
2739{
2740 struct iwreq *wrq = (struct iwreq *) rq;
2741 int ret = -1;
2742 switch (cmd) {
2743 case PRISM54_HOSTAPD:
2744 if (!capable(CAP_NET_ADMIN))
2745 return -EPERM;
2746 ret = prism54_hostapd(ndev, &wrq->u.data);
2747 return ret;
2748 }
2749 return -EOPNOTSUPP;
2750}
diff --git a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h
new file mode 100644
index 000000000000..46d5cde80c85
--- /dev/null
+++ b/drivers/net/wireless/prism54/isl_ioctl.h
@@ -0,0 +1,51 @@
1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc.
4 * (C) 2003 Aurelien Alleaume <slts@free.fr>
5 * (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#ifndef _ISL_IOCTL_H
23#define _ISL_IOCTL_H
24
25#include "islpci_mgt.h"
26#include "islpci_dev.h"
27
28#include <net/iw_handler.h> /* New driver API */
29
30#define SUPPORTED_WIRELESS_EXT 16
31
32void prism54_mib_init(islpci_private *);
33
34struct iw_statistics *prism54_get_wireless_stats(struct net_device *);
35void prism54_update_stats(islpci_private *);
36
37void prism54_acl_init(struct islpci_acl *);
38void prism54_acl_clean(struct islpci_acl *);
39
40void prism54_process_trap(void *);
41
42void prism54_wpa_ie_init(islpci_private *priv);
43void prism54_wpa_ie_clean(islpci_private *priv);
44
45int prism54_set_mac_address(struct net_device *, void *);
46
47int prism54_ioctl(struct net_device *, struct ifreq *, int);
48
49extern const struct iw_handler_def prism54_handler_def;
50
51#endif /* _ISL_IOCTL_H */
diff --git a/drivers/net/wireless/prism54/isl_oid.h b/drivers/net/wireless/prism54/isl_oid.h
new file mode 100644
index 000000000000..419edf7ccf1a
--- /dev/null
+++ b/drivers/net/wireless/prism54/isl_oid.h
@@ -0,0 +1,507 @@
1/*
2 *
3 *
4 * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
5 * Copyright (C) 2004 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
6 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#if !defined(_ISL_OID_H)
24#define _ISL_OID_H
25
26/*
27 * MIB related constant and structure definitions for communicating
28 * with the device firmware
29 */
30
31struct obj_ssid {
32 u8 length;
33 char octets[33];
34} __attribute__ ((packed));
35
36struct obj_key {
37 u8 type; /* dot11_priv_t */
38 u8 length;
39 char key[32];
40} __attribute__ ((packed));
41
42struct obj_mlme {
43 u8 address[6];
44 u16 id;
45 u16 state;
46 u16 code;
47} __attribute__ ((packed));
48
49struct obj_mlmeex {
50 u8 address[6];
51 u16 id;
52 u16 state;
53 u16 code;
54 u16 size;
55 u8 data[0];
56} __attribute__ ((packed));
57
58struct obj_buffer {
59 u32 size;
60 u32 addr; /* 32bit bus address */
61} __attribute__ ((packed));
62
63struct obj_bss {
64 u8 address[6];
65 int:16; /* padding */
66
67 char state;
68 char reserved;
69 short age;
70
71 char quality;
72 char rssi;
73
74 struct obj_ssid ssid;
75 short channel;
76 char beacon_period;
77 char dtim_period;
78 short capinfo;
79 short rates;
80 short basic_rates;
81 int:16; /* padding */
82} __attribute__ ((packed));
83
84struct obj_bsslist {
85 u32 nr;
86 struct obj_bss bsslist[0];
87} __attribute__ ((packed));
88
89struct obj_frequencies {
90 u16 nr;
91 u16 mhz[0];
92} __attribute__ ((packed));
93
94struct obj_attachment {
95 char type;
96 char reserved;
97 short id;
98 short size;
99 char data[0];
100} __attribute__((packed));
101
102/*
103 * in case everything's ok, the inlined function below will be
104 * optimized away by the compiler...
105 */
106static inline void
107__bug_on_wrong_struct_sizes(void)
108{
109 BUG_ON(sizeof (struct obj_ssid) != 34);
110 BUG_ON(sizeof (struct obj_key) != 34);
111 BUG_ON(sizeof (struct obj_mlme) != 12);
112 BUG_ON(sizeof (struct obj_mlmeex) != 14);
113 BUG_ON(sizeof (struct obj_buffer) != 8);
114 BUG_ON(sizeof (struct obj_bss) != 60);
115 BUG_ON(sizeof (struct obj_bsslist) != 4);
116 BUG_ON(sizeof (struct obj_frequencies) != 2);
117}
118
119enum dot11_state_t {
120 DOT11_STATE_NONE = 0,
121 DOT11_STATE_AUTHING = 1,
122 DOT11_STATE_AUTH = 2,
123 DOT11_STATE_ASSOCING = 3,
124
125 DOT11_STATE_ASSOC = 5,
126 DOT11_STATE_IBSS = 6,
127 DOT11_STATE_WDS = 7
128};
129
130enum dot11_bsstype_t {
131 DOT11_BSSTYPE_NONE = 0,
132 DOT11_BSSTYPE_INFRA = 1,
133 DOT11_BSSTYPE_IBSS = 2,
134 DOT11_BSSTYPE_ANY = 3
135};
136
137enum dot11_auth_t {
138 DOT11_AUTH_NONE = 0,
139 DOT11_AUTH_OS = 1,
140 DOT11_AUTH_SK = 2,
141 DOT11_AUTH_BOTH = 3
142};
143
144enum dot11_mlme_t {
145 DOT11_MLME_AUTO = 0,
146 DOT11_MLME_INTERMEDIATE = 1,
147 DOT11_MLME_EXTENDED = 2
148};
149
150enum dot11_priv_t {
151 DOT11_PRIV_WEP = 0,
152 DOT11_PRIV_TKIP = 1
153};
154
155/* Prism "Nitro" / Frameburst / "Packet Frame Grouping"
156 * Value is in microseconds. Represents the # microseconds
157 * the firmware will take to group frames before sending out then out
158 * together with a CSMA contention. Without this all frames are
159 * sent with a CSMA contention.
160 * Bibliography:
161 * http://www.hpl.hp.com/personal/Jean_Tourrilhes/Papers/Packet.Frame.Grouping.html
162 */
163enum dot11_maxframeburst_t {
164 /* Values for DOT11_OID_MAXFRAMEBURST */
165 DOT11_MAXFRAMEBURST_OFF = 0, /* Card firmware default */
166 DOT11_MAXFRAMEBURST_MIXED_SAFE = 650, /* 802.11 a,b,g safe */
167 DOT11_MAXFRAMEBURST_IDEAL = 1300, /* Theoretical ideal level */
168 DOT11_MAXFRAMEBURST_MAX = 5000, /* Use this as max,
169 * Note: firmware allows for greater values. This is a
170 * recommended max. I'll update this as I find
171 * out what the real MAX is. Also note that you don't necessarily
172 * get better results with a greater value here.
173 */
174};
175
176/* Support for 802.11 long and short frame preambles.
177 * Long preamble uses 128-bit sync field, 8-bit CRC
178 * Short preamble uses 56-bit sync field, 16-bit CRC
179 *
180 * 802.11a -- not sure, both optionally ?
181 * 802.11b supports long and optionally short
182 * 802.11g supports both */
183enum dot11_preamblesettings_t {
184 DOT11_PREAMBLESETTING_LONG = 0,
185 /* Allows *only* long 802.11 preambles */
186 DOT11_PREAMBLESETTING_SHORT = 1,
187 /* Allows *only* short 802.11 preambles */
188 DOT11_PREAMBLESETTING_DYNAMIC = 2
189 /* AutomatiGically set */
190};
191
192/* Support for 802.11 slot timing (time between packets).
193 *
194 * Long uses 802.11a slot timing (9 usec ?)
195 * Short uses 802.11b slot timing (20 use ?) */
196enum dot11_slotsettings_t {
197 DOT11_SLOTSETTINGS_LONG = 0,
198 /* Allows *only* long 802.11b slot timing */
199 DOT11_SLOTSETTINGS_SHORT = 1,
200 /* Allows *only* long 802.11a slot timing */
201 DOT11_SLOTSETTINGS_DYNAMIC = 2
202 /* AutomatiGically set */
203};
204
205/* All you need to know, ERP is "Extended Rate PHY".
206 * An Extended Rate PHY (ERP) STA or AP shall support three different
207 * preamble and header formats:
208 * Long preamble (refer to above)
209 * Short preamble (refer to above)
210 * OFDM preamble ( ? )
211 *
212 * I'm assuming here Protection tells the AP
213 * to be careful, a STA which cannot handle the long pre-amble
214 * has joined.
215 */
216enum do11_nonerpstatus_t {
217 DOT11_ERPSTAT_NONEPRESENT = 0,
218 DOT11_ERPSTAT_USEPROTECTION = 1
219};
220
221/* (ERP is "Extended Rate PHY") Way to read NONERP is NON-ERP-*
222 * The key here is DOT11 NON ERP NEVER protects against
223 * NON ERP STA's. You *don't* want this unless
224 * you know what you are doing. It means you will only
225 * get Extended Rate capabilities */
226enum dot11_nonerpprotection_t {
227 DOT11_NONERP_NEVER = 0,
228 DOT11_NONERP_ALWAYS = 1,
229 DOT11_NONERP_DYNAMIC = 2
230};
231
232/* Preset OID configuration for 802.11 modes
233 * Note: DOT11_OID_CW[MIN|MAX] hold the values of the
234 * DCS MIN|MAX backoff used */
235enum dot11_profile_t { /* And set/allowed values */
236 /* Allowed values for DOT11_OID_PROFILES */
237 DOT11_PROFILE_B_ONLY = 0,
238 /* DOT11_OID_RATES: 1, 2, 5.5, 11Mbps
239 * DOT11_OID_PREAMBLESETTINGS: DOT11_PREAMBLESETTING_DYNAMIC
240 * DOT11_OID_CWMIN: 31
241 * DOT11_OID_NONEPROTECTION: DOT11_NOERP_DYNAMIC
242 * DOT11_OID_SLOTSETTINGS: DOT11_SLOTSETTINGS_LONG
243 */
244 DOT11_PROFILE_MIXED_G_WIFI = 1,
245 /* DOT11_OID_RATES: 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54Mbs
246 * DOT11_OID_PREAMBLESETTINGS: DOT11_PREAMBLESETTING_DYNAMIC
247 * DOT11_OID_CWMIN: 15
248 * DOT11_OID_NONEPROTECTION: DOT11_NOERP_DYNAMIC
249 * DOT11_OID_SLOTSETTINGS: DOT11_SLOTSETTINGS_DYNAMIC
250 */
251 DOT11_PROFILE_MIXED_LONG = 2, /* "Long range" */
252 /* Same as Profile MIXED_G_WIFI */
253 DOT11_PROFILE_G_ONLY = 3,
254 /* Same as Profile MIXED_G_WIFI */
255 DOT11_PROFILE_TEST = 4,
256 /* Same as Profile MIXED_G_WIFI except:
257 * DOT11_OID_PREAMBLESETTINGS: DOT11_PREAMBLESETTING_SHORT
258 * DOT11_OID_NONEPROTECTION: DOT11_NOERP_NEVER
259 * DOT11_OID_SLOTSETTINGS: DOT11_SLOTSETTINGS_SHORT
260 */
261 DOT11_PROFILE_B_WIFI = 5,
262 /* Same as Profile B_ONLY */
263 DOT11_PROFILE_A_ONLY = 6,
264 /* Same as Profile MIXED_G_WIFI except:
265 * DOT11_OID_RATES: 6, 9, 12, 18, 24, 36, 48, 54Mbs
266 */
267 DOT11_PROFILE_MIXED_SHORT = 7
268 /* Same as MIXED_G_WIFI */
269};
270
271
272/* The dot11d conformance level configures the 802.11d conformance levels.
273 * The following conformance levels exist:*/
274enum oid_inl_conformance_t {
275 OID_INL_CONFORMANCE_NONE = 0, /* Perform active scanning */
276 OID_INL_CONFORMANCE_STRICT = 1, /* Strictly adhere to 802.11d */
277 OID_INL_CONFORMANCE_FLEXIBLE = 2, /* Use passed 802.11d info to
278 * determine channel AND/OR just make assumption that active
279 * channels are valid channels */
280};
281
282enum oid_inl_mode_t {
283 INL_MODE_NONE = -1,
284 INL_MODE_PROMISCUOUS = 0,
285 INL_MODE_CLIENT = 1,
286 INL_MODE_AP = 2,
287 INL_MODE_SNIFFER = 3
288};
289
290enum oid_inl_config_t {
291 INL_CONFIG_NOTHING = 0x00,
292 INL_CONFIG_MANUALRUN = 0x01,
293 INL_CONFIG_FRAMETRAP = 0x02,
294 INL_CONFIG_RXANNEX = 0x04,
295 INL_CONFIG_TXANNEX = 0x08,
296 INL_CONFIG_WDS = 0x10
297};
298
299enum oid_inl_phycap_t {
300 INL_PHYCAP_2400MHZ = 1,
301 INL_PHYCAP_5000MHZ = 2,
302 INL_PHYCAP_FAA = 0x80000000, /* Means card supports the FAA switch */
303};
304
305
306enum oid_num_t {
307 GEN_OID_MACADDRESS = 0,
308 GEN_OID_LINKSTATE,
309 GEN_OID_WATCHDOG,
310 GEN_OID_MIBOP,
311 GEN_OID_OPTIONS,
312 GEN_OID_LEDCONFIG,
313
314 /* 802.11 */
315 DOT11_OID_BSSTYPE,
316 DOT11_OID_BSSID,
317 DOT11_OID_SSID,
318 DOT11_OID_STATE,
319 DOT11_OID_AID,
320 DOT11_OID_COUNTRYSTRING,
321 DOT11_OID_SSIDOVERRIDE,
322
323 DOT11_OID_MEDIUMLIMIT,
324 DOT11_OID_BEACONPERIOD,
325 DOT11_OID_DTIMPERIOD,
326 DOT11_OID_ATIMWINDOW,
327 DOT11_OID_LISTENINTERVAL,
328 DOT11_OID_CFPPERIOD,
329 DOT11_OID_CFPDURATION,
330
331 DOT11_OID_AUTHENABLE,
332 DOT11_OID_PRIVACYINVOKED,
333 DOT11_OID_EXUNENCRYPTED,
334 DOT11_OID_DEFKEYID,
335 DOT11_OID_DEFKEYX, /* DOT11_OID_DEFKEY1,...DOT11_OID_DEFKEY4 */
336 DOT11_OID_STAKEY,
337 DOT11_OID_REKEYTHRESHOLD,
338 DOT11_OID_STASC,
339
340 DOT11_OID_PRIVTXREJECTED,
341 DOT11_OID_PRIVRXPLAIN,
342 DOT11_OID_PRIVRXFAILED,
343 DOT11_OID_PRIVRXNOKEY,
344
345 DOT11_OID_RTSTHRESH,
346 DOT11_OID_FRAGTHRESH,
347 DOT11_OID_SHORTRETRIES,
348 DOT11_OID_LONGRETRIES,
349 DOT11_OID_MAXTXLIFETIME,
350 DOT11_OID_MAXRXLIFETIME,
351 DOT11_OID_AUTHRESPTIMEOUT,
352 DOT11_OID_ASSOCRESPTIMEOUT,
353
354 DOT11_OID_ALOFT_TABLE,
355 DOT11_OID_ALOFT_CTRL_TABLE,
356 DOT11_OID_ALOFT_RETREAT,
357 DOT11_OID_ALOFT_PROGRESS,
358 DOT11_OID_ALOFT_FIXEDRATE,
359 DOT11_OID_ALOFT_RSSIGRAPH,
360 DOT11_OID_ALOFT_CONFIG,
361
362 DOT11_OID_VDCFX,
363 DOT11_OID_MAXFRAMEBURST,
364
365 DOT11_OID_PSM,
366 DOT11_OID_CAMTIMEOUT,
367 DOT11_OID_RECEIVEDTIMS,
368 DOT11_OID_ROAMPREFERENCE,
369
370 DOT11_OID_BRIDGELOCAL,
371 DOT11_OID_CLIENTS,
372 DOT11_OID_CLIENTSASSOCIATED,
373 DOT11_OID_CLIENTX, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
374
375 DOT11_OID_CLIENTFIND,
376 DOT11_OID_WDSLINKADD,
377 DOT11_OID_WDSLINKREMOVE,
378 DOT11_OID_EAPAUTHSTA,
379 DOT11_OID_EAPUNAUTHSTA,
380 DOT11_OID_DOT1XENABLE,
381 DOT11_OID_MICFAILURE,
382 DOT11_OID_REKEYINDICATE,
383
384 DOT11_OID_MPDUTXSUCCESSFUL,
385 DOT11_OID_MPDUTXONERETRY,
386 DOT11_OID_MPDUTXMULTIPLERETRIES,
387 DOT11_OID_MPDUTXFAILED,
388 DOT11_OID_MPDURXSUCCESSFUL,
389 DOT11_OID_MPDURXDUPS,
390 DOT11_OID_RTSSUCCESSFUL,
391 DOT11_OID_RTSFAILED,
392 DOT11_OID_ACKFAILED,
393 DOT11_OID_FRAMERECEIVES,
394 DOT11_OID_FRAMEERRORS,
395 DOT11_OID_FRAMEABORTS,
396 DOT11_OID_FRAMEABORTSPHY,
397
398 DOT11_OID_SLOTTIME,
399 DOT11_OID_CWMIN, /* MIN DCS backoff */
400 DOT11_OID_CWMAX, /* MAX DCS backoff */
401 DOT11_OID_ACKWINDOW,
402 DOT11_OID_ANTENNARX,
403 DOT11_OID_ANTENNATX,
404 DOT11_OID_ANTENNADIVERSITY,
405 DOT11_OID_CHANNEL,
406 DOT11_OID_EDTHRESHOLD,
407 DOT11_OID_PREAMBLESETTINGS,
408 DOT11_OID_RATES,
409 DOT11_OID_CCAMODESUPPORTED,
410 DOT11_OID_CCAMODE,
411 DOT11_OID_RSSIVECTOR,
412 DOT11_OID_OUTPUTPOWERTABLE,
413 DOT11_OID_OUTPUTPOWER,
414 DOT11_OID_SUPPORTEDRATES,
415 DOT11_OID_FREQUENCY,
416 DOT11_OID_SUPPORTEDFREQUENCIES,
417 DOT11_OID_NOISEFLOOR,
418 DOT11_OID_FREQUENCYACTIVITY,
419 DOT11_OID_IQCALIBRATIONTABLE,
420 DOT11_OID_NONERPPROTECTION,
421 DOT11_OID_SLOTSETTINGS,
422 DOT11_OID_NONERPTIMEOUT,
423 DOT11_OID_PROFILES,
424 DOT11_OID_EXTENDEDRATES,
425
426 DOT11_OID_DEAUTHENTICATE,
427 DOT11_OID_AUTHENTICATE,
428 DOT11_OID_DISASSOCIATE,
429 DOT11_OID_ASSOCIATE,
430 DOT11_OID_SCAN,
431 DOT11_OID_BEACON,
432 DOT11_OID_PROBE,
433 DOT11_OID_DEAUTHENTICATEEX,
434 DOT11_OID_AUTHENTICATEEX,
435 DOT11_OID_DISASSOCIATEEX,
436 DOT11_OID_ASSOCIATEEX,
437 DOT11_OID_REASSOCIATE,
438 DOT11_OID_REASSOCIATEEX,
439
440 DOT11_OID_NONERPSTATUS,
441
442 DOT11_OID_STATIMEOUT,
443 DOT11_OID_MLMEAUTOLEVEL,
444 DOT11_OID_BSSTIMEOUT,
445 DOT11_OID_ATTACHMENT,
446 DOT11_OID_PSMBUFFER,
447
448 DOT11_OID_BSSS,
449 DOT11_OID_BSSX, /*DOT11_OID_BSS1,...,DOT11_OID_BSS64 */
450 DOT11_OID_BSSFIND,
451 DOT11_OID_BSSLIST,
452
453 OID_INL_TUNNEL,
454 OID_INL_MEMADDR,
455 OID_INL_MEMORY,
456 OID_INL_MODE,
457 OID_INL_COMPONENT_NR,
458 OID_INL_VERSION,
459 OID_INL_INTERFACE_ID,
460 OID_INL_COMPONENT_ID,
461 OID_INL_CONFIG,
462 OID_INL_DOT11D_CONFORMANCE,
463 OID_INL_PHYCAPABILITIES,
464 OID_INL_OUTPUTPOWER,
465
466 OID_NUM_LAST
467};
468
469#define OID_FLAG_CACHED 0x80
470#define OID_FLAG_TYPE 0x7f
471
472#define OID_TYPE_U32 0x01
473#define OID_TYPE_SSID 0x02
474#define OID_TYPE_KEY 0x03
475#define OID_TYPE_BUFFER 0x04
476#define OID_TYPE_BSS 0x05
477#define OID_TYPE_BSSLIST 0x06
478#define OID_TYPE_FREQUENCIES 0x07
479#define OID_TYPE_MLME 0x08
480#define OID_TYPE_MLMEEX 0x09
481#define OID_TYPE_ADDR 0x0A
482#define OID_TYPE_RAW 0x0B
483#define OID_TYPE_ATTACH 0x0C
484
485/* OID_TYPE_MLMEEX is special because of a variable size field when sending.
486 * Not yet implemented (not used in driver anyway).
487 */
488
489struct oid_t {
490 enum oid_num_t oid;
491 short range; /* to define a range of oid */
492 short size; /* max size of the associated data */
493 char flags;
494};
495
496union oid_res_t {
497 void *ptr;
498 u32 u;
499};
500
501#define IWMAX_BITRATES 20
502#define IWMAX_BSS 24
503#define IWMAX_FREQ 30
504#define PRIV_STR_SIZE 1024
505
506#endif /* !defined(_ISL_OID_H) */
507/* EOF */
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
new file mode 100644
index 000000000000..efab07e9e24e
--- /dev/null
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -0,0 +1,956 @@
1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc.
4 * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
5 * Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <linux/version.h>
23#include <linux/module.h>
24
25#include <linux/netdevice.h>
26#include <linux/pci.h>
27#include <linux/etherdevice.h>
28#include <linux/delay.h>
29#include <linux/if_arp.h>
30
31#include <asm/io.h>
32
33#include "prismcompat.h"
34#include "isl_38xx.h"
35#include "isl_ioctl.h"
36#include "islpci_dev.h"
37#include "islpci_mgt.h"
38#include "islpci_eth.h"
39#include "oid_mgt.h"
40
41#define ISL3877_IMAGE_FILE "isl3877"
42#define ISL3886_IMAGE_FILE "isl3886"
43#define ISL3890_IMAGE_FILE "isl3890"
44
45static int prism54_bring_down(islpci_private *);
46static int islpci_alloc_memory(islpci_private *);
47static struct net_device_stats *islpci_statistics(struct net_device *);
48
49/* Temporary dummy MAC address to use until firmware is loaded.
50 * The idea there is that some tools (such as nameif) may query
51 * the MAC address before the netdev is 'open'. By using a valid
52 * OUI prefix, they can process the netdev properly.
53 * Of course, this is not the final/real MAC address. It doesn't
54 * matter, as you are suppose to be able to change it anytime via
55 * ndev->set_mac_address. Jean II */
56static const unsigned char dummy_mac[6] = { 0x00, 0x30, 0xB4, 0x00, 0x00, 0x00 };
57
58static int
59isl_upload_firmware(islpci_private *priv)
60{
61 u32 reg, rc;
62 void __iomem *device_base = priv->device_base;
63
64 /* clear the RAMBoot and the Reset bit */
65 reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
66 reg &= ~ISL38XX_CTRL_STAT_RESET;
67 reg &= ~ISL38XX_CTRL_STAT_RAMBOOT;
68 writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
69 wmb();
70 udelay(ISL38XX_WRITEIO_DELAY);
71
72 /* set the Reset bit without reading the register ! */
73 reg |= ISL38XX_CTRL_STAT_RESET;
74 writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
75 wmb();
76 udelay(ISL38XX_WRITEIO_DELAY);
77
78 /* clear the Reset bit */
79 reg &= ~ISL38XX_CTRL_STAT_RESET;
80 writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
81 wmb();
82
83 /* wait a while for the device to reboot */
84 mdelay(50);
85
86 {
87 const struct firmware *fw_entry = NULL;
88 long fw_len;
89 const u32 *fw_ptr;
90
91 rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV);
92 if (rc) {
93 printk(KERN_ERR
94 "%s: request_firmware() failed for '%s'\n",
95 "prism54", priv->firmware);
96 return rc;
97 }
98 /* prepare the Direct Memory Base register */
99 reg = ISL38XX_DEV_FIRMWARE_ADDRES;
100
101 fw_ptr = (u32 *) fw_entry->data;
102 fw_len = fw_entry->size;
103
104 if (fw_len % 4) {
105 printk(KERN_ERR
106 "%s: firmware '%s' size is not multiple of 32bit, aborting!\n",
107 "prism54", priv->firmware);
108 release_firmware(fw_entry);
109 return -EILSEQ; /* Illegal byte sequence */;
110 }
111
112 while (fw_len > 0) {
113 long _fw_len =
114 (fw_len >
115 ISL38XX_MEMORY_WINDOW_SIZE) ?
116 ISL38XX_MEMORY_WINDOW_SIZE : fw_len;
117 u32 __iomem *dev_fw_ptr = device_base + ISL38XX_DIRECT_MEM_WIN;
118
119 /* set the cards base address for writting the data */
120 isl38xx_w32_flush(device_base, reg,
121 ISL38XX_DIR_MEM_BASE_REG);
122 wmb(); /* be paranoid */
123
124 /* increment the write address for next iteration */
125 reg += _fw_len;
126 fw_len -= _fw_len;
127
128 /* write the data to the Direct Memory Window 32bit-wise */
129 /* memcpy_toio() doesn't guarantee 32bit writes :-| */
130 while (_fw_len > 0) {
131 /* use non-swapping writel() */
132 __raw_writel(*fw_ptr, dev_fw_ptr);
133 fw_ptr++, dev_fw_ptr++;
134 _fw_len -= 4;
135 }
136
137 /* flush PCI posting */
138 (void) readl(device_base + ISL38XX_PCI_POSTING_FLUSH);
139 wmb(); /* be paranoid again */
140
141 BUG_ON(_fw_len != 0);
142 }
143
144 BUG_ON(fw_len != 0);
145
146 /* Firmware version is at offset 40 (also for "newmac") */
147 printk(KERN_DEBUG "%s: firmware version: %.8s\n",
148 priv->ndev->name, fw_entry->data + 40);
149
150 release_firmware(fw_entry);
151 }
152
153 /* now reset the device
154 * clear the Reset & ClkRun bit, set the RAMBoot bit */
155 reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
156 reg &= ~ISL38XX_CTRL_STAT_CLKRUN;
157 reg &= ~ISL38XX_CTRL_STAT_RESET;
158 reg |= ISL38XX_CTRL_STAT_RAMBOOT;
159 isl38xx_w32_flush(device_base, reg, ISL38XX_CTRL_STAT_REG);
160 wmb();
161 udelay(ISL38XX_WRITEIO_DELAY);
162
163 /* set the reset bit latches the host override and RAMBoot bits
164 * into the device for operation when the reset bit is reset */
165 reg |= ISL38XX_CTRL_STAT_RESET;
166 writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
167 /* don't do flush PCI posting here! */
168 wmb();
169 udelay(ISL38XX_WRITEIO_DELAY);
170
171 /* clear the reset bit should start the whole circus */
172 reg &= ~ISL38XX_CTRL_STAT_RESET;
173 writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
174 /* don't do flush PCI posting here! */
175 wmb();
176 udelay(ISL38XX_WRITEIO_DELAY);
177
178 return 0;
179}
180
181/******************************************************************************
182 Device Interrupt Handler
183******************************************************************************/
184
185irqreturn_t
186islpci_interrupt(int irq, void *config, struct pt_regs *regs)
187{
188 u32 reg;
189 islpci_private *priv = config;
190 struct net_device *ndev = priv->ndev;
191 void __iomem *device = priv->device_base;
192 int powerstate = ISL38XX_PSM_POWERSAVE_STATE;
193
194 /* lock the interrupt handler */
195 spin_lock(&priv->slock);
196
197 /* received an interrupt request on a shared IRQ line
198 * first check whether the device is in sleep mode */
199 reg = readl(device + ISL38XX_CTRL_STAT_REG);
200 if (reg & ISL38XX_CTRL_STAT_SLEEPMODE)
201 /* device is in sleep mode, IRQ was generated by someone else */
202 {
203#if VERBOSE > SHOW_ERROR_MESSAGES
204 DEBUG(SHOW_TRACING, "Assuming someone else called the IRQ\n");
205#endif
206 spin_unlock(&priv->slock);
207 return IRQ_NONE;
208 }
209
210
211 /* check whether there is any source of interrupt on the device */
212 reg = readl(device + ISL38XX_INT_IDENT_REG);
213
214 /* also check the contents of the Interrupt Enable Register, because this
215 * will filter out interrupt sources from other devices on the same irq ! */
216 reg &= readl(device + ISL38XX_INT_EN_REG);
217 reg &= ISL38XX_INT_SOURCES;
218
219 if (reg != 0) {
220 if (islpci_get_state(priv) != PRV_STATE_SLEEP)
221 powerstate = ISL38XX_PSM_ACTIVE_STATE;
222
223 /* reset the request bits in the Identification register */
224 isl38xx_w32_flush(device, reg, ISL38XX_INT_ACK_REG);
225
226#if VERBOSE > SHOW_ERROR_MESSAGES
227 DEBUG(SHOW_FUNCTION_CALLS,
228 "IRQ: Identification register 0x%p 0x%x \n", device, reg);
229#endif
230
231 /* check for each bit in the register separately */
232 if (reg & ISL38XX_INT_IDENT_UPDATE) {
233#if VERBOSE > SHOW_ERROR_MESSAGES
234 /* Queue has been updated */
235 DEBUG(SHOW_TRACING, "IRQ: Update flag \n");
236
237 DEBUG(SHOW_QUEUE_INDEXES,
238 "CB drv Qs: [%i][%i][%i][%i][%i][%i]\n",
239 le32_to_cpu(priv->control_block->
240 driver_curr_frag[0]),
241 le32_to_cpu(priv->control_block->
242 driver_curr_frag[1]),
243 le32_to_cpu(priv->control_block->
244 driver_curr_frag[2]),
245 le32_to_cpu(priv->control_block->
246 driver_curr_frag[3]),
247 le32_to_cpu(priv->control_block->
248 driver_curr_frag[4]),
249 le32_to_cpu(priv->control_block->
250 driver_curr_frag[5])
251 );
252
253 DEBUG(SHOW_QUEUE_INDEXES,
254 "CB dev Qs: [%i][%i][%i][%i][%i][%i]\n",
255 le32_to_cpu(priv->control_block->
256 device_curr_frag[0]),
257 le32_to_cpu(priv->control_block->
258 device_curr_frag[1]),
259 le32_to_cpu(priv->control_block->
260 device_curr_frag[2]),
261 le32_to_cpu(priv->control_block->
262 device_curr_frag[3]),
263 le32_to_cpu(priv->control_block->
264 device_curr_frag[4]),
265 le32_to_cpu(priv->control_block->
266 device_curr_frag[5])
267 );
268#endif
269
270 /* cleanup the data low transmit queue */
271 islpci_eth_cleanup_transmit(priv, priv->control_block);
272
273 /* device is in active state, update the
274 * powerstate flag if necessary */
275 powerstate = ISL38XX_PSM_ACTIVE_STATE;
276
277 /* check all three queues in priority order
278 * call the PIMFOR receive function until the
279 * queue is empty */
280 if (isl38xx_in_queue(priv->control_block,
281 ISL38XX_CB_RX_MGMTQ) != 0) {
282#if VERBOSE > SHOW_ERROR_MESSAGES
283 DEBUG(SHOW_TRACING,
284 "Received frame in Management Queue\n");
285#endif
286 islpci_mgt_receive(ndev);
287
288 islpci_mgt_cleanup_transmit(ndev);
289
290 /* Refill slots in receive queue */
291 islpci_mgmt_rx_fill(ndev);
292
293 /* no need to trigger the device, next
294 islpci_mgt_transaction does it */
295 }
296
297 while (isl38xx_in_queue(priv->control_block,
298 ISL38XX_CB_RX_DATA_LQ) != 0) {
299#if VERBOSE > SHOW_ERROR_MESSAGES
300 DEBUG(SHOW_TRACING,
301 "Received frame in Data Low Queue \n");
302#endif
303 islpci_eth_receive(priv);
304 }
305
306 /* check whether the data transmit queues were full */
307 if (priv->data_low_tx_full) {
308 /* check whether the transmit is not full anymore */
309 if (ISL38XX_CB_TX_QSIZE -
310 isl38xx_in_queue(priv->control_block,
311 ISL38XX_CB_TX_DATA_LQ) >=
312 ISL38XX_MIN_QTHRESHOLD) {
313 /* nope, the driver is ready for more network frames */
314 netif_wake_queue(priv->ndev);
315
316 /* reset the full flag */
317 priv->data_low_tx_full = 0;
318 }
319 }
320 }
321
322 if (reg & ISL38XX_INT_IDENT_INIT) {
323 /* Device has been initialized */
324#if VERBOSE > SHOW_ERROR_MESSAGES
325 DEBUG(SHOW_TRACING,
326 "IRQ: Init flag, device initialized \n");
327#endif
328 wake_up(&priv->reset_done);
329 }
330
331 if (reg & ISL38XX_INT_IDENT_SLEEP) {
332 /* Device intends to move to powersave state */
333#if VERBOSE > SHOW_ERROR_MESSAGES
334 DEBUG(SHOW_TRACING, "IRQ: Sleep flag \n");
335#endif
336 isl38xx_handle_sleep_request(priv->control_block,
337 &powerstate,
338 priv->device_base);
339 }
340
341 if (reg & ISL38XX_INT_IDENT_WAKEUP) {
342 /* Device has been woken up to active state */
343#if VERBOSE > SHOW_ERROR_MESSAGES
344 DEBUG(SHOW_TRACING, "IRQ: Wakeup flag \n");
345#endif
346
347 isl38xx_handle_wakeup(priv->control_block,
348 &powerstate, priv->device_base);
349 }
350 } else {
351#if VERBOSE > SHOW_ERROR_MESSAGES
352 DEBUG(SHOW_TRACING, "Assuming someone else called the IRQ\n");
353#endif
354 spin_unlock(&priv->slock);
355 return IRQ_NONE;
356 }
357
358 /* sleep -> ready */
359 if (islpci_get_state(priv) == PRV_STATE_SLEEP
360 && powerstate == ISL38XX_PSM_ACTIVE_STATE)
361 islpci_set_state(priv, PRV_STATE_READY);
362
363 /* !sleep -> sleep */
364 if (islpci_get_state(priv) != PRV_STATE_SLEEP
365 && powerstate == ISL38XX_PSM_POWERSAVE_STATE)
366 islpci_set_state(priv, PRV_STATE_SLEEP);
367
368 /* unlock the interrupt handler */
369 spin_unlock(&priv->slock);
370
371 return IRQ_HANDLED;
372}
373
374/******************************************************************************
375 Network Interface Control & Statistical functions
376******************************************************************************/
377static int
378islpci_open(struct net_device *ndev)
379{
380 u32 rc;
381 islpci_private *priv = netdev_priv(ndev);
382
383 /* reset data structures, upload firmware and reset device */
384 rc = islpci_reset(priv,1);
385 if (rc) {
386 prism54_bring_down(priv);
387 return rc; /* Returns informative message */
388 }
389
390 netif_start_queue(ndev);
391/* netif_mark_up( ndev ); */
392
393 return 0;
394}
395
396static int
397islpci_close(struct net_device *ndev)
398{
399 islpci_private *priv = netdev_priv(ndev);
400
401 printk(KERN_DEBUG "%s: islpci_close ()\n", ndev->name);
402
403 netif_stop_queue(ndev);
404
405 return prism54_bring_down(priv);
406}
407
408static int
409prism54_bring_down(islpci_private *priv)
410{
411 void __iomem *device_base = priv->device_base;
412 u32 reg;
413 /* we are going to shutdown the device */
414 islpci_set_state(priv, PRV_STATE_PREBOOT);
415
416 /* disable all device interrupts in case they weren't */
417 isl38xx_disable_interrupts(priv->device_base);
418
419 /* For safety reasons, we may want to ensure that no DMA transfer is
420 * currently in progress by emptying the TX and RX queues. */
421
422 /* wait until interrupts have finished executing on other CPUs */
423 synchronize_irq(priv->pdev->irq);
424
425 reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
426 reg &= ~(ISL38XX_CTRL_STAT_RESET | ISL38XX_CTRL_STAT_RAMBOOT);
427 writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
428 wmb();
429 udelay(ISL38XX_WRITEIO_DELAY);
430
431 reg |= ISL38XX_CTRL_STAT_RESET;
432 writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
433 wmb();
434 udelay(ISL38XX_WRITEIO_DELAY);
435
436 /* clear the Reset bit */
437 reg &= ~ISL38XX_CTRL_STAT_RESET;
438 writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
439 wmb();
440
441 /* wait a while for the device to reset */
442 set_current_state(TASK_UNINTERRUPTIBLE);
443 schedule_timeout(50*HZ/1000);
444
445 return 0;
446}
447
448static int
449islpci_upload_fw(islpci_private *priv)
450{
451 islpci_state_t old_state;
452 u32 rc;
453
454 old_state = islpci_set_state(priv, PRV_STATE_BOOT);
455
456 printk(KERN_DEBUG "%s: uploading firmware...\n", priv->ndev->name);
457
458 rc = isl_upload_firmware(priv);
459 if (rc) {
460 /* error uploading the firmware */
461 printk(KERN_ERR "%s: could not upload firmware ('%s')\n",
462 priv->ndev->name, priv->firmware);
463
464 islpci_set_state(priv, old_state);
465 return rc;
466 }
467
468 printk(KERN_DEBUG "%s: firmware upload complete\n",
469 priv->ndev->name);
470
471 islpci_set_state(priv, PRV_STATE_POSTBOOT);
472
473 return 0;
474}
475
476static int
477islpci_reset_if(islpci_private *priv)
478{
479 long remaining;
480 int result = -ETIME;
481 int count;
482
483 DEFINE_WAIT(wait);
484 prepare_to_wait(&priv->reset_done, &wait, TASK_UNINTERRUPTIBLE);
485
486 /* now the last step is to reset the interface */
487 isl38xx_interface_reset(priv->device_base, priv->device_host_address);
488 islpci_set_state(priv, PRV_STATE_PREINIT);
489
490 for(count = 0; count < 2 && result; count++) {
491 /* The software reset acknowledge needs about 220 msec here.
492 * Be conservative and wait for up to one second. */
493
494 set_current_state(TASK_UNINTERRUPTIBLE);
495 remaining = schedule_timeout(HZ);
496
497 if(remaining > 0) {
498 result = 0;
499 break;
500 }
501
502 /* If we're here it's because our IRQ hasn't yet gone through.
503 * Retry a bit more...
504 */
505 printk(KERN_ERR "%s: no 'reset complete' IRQ seen - retrying\n",
506 priv->ndev->name);
507 }
508
509 finish_wait(&priv->reset_done, &wait);
510
511 if (result) {
512 printk(KERN_ERR "%s: interface reset failure\n", priv->ndev->name);
513 return result;
514 }
515
516 islpci_set_state(priv, PRV_STATE_INIT);
517
518 /* Now that the device is 100% up, let's allow
519 * for the other interrupts --
520 * NOTE: this is not *yet* true since we've only allowed the
521 * INIT interrupt on the IRQ line. We can perhaps poll
522 * the IRQ line until we know for sure the reset went through */
523 isl38xx_enable_common_interrupts(priv->device_base);
524
525 down_write(&priv->mib_sem);
526 result = mgt_commit(priv);
527 if (result) {
528 printk(KERN_ERR "%s: interface reset failure\n", priv->ndev->name);
529 up_write(&priv->mib_sem);
530 return result;
531 }
532 up_write(&priv->mib_sem);
533
534 islpci_set_state(priv, PRV_STATE_READY);
535
536 printk(KERN_DEBUG "%s: interface reset complete\n", priv->ndev->name);
537 return 0;
538}
539
540int
541islpci_reset(islpci_private *priv, int reload_firmware)
542{
543 isl38xx_control_block *cb = /* volatile not needed */
544 (isl38xx_control_block *) priv->control_block;
545 unsigned counter;
546 int rc;
547
548 if (reload_firmware)
549 islpci_set_state(priv, PRV_STATE_PREBOOT);
550 else
551 islpci_set_state(priv, PRV_STATE_POSTBOOT);
552
553 printk(KERN_DEBUG "%s: resetting device...\n", priv->ndev->name);
554
555 /* disable all device interrupts in case they weren't */
556 isl38xx_disable_interrupts(priv->device_base);
557
558 /* flush all management queues */
559 priv->index_mgmt_tx = 0;
560 priv->index_mgmt_rx = 0;
561
562 /* clear the indexes in the frame pointer */
563 for (counter = 0; counter < ISL38XX_CB_QCOUNT; counter++) {
564 cb->driver_curr_frag[counter] = cpu_to_le32(0);
565 cb->device_curr_frag[counter] = cpu_to_le32(0);
566 }
567
568 /* reset the mgmt receive queue */
569 for (counter = 0; counter < ISL38XX_CB_MGMT_QSIZE; counter++) {
570 isl38xx_fragment *frag = &cb->rx_data_mgmt[counter];
571 frag->size = cpu_to_le16(MGMT_FRAME_SIZE);
572 frag->flags = 0;
573 frag->address = cpu_to_le32(priv->mgmt_rx[counter].pci_addr);
574 }
575
576 for (counter = 0; counter < ISL38XX_CB_RX_QSIZE; counter++) {
577 cb->rx_data_low[counter].address =
578 cpu_to_le32((u32) priv->pci_map_rx_address[counter]);
579 }
580
581 /* since the receive queues are filled with empty fragments, now we can
582 * set the corresponding indexes in the Control Block */
583 priv->control_block->driver_curr_frag[ISL38XX_CB_RX_DATA_LQ] =
584 cpu_to_le32(ISL38XX_CB_RX_QSIZE);
585 priv->control_block->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] =
586 cpu_to_le32(ISL38XX_CB_MGMT_QSIZE);
587
588 /* reset the remaining real index registers and full flags */
589 priv->free_data_rx = 0;
590 priv->free_data_tx = 0;
591 priv->data_low_tx_full = 0;
592
593 if (reload_firmware) { /* Should we load the firmware ? */
594 /* now that the data structures are cleaned up, upload
595 * firmware and reset interface */
596 rc = islpci_upload_fw(priv);
597 if (rc) {
598 printk(KERN_ERR "%s: islpci_reset: failure\n",
599 priv->ndev->name);
600 return rc;
601 }
602 }
603
604 /* finally reset interface */
605 rc = islpci_reset_if(priv);
606 if (rc)
607 printk(KERN_ERR "prism54: Your card/socket may be faulty, or IRQ line too busy :(\n");
608 return rc;
609}
610
611static struct net_device_stats *
612islpci_statistics(struct net_device *ndev)
613{
614 islpci_private *priv = netdev_priv(ndev);
615
616#if VERBOSE > SHOW_ERROR_MESSAGES
617 DEBUG(SHOW_FUNCTION_CALLS, "islpci_statistics\n");
618#endif
619
620 return &priv->statistics;
621}
622
623/******************************************************************************
624 Network device configuration functions
625******************************************************************************/
626static int
627islpci_alloc_memory(islpci_private *priv)
628{
629 int counter;
630
631#if VERBOSE > SHOW_ERROR_MESSAGES
632 printk(KERN_DEBUG "islpci_alloc_memory\n");
633#endif
634
635 /* remap the PCI device base address to accessable */
636 if (!(priv->device_base =
637 ioremap(pci_resource_start(priv->pdev, 0),
638 ISL38XX_PCI_MEM_SIZE))) {
639 /* error in remapping the PCI device memory address range */
640 printk(KERN_ERR "PCI memory remapping failed \n");
641 return -1;
642 }
643
644 /* memory layout for consistent DMA region:
645 *
646 * Area 1: Control Block for the device interface
647 * Area 2: Power Save Mode Buffer for temporary frame storage. Be aware that
648 * the number of supported stations in the AP determines the minimal
649 * size of the buffer !
650 */
651
652 /* perform the allocation */
653 priv->driver_mem_address = pci_alloc_consistent(priv->pdev,
654 HOST_MEM_BLOCK,
655 &priv->
656 device_host_address);
657
658 if (!priv->driver_mem_address) {
659 /* error allocating the block of PCI memory */
660 printk(KERN_ERR "%s: could not allocate DMA memory, aborting!",
661 "prism54");
662 return -1;
663 }
664
665 /* assign the Control Block to the first address of the allocated area */
666 priv->control_block =
667 (isl38xx_control_block *) priv->driver_mem_address;
668
669 /* set the Power Save Buffer pointer directly behind the CB */
670 priv->device_psm_buffer =
671 priv->device_host_address + CONTROL_BLOCK_SIZE;
672
673 /* make sure all buffer pointers are initialized */
674 for (counter = 0; counter < ISL38XX_CB_QCOUNT; counter++) {
675 priv->control_block->driver_curr_frag[counter] = cpu_to_le32(0);
676 priv->control_block->device_curr_frag[counter] = cpu_to_le32(0);
677 }
678
679 priv->index_mgmt_rx = 0;
680 memset(priv->mgmt_rx, 0, sizeof(priv->mgmt_rx));
681 memset(priv->mgmt_tx, 0, sizeof(priv->mgmt_tx));
682
683 /* allocate rx queue for management frames */
684 if (islpci_mgmt_rx_fill(priv->ndev) < 0)
685 goto out_free;
686
687 /* now get the data rx skb's */
688 memset(priv->data_low_rx, 0, sizeof (priv->data_low_rx));
689 memset(priv->pci_map_rx_address, 0, sizeof (priv->pci_map_rx_address));
690
691 for (counter = 0; counter < ISL38XX_CB_RX_QSIZE; counter++) {
692 struct sk_buff *skb;
693
694 /* allocate an sk_buff for received data frames storage
695 * each frame on receive size consists of 1 fragment
696 * include any required allignment operations */
697 if (!(skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2))) {
698 /* error allocating an sk_buff structure elements */
699 printk(KERN_ERR "Error allocating skb.\n");
700 skb = NULL;
701 goto out_free;
702 }
703 skb_reserve(skb, (4 - (long) skb->data) & 0x03);
704 /* add the new allocated sk_buff to the buffer array */
705 priv->data_low_rx[counter] = skb;
706
707 /* map the allocated skb data area to pci */
708 priv->pci_map_rx_address[counter] =
709 pci_map_single(priv->pdev, (void *) skb->data,
710 MAX_FRAGMENT_SIZE_RX + 2,
711 PCI_DMA_FROMDEVICE);
712 if (!priv->pci_map_rx_address[counter]) {
713 /* error mapping the buffer to device
714 accessable memory address */
715 printk(KERN_ERR "failed to map skb DMA'able\n");
716 goto out_free;
717 }
718 }
719
720 prism54_acl_init(&priv->acl);
721 prism54_wpa_ie_init(priv);
722 if (mgt_init(priv))
723 goto out_free;
724
725 return 0;
726 out_free:
727 islpci_free_memory(priv);
728 return -1;
729}
730
731int
732islpci_free_memory(islpci_private *priv)
733{
734 int counter;
735
736 if (priv->device_base)
737 iounmap(priv->device_base);
738 priv->device_base = NULL;
739
740 /* free consistent DMA area... */
741 if (priv->driver_mem_address)
742 pci_free_consistent(priv->pdev, HOST_MEM_BLOCK,
743 priv->driver_mem_address,
744 priv->device_host_address);
745
746 /* clear some dangling pointers */
747 priv->driver_mem_address = NULL;
748 priv->device_host_address = 0;
749 priv->device_psm_buffer = 0;
750 priv->control_block = NULL;
751
752 /* clean up mgmt rx buffers */
753 for (counter = 0; counter < ISL38XX_CB_MGMT_QSIZE; counter++) {
754 struct islpci_membuf *buf = &priv->mgmt_rx[counter];
755 if (buf->pci_addr)
756 pci_unmap_single(priv->pdev, buf->pci_addr,
757 buf->size, PCI_DMA_FROMDEVICE);
758 buf->pci_addr = 0;
759 if (buf->mem)
760 kfree(buf->mem);
761 buf->size = 0;
762 buf->mem = NULL;
763 }
764
765 /* clean up data rx buffers */
766 for (counter = 0; counter < ISL38XX_CB_RX_QSIZE; counter++) {
767 if (priv->pci_map_rx_address[counter])
768 pci_unmap_single(priv->pdev,
769 priv->pci_map_rx_address[counter],
770 MAX_FRAGMENT_SIZE_RX + 2,
771 PCI_DMA_FROMDEVICE);
772 priv->pci_map_rx_address[counter] = 0;
773
774 if (priv->data_low_rx[counter])
775 dev_kfree_skb(priv->data_low_rx[counter]);
776 priv->data_low_rx[counter] = NULL;
777 }
778
779 /* Free the acces control list and the WPA list */
780 prism54_acl_clean(&priv->acl);
781 prism54_wpa_ie_clean(priv);
782 mgt_clean(priv);
783
784 return 0;
785}
786
787#if 0
788static void
789islpci_set_multicast_list(struct net_device *dev)
790{
791 /* put device into promisc mode and let network layer handle it */
792}
793#endif
794
795struct net_device *
796islpci_setup(struct pci_dev *pdev)
797{
798 islpci_private *priv;
799 struct net_device *ndev = alloc_etherdev(sizeof (islpci_private));
800
801 if (!ndev)
802 return ndev;
803
804 SET_MODULE_OWNER(ndev);
805 pci_set_drvdata(pdev, ndev);
806#if defined(SET_NETDEV_DEV)
807 SET_NETDEV_DEV(ndev, &pdev->dev);
808#endif
809
810 /* setup the structure members */
811 ndev->base_addr = pci_resource_start(pdev, 0);
812 ndev->irq = pdev->irq;
813
814 /* initialize the function pointers */
815 ndev->open = &islpci_open;
816 ndev->stop = &islpci_close;
817 ndev->get_stats = &islpci_statistics;
818 ndev->get_wireless_stats = &prism54_get_wireless_stats;
819 ndev->do_ioctl = &prism54_ioctl;
820 ndev->wireless_handlers =
821 (struct iw_handler_def *) &prism54_handler_def;
822
823 ndev->hard_start_xmit = &islpci_eth_transmit;
824 /* ndev->set_multicast_list = &islpci_set_multicast_list; */
825 ndev->addr_len = ETH_ALEN;
826 ndev->set_mac_address = &prism54_set_mac_address;
827 /* Get a non-zero dummy MAC address for nameif. Jean II */
828 memcpy(ndev->dev_addr, dummy_mac, 6);
829
830#ifdef HAVE_TX_TIMEOUT
831 ndev->watchdog_timeo = ISLPCI_TX_TIMEOUT;
832 ndev->tx_timeout = &islpci_eth_tx_timeout;
833#endif
834
835 /* allocate a private device structure to the network device */
836 priv = netdev_priv(ndev);
837 priv->ndev = ndev;
838 priv->pdev = pdev;
839 priv->monitor_type = ARPHRD_IEEE80211;
840 priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) ?
841 priv->monitor_type : ARPHRD_ETHER;
842
843#if WIRELESS_EXT > 16
844 /* Add pointers to enable iwspy support. */
845 priv->wireless_data.spy_data = &priv->spy_data;
846 ndev->wireless_data = &priv->wireless_data;
847#endif /* WIRELESS_EXT > 16 */
848
849 /* save the start and end address of the PCI memory area */
850 ndev->mem_start = (unsigned long) priv->device_base;
851 ndev->mem_end = ndev->mem_start + ISL38XX_PCI_MEM_SIZE;
852
853#if VERBOSE > SHOW_ERROR_MESSAGES
854 DEBUG(SHOW_TRACING, "PCI Memory remapped to 0x%p\n", priv->device_base);
855#endif
856
857 init_waitqueue_head(&priv->reset_done);
858
859 /* init the queue read locks, process wait counter */
860 sema_init(&priv->mgmt_sem, 1);
861 priv->mgmt_received = NULL;
862 init_waitqueue_head(&priv->mgmt_wqueue);
863 sema_init(&priv->stats_sem, 1);
864 spin_lock_init(&priv->slock);
865
866 /* init state machine with off#1 state */
867 priv->state = PRV_STATE_OFF;
868 priv->state_off = 1;
869
870 /* initialize workqueue's */
871 INIT_WORK(&priv->stats_work,
872 (void (*)(void *)) prism54_update_stats, priv);
873 priv->stats_timestamp = 0;
874
875 INIT_WORK(&priv->reset_task, islpci_do_reset_and_wake, priv);
876 priv->reset_task_pending = 0;
877
878 /* allocate various memory areas */
879 if (islpci_alloc_memory(priv))
880 goto do_free_netdev;
881
882 /* select the firmware file depending on the device id */
883 switch (pdev->device) {
884 case 0x3877:
885 strcpy(priv->firmware, ISL3877_IMAGE_FILE);
886 break;
887
888 case 0x3886:
889 strcpy(priv->firmware, ISL3886_IMAGE_FILE);
890 break;
891
892 default:
893 strcpy(priv->firmware, ISL3890_IMAGE_FILE);
894 break;
895 }
896
897 if (register_netdev(ndev)) {
898 DEBUG(SHOW_ERROR_MESSAGES,
899 "ERROR: register_netdev() failed \n");
900 goto do_islpci_free_memory;
901 }
902
903 return ndev;
904
905 do_islpci_free_memory:
906 islpci_free_memory(priv);
907 do_free_netdev:
908 pci_set_drvdata(pdev, NULL);
909 free_netdev(ndev);
910 priv = NULL;
911 return NULL;
912}
913
914islpci_state_t
915islpci_set_state(islpci_private *priv, islpci_state_t new_state)
916{
917 islpci_state_t old_state;
918
919 /* lock */
920 old_state = priv->state;
921
922 /* this means either a race condition or some serious error in
923 * the driver code */
924 switch (new_state) {
925 case PRV_STATE_OFF:
926 priv->state_off++;
927 default:
928 priv->state = new_state;
929 break;
930
931 case PRV_STATE_PREBOOT:
932 /* there are actually many off-states, enumerated by
933 * state_off */
934 if (old_state == PRV_STATE_OFF)
935 priv->state_off--;
936
937 /* only if hw_unavailable is zero now it means we either
938 * were in off#1 state, or came here from
939 * somewhere else */
940 if (!priv->state_off)
941 priv->state = new_state;
942 break;
943 };
944#if 0
945 printk(KERN_DEBUG "%s: state transition %d -> %d (off#%d)\n",
946 priv->ndev->name, old_state, new_state, priv->state_off);
947#endif
948
949 /* invariants */
950 BUG_ON(priv->state_off < 0);
951 BUG_ON(priv->state_off && (priv->state != PRV_STATE_OFF));
952 BUG_ON(!priv->state_off && (priv->state == PRV_STATE_OFF));
953
954 /* unlock */
955 return old_state;
956}
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
new file mode 100644
index 000000000000..32a1019f1b36
--- /dev/null
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -0,0 +1,216 @@
1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc.
4 * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
5 * Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
6 * Copyright (C) 2003 Aurelien Alleaume <slts@free.fr>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifndef _ISLPCI_DEV_H
24#define _ISLPCI_DEV_H
25
26#include <linux/version.h>
27#include <linux/netdevice.h>
28#include <linux/wireless.h>
29#include <net/iw_handler.h>
30#include <linux/list.h>
31
32#include "isl_38xx.h"
33#include "isl_oid.h"
34#include "islpci_mgt.h"
35
36/* some states might not be superflous and may be removed when
37 design is finalized (hvr) */
38typedef enum {
39 PRV_STATE_OFF = 0, /* this means hw_unavailable is != 0 */
40 PRV_STATE_PREBOOT, /* we are in a pre-boot state (empty RAM) */
41 PRV_STATE_BOOT, /* boot state (fw upload, run fw) */
42 PRV_STATE_POSTBOOT, /* after boot state, need reset now */
43 PRV_STATE_PREINIT, /* pre-init state */
44 PRV_STATE_INIT, /* init state (restore MIB backup to device) */
45 PRV_STATE_READY, /* driver&device are in operational state */
46 PRV_STATE_SLEEP /* device in sleep mode */
47} islpci_state_t;
48
49/* ACL using MAC address */
50struct mac_entry {
51 struct list_head _list;
52 char addr[ETH_ALEN];
53};
54
55struct islpci_acl {
56 enum { MAC_POLICY_OPEN=0, MAC_POLICY_ACCEPT=1, MAC_POLICY_REJECT=2 } policy;
57 struct list_head mac_list; /* a list of mac_entry */
58 int size; /* size of queue */
59 struct semaphore sem; /* accessed in ioctls and trap_work */
60};
61
62struct islpci_membuf {
63 int size; /* size of memory */
64 void *mem; /* address of memory as seen by CPU */
65 dma_addr_t pci_addr; /* address of memory as seen by device */
66};
67
68#define MAX_BSS_WPA_IE_COUNT 64
69#define MAX_WPA_IE_LEN 64
70struct islpci_bss_wpa_ie {
71 struct list_head list;
72 unsigned long last_update;
73 u8 bssid[ETH_ALEN];
74 u8 wpa_ie[MAX_WPA_IE_LEN];
75 size_t wpa_ie_len;
76
77};
78
79typedef struct {
80 spinlock_t slock; /* generic spinlock; */
81
82 u32 priv_oid;
83
84 /* our mib cache */
85 u32 iw_mode;
86 struct rw_semaphore mib_sem;
87 void **mib;
88 char nickname[IW_ESSID_MAX_SIZE+1];
89
90 /* Take care of the wireless stats */
91 struct work_struct stats_work;
92 struct semaphore stats_sem;
93 /* remember when we last updated the stats */
94 unsigned long stats_timestamp;
95 /* The first is accessed under semaphore locking.
96 * The second is the clean one we return to iwconfig.
97 */
98 struct iw_statistics local_iwstatistics;
99 struct iw_statistics iwstatistics;
100
101 struct iw_spy_data spy_data; /* iwspy support */
102
103#if WIRELESS_EXT > 16
104 struct iw_public_data wireless_data;
105#endif /* WIRELESS_EXT > 16 */
106
107 int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
108
109 struct islpci_acl acl;
110
111 /* PCI bus allocation & configuration members */
112 struct pci_dev *pdev; /* PCI structure information */
113 char firmware[33];
114
115 void __iomem *device_base; /* ioremapped device base address */
116
117 /* consistent DMA region */
118 void *driver_mem_address; /* base DMA address */
119 dma_addr_t device_host_address; /* base DMA address (bus address) */
120 dma_addr_t device_psm_buffer; /* host memory for PSM buffering (bus address) */
121
122 /* our network_device structure */
123 struct net_device *ndev;
124
125 /* device queue interface members */
126 struct isl38xx_cb *control_block; /* device control block
127 (== driver_mem_address!) */
128
129 /* Each queue has three indexes:
130 * free/index_mgmt/data_rx/tx (called index, see below),
131 * driver_curr_frag, and device_curr_frag (in the control block)
132 * All indexes are ever-increasing, but interpreted modulo the
133 * device queue size when used.
134 * index <= device_curr_frag <= driver_curr_frag at all times
135 * For rx queues, [index, device_curr_frag) contains fragments
136 * that the interrupt processing needs to handle (owned by driver).
137 * [device_curr_frag, driver_curr_frag) is the free space in the
138 * rx queue, waiting for data (owned by device). The driver
139 * increments driver_curr_frag to indicate to the device that more
140 * buffers are available.
141 * If device_curr_frag == driver_curr_frag, no more rx buffers are
142 * available, and the rx DMA engine of the device is halted.
143 * For tx queues, [index, device_curr_frag) contains fragments
144 * where tx is done; they need to be freed (owned by driver).
145 * [device_curr_frag, driver_curr_frag) contains the frames
146 * that are being transferred (owned by device). The driver
147 * increments driver_curr_frag to indicate that more tx work
148 * needs to be done.
149 */
150 u32 index_mgmt_rx; /* real index mgmt rx queue */
151 u32 index_mgmt_tx; /* read index mgmt tx queue */
152 u32 free_data_rx; /* free pointer data rx queue */
153 u32 free_data_tx; /* free pointer data tx queue */
154 u32 data_low_tx_full; /* full detected flag */
155
156 /* frame memory buffers for the device queues */
157 struct islpci_membuf mgmt_tx[ISL38XX_CB_MGMT_QSIZE];
158 struct islpci_membuf mgmt_rx[ISL38XX_CB_MGMT_QSIZE];
159 struct sk_buff *data_low_tx[ISL38XX_CB_TX_QSIZE];
160 struct sk_buff *data_low_rx[ISL38XX_CB_RX_QSIZE];
161 dma_addr_t pci_map_tx_address[ISL38XX_CB_TX_QSIZE];
162 dma_addr_t pci_map_rx_address[ISL38XX_CB_RX_QSIZE];
163
164 /* driver network interface members */
165 struct net_device_stats statistics;
166
167 /* wait for a reset interrupt */
168 wait_queue_head_t reset_done;
169
170 /* used by islpci_mgt_transaction */
171 struct semaphore mgmt_sem; /* serialize access to mailbox and wqueue */
172 struct islpci_mgmtframe *mgmt_received; /* mbox for incoming frame */
173 wait_queue_head_t mgmt_wqueue; /* waitqueue for mbox */
174
175 /* state machine */
176 islpci_state_t state;
177 int state_off; /* enumeration of off-state, if 0 then
178 * we're not in any off-state */
179
180 /* WPA stuff */
181 int wpa; /* WPA mode enabled */
182 struct list_head bss_wpa_list;
183 int num_bss_wpa;
184 struct semaphore wpa_sem;
185
186 struct work_struct reset_task;
187 int reset_task_pending;
188} islpci_private;
189
190static inline islpci_state_t
191islpci_get_state(islpci_private *priv)
192{
193 /* lock */
194 return priv->state;
195 /* unlock */
196}
197
198islpci_state_t islpci_set_state(islpci_private *priv, islpci_state_t new_state);
199
200#define ISLPCI_TX_TIMEOUT (2*HZ)
201
202irqreturn_t islpci_interrupt(int, void *, struct pt_regs *);
203
204int prism54_post_setup(islpci_private *, int);
205int islpci_reset(islpci_private *, int);
206
207static inline void
208islpci_trigger(islpci_private *priv)
209{
210 isl38xx_trigger_device(islpci_get_state(priv) == PRV_STATE_SLEEP,
211 priv->device_base);
212}
213
214int islpci_free_memory(islpci_private *);
215struct net_device *islpci_setup(struct pci_dev *);
216#endif /* _ISLPCI_DEV_H */
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
new file mode 100644
index 000000000000..5952e9960499
--- /dev/null
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -0,0 +1,519 @@
1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc.
4 * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19
20#include <linux/version.h>
21#include <linux/module.h>
22
23#include <linux/pci.h>
24#include <linux/delay.h>
25#include <linux/netdevice.h>
26#include <linux/etherdevice.h>
27#include <linux/if_arp.h>
28
29#include "prismcompat.h"
30#include "isl_38xx.h"
31#include "islpci_eth.h"
32#include "islpci_mgt.h"
33#include "oid_mgt.h"
34
35/******************************************************************************
36 Network Interface functions
37******************************************************************************/
38void
39islpci_eth_cleanup_transmit(islpci_private *priv,
40 isl38xx_control_block *control_block)
41{
42 struct sk_buff *skb;
43 u32 index;
44
45 /* compare the control block read pointer with the free pointer */
46 while (priv->free_data_tx !=
47 le32_to_cpu(control_block->
48 device_curr_frag[ISL38XX_CB_TX_DATA_LQ])) {
49 /* read the index of the first fragment to be freed */
50 index = priv->free_data_tx % ISL38XX_CB_TX_QSIZE;
51
52 /* check for holes in the arrays caused by multi fragment frames
53 * searching for the last fragment of a frame */
54 if (priv->pci_map_tx_address[index] != (dma_addr_t) NULL) {
55 /* entry is the last fragment of a frame
56 * free the skb structure and unmap pci memory */
57 skb = priv->data_low_tx[index];
58
59#if VERBOSE > SHOW_ERROR_MESSAGES
60 DEBUG(SHOW_TRACING,
61 "cleanup skb %p skb->data %p skb->len %u truesize %u\n ",
62 skb, skb->data, skb->len, skb->truesize);
63#endif
64
65 pci_unmap_single(priv->pdev,
66 priv->pci_map_tx_address[index],
67 skb->len, PCI_DMA_TODEVICE);
68 dev_kfree_skb_irq(skb);
69 skb = NULL;
70 }
71 /* increment the free data low queue pointer */
72 priv->free_data_tx++;
73 }
74}
75
76int
77islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
78{
79 islpci_private *priv = netdev_priv(ndev);
80 isl38xx_control_block *cb = priv->control_block;
81 u32 index;
82 dma_addr_t pci_map_address;
83 int frame_size;
84 isl38xx_fragment *fragment;
85 int offset;
86 struct sk_buff *newskb;
87 int newskb_offset;
88 unsigned long flags;
89 unsigned char wds_mac[6];
90 u32 curr_frag;
91 int err = 0;
92
93#if VERBOSE > SHOW_ERROR_MESSAGES
94 DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_transmit \n");
95#endif
96
97 /* lock the driver code */
98 spin_lock_irqsave(&priv->slock, flags);
99
100 /* determine the amount of fragments needed to store the frame */
101
102 frame_size = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
103 if (init_wds)
104 frame_size += 6;
105
106 /* check whether the destination queue has enough fragments for the frame */
107 curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ]);
108 if (unlikely(curr_frag - priv->free_data_tx >= ISL38XX_CB_TX_QSIZE)) {
109 printk(KERN_ERR "%s: transmit device queue full when awake\n",
110 ndev->name);
111 netif_stop_queue(ndev);
112
113 /* trigger the device */
114 isl38xx_w32_flush(priv->device_base, ISL38XX_DEV_INT_UPDATE,
115 ISL38XX_DEV_INT_REG);
116 udelay(ISL38XX_WRITEIO_DELAY);
117
118 err = -EBUSY;
119 goto drop_free;
120 }
121 /* Check alignment and WDS frame formatting. The start of the packet should
122 * be aligned on a 4-byte boundary. If WDS is enabled add another 6 bytes
123 * and add WDS address information */
124 if (likely(((long) skb->data & 0x03) | init_wds)) {
125 /* get the number of bytes to add and re-allign */
126 offset = (4 - (long) skb->data) & 0x03;
127 offset += init_wds ? 6 : 0;
128
129 /* check whether the current skb can be used */
130 if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
131 unsigned char *src = skb->data;
132
133#if VERBOSE > SHOW_ERROR_MESSAGES
134 DEBUG(SHOW_TRACING, "skb offset %i wds %i\n", offset,
135 init_wds);
136#endif
137
138 /* align the buffer on 4-byte boundary */
139 skb_reserve(skb, (4 - (long) skb->data) & 0x03);
140 if (init_wds) {
141 /* wds requires an additional address field of 6 bytes */
142 skb_put(skb, 6);
143#ifdef ISLPCI_ETH_DEBUG
144 printk("islpci_eth_transmit:wds_mac\n");
145#endif
146 memmove(skb->data + 6, src, skb->len);
147 memcpy(skb->data, wds_mac, 6);
148 } else {
149 memmove(skb->data, src, skb->len);
150 }
151
152#if VERBOSE > SHOW_ERROR_MESSAGES
153 DEBUG(SHOW_TRACING, "memmove %p %p %i \n", skb->data,
154 src, skb->len);
155#endif
156 } else {
157 newskb =
158 dev_alloc_skb(init_wds ? skb->len + 6 : skb->len);
159 if (unlikely(newskb == NULL)) {
160 printk(KERN_ERR "%s: Cannot allocate skb\n",
161 ndev->name);
162 err = -ENOMEM;
163 goto drop_free;
164 }
165 newskb_offset = (4 - (long) newskb->data) & 0x03;
166
167 /* Check if newskb->data is aligned */
168 if (newskb_offset)
169 skb_reserve(newskb, newskb_offset);
170
171 skb_put(newskb, init_wds ? skb->len + 6 : skb->len);
172 if (init_wds) {
173 memcpy(newskb->data + 6, skb->data, skb->len);
174 memcpy(newskb->data, wds_mac, 6);
175#ifdef ISLPCI_ETH_DEBUG
176 printk("islpci_eth_transmit:wds_mac\n");
177#endif
178 } else
179 memcpy(newskb->data, skb->data, skb->len);
180
181#if VERBOSE > SHOW_ERROR_MESSAGES
182 DEBUG(SHOW_TRACING, "memcpy %p %p %i wds %i\n",
183 newskb->data, skb->data, skb->len, init_wds);
184#endif
185
186 newskb->dev = skb->dev;
187 dev_kfree_skb(skb);
188 skb = newskb;
189 }
190 }
191 /* display the buffer contents for debugging */
192#if VERBOSE > SHOW_ERROR_MESSAGES
193 DEBUG(SHOW_BUFFER_CONTENTS, "\ntx %p ", skb->data);
194 display_buffer((char *) skb->data, skb->len);
195#endif
196
197 /* map the skb buffer to pci memory for DMA operation */
198 pci_map_address = pci_map_single(priv->pdev,
199 (void *) skb->data, skb->len,
200 PCI_DMA_TODEVICE);
201 if (unlikely(pci_map_address == 0)) {
202 printk(KERN_WARNING "%s: cannot map buffer to PCI\n",
203 ndev->name);
204
205 err = -EIO;
206 goto drop_free;
207 }
208 /* Place the fragment in the control block structure. */
209 index = curr_frag % ISL38XX_CB_TX_QSIZE;
210 fragment = &cb->tx_data_low[index];
211
212 priv->pci_map_tx_address[index] = pci_map_address;
213 /* store the skb address for future freeing */
214 priv->data_low_tx[index] = skb;
215 /* set the proper fragment start address and size information */
216 fragment->size = cpu_to_le16(frame_size);
217 fragment->flags = cpu_to_le16(0); /* set to 1 if more fragments */
218 fragment->address = cpu_to_le32(pci_map_address);
219 curr_frag++;
220
221 /* The fragment address in the control block must have been
222 * written before announcing the frame buffer to device. */
223 wmb();
224 cb->driver_curr_frag[ISL38XX_CB_TX_DATA_LQ] = cpu_to_le32(curr_frag);
225
226 if (curr_frag - priv->free_data_tx + ISL38XX_MIN_QTHRESHOLD
227 > ISL38XX_CB_TX_QSIZE) {
228 /* stop sends from upper layers */
229 netif_stop_queue(ndev);
230
231 /* set the full flag for the transmission queue */
232 priv->data_low_tx_full = 1;
233 }
234
235 /* trigger the device */
236 islpci_trigger(priv);
237
238 /* unlock the driver code */
239 spin_unlock_irqrestore(&priv->slock, flags);
240
241 /* set the transmission time */
242 ndev->trans_start = jiffies;
243 priv->statistics.tx_packets++;
244 priv->statistics.tx_bytes += skb->len;
245
246 return 0;
247
248 drop_free:
249 /* free the skbuf structure before aborting */
250 dev_kfree_skb(skb);
251 skb = NULL;
252
253 priv->statistics.tx_dropped++;
254 spin_unlock_irqrestore(&priv->slock, flags);
255 return err;
256}
257
258static inline int
259islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb)
260{
261 /* The card reports full 802.11 packets but with a 20 bytes
262 * header and without the FCS. But there a is a bit that
263 * indicates if the packet is corrupted :-) */
264 struct rfmon_header *hdr = (struct rfmon_header *) (*skb)->data;
265 if (hdr->flags & 0x01)
266 /* This one is bad. Drop it ! */
267 return -1;
268 if (priv->ndev->type == ARPHRD_IEEE80211_PRISM) {
269 struct avs_80211_1_header *avs;
270 /* extract the relevant data from the header */
271 u32 clock = le32_to_cpu(hdr->clock);
272 u8 rate = hdr->rate;
273 u16 freq = le16_to_cpu(hdr->freq);
274 u8 rssi = hdr->rssi;
275
276 skb_pull(*skb, sizeof (struct rfmon_header));
277
278 if (skb_headroom(*skb) < sizeof (struct avs_80211_1_header)) {
279 struct sk_buff *newskb = skb_copy_expand(*skb,
280 sizeof (struct
281 avs_80211_1_header),
282 0, GFP_ATOMIC);
283 if (newskb) {
284 dev_kfree_skb_irq(*skb);
285 *skb = newskb;
286 } else
287 return -1;
288 /* This behavior is not very subtile... */
289 }
290
291 /* make room for the new header and fill it. */
292 avs =
293 (struct avs_80211_1_header *) skb_push(*skb,
294 sizeof (struct
295 avs_80211_1_header));
296
297 avs->version = cpu_to_be32(P80211CAPTURE_VERSION);
298 avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header));
299 avs->mactime = cpu_to_be64(le64_to_cpu(clock));
300 avs->hosttime = cpu_to_be64(jiffies);
301 avs->phytype = cpu_to_be32(6); /*OFDM: 6 for (g), 8 for (a) */
302 avs->channel = cpu_to_be32(channel_of_freq(freq));
303 avs->datarate = cpu_to_be32(rate * 5);
304 avs->antenna = cpu_to_be32(0); /*unknown */
305 avs->priority = cpu_to_be32(0); /*unknown */
306 avs->ssi_type = cpu_to_be32(3); /*2: dBm, 3: raw RSSI */
307 avs->ssi_signal = cpu_to_be32(rssi & 0x7f);
308 avs->ssi_noise = cpu_to_be32(priv->local_iwstatistics.qual.noise); /*better than 'undefined', I assume */
309 avs->preamble = cpu_to_be32(0); /*unknown */
310 avs->encoding = cpu_to_be32(0); /*unknown */
311 } else
312 skb_pull(*skb, sizeof (struct rfmon_header));
313
314 (*skb)->protocol = htons(ETH_P_802_2);
315 (*skb)->mac.raw = (*skb)->data;
316 (*skb)->pkt_type = PACKET_OTHERHOST;
317
318 return 0;
319}
320
321int
322islpci_eth_receive(islpci_private *priv)
323{
324 struct net_device *ndev = priv->ndev;
325 isl38xx_control_block *control_block = priv->control_block;
326 struct sk_buff *skb;
327 u16 size;
328 u32 index, offset;
329 unsigned char *src;
330 int discard = 0;
331
332#if VERBOSE > SHOW_ERROR_MESSAGES
333 DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_receive \n");
334#endif
335
336 /* the device has written an Ethernet frame in the data area
337 * of the sk_buff without updating the structure, do it now */
338 index = priv->free_data_rx % ISL38XX_CB_RX_QSIZE;
339 size = le16_to_cpu(control_block->rx_data_low[index].size);
340 skb = priv->data_low_rx[index];
341 offset = ((unsigned long)
342 le32_to_cpu(control_block->rx_data_low[index].address) -
343 (unsigned long) skb->data) & 3;
344
345#if VERBOSE > SHOW_ERROR_MESSAGES
346 DEBUG(SHOW_TRACING,
347 "frq->addr %x skb->data %p skb->len %u offset %u truesize %u\n ",
348 control_block->rx_data_low[priv->free_data_rx].address, skb->data,
349 skb->len, offset, skb->truesize);
350#endif
351
352 /* delete the streaming DMA mapping before processing the skb */
353 pci_unmap_single(priv->pdev,
354 priv->pci_map_rx_address[index],
355 MAX_FRAGMENT_SIZE_RX + 2, PCI_DMA_FROMDEVICE);
356
357 /* update the skb structure and allign the buffer */
358 skb_put(skb, size);
359 if (offset) {
360 /* shift the buffer allocation offset bytes to get the right frame */
361 skb_pull(skb, 2);
362 skb_put(skb, 2);
363 }
364#if VERBOSE > SHOW_ERROR_MESSAGES
365 /* display the buffer contents for debugging */
366 DEBUG(SHOW_BUFFER_CONTENTS, "\nrx %p ", skb->data);
367 display_buffer((char *) skb->data, skb->len);
368#endif
369
370 /* check whether WDS is enabled and whether the data frame is a WDS frame */
371
372 if (init_wds) {
373 /* WDS enabled, check for the wds address on the first 6 bytes of the buffer */
374 src = skb->data + 6;
375 memmove(skb->data, src, skb->len - 6);
376 skb_trim(skb, skb->len - 6);
377 }
378#if VERBOSE > SHOW_ERROR_MESSAGES
379 DEBUG(SHOW_TRACING, "Fragment size %i in skb at %p\n", size, skb);
380 DEBUG(SHOW_TRACING, "Skb data at %p, length %i\n", skb->data, skb->len);
381
382 /* display the buffer contents for debugging */
383 DEBUG(SHOW_BUFFER_CONTENTS, "\nrx %p ", skb->data);
384 display_buffer((char *) skb->data, skb->len);
385#endif
386
387 /* do some additional sk_buff and network layer parameters */
388 skb->dev = ndev;
389
390 /* take care of monitor mode and spy monitoring. */
391 if (unlikely(priv->iw_mode == IW_MODE_MONITOR))
392 discard = islpci_monitor_rx(priv, &skb);
393 else {
394 if (unlikely(skb->data[2 * ETH_ALEN] == 0)) {
395 /* The packet has a rx_annex. Read it for spy monitoring, Then
396 * remove it, while keeping the 2 leading MAC addr.
397 */
398 struct iw_quality wstats;
399 struct rx_annex_header *annex =
400 (struct rx_annex_header *) skb->data;
401 wstats.level = annex->rfmon.rssi;
402 /* The noise value can be a bit outdated if nobody's
403 * reading wireless stats... */
404 wstats.noise = priv->local_iwstatistics.qual.noise;
405 wstats.qual = wstats.level - wstats.noise;
406 wstats.updated = 0x07;
407 /* Update spy records */
408 wireless_spy_update(ndev, annex->addr2, &wstats);
409
410 memcpy(skb->data + sizeof (struct rfmon_header),
411 skb->data, 2 * ETH_ALEN);
412 skb_pull(skb, sizeof (struct rfmon_header));
413 }
414 skb->protocol = eth_type_trans(skb, ndev);
415 }
416 skb->ip_summed = CHECKSUM_NONE;
417 priv->statistics.rx_packets++;
418 priv->statistics.rx_bytes += size;
419
420 /* deliver the skb to the network layer */
421#ifdef ISLPCI_ETH_DEBUG
422 printk
423 ("islpci_eth_receive:netif_rx %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
424 skb->data[0], skb->data[1], skb->data[2], skb->data[3],
425 skb->data[4], skb->data[5]);
426#endif
427 if (unlikely(discard)) {
428 dev_kfree_skb_irq(skb);
429 skb = NULL;
430 } else
431 netif_rx(skb);
432
433 /* increment the read index for the rx data low queue */
434 priv->free_data_rx++;
435
436 /* add one or more sk_buff structures */
437 while (index =
438 le32_to_cpu(control_block->
439 driver_curr_frag[ISL38XX_CB_RX_DATA_LQ]),
440 index - priv->free_data_rx < ISL38XX_CB_RX_QSIZE) {
441 /* allocate an sk_buff for received data frames storage
442 * include any required allignment operations */
443 skb = dev_alloc_skb(MAX_FRAGMENT_SIZE_RX + 2);
444 if (unlikely(skb == NULL)) {
445 /* error allocating an sk_buff structure elements */
446 DEBUG(SHOW_ERROR_MESSAGES, "Error allocating skb \n");
447 break;
448 }
449 skb_reserve(skb, (4 - (long) skb->data) & 0x03);
450 /* store the new skb structure pointer */
451 index = index % ISL38XX_CB_RX_QSIZE;
452 priv->data_low_rx[index] = skb;
453
454#if VERBOSE > SHOW_ERROR_MESSAGES
455 DEBUG(SHOW_TRACING,
456 "new alloc skb %p skb->data %p skb->len %u index %u truesize %u\n ",
457 skb, skb->data, skb->len, index, skb->truesize);
458#endif
459
460 /* set the streaming DMA mapping for proper PCI bus operation */
461 priv->pci_map_rx_address[index] =
462 pci_map_single(priv->pdev, (void *) skb->data,
463 MAX_FRAGMENT_SIZE_RX + 2,
464 PCI_DMA_FROMDEVICE);
465 if (unlikely(priv->pci_map_rx_address[index] == (dma_addr_t) NULL)) {
466 /* error mapping the buffer to device accessable memory address */
467 DEBUG(SHOW_ERROR_MESSAGES,
468 "Error mapping DMA address\n");
469
470 /* free the skbuf structure before aborting */
471 dev_kfree_skb_irq((struct sk_buff *) skb);
472 skb = NULL;
473 break;
474 }
475 /* update the fragment address */
476 control_block->rx_data_low[index].address = cpu_to_le32((u32)
477 priv->
478 pci_map_rx_address
479 [index]);
480 wmb();
481
482 /* increment the driver read pointer */
483 add_le32p((u32 *) &control_block->
484 driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1);
485 }
486
487 /* trigger the device */
488 islpci_trigger(priv);
489
490 return 0;
491}
492
493void
494islpci_do_reset_and_wake(void *data)
495{
496 islpci_private *priv = (islpci_private *) data;
497 islpci_reset(priv, 1);
498 netif_wake_queue(priv->ndev);
499 priv->reset_task_pending = 0;
500}
501
502void
503islpci_eth_tx_timeout(struct net_device *ndev)
504{
505 islpci_private *priv = netdev_priv(ndev);
506 struct net_device_stats *statistics = &priv->statistics;
507
508 /* increment the transmit error counter */
509 statistics->tx_errors++;
510
511 printk(KERN_WARNING "%s: tx_timeout", ndev->name);
512 if (!priv->reset_task_pending) {
513 priv->reset_task_pending = 1;
514 printk(", scheduling a reset");
515 netif_stop_queue(ndev);
516 schedule_work(&priv->reset_task);
517 }
518 printk("\n");
519}
diff --git a/drivers/net/wireless/prism54/islpci_eth.h b/drivers/net/wireless/prism54/islpci_eth.h
new file mode 100644
index 000000000000..bc9d7a60b8d6
--- /dev/null
+++ b/drivers/net/wireless/prism54/islpci_eth.h
@@ -0,0 +1,73 @@
1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19
20#ifndef _ISLPCI_ETH_H
21#define _ISLPCI_ETH_H
22
23#include "isl_38xx.h"
24#include "islpci_dev.h"
25
26struct rfmon_header {
27 u16 unk0; /* = 0x0000 */
28 u16 length; /* = 0x1400 */
29 u32 clock; /* 1MHz clock */
30 u8 flags;
31 u8 unk1;
32 u8 rate;
33 u8 unk2;
34 u16 freq;
35 u16 unk3;
36 u8 rssi;
37 u8 padding[3];
38} __attribute__ ((packed));
39
40struct rx_annex_header {
41 u8 addr1[ETH_ALEN];
42 u8 addr2[ETH_ALEN];
43 struct rfmon_header rfmon;
44} __attribute__ ((packed));
45
46/* wlan-ng (and hopefully others) AVS header, version one. Fields in
47 * network byte order. */
48#define P80211CAPTURE_VERSION 0x80211001
49
50struct avs_80211_1_header {
51 uint32_t version;
52 uint32_t length;
53 uint64_t mactime;
54 uint64_t hosttime;
55 uint32_t phytype;
56 uint32_t channel;
57 uint32_t datarate;
58 uint32_t antenna;
59 uint32_t priority;
60 uint32_t ssi_type;
61 int32_t ssi_signal;
62 int32_t ssi_noise;
63 uint32_t preamble;
64 uint32_t encoding;
65};
66
67void islpci_eth_cleanup_transmit(islpci_private *, isl38xx_control_block *);
68int islpci_eth_transmit(struct sk_buff *, struct net_device *);
69int islpci_eth_receive(islpci_private *);
70void islpci_eth_tx_timeout(struct net_device *);
71void islpci_do_reset_and_wake(void *data);
72
73#endif /* _ISL_GEN_H */
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
new file mode 100644
index 000000000000..efd4d213ac3d
--- /dev/null
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -0,0 +1,339 @@
1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc.
4 * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <linux/version.h>
22#include <linux/module.h>
23#include <linux/pci.h>
24#include <linux/delay.h>
25#include <linux/init.h> /* For __init, __exit */
26
27#include "prismcompat.h"
28#include "islpci_dev.h"
29#include "islpci_mgt.h" /* for pc_debug */
30#include "isl_oid.h"
31
32#define DRV_NAME "prism54"
33#define DRV_VERSION "1.2"
34
35MODULE_AUTHOR("[Intersil] R.Bastings and W.Termorshuizen, The prism54.org Development Team <prism54-devel@prism54.org>");
36MODULE_DESCRIPTION("The Prism54 802.11 Wireless LAN adapter");
37MODULE_LICENSE("GPL");
38
39static int init_pcitm = 0;
40module_param(init_pcitm, int, 0);
41
42/* In this order: vendor, device, subvendor, subdevice, class, class_mask,
43 * driver_data
44 * If you have an update for this please contact prism54-devel@prism54.org
45 * The latest list can be found at http://prism54.org/supported_cards.php */
46static const struct pci_device_id prism54_id_tbl[] = {
47 /* Intersil PRISM Duette/Prism GT Wireless LAN adapter */
48 {
49 0x1260, 0x3890,
50 PCI_ANY_ID, PCI_ANY_ID,
51 0, 0, 0
52 },
53
54 /* 3COM 3CRWE154G72 Wireless LAN adapter */
55 {
56 0x10b7, 0x6001,
57 PCI_ANY_ID, PCI_ANY_ID,
58 0, 0, 0
59 },
60
61 /* Intersil PRISM Indigo Wireless LAN adapter */
62 {
63 0x1260, 0x3877,
64 PCI_ANY_ID, PCI_ANY_ID,
65 0, 0, 0
66 },
67
68 /* Intersil PRISM Javelin/Xbow Wireless LAN adapter */
69 {
70 0x1260, 0x3886,
71 PCI_ANY_ID, PCI_ANY_ID,
72 0, 0, 0
73 },
74
75 /* End of list */
76 {0,0,0,0,0,0,0}
77};
78
79/* register the device with the Hotplug facilities of the kernel */
80MODULE_DEVICE_TABLE(pci, prism54_id_tbl);
81
82static int prism54_probe(struct pci_dev *, const struct pci_device_id *);
83static void prism54_remove(struct pci_dev *);
84static int prism54_suspend(struct pci_dev *, u32 state);
85static int prism54_resume(struct pci_dev *);
86
87static struct pci_driver prism54_driver = {
88 .name = DRV_NAME,
89 .id_table = prism54_id_tbl,
90 .probe = prism54_probe,
91 .remove = prism54_remove,
92 .suspend = prism54_suspend,
93 .resume = prism54_resume,
94 /* .enable_wake ; we don't support this yet */
95};
96
97/******************************************************************************
98 Module initialization functions
99******************************************************************************/
100
101int
102prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
103{
104 struct net_device *ndev;
105 u8 latency_tmr;
106 u32 mem_addr;
107 islpci_private *priv;
108 int rvalue;
109
110 /* Enable the pci device */
111 if (pci_enable_device(pdev)) {
112 printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME);
113 return -ENODEV;
114 }
115
116 /* check whether the latency timer is set correctly */
117 pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_tmr);
118#if VERBOSE > SHOW_ERROR_MESSAGES
119 DEBUG(SHOW_TRACING, "latency timer: %x\n", latency_tmr);
120#endif
121 if (latency_tmr < PCIDEVICE_LATENCY_TIMER_MIN) {
122 /* set the latency timer */
123 pci_write_config_byte(pdev, PCI_LATENCY_TIMER,
124 PCIDEVICE_LATENCY_TIMER_VAL);
125 }
126
127 /* enable PCI DMA */
128 if (pci_set_dma_mask(pdev, 0xffffffff)) {
129 printk(KERN_ERR "%s: 32-bit PCI DMA not supported", DRV_NAME);
130 goto do_pci_disable_device;
131 }
132
133 /* 0x40 is the programmable timer to configure the response timeout (TRDY_TIMEOUT)
134 * 0x41 is the programmable timer to configure the retry timeout (RETRY_TIMEOUT)
135 * The RETRY_TIMEOUT is used to set the number of retries that the core, as a
136 * Master, will perform before abandoning a cycle. The default value for
137 * RETRY_TIMEOUT is 0x80, which far exceeds the PCI 2.1 requirement for new
138 * devices. A write of zero to the RETRY_TIMEOUT register disables this
139 * function to allow use with any non-compliant legacy devices that may
140 * execute more retries.
141 *
142 * Writing zero to both these two registers will disable both timeouts and
143 * *can* solve problems caused by devices that are slow to respond.
144 * Make this configurable - MSW
145 */
146 if ( init_pcitm >= 0 ) {
147 pci_write_config_byte(pdev, 0x40, (u8)init_pcitm);
148 pci_write_config_byte(pdev, 0x41, (u8)init_pcitm);
149 } else {
150 printk(KERN_INFO "PCI TRDY/RETRY unchanged\n");
151 }
152
153 /* request the pci device I/O regions */
154 rvalue = pci_request_regions(pdev, DRV_NAME);
155 if (rvalue) {
156 printk(KERN_ERR "%s: pci_request_regions failure (rc=%d)\n",
157 DRV_NAME, rvalue);
158 goto do_pci_disable_device;
159 }
160
161 /* check if the memory window is indeed set */
162 rvalue = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &mem_addr);
163 if (rvalue || !mem_addr) {
164 printk(KERN_ERR "%s: PCI device memory region not configured; fix your BIOS or CardBus bridge/drivers\n",
165 DRV_NAME);
166 goto do_pci_release_regions;
167 }
168
169 /* enable PCI bus-mastering */
170 DEBUG(SHOW_TRACING, "%s: pci_set_master(pdev)\n", DRV_NAME);
171 pci_set_master(pdev);
172
173 /* enable MWI */
174 pci_set_mwi(pdev);
175
176 /* setup the network device interface and its structure */
177 if (!(ndev = islpci_setup(pdev))) {
178 /* error configuring the driver as a network device */
179 printk(KERN_ERR "%s: could not configure network device\n",
180 DRV_NAME);
181 goto do_pci_release_regions;
182 }
183
184 priv = netdev_priv(ndev);
185 islpci_set_state(priv, PRV_STATE_PREBOOT); /* we are attempting to boot */
186
187 /* card is in unknown state yet, might have some interrupts pending */
188 isl38xx_disable_interrupts(priv->device_base);
189
190 /* request for the interrupt before uploading the firmware */
191 rvalue = request_irq(pdev->irq, &islpci_interrupt,
192 SA_SHIRQ, ndev->name, priv);
193
194 if (rvalue) {
195 /* error, could not hook the handler to the irq */
196 printk(KERN_ERR "%s: could not install IRQ handler\n",
197 ndev->name);
198 goto do_unregister_netdev;
199 }
200
201 /* firmware upload is triggered in islpci_open */
202
203 return 0;
204
205 do_unregister_netdev:
206 unregister_netdev(ndev);
207 islpci_free_memory(priv);
208 pci_set_drvdata(pdev, NULL);
209 free_netdev(ndev);
210 priv = NULL;
211 do_pci_release_regions:
212 pci_release_regions(pdev);
213 do_pci_disable_device:
214 pci_disable_device(pdev);
215 return -EIO;
216}
217
218/* set by cleanup_module */
219static volatile int __in_cleanup_module = 0;
220
221/* this one removes one(!!) instance only */
222void
223prism54_remove(struct pci_dev *pdev)
224{
225 struct net_device *ndev = pci_get_drvdata(pdev);
226 islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
227 BUG_ON(!priv);
228
229 if (!__in_cleanup_module) {
230 printk(KERN_DEBUG "%s: hot unplug detected\n", ndev->name);
231 islpci_set_state(priv, PRV_STATE_OFF);
232 }
233
234 printk(KERN_DEBUG "%s: removing device\n", ndev->name);
235
236 unregister_netdev(ndev);
237
238 /* free the interrupt request */
239
240 if (islpci_get_state(priv) != PRV_STATE_OFF) {
241 isl38xx_disable_interrupts(priv->device_base);
242 islpci_set_state(priv, PRV_STATE_OFF);
243 /* This bellow causes a lockup at rmmod time. It might be
244 * because some interrupts still linger after rmmod time,
245 * see bug #17 */
246 /* pci_set_power_state(pdev, 3);*/ /* try to power-off */
247 }
248
249 free_irq(pdev->irq, priv);
250
251 /* free the PCI memory and unmap the remapped page */
252 islpci_free_memory(priv);
253
254 pci_set_drvdata(pdev, NULL);
255 free_netdev(ndev);
256 priv = NULL;
257
258 pci_release_regions(pdev);
259
260 pci_disable_device(pdev);
261}
262
263int
264prism54_suspend(struct pci_dev *pdev, u32 state)
265{
266 struct net_device *ndev = pci_get_drvdata(pdev);
267 islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
268 BUG_ON(!priv);
269
270 printk(KERN_NOTICE "%s: got suspend request (state %d)\n",
271 ndev->name, state);
272
273 pci_save_state(pdev);
274
275 /* tell the device not to trigger interrupts for now... */
276 isl38xx_disable_interrupts(priv->device_base);
277
278 /* from now on assume the hardware was already powered down
279 and don't touch it anymore */
280 islpci_set_state(priv, PRV_STATE_OFF);
281
282 netif_stop_queue(ndev);
283 netif_device_detach(ndev);
284
285 return 0;
286}
287
288int
289prism54_resume(struct pci_dev *pdev)
290{
291 struct net_device *ndev = pci_get_drvdata(pdev);
292 islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
293 BUG_ON(!priv);
294
295 pci_enable_device(pdev);
296
297 printk(KERN_NOTICE "%s: got resume request\n", ndev->name);
298
299 pci_restore_state(pdev);
300
301 /* alright let's go into the PREBOOT state */
302 islpci_reset(priv, 1);
303
304 netif_device_attach(ndev);
305 netif_start_queue(ndev);
306
307 return 0;
308}
309
310static int __init
311prism54_module_init(void)
312{
313 printk(KERN_INFO "Loaded %s driver, version %s\n",
314 DRV_NAME, DRV_VERSION);
315
316 __bug_on_wrong_struct_sizes ();
317
318 return pci_module_init(&prism54_driver);
319}
320
321/* by the time prism54_module_exit() terminates, as a postcondition
322 * all instances will have been destroyed by calls to
323 * prism54_remove() */
324static void __exit
325prism54_module_exit(void)
326{
327 __in_cleanup_module = 1;
328
329 pci_unregister_driver(&prism54_driver);
330
331 printk(KERN_INFO "Unloaded %s driver\n", DRV_NAME);
332
333 __in_cleanup_module = 0;
334}
335
336/* register entry points */
337module_init(prism54_module_init);
338module_exit(prism54_module_exit);
339/* EOF */
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
new file mode 100644
index 000000000000..b6f2e5a223be
--- /dev/null
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -0,0 +1,513 @@
1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc.
4 * Copyright 2004 Jens Maurer <Jens.Maurer@gmx.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <linux/config.h>
22#include <linux/netdevice.h>
23#include <linux/module.h>
24#include <linux/pci.h>
25
26#include <asm/io.h>
27#include <asm/system.h>
28#include <linux/if_arp.h>
29
30#include "prismcompat.h"
31#include "isl_38xx.h"
32#include "islpci_mgt.h"
33#include "isl_oid.h" /* additional types and defs for isl38xx fw */
34#include "isl_ioctl.h"
35
36#include <net/iw_handler.h>
37
38/******************************************************************************
39 Global variable definition section
40******************************************************************************/
41int pc_debug = VERBOSE;
42module_param(pc_debug, int, 0);
43
44/******************************************************************************
45 Driver general functions
46******************************************************************************/
47#if VERBOSE > SHOW_ERROR_MESSAGES
48void
49display_buffer(char *buffer, int length)
50{
51 if ((pc_debug & SHOW_BUFFER_CONTENTS) == 0)
52 return;
53
54 while (length > 0) {
55 printk("[%02x]", *buffer & 255);
56 length--;
57 buffer++;
58 }
59
60 printk("\n");
61}
62#endif
63
64/*****************************************************************************
65 Queue handling for management frames
66******************************************************************************/
67
68/*
69 * Helper function to create a PIMFOR management frame header.
70 */
71static void
72pimfor_encode_header(int operation, u32 oid, u32 length, pimfor_header_t *h)
73{
74 h->version = PIMFOR_VERSION;
75 h->operation = operation;
76 h->device_id = PIMFOR_DEV_ID_MHLI_MIB;
77 h->flags = 0;
78 h->oid = cpu_to_be32(oid);
79 h->length = cpu_to_be32(length);
80}
81
82/*
83 * Helper function to analyze a PIMFOR management frame header.
84 */
85static pimfor_header_t *
86pimfor_decode_header(void *data, int len)
87{
88 pimfor_header_t *h = data;
89
90 while ((void *) h < data + len) {
91 if (h->flags & PIMFOR_FLAG_LITTLE_ENDIAN) {
92 le32_to_cpus(&h->oid);
93 le32_to_cpus(&h->length);
94 } else {
95 be32_to_cpus(&h->oid);
96 be32_to_cpus(&h->length);
97 }
98 if (h->oid != OID_INL_TUNNEL)
99 return h;
100 h++;
101 }
102 return NULL;
103}
104
105/*
106 * Fill the receive queue for management frames with fresh buffers.
107 */
108int
109islpci_mgmt_rx_fill(struct net_device *ndev)
110{
111 islpci_private *priv = netdev_priv(ndev);
112 isl38xx_control_block *cb = /* volatile not needed */
113 (isl38xx_control_block *) priv->control_block;
114 u32 curr = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ]);
115
116#if VERBOSE > SHOW_ERROR_MESSAGES
117 DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgmt_rx_fill \n");
118#endif
119
120 while (curr - priv->index_mgmt_rx < ISL38XX_CB_MGMT_QSIZE) {
121 u32 index = curr % ISL38XX_CB_MGMT_QSIZE;
122 struct islpci_membuf *buf = &priv->mgmt_rx[index];
123 isl38xx_fragment *frag = &cb->rx_data_mgmt[index];
124
125 if (buf->mem == NULL) {
126 buf->mem = kmalloc(MGMT_FRAME_SIZE, GFP_ATOMIC);
127 if (!buf->mem) {
128 printk(KERN_WARNING
129 "Error allocating management frame.\n");
130 return -ENOMEM;
131 }
132 buf->size = MGMT_FRAME_SIZE;
133 }
134 if (buf->pci_addr == 0) {
135 buf->pci_addr = pci_map_single(priv->pdev, buf->mem,
136 MGMT_FRAME_SIZE,
137 PCI_DMA_FROMDEVICE);
138 if (!buf->pci_addr) {
139 printk(KERN_WARNING
140 "Failed to make memory DMA'able\n.");
141 return -ENOMEM;
142 }
143 }
144
145 /* be safe: always reset control block information */
146 frag->size = cpu_to_le16(MGMT_FRAME_SIZE);
147 frag->flags = 0;
148 frag->address = cpu_to_le32(buf->pci_addr);
149 curr++;
150
151 /* The fragment address in the control block must have
152 * been written before announcing the frame buffer to
153 * device */
154 wmb();
155 cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] = cpu_to_le32(curr);
156 }
157 return 0;
158}
159
160/*
161 * Create and transmit a management frame using "operation" and "oid",
162 * with arguments data/length.
163 * We either return an error and free the frame, or we return 0 and
164 * islpci_mgt_cleanup_transmit() frees the frame in the tx-done
165 * interrupt.
166 */
167static int
168islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid,
169 void *data, int length)
170{
171 islpci_private *priv = netdev_priv(ndev);
172 isl38xx_control_block *cb =
173 (isl38xx_control_block *) priv->control_block;
174 void *p;
175 int err = -EINVAL;
176 unsigned long flags;
177 isl38xx_fragment *frag;
178 struct islpci_membuf buf;
179 u32 curr_frag;
180 int index;
181 int frag_len = length + PIMFOR_HEADER_SIZE;
182
183#if VERBOSE > SHOW_ERROR_MESSAGES
184 DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_transmit\n");
185#endif
186
187 if (frag_len > MGMT_FRAME_SIZE) {
188 printk(KERN_DEBUG "%s: mgmt frame too large %d\n",
189 ndev->name, frag_len);
190 goto error;
191 }
192
193 err = -ENOMEM;
194 p = buf.mem = kmalloc(frag_len, GFP_KERNEL);
195 if (!buf.mem) {
196 printk(KERN_DEBUG "%s: cannot allocate mgmt frame\n",
197 ndev->name);
198 goto error;
199 }
200 buf.size = frag_len;
201
202 /* create the header directly in the fragment data area */
203 pimfor_encode_header(operation, oid, length, (pimfor_header_t *) p);
204 p += PIMFOR_HEADER_SIZE;
205
206 if (data)
207 memcpy(p, data, length);
208 else
209 memset(p, 0, length);
210
211#if VERBOSE > SHOW_ERROR_MESSAGES
212 {
213 pimfor_header_t *h = buf.mem;
214 DEBUG(SHOW_PIMFOR_FRAMES,
215 "PIMFOR: op %i, oid 0x%08lx, device %i, flags 0x%x length 0x%x \n",
216 h->operation, oid, h->device_id, h->flags, length);
217
218 /* display the buffer contents for debugging */
219 display_buffer((char *) h, sizeof (pimfor_header_t));
220 display_buffer(p, length);
221 }
222#endif
223
224 err = -ENOMEM;
225 buf.pci_addr = pci_map_single(priv->pdev, buf.mem, frag_len,
226 PCI_DMA_TODEVICE);
227 if (!buf.pci_addr) {
228 printk(KERN_WARNING "%s: cannot map PCI memory for mgmt\n",
229 ndev->name);
230 goto error_free;
231 }
232
233 /* Protect the control block modifications against interrupts. */
234 spin_lock_irqsave(&priv->slock, flags);
235 curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ]);
236 if (curr_frag - priv->index_mgmt_tx >= ISL38XX_CB_MGMT_QSIZE) {
237 printk(KERN_WARNING "%s: mgmt tx queue is still full\n",
238 ndev->name);
239 goto error_unlock;
240 }
241
242 /* commit the frame to the tx device queue */
243 index = curr_frag % ISL38XX_CB_MGMT_QSIZE;
244 priv->mgmt_tx[index] = buf;
245 frag = &cb->tx_data_mgmt[index];
246 frag->size = cpu_to_le16(frag_len);
247 frag->flags = 0; /* for any other than the last fragment, set to 1 */
248 frag->address = cpu_to_le32(buf.pci_addr);
249
250 /* The fragment address in the control block must have
251 * been written before announcing the frame buffer to
252 * device */
253 wmb();
254 cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ] = cpu_to_le32(curr_frag + 1);
255 spin_unlock_irqrestore(&priv->slock, flags);
256
257 /* trigger the device */
258 islpci_trigger(priv);
259 return 0;
260
261 error_unlock:
262 spin_unlock_irqrestore(&priv->slock, flags);
263 error_free:
264 kfree(buf.mem);
265 error:
266 return err;
267}
268
269/*
270 * Receive a management frame from the device.
271 * This can be an arbitrary number of traps, and at most one response
272 * frame for a previous request sent via islpci_mgt_transmit().
273 */
274int
275islpci_mgt_receive(struct net_device *ndev)
276{
277 islpci_private *priv = netdev_priv(ndev);
278 isl38xx_control_block *cb =
279 (isl38xx_control_block *) priv->control_block;
280 u32 curr_frag;
281
282#if VERBOSE > SHOW_ERROR_MESSAGES
283 DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_receive \n");
284#endif
285
286 /* Only once per interrupt, determine fragment range to
287 * process. This avoids an endless loop (i.e. lockup) if
288 * frames come in faster than we can process them. */
289 curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_RX_MGMTQ]);
290 barrier();
291
292 for (; priv->index_mgmt_rx < curr_frag; priv->index_mgmt_rx++) {
293 pimfor_header_t *header;
294 u32 index = priv->index_mgmt_rx % ISL38XX_CB_MGMT_QSIZE;
295 struct islpci_membuf *buf = &priv->mgmt_rx[index];
296 u16 frag_len;
297 int size;
298 struct islpci_mgmtframe *frame;
299
300 /* I have no idea (and no documentation) if flags != 0
301 * is possible. Drop the frame, reuse the buffer. */
302 if (le16_to_cpu(cb->rx_data_mgmt[index].flags) != 0) {
303 printk(KERN_WARNING "%s: unknown flags 0x%04x\n",
304 ndev->name,
305 le16_to_cpu(cb->rx_data_mgmt[index].flags));
306 continue;
307 }
308
309 /* The device only returns the size of the header(s) here. */
310 frag_len = le16_to_cpu(cb->rx_data_mgmt[index].size);
311
312 /*
313 * We appear to have no way to tell the device the
314 * size of a receive buffer. Thus, if this check
315 * triggers, we likely have kernel heap corruption. */
316 if (frag_len > MGMT_FRAME_SIZE) {
317 printk(KERN_WARNING
318 "%s: Bogus packet size of %d (%#x).\n",
319 ndev->name, frag_len, frag_len);
320 frag_len = MGMT_FRAME_SIZE;
321 }
322
323 /* Ensure the results of device DMA are visible to the CPU. */
324 pci_dma_sync_single_for_cpu(priv->pdev, buf->pci_addr,
325 buf->size, PCI_DMA_FROMDEVICE);
326
327 /* Perform endianess conversion for PIMFOR header in-place. */
328 header = pimfor_decode_header(buf->mem, frag_len);
329 if (!header) {
330 printk(KERN_WARNING "%s: no PIMFOR header found\n",
331 ndev->name);
332 continue;
333 }
334
335 /* The device ID from the PIMFOR packet received from
336 * the MVC is always 0. We forward a sensible device_id.
337 * Not that anyone upstream would care... */
338 header->device_id = priv->ndev->ifindex;
339
340#if VERBOSE > SHOW_ERROR_MESSAGES
341 DEBUG(SHOW_PIMFOR_FRAMES,
342 "PIMFOR: op %i, oid 0x%08x, device %i, flags 0x%x length 0x%x \n",
343 header->operation, header->oid, header->device_id,
344 header->flags, header->length);
345
346 /* display the buffer contents for debugging */
347 display_buffer((char *) header, PIMFOR_HEADER_SIZE);
348 display_buffer((char *) header + PIMFOR_HEADER_SIZE,
349 header->length);
350#endif
351
352 /* nobody sends these */
353 if (header->flags & PIMFOR_FLAG_APPLIC_ORIGIN) {
354 printk(KERN_DEBUG
355 "%s: errant PIMFOR application frame\n",
356 ndev->name);
357 continue;
358 }
359
360 /* Determine frame size, skipping OID_INL_TUNNEL headers. */
361 size = PIMFOR_HEADER_SIZE + header->length;
362 frame = kmalloc(sizeof (struct islpci_mgmtframe) + size,
363 GFP_ATOMIC);
364 if (!frame) {
365 printk(KERN_WARNING
366 "%s: Out of memory, cannot handle oid 0x%08x\n",
367 ndev->name, header->oid);
368 continue;
369 }
370 frame->ndev = ndev;
371 memcpy(&frame->buf, header, size);
372 frame->header = (pimfor_header_t *) frame->buf;
373 frame->data = frame->buf + PIMFOR_HEADER_SIZE;
374
375#if VERBOSE > SHOW_ERROR_MESSAGES
376 DEBUG(SHOW_PIMFOR_FRAMES,
377 "frame: header: %p, data: %p, size: %d\n",
378 frame->header, frame->data, size);
379#endif
380
381 if (header->operation == PIMFOR_OP_TRAP) {
382#if VERBOSE > SHOW_ERROR_MESSAGES
383 printk(KERN_DEBUG
384 "TRAP: oid 0x%x, device %i, flags 0x%x length %i\n",
385 header->oid, header->device_id, header->flags,
386 header->length);
387#endif
388
389 /* Create work to handle trap out of interrupt
390 * context. */
391 INIT_WORK(&frame->ws, prism54_process_trap, frame);
392 schedule_work(&frame->ws);
393
394 } else {
395 /* Signal the one waiting process that a response
396 * has been received. */
397 if ((frame = xchg(&priv->mgmt_received, frame)) != NULL) {
398 printk(KERN_WARNING
399 "%s: mgmt response not collected\n",
400 ndev->name);
401 kfree(frame);
402 }
403#if VERBOSE > SHOW_ERROR_MESSAGES
404 DEBUG(SHOW_TRACING, "Wake up Mgmt Queue\n");
405#endif
406 wake_up(&priv->mgmt_wqueue);
407 }
408
409 }
410
411 return 0;
412}
413
414/*
415 * Cleanup the transmit queue by freeing all frames handled by the device.
416 */
417void
418islpci_mgt_cleanup_transmit(struct net_device *ndev)
419{
420 islpci_private *priv = netdev_priv(ndev);
421 isl38xx_control_block *cb = /* volatile not needed */
422 (isl38xx_control_block *) priv->control_block;
423 u32 curr_frag;
424
425#if VERBOSE > SHOW_ERROR_MESSAGES
426 DEBUG(SHOW_FUNCTION_CALLS, "islpci_mgt_cleanup_transmit\n");
427#endif
428
429 /* Only once per cleanup, determine fragment range to
430 * process. This avoids an endless loop (i.e. lockup) if
431 * the device became confused, incrementing device_curr_frag
432 * rapidly. */
433 curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_TX_MGMTQ]);
434 barrier();
435
436 for (; priv->index_mgmt_tx < curr_frag; priv->index_mgmt_tx++) {
437 int index = priv->index_mgmt_tx % ISL38XX_CB_MGMT_QSIZE;
438 struct islpci_membuf *buf = &priv->mgmt_tx[index];
439 pci_unmap_single(priv->pdev, buf->pci_addr, buf->size,
440 PCI_DMA_TODEVICE);
441 buf->pci_addr = 0;
442 kfree(buf->mem);
443 buf->mem = NULL;
444 buf->size = 0;
445 }
446}
447
448/*
449 * Perform one request-response transaction to the device.
450 */
451int
452islpci_mgt_transaction(struct net_device *ndev,
453 int operation, unsigned long oid,
454 void *senddata, int sendlen,
455 struct islpci_mgmtframe **recvframe)
456{
457 islpci_private *priv = netdev_priv(ndev);
458 const long wait_cycle_jiffies = (ISL38XX_WAIT_CYCLE * 10 * HZ) / 1000;
459 long timeout_left = ISL38XX_MAX_WAIT_CYCLES * wait_cycle_jiffies;
460 int err;
461 DEFINE_WAIT(wait);
462
463 *recvframe = NULL;
464
465 if (down_interruptible(&priv->mgmt_sem))
466 return -ERESTARTSYS;
467
468 prepare_to_wait(&priv->mgmt_wqueue, &wait, TASK_UNINTERRUPTIBLE);
469 err = islpci_mgt_transmit(ndev, operation, oid, senddata, sendlen);
470 if (err)
471 goto out;
472
473 err = -ETIMEDOUT;
474 while (timeout_left > 0) {
475 int timeleft;
476 struct islpci_mgmtframe *frame;
477
478 set_current_state(TASK_UNINTERRUPTIBLE);
479 timeleft = schedule_timeout(wait_cycle_jiffies);
480 frame = xchg(&priv->mgmt_received, NULL);
481 if (frame) {
482 if (frame->header->oid == oid) {
483 *recvframe = frame;
484 err = 0;
485 goto out;
486 } else {
487 printk(KERN_DEBUG
488 "%s: expecting oid 0x%x, received 0x%x.\n",
489 ndev->name, (unsigned int) oid,
490 frame->header->oid);
491 kfree(frame);
492 frame = NULL;
493 }
494 }
495 if (timeleft == 0) {
496 printk(KERN_DEBUG
497 "%s: timeout waiting for mgmt response %lu, "
498 "triggering device\n",
499 ndev->name, timeout_left);
500 islpci_trigger(priv);
501 }
502 timeout_left += timeleft - wait_cycle_jiffies;
503 }
504 printk(KERN_WARNING "%s: timeout waiting for mgmt response\n",
505 ndev->name);
506
507 /* TODO: we should reset the device here */
508 out:
509 finish_wait(&priv->mgmt_wqueue, &wait);
510 up(&priv->mgmt_sem);
511 return err;
512}
513
diff --git a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h
new file mode 100644
index 000000000000..2982be3363ef
--- /dev/null
+++ b/drivers/net/wireless/prism54/islpci_mgt.h
@@ -0,0 +1,145 @@
1/*
2 *
3 * Copyright (C) 2002 Intersil Americas Inc.
4 * Copyright (C) 2003 Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#ifndef _ISLPCI_MGT_H
22#define _ISLPCI_MGT_H
23
24#include <linux/wireless.h>
25#include <linux/skbuff.h>
26
27/*
28 * Function definitions
29 */
30
31#define K_DEBUG(f, m, args...) do { if(f & m) printk(KERN_DEBUG args); } while(0)
32#define DEBUG(f, args...) K_DEBUG(f, pc_debug, args)
33
34extern int pc_debug;
35#define init_wds 0 /* help compiler optimize away dead code */
36
37
38/* General driver definitions */
39#define PCIDEVICE_LATENCY_TIMER_MIN 0x40
40#define PCIDEVICE_LATENCY_TIMER_VAL 0x50
41
42/* Debugging verbose definitions */
43#define SHOW_NOTHING 0x00 /* overrules everything */
44#define SHOW_ANYTHING 0xFF
45#define SHOW_ERROR_MESSAGES 0x01
46#define SHOW_TRAPS 0x02
47#define SHOW_FUNCTION_CALLS 0x04
48#define SHOW_TRACING 0x08
49#define SHOW_QUEUE_INDEXES 0x10
50#define SHOW_PIMFOR_FRAMES 0x20
51#define SHOW_BUFFER_CONTENTS 0x40
52#define VERBOSE 0x01
53
54/* Default card definitions */
55#define CARD_DEFAULT_CHANNEL 6
56#define CARD_DEFAULT_MODE INL_MODE_CLIENT
57#define CARD_DEFAULT_IW_MODE IW_MODE_INFRA
58#define CARD_DEFAULT_BSSTYPE DOT11_BSSTYPE_INFRA
59#define CARD_DEFAULT_CLIENT_SSID ""
60#define CARD_DEFAULT_AP_SSID "default"
61#define CARD_DEFAULT_KEY1 "default_key_1"
62#define CARD_DEFAULT_KEY2 "default_key_2"
63#define CARD_DEFAULT_KEY3 "default_key_3"
64#define CARD_DEFAULT_KEY4 "default_key_4"
65#define CARD_DEFAULT_WEP 0
66#define CARD_DEFAULT_FILTER 0
67#define CARD_DEFAULT_WDS 0
68#define CARD_DEFAULT_AUTHEN DOT11_AUTH_OS
69#define CARD_DEFAULT_DOT1X 0
70#define CARD_DEFAULT_MLME_MODE DOT11_MLME_AUTO
71#define CARD_DEFAULT_CONFORMANCE OID_INL_CONFORMANCE_NONE
72#define CARD_DEFAULT_PROFILE DOT11_PROFILE_MIXED_G_WIFI
73#define CARD_DEFAULT_MAXFRAMEBURST DOT11_MAXFRAMEBURST_MIXED_SAFE
74
75/* PIMFOR package definitions */
76#define PIMFOR_ETHERTYPE 0x8828
77#define PIMFOR_HEADER_SIZE 12
78#define PIMFOR_VERSION 1
79#define PIMFOR_OP_GET 0
80#define PIMFOR_OP_SET 1
81#define PIMFOR_OP_RESPONSE 2
82#define PIMFOR_OP_ERROR 3
83#define PIMFOR_OP_TRAP 4
84#define PIMFOR_OP_RESERVED 5 /* till 255 */
85#define PIMFOR_DEV_ID_MHLI_MIB 0
86#define PIMFOR_FLAG_APPLIC_ORIGIN 0x01
87#define PIMFOR_FLAG_LITTLE_ENDIAN 0x02
88
89static inline void
90add_le32p(u32 * le_number, u32 add)
91{
92 *le_number = cpu_to_le32(le32_to_cpup(le_number) + add);
93}
94
95void display_buffer(char *, int);
96
97/*
98 * Type definition section
99 *
100 * the structure defines only the header allowing copyless
101 * frame handling
102 */
103typedef struct {
104 u8 version;
105 u8 operation;
106 u32 oid;
107 u8 device_id;
108 u8 flags;
109 u32 length;
110} __attribute__ ((packed))
111pimfor_header_t;
112
113/* A received and interrupt-processed management frame, either for
114 * schedule_work(prism54_process_trap) or for priv->mgmt_received,
115 * processed by islpci_mgt_transaction(). */
116struct islpci_mgmtframe {
117 struct net_device *ndev; /* pointer to network device */
118 pimfor_header_t *header; /* payload header, points into buf */
119 void *data; /* payload ex header, points into buf */
120 struct work_struct ws; /* argument for schedule_work() */
121 char buf[0]; /* fragment buffer */
122};
123
124int
125islpci_mgt_receive(struct net_device *ndev);
126
127int
128islpci_mgmt_rx_fill(struct net_device *ndev);
129
130void
131islpci_mgt_cleanup_transmit(struct net_device *ndev);
132
133int
134islpci_mgt_transaction(struct net_device *ndev,
135 int operation, unsigned long oid,
136 void *senddata, int sendlen,
137 struct islpci_mgmtframe **recvframe);
138
139static inline void
140islpci_mgt_release(struct islpci_mgmtframe *frame)
141{
142 kfree(frame);
143}
144
145#endif /* _ISLPCI_MGT_H */
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
new file mode 100644
index 000000000000..12123e24b113
--- /dev/null
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -0,0 +1,907 @@
1/*
2 * Copyright (C) 2003,2004 Aurelien Alleaume <slts@free.fr>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 */
18
19#include "prismcompat.h"
20#include "islpci_dev.h"
21#include "islpci_mgt.h"
22#include "isl_oid.h"
23#include "oid_mgt.h"
24#include "isl_ioctl.h"
25
26/* to convert between channel and freq */
27static const int frequency_list_bg[] = { 2412, 2417, 2422, 2427, 2432,
28 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484
29};
30
31int
32channel_of_freq(int f)
33{
34 int c = 0;
35
36 if ((f >= 2412) && (f <= 2484)) {
37 while ((c < 14) && (f != frequency_list_bg[c]))
38 c++;
39 return (c >= 14) ? 0 : ++c;
40 } else if ((f >= (int) 5000) && (f <= (int) 6000)) {
41 return ( (f - 5000) / 5 );
42 } else
43 return 0;
44}
45
46#define OID_STRUCT(name,oid,s,t) [name] = {oid, 0, sizeof(s), t}
47#define OID_STRUCT_C(name,oid,s,t) OID_STRUCT(name,oid,s,t | OID_FLAG_CACHED)
48#define OID_U32(name,oid) OID_STRUCT(name,oid,u32,OID_TYPE_U32)
49#define OID_U32_C(name,oid) OID_STRUCT_C(name,oid,u32,OID_TYPE_U32)
50#define OID_STRUCT_MLME(name,oid) OID_STRUCT(name,oid,struct obj_mlme,OID_TYPE_MLME)
51#define OID_STRUCT_MLMEEX(name,oid) OID_STRUCT(name,oid,struct obj_mlmeex,OID_TYPE_MLMEEX)
52
53#define OID_UNKNOWN(name,oid) OID_STRUCT(name,oid,0,0)
54
55struct oid_t isl_oid[] = {
56 OID_STRUCT(GEN_OID_MACADDRESS, 0x00000000, u8[6], OID_TYPE_ADDR),
57 OID_U32(GEN_OID_LINKSTATE, 0x00000001),
58 OID_UNKNOWN(GEN_OID_WATCHDOG, 0x00000002),
59 OID_UNKNOWN(GEN_OID_MIBOP, 0x00000003),
60 OID_UNKNOWN(GEN_OID_OPTIONS, 0x00000004),
61 OID_UNKNOWN(GEN_OID_LEDCONFIG, 0x00000005),
62
63 /* 802.11 */
64 OID_U32_C(DOT11_OID_BSSTYPE, 0x10000000),
65 OID_STRUCT_C(DOT11_OID_BSSID, 0x10000001, u8[6], OID_TYPE_RAW),
66 OID_STRUCT_C(DOT11_OID_SSID, 0x10000002, struct obj_ssid,
67 OID_TYPE_SSID),
68 OID_U32(DOT11_OID_STATE, 0x10000003),
69 OID_U32(DOT11_OID_AID, 0x10000004),
70 OID_STRUCT(DOT11_OID_COUNTRYSTRING, 0x10000005, u8[4], OID_TYPE_RAW),
71 OID_STRUCT_C(DOT11_OID_SSIDOVERRIDE, 0x10000006, struct obj_ssid,
72 OID_TYPE_SSID),
73
74 OID_U32(DOT11_OID_MEDIUMLIMIT, 0x11000000),
75 OID_U32_C(DOT11_OID_BEACONPERIOD, 0x11000001),
76 OID_U32(DOT11_OID_DTIMPERIOD, 0x11000002),
77 OID_U32(DOT11_OID_ATIMWINDOW, 0x11000003),
78 OID_U32(DOT11_OID_LISTENINTERVAL, 0x11000004),
79 OID_U32(DOT11_OID_CFPPERIOD, 0x11000005),
80 OID_U32(DOT11_OID_CFPDURATION, 0x11000006),
81
82 OID_U32_C(DOT11_OID_AUTHENABLE, 0x12000000),
83 OID_U32_C(DOT11_OID_PRIVACYINVOKED, 0x12000001),
84 OID_U32_C(DOT11_OID_EXUNENCRYPTED, 0x12000002),
85 OID_U32_C(DOT11_OID_DEFKEYID, 0x12000003),
86 [DOT11_OID_DEFKEYX] = {0x12000004, 3, sizeof (struct obj_key),
87 OID_FLAG_CACHED | OID_TYPE_KEY}, /* DOT11_OID_DEFKEY1,...DOT11_OID_DEFKEY4 */
88 OID_UNKNOWN(DOT11_OID_STAKEY, 0x12000008),
89 OID_U32(DOT11_OID_REKEYTHRESHOLD, 0x12000009),
90 OID_UNKNOWN(DOT11_OID_STASC, 0x1200000a),
91
92 OID_U32(DOT11_OID_PRIVTXREJECTED, 0x1a000000),
93 OID_U32(DOT11_OID_PRIVRXPLAIN, 0x1a000001),
94 OID_U32(DOT11_OID_PRIVRXFAILED, 0x1a000002),
95 OID_U32(DOT11_OID_PRIVRXNOKEY, 0x1a000003),
96
97 OID_U32_C(DOT11_OID_RTSTHRESH, 0x13000000),
98 OID_U32_C(DOT11_OID_FRAGTHRESH, 0x13000001),
99 OID_U32_C(DOT11_OID_SHORTRETRIES, 0x13000002),
100 OID_U32_C(DOT11_OID_LONGRETRIES, 0x13000003),
101 OID_U32_C(DOT11_OID_MAXTXLIFETIME, 0x13000004),
102 OID_U32(DOT11_OID_MAXRXLIFETIME, 0x13000005),
103 OID_U32(DOT11_OID_AUTHRESPTIMEOUT, 0x13000006),
104 OID_U32(DOT11_OID_ASSOCRESPTIMEOUT, 0x13000007),
105
106 OID_UNKNOWN(DOT11_OID_ALOFT_TABLE, 0x1d000000),
107 OID_UNKNOWN(DOT11_OID_ALOFT_CTRL_TABLE, 0x1d000001),
108 OID_UNKNOWN(DOT11_OID_ALOFT_RETREAT, 0x1d000002),
109 OID_UNKNOWN(DOT11_OID_ALOFT_PROGRESS, 0x1d000003),
110 OID_U32(DOT11_OID_ALOFT_FIXEDRATE, 0x1d000004),
111 OID_UNKNOWN(DOT11_OID_ALOFT_RSSIGRAPH, 0x1d000005),
112 OID_UNKNOWN(DOT11_OID_ALOFT_CONFIG, 0x1d000006),
113
114 [DOT11_OID_VDCFX] = {0x1b000000, 7, 0, 0},
115 OID_U32(DOT11_OID_MAXFRAMEBURST, 0x1b000008),
116
117 OID_U32(DOT11_OID_PSM, 0x14000000),
118 OID_U32(DOT11_OID_CAMTIMEOUT, 0x14000001),
119 OID_U32(DOT11_OID_RECEIVEDTIMS, 0x14000002),
120 OID_U32(DOT11_OID_ROAMPREFERENCE, 0x14000003),
121
122 OID_U32(DOT11_OID_BRIDGELOCAL, 0x15000000),
123 OID_U32(DOT11_OID_CLIENTS, 0x15000001),
124 OID_U32(DOT11_OID_CLIENTSASSOCIATED, 0x15000002),
125 [DOT11_OID_CLIENTX] = {0x15000003, 2006, 0, 0}, /* DOT11_OID_CLIENTX,...DOT11_OID_CLIENT2007 */
126
127 OID_STRUCT(DOT11_OID_CLIENTFIND, 0x150007DB, u8[6], OID_TYPE_ADDR),
128 OID_STRUCT(DOT11_OID_WDSLINKADD, 0x150007DC, u8[6], OID_TYPE_ADDR),
129 OID_STRUCT(DOT11_OID_WDSLINKREMOVE, 0x150007DD, u8[6], OID_TYPE_ADDR),
130 OID_STRUCT(DOT11_OID_EAPAUTHSTA, 0x150007DE, u8[6], OID_TYPE_ADDR),
131 OID_STRUCT(DOT11_OID_EAPUNAUTHSTA, 0x150007DF, u8[6], OID_TYPE_ADDR),
132 OID_U32_C(DOT11_OID_DOT1XENABLE, 0x150007E0),
133 OID_UNKNOWN(DOT11_OID_MICFAILURE, 0x150007E1),
134 OID_UNKNOWN(DOT11_OID_REKEYINDICATE, 0x150007E2),
135
136 OID_U32(DOT11_OID_MPDUTXSUCCESSFUL, 0x16000000),
137 OID_U32(DOT11_OID_MPDUTXONERETRY, 0x16000001),
138 OID_U32(DOT11_OID_MPDUTXMULTIPLERETRIES, 0x16000002),
139 OID_U32(DOT11_OID_MPDUTXFAILED, 0x16000003),
140 OID_U32(DOT11_OID_MPDURXSUCCESSFUL, 0x16000004),
141 OID_U32(DOT11_OID_MPDURXDUPS, 0x16000005),
142 OID_U32(DOT11_OID_RTSSUCCESSFUL, 0x16000006),
143 OID_U32(DOT11_OID_RTSFAILED, 0x16000007),
144 OID_U32(DOT11_OID_ACKFAILED, 0x16000008),
145 OID_U32(DOT11_OID_FRAMERECEIVES, 0x16000009),
146 OID_U32(DOT11_OID_FRAMEERRORS, 0x1600000A),
147 OID_U32(DOT11_OID_FRAMEABORTS, 0x1600000B),
148 OID_U32(DOT11_OID_FRAMEABORTSPHY, 0x1600000C),
149
150 OID_U32(DOT11_OID_SLOTTIME, 0x17000000),
151 OID_U32(DOT11_OID_CWMIN, 0x17000001),
152 OID_U32(DOT11_OID_CWMAX, 0x17000002),
153 OID_U32(DOT11_OID_ACKWINDOW, 0x17000003),
154 OID_U32(DOT11_OID_ANTENNARX, 0x17000004),
155 OID_U32(DOT11_OID_ANTENNATX, 0x17000005),
156 OID_U32(DOT11_OID_ANTENNADIVERSITY, 0x17000006),
157 OID_U32_C(DOT11_OID_CHANNEL, 0x17000007),
158 OID_U32_C(DOT11_OID_EDTHRESHOLD, 0x17000008),
159 OID_U32(DOT11_OID_PREAMBLESETTINGS, 0x17000009),
160 OID_STRUCT(DOT11_OID_RATES, 0x1700000A, u8[IWMAX_BITRATES + 1],
161 OID_TYPE_RAW),
162 OID_U32(DOT11_OID_CCAMODESUPPORTED, 0x1700000B),
163 OID_U32(DOT11_OID_CCAMODE, 0x1700000C),
164 OID_UNKNOWN(DOT11_OID_RSSIVECTOR, 0x1700000D),
165 OID_UNKNOWN(DOT11_OID_OUTPUTPOWERTABLE, 0x1700000E),
166 OID_U32(DOT11_OID_OUTPUTPOWER, 0x1700000F),
167 OID_STRUCT(DOT11_OID_SUPPORTEDRATES, 0x17000010,
168 u8[IWMAX_BITRATES + 1], OID_TYPE_RAW),
169 OID_U32_C(DOT11_OID_FREQUENCY, 0x17000011),
170 [DOT11_OID_SUPPORTEDFREQUENCIES] =
171 {0x17000012, 0, sizeof (struct obj_frequencies)
172 + sizeof (u16) * IWMAX_FREQ, OID_TYPE_FREQUENCIES},
173
174 OID_U32(DOT11_OID_NOISEFLOOR, 0x17000013),
175 OID_STRUCT(DOT11_OID_FREQUENCYACTIVITY, 0x17000014, u8[IWMAX_FREQ + 1],
176 OID_TYPE_RAW),
177 OID_UNKNOWN(DOT11_OID_IQCALIBRATIONTABLE, 0x17000015),
178 OID_U32(DOT11_OID_NONERPPROTECTION, 0x17000016),
179 OID_U32(DOT11_OID_SLOTSETTINGS, 0x17000017),
180 OID_U32(DOT11_OID_NONERPTIMEOUT, 0x17000018),
181 OID_U32(DOT11_OID_PROFILES, 0x17000019),
182 OID_STRUCT(DOT11_OID_EXTENDEDRATES, 0x17000020,
183 u8[IWMAX_BITRATES + 1], OID_TYPE_RAW),
184
185 OID_STRUCT_MLME(DOT11_OID_DEAUTHENTICATE, 0x18000000),
186 OID_STRUCT_MLME(DOT11_OID_AUTHENTICATE, 0x18000001),
187 OID_STRUCT_MLME(DOT11_OID_DISASSOCIATE, 0x18000002),
188 OID_STRUCT_MLME(DOT11_OID_ASSOCIATE, 0x18000003),
189 OID_UNKNOWN(DOT11_OID_SCAN, 0x18000004),
190 OID_STRUCT_MLMEEX(DOT11_OID_BEACON, 0x18000005),
191 OID_STRUCT_MLMEEX(DOT11_OID_PROBE, 0x18000006),
192 OID_STRUCT_MLMEEX(DOT11_OID_DEAUTHENTICATEEX, 0x18000007),
193 OID_STRUCT_MLMEEX(DOT11_OID_AUTHENTICATEEX, 0x18000008),
194 OID_STRUCT_MLMEEX(DOT11_OID_DISASSOCIATEEX, 0x18000009),
195 OID_STRUCT_MLMEEX(DOT11_OID_ASSOCIATEEX, 0x1800000A),
196 OID_STRUCT_MLMEEX(DOT11_OID_REASSOCIATE, 0x1800000B),
197 OID_STRUCT_MLMEEX(DOT11_OID_REASSOCIATEEX, 0x1800000C),
198
199 OID_U32(DOT11_OID_NONERPSTATUS, 0x1E000000),
200
201 OID_U32(DOT11_OID_STATIMEOUT, 0x19000000),
202 OID_U32_C(DOT11_OID_MLMEAUTOLEVEL, 0x19000001),
203 OID_U32(DOT11_OID_BSSTIMEOUT, 0x19000002),
204 [DOT11_OID_ATTACHMENT] = {0x19000003, 0,
205 sizeof(struct obj_attachment), OID_TYPE_ATTACH},
206 OID_STRUCT_C(DOT11_OID_PSMBUFFER, 0x19000004, struct obj_buffer,
207 OID_TYPE_BUFFER),
208
209 OID_U32(DOT11_OID_BSSS, 0x1C000000),
210 [DOT11_OID_BSSX] = {0x1C000001, 63, sizeof (struct obj_bss),
211 OID_TYPE_BSS}, /*DOT11_OID_BSS1,...,DOT11_OID_BSS64 */
212 OID_STRUCT(DOT11_OID_BSSFIND, 0x1C000042, struct obj_bss, OID_TYPE_BSS),
213 [DOT11_OID_BSSLIST] = {0x1C000043, 0, sizeof (struct
214 obj_bsslist) +
215 sizeof (struct obj_bss[IWMAX_BSS]),
216 OID_TYPE_BSSLIST},
217
218 OID_UNKNOWN(OID_INL_TUNNEL, 0xFF020000),
219 OID_UNKNOWN(OID_INL_MEMADDR, 0xFF020001),
220 OID_UNKNOWN(OID_INL_MEMORY, 0xFF020002),
221 OID_U32_C(OID_INL_MODE, 0xFF020003),
222 OID_UNKNOWN(OID_INL_COMPONENT_NR, 0xFF020004),
223 OID_STRUCT(OID_INL_VERSION, 0xFF020005, u8[8], OID_TYPE_RAW),
224 OID_UNKNOWN(OID_INL_INTERFACE_ID, 0xFF020006),
225 OID_UNKNOWN(OID_INL_COMPONENT_ID, 0xFF020007),
226 OID_U32_C(OID_INL_CONFIG, 0xFF020008),
227 OID_U32_C(OID_INL_DOT11D_CONFORMANCE, 0xFF02000C),
228 OID_U32(OID_INL_PHYCAPABILITIES, 0xFF02000D),
229 OID_U32_C(OID_INL_OUTPUTPOWER, 0xFF02000F),
230
231};
232
233int
234mgt_init(islpci_private *priv)
235{
236 int i;
237
238 priv->mib = kmalloc(OID_NUM_LAST * sizeof (void *), GFP_KERNEL);
239 if (!priv->mib)
240 return -ENOMEM;
241
242 memset(priv->mib, 0, OID_NUM_LAST * sizeof (void *));
243
244 /* Alloc the cache */
245 for (i = 0; i < OID_NUM_LAST; i++) {
246 if (isl_oid[i].flags & OID_FLAG_CACHED) {
247 priv->mib[i] = kmalloc(isl_oid[i].size *
248 (isl_oid[i].range + 1),
249 GFP_KERNEL);
250 if (!priv->mib[i])
251 return -ENOMEM;
252 memset(priv->mib[i], 0,
253 isl_oid[i].size * (isl_oid[i].range + 1));
254 } else
255 priv->mib[i] = NULL;
256 }
257
258 init_rwsem(&priv->mib_sem);
259 prism54_mib_init(priv);
260
261 return 0;
262}
263
264void
265mgt_clean(islpci_private *priv)
266{
267 int i;
268
269 if (!priv->mib)
270 return;
271 for (i = 0; i < OID_NUM_LAST; i++)
272 if (priv->mib[i]) {
273 kfree(priv->mib[i]);
274 priv->mib[i] = NULL;
275 }
276 kfree(priv->mib);
277 priv->mib = NULL;
278}
279
280void
281mgt_le_to_cpu(int type, void *data)
282{
283 switch (type) {
284 case OID_TYPE_U32:
285 *(u32 *) data = le32_to_cpu(*(u32 *) data);
286 break;
287 case OID_TYPE_BUFFER:{
288 struct obj_buffer *buff = data;
289 buff->size = le32_to_cpu(buff->size);
290 buff->addr = le32_to_cpu(buff->addr);
291 break;
292 }
293 case OID_TYPE_BSS:{
294 struct obj_bss *bss = data;
295 bss->age = le16_to_cpu(bss->age);
296 bss->channel = le16_to_cpu(bss->channel);
297 bss->capinfo = le16_to_cpu(bss->capinfo);
298 bss->rates = le16_to_cpu(bss->rates);
299 bss->basic_rates = le16_to_cpu(bss->basic_rates);
300 break;
301 }
302 case OID_TYPE_BSSLIST:{
303 struct obj_bsslist *list = data;
304 int i;
305 list->nr = le32_to_cpu(list->nr);
306 for (i = 0; i < list->nr; i++)
307 mgt_le_to_cpu(OID_TYPE_BSS, &list->bsslist[i]);
308 break;
309 }
310 case OID_TYPE_FREQUENCIES:{
311 struct obj_frequencies *freq = data;
312 int i;
313 freq->nr = le16_to_cpu(freq->nr);
314 for (i = 0; i < freq->nr; i++)
315 freq->mhz[i] = le16_to_cpu(freq->mhz[i]);
316 break;
317 }
318 case OID_TYPE_MLME:{
319 struct obj_mlme *mlme = data;
320 mlme->id = le16_to_cpu(mlme->id);
321 mlme->state = le16_to_cpu(mlme->state);
322 mlme->code = le16_to_cpu(mlme->code);
323 break;
324 }
325 case OID_TYPE_MLMEEX:{
326 struct obj_mlmeex *mlme = data;
327 mlme->id = le16_to_cpu(mlme->id);
328 mlme->state = le16_to_cpu(mlme->state);
329 mlme->code = le16_to_cpu(mlme->code);
330 mlme->size = le16_to_cpu(mlme->size);
331 break;
332 }
333 case OID_TYPE_ATTACH:{
334 struct obj_attachment *attach = data;
335 attach->id = le16_to_cpu(attach->id);
336 attach->size = le16_to_cpu(attach->size);;
337 break;
338 }
339 case OID_TYPE_SSID:
340 case OID_TYPE_KEY:
341 case OID_TYPE_ADDR:
342 case OID_TYPE_RAW:
343 break;
344 default:
345 BUG();
346 }
347}
348
349static void
350mgt_cpu_to_le(int type, void *data)
351{
352 switch (type) {
353 case OID_TYPE_U32:
354 *(u32 *) data = cpu_to_le32(*(u32 *) data);
355 break;
356 case OID_TYPE_BUFFER:{
357 struct obj_buffer *buff = data;
358 buff->size = cpu_to_le32(buff->size);
359 buff->addr = cpu_to_le32(buff->addr);
360 break;
361 }
362 case OID_TYPE_BSS:{
363 struct obj_bss *bss = data;
364 bss->age = cpu_to_le16(bss->age);
365 bss->channel = cpu_to_le16(bss->channel);
366 bss->capinfo = cpu_to_le16(bss->capinfo);
367 bss->rates = cpu_to_le16(bss->rates);
368 bss->basic_rates = cpu_to_le16(bss->basic_rates);
369 break;
370 }
371 case OID_TYPE_BSSLIST:{
372 struct obj_bsslist *list = data;
373 int i;
374 list->nr = cpu_to_le32(list->nr);
375 for (i = 0; i < list->nr; i++)
376 mgt_cpu_to_le(OID_TYPE_BSS, &list->bsslist[i]);
377 break;
378 }
379 case OID_TYPE_FREQUENCIES:{
380 struct obj_frequencies *freq = data;
381 int i;
382 freq->nr = cpu_to_le16(freq->nr);
383 for (i = 0; i < freq->nr; i++)
384 freq->mhz[i] = cpu_to_le16(freq->mhz[i]);
385 break;
386 }
387 case OID_TYPE_MLME:{
388 struct obj_mlme *mlme = data;
389 mlme->id = cpu_to_le16(mlme->id);
390 mlme->state = cpu_to_le16(mlme->state);
391 mlme->code = cpu_to_le16(mlme->code);
392 break;
393 }
394 case OID_TYPE_MLMEEX:{
395 struct obj_mlmeex *mlme = data;
396 mlme->id = cpu_to_le16(mlme->id);
397 mlme->state = cpu_to_le16(mlme->state);
398 mlme->code = cpu_to_le16(mlme->code);
399 mlme->size = cpu_to_le16(mlme->size);
400 break;
401 }
402 case OID_TYPE_ATTACH:{
403 struct obj_attachment *attach = data;
404 attach->id = cpu_to_le16(attach->id);
405 attach->size = cpu_to_le16(attach->size);;
406 break;
407 }
408 case OID_TYPE_SSID:
409 case OID_TYPE_KEY:
410 case OID_TYPE_ADDR:
411 case OID_TYPE_RAW:
412 break;
413 default:
414 BUG();
415 }
416}
417
418/* Note : data is modified during this function */
419
420int
421mgt_set_request(islpci_private *priv, enum oid_num_t n, int extra, void *data)
422{
423 int ret = 0;
424 struct islpci_mgmtframe *response = NULL;
425 int response_op = PIMFOR_OP_ERROR;
426 int dlen;
427 void *cache, *_data = data;
428 u32 oid;
429
430 BUG_ON(OID_NUM_LAST <= n);
431 BUG_ON(extra > isl_oid[n].range);
432
433 if (!priv->mib)
434 /* memory has been freed */
435 return -1;
436
437 dlen = isl_oid[n].size;
438 cache = priv->mib[n];
439 cache += (cache ? extra * dlen : 0);
440 oid = isl_oid[n].oid + extra;
441
442 if (_data == NULL)
443 /* we are requested to re-set a cached value */
444 _data = cache;
445 else
446 mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, _data);
447 /* If we are going to write to the cache, we don't want anyone to read
448 * it -> acquire write lock.
449 * Else we could acquire a read lock to be sure we don't bother the
450 * commit process (which takes a write lock). But I'm not sure if it's
451 * needed.
452 */
453 if (cache)
454 down_write(&priv->mib_sem);
455
456 if (islpci_get_state(priv) >= PRV_STATE_READY) {
457 ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid,
458 _data, dlen, &response);
459 if (!ret) {
460 response_op = response->header->operation;
461 islpci_mgt_release(response);
462 }
463 if (ret || response_op == PIMFOR_OP_ERROR)
464 ret = -EIO;
465 } else if (!cache)
466 ret = -EIO;
467
468 if (cache) {
469 if (!ret && data)
470 memcpy(cache, _data, dlen);
471 up_write(&priv->mib_sem);
472 }
473
474 /* re-set given data to what it was */
475 if (data)
476 mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data);
477
478 return ret;
479}
480
481/* None of these are cached */
482int
483mgt_set_varlen(islpci_private *priv, enum oid_num_t n, void *data, int extra_len)
484{
485 int ret = 0;
486 struct islpci_mgmtframe *response;
487 int response_op = PIMFOR_OP_ERROR;
488 int dlen;
489 u32 oid;
490
491 BUG_ON(OID_NUM_LAST <= n);
492
493 dlen = isl_oid[n].size;
494 oid = isl_oid[n].oid;
495
496 mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, data);
497
498 if (islpci_get_state(priv) >= PRV_STATE_READY) {
499 ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid,
500 data, dlen + extra_len, &response);
501 if (!ret) {
502 response_op = response->header->operation;
503 islpci_mgt_release(response);
504 }
505 if (ret || response_op == PIMFOR_OP_ERROR)
506 ret = -EIO;
507 } else
508 ret = -EIO;
509
510 /* re-set given data to what it was */
511 if (data)
512 mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data);
513
514 return ret;
515}
516
517int
518mgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data,
519 union oid_res_t *res)
520{
521
522 int ret = -EIO;
523 int reslen = 0;
524 struct islpci_mgmtframe *response = NULL;
525
526 int dlen;
527 void *cache, *_res = NULL;
528 u32 oid;
529
530 BUG_ON(OID_NUM_LAST <= n);
531 BUG_ON(extra > isl_oid[n].range);
532
533 res->ptr = NULL;
534
535 if (!priv->mib)
536 /* memory has been freed */
537 return -1;
538
539 dlen = isl_oid[n].size;
540 cache = priv->mib[n];
541 cache += cache ? extra * dlen : 0;
542 oid = isl_oid[n].oid + extra;
543 reslen = dlen;
544
545 if (cache)
546 down_read(&priv->mib_sem);
547
548 if (islpci_get_state(priv) >= PRV_STATE_READY) {
549 ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET,
550 oid, data, dlen, &response);
551 if (ret || !response ||
552 response->header->operation == PIMFOR_OP_ERROR) {
553 if (response)
554 islpci_mgt_release(response);
555 ret = -EIO;
556 }
557 if (!ret) {
558 _res = response->data;
559 reslen = response->header->length;
560 }
561 } else if (cache) {
562 _res = cache;
563 ret = 0;
564 }
565 if ((isl_oid[n].flags & OID_FLAG_TYPE) == OID_TYPE_U32)
566 res->u = ret ? 0 : le32_to_cpu(*(u32 *) _res);
567 else {
568 res->ptr = kmalloc(reslen, GFP_KERNEL);
569 BUG_ON(res->ptr == NULL);
570 if (ret)
571 memset(res->ptr, 0, reslen);
572 else {
573 memcpy(res->ptr, _res, reslen);
574 mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE,
575 res->ptr);
576 }
577 }
578 if (cache)
579 up_read(&priv->mib_sem);
580
581 if (response && !ret)
582 islpci_mgt_release(response);
583
584 if (reslen > isl_oid[n].size)
585 printk(KERN_DEBUG
586 "mgt_get_request(0x%x): received data length was bigger "
587 "than expected (%d > %d). Memory is probably corrupted...",
588 oid, reslen, isl_oid[n].size);
589
590 return ret;
591}
592
593/* lock outside */
594int
595mgt_commit_list(islpci_private *priv, enum oid_num_t *l, int n)
596{
597 int i, ret = 0;
598 struct islpci_mgmtframe *response;
599
600 for (i = 0; i < n; i++) {
601 struct oid_t *t = &(isl_oid[l[i]]);
602 void *data = priv->mib[l[i]];
603 int j = 0;
604 u32 oid = t->oid;
605 BUG_ON(data == NULL);
606 while (j <= t->range) {
607 int r = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET,
608 oid, data, t->size,
609 &response);
610 if (response) {
611 r |= (response->header->operation == PIMFOR_OP_ERROR);
612 islpci_mgt_release(response);
613 }
614 if (r)
615 printk(KERN_ERR "%s: mgt_commit_list: failure. "
616 "oid=%08x err=%d\n",
617 priv->ndev->name, oid, r);
618 ret |= r;
619 j++;
620 oid++;
621 data += t->size;
622 }
623 }
624 return ret;
625}
626
627/* Lock outside */
628
629void
630mgt_set(islpci_private *priv, enum oid_num_t n, void *data)
631{
632 BUG_ON(OID_NUM_LAST <= n);
633 BUG_ON(priv->mib[n] == NULL);
634
635 memcpy(priv->mib[n], data, isl_oid[n].size);
636 mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, priv->mib[n]);
637}
638
639void
640mgt_get(islpci_private *priv, enum oid_num_t n, void *res)
641{
642 BUG_ON(OID_NUM_LAST <= n);
643 BUG_ON(priv->mib[n] == NULL);
644 BUG_ON(res == NULL);
645
646 memcpy(res, priv->mib[n], isl_oid[n].size);
647 mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, res);
648}
649
650/* Commits the cache. Lock outside. */
651
652static enum oid_num_t commit_part1[] = {
653 OID_INL_CONFIG,
654 OID_INL_MODE,
655 DOT11_OID_BSSTYPE,
656 DOT11_OID_CHANNEL,
657 DOT11_OID_MLMEAUTOLEVEL
658};
659
660static enum oid_num_t commit_part2[] = {
661 DOT11_OID_SSID,
662 DOT11_OID_PSMBUFFER,
663 DOT11_OID_AUTHENABLE,
664 DOT11_OID_PRIVACYINVOKED,
665 DOT11_OID_EXUNENCRYPTED,
666 DOT11_OID_DEFKEYX, /* MULTIPLE */
667 DOT11_OID_DEFKEYID,
668 DOT11_OID_DOT1XENABLE,
669 OID_INL_DOT11D_CONFORMANCE,
670 /* Do not initialize this - fw < 1.0.4.3 rejects it
671 OID_INL_OUTPUTPOWER,
672 */
673};
674
675/* update the MAC addr. */
676static int
677mgt_update_addr(islpci_private *priv)
678{
679 struct islpci_mgmtframe *res;
680 int ret;
681
682 ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET,
683 isl_oid[GEN_OID_MACADDRESS].oid, NULL,
684 isl_oid[GEN_OID_MACADDRESS].size, &res);
685
686 if ((ret == 0) && res && (res->header->operation != PIMFOR_OP_ERROR))
687 memcpy(priv->ndev->dev_addr, res->data, 6);
688 else
689 ret = -EIO;
690 if (res)
691 islpci_mgt_release(res);
692
693 if (ret)
694 printk(KERN_ERR "%s: mgt_update_addr: failure\n", priv->ndev->name);
695 return ret;
696}
697
698#define VEC_SIZE(a) (sizeof(a)/sizeof(a[0]))
699
700int
701mgt_commit(islpci_private *priv)
702{
703 int rvalue;
704 u32 u;
705
706 if (islpci_get_state(priv) < PRV_STATE_INIT)
707 return 0;
708
709 rvalue = mgt_commit_list(priv, commit_part1, VEC_SIZE(commit_part1));
710
711 if (priv->iw_mode != IW_MODE_MONITOR)
712 rvalue |= mgt_commit_list(priv, commit_part2, VEC_SIZE(commit_part2));
713
714 u = OID_INL_MODE;
715 rvalue |= mgt_commit_list(priv, &u, 1);
716 rvalue |= mgt_update_addr(priv);
717
718 if (rvalue) {
719 /* some request have failed. The device might be in an
720 incoherent state. We should reset it ! */
721 printk(KERN_DEBUG "%s: mgt_commit: failure\n", priv->ndev->name);
722 }
723 return rvalue;
724}
725
726/* The following OIDs need to be "unlatched":
727 *
728 * MEDIUMLIMIT,BEACONPERIOD,DTIMPERIOD,ATIMWINDOW,LISTENINTERVAL
729 * FREQUENCY,EXTENDEDRATES.
730 *
731 * The way to do this is to set ESSID. Note though that they may get
732 * unlatch before though by setting another OID. */
733#if 0
734void
735mgt_unlatch_all(islpci_private *priv)
736{
737 u32 u;
738 int rvalue = 0;
739
740 if (islpci_get_state(priv) < PRV_STATE_INIT)
741 return;
742
743 u = DOT11_OID_SSID;
744 rvalue = mgt_commit_list(priv, &u, 1);
745 /* Necessary if in MANUAL RUN mode? */
746#if 0
747 u = OID_INL_MODE;
748 rvalue |= mgt_commit_list(priv, &u, 1);
749
750 u = DOT11_OID_MLMEAUTOLEVEL;
751 rvalue |= mgt_commit_list(priv, &u, 1);
752
753 u = OID_INL_MODE;
754 rvalue |= mgt_commit_list(priv, &u, 1);
755#endif
756
757 if (rvalue)
758 printk(KERN_DEBUG "%s: Unlatching OIDs failed\n", priv->ndev->name);
759}
760#endif
761
762/* This will tell you if you are allowed to answer a mlme(ex) request .*/
763
764int
765mgt_mlme_answer(islpci_private *priv)
766{
767 u32 mlmeautolevel;
768 /* Acquire a read lock because if we are in a mode change, it's
769 * possible to answer true, while the card is leaving master to managed
770 * mode. Answering to a mlme in this situation could hang the card.
771 */
772 down_read(&priv->mib_sem);
773 mlmeautolevel =
774 le32_to_cpu(*(u32 *) priv->mib[DOT11_OID_MLMEAUTOLEVEL]);
775 up_read(&priv->mib_sem);
776
777 return ((priv->iw_mode == IW_MODE_MASTER) &&
778 (mlmeautolevel >= DOT11_MLME_INTERMEDIATE));
779}
780
781enum oid_num_t
782mgt_oidtonum(u32 oid)
783{
784 int i;
785
786 for (i = 0; i < OID_NUM_LAST; i++)
787 if (isl_oid[i].oid == oid)
788 return i;
789
790 printk(KERN_DEBUG "looking for an unknown oid 0x%x", oid);
791
792 return OID_NUM_LAST;
793}
794
795int
796mgt_response_to_str(enum oid_num_t n, union oid_res_t *r, char *str)
797{
798 switch (isl_oid[n].flags & OID_FLAG_TYPE) {
799 case OID_TYPE_U32:
800 return snprintf(str, PRIV_STR_SIZE, "%u\n", r->u);
801 break;
802 case OID_TYPE_BUFFER:{
803 struct obj_buffer *buff = r->ptr;
804 return snprintf(str, PRIV_STR_SIZE,
805 "size=%u\naddr=0x%X\n", buff->size,
806 buff->addr);
807 }
808 break;
809 case OID_TYPE_BSS:{
810 struct obj_bss *bss = r->ptr;
811 return snprintf(str, PRIV_STR_SIZE,
812 "age=%u\nchannel=%u\n"
813 "capinfo=0x%X\nrates=0x%X\n"
814 "basic_rates=0x%X\n", bss->age,
815 bss->channel, bss->capinfo,
816 bss->rates, bss->basic_rates);
817 }
818 break;
819 case OID_TYPE_BSSLIST:{
820 struct obj_bsslist *list = r->ptr;
821 int i, k;
822 k = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", list->nr);
823 for (i = 0; i < list->nr; i++)
824 k += snprintf(str + k, PRIV_STR_SIZE - k,
825 "bss[%u] : \nage=%u\nchannel=%u\n"
826 "capinfo=0x%X\nrates=0x%X\n"
827 "basic_rates=0x%X\n",
828 i, list->bsslist[i].age,
829 list->bsslist[i].channel,
830 list->bsslist[i].capinfo,
831 list->bsslist[i].rates,
832 list->bsslist[i].basic_rates);
833 return k;
834 }
835 break;
836 case OID_TYPE_FREQUENCIES:{
837 struct obj_frequencies *freq = r->ptr;
838 int i, t;
839 printk("nr : %u\n", freq->nr);
840 t = snprintf(str, PRIV_STR_SIZE, "nr=%u\n", freq->nr);
841 for (i = 0; i < freq->nr; i++)
842 t += snprintf(str + t, PRIV_STR_SIZE - t,
843 "mhz[%u]=%u\n", i, freq->mhz[i]);
844 return t;
845 }
846 break;
847 case OID_TYPE_MLME:{
848 struct obj_mlme *mlme = r->ptr;
849 return snprintf(str, PRIV_STR_SIZE,
850 "id=0x%X\nstate=0x%X\ncode=0x%X\n",
851 mlme->id, mlme->state, mlme->code);
852 }
853 break;
854 case OID_TYPE_MLMEEX:{
855 struct obj_mlmeex *mlme = r->ptr;
856 return snprintf(str, PRIV_STR_SIZE,
857 "id=0x%X\nstate=0x%X\n"
858 "code=0x%X\nsize=0x%X\n", mlme->id,
859 mlme->state, mlme->code, mlme->size);
860 }
861 break;
862 case OID_TYPE_ATTACH:{
863 struct obj_attachment *attach = r->ptr;
864 return snprintf(str, PRIV_STR_SIZE,
865 "id=%d\nsize=%d\n",
866 attach->id,
867 attach->size);
868 }
869 break;
870 case OID_TYPE_SSID:{
871 struct obj_ssid *ssid = r->ptr;
872 return snprintf(str, PRIV_STR_SIZE,
873 "length=%u\noctets=%.*s\n",
874 ssid->length, ssid->length,
875 ssid->octets);
876 }
877 break;
878 case OID_TYPE_KEY:{
879 struct obj_key *key = r->ptr;
880 int t, i;
881 t = snprintf(str, PRIV_STR_SIZE,
882 "type=0x%X\nlength=0x%X\nkey=0x",
883 key->type, key->length);
884 for (i = 0; i < key->length; i++)
885 t += snprintf(str + t, PRIV_STR_SIZE - t,
886 "%02X:", key->key[i]);
887 t += snprintf(str + t, PRIV_STR_SIZE - t, "\n");
888 return t;
889 }
890 break;
891 case OID_TYPE_RAW:
892 case OID_TYPE_ADDR:{
893 unsigned char *buff = r->ptr;
894 int t, i;
895 t = snprintf(str, PRIV_STR_SIZE, "hex data=");
896 for (i = 0; i < isl_oid[n].size; i++)
897 t += snprintf(str + t, PRIV_STR_SIZE - t,
898 "%02X:", buff[i]);
899 t += snprintf(str + t, PRIV_STR_SIZE - t, "\n");
900 return t;
901 }
902 break;
903 default:
904 BUG();
905 }
906 return 0;
907}
diff --git a/drivers/net/wireless/prism54/oid_mgt.h b/drivers/net/wireless/prism54/oid_mgt.h
new file mode 100644
index 000000000000..92c8a2d4acd8
--- /dev/null
+++ b/drivers/net/wireless/prism54/oid_mgt.h
@@ -0,0 +1,59 @@
1/*
2 * Copyright (C) 2003 Aurelien Alleaume <slts@free.fr>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 */
18
19#if !defined(_OID_MGT_H)
20#define _OID_MGT_H
21
22#include "isl_oid.h"
23#include "islpci_dev.h"
24
25extern struct oid_t isl_oid[];
26
27int mgt_init(islpci_private *);
28
29void mgt_clean(islpci_private *);
30
31/* I don't know where to put these 2 */
32extern const int frequency_list_a[];
33int channel_of_freq(int);
34
35void mgt_le_to_cpu(int, void *);
36
37int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);
38int mgt_set_varlen(islpci_private *, enum oid_num_t, void *, int);
39
40
41int mgt_get_request(islpci_private *, enum oid_num_t, int, void *,
42 union oid_res_t *);
43
44int mgt_commit_list(islpci_private *, enum oid_num_t *, int);
45
46void mgt_set(islpci_private *, enum oid_num_t, void *);
47
48void mgt_get(islpci_private *, enum oid_num_t, void *);
49
50int mgt_commit(islpci_private *);
51
52int mgt_mlme_answer(islpci_private *);
53
54enum oid_num_t mgt_oidtonum(u32 oid);
55
56int mgt_response_to_str(enum oid_num_t, union oid_res_t *, char *);
57
58#endif /* !defined(_OID_MGT_H) */
59/* EOF */
diff --git a/drivers/net/wireless/prism54/prismcompat.h b/drivers/net/wireless/prism54/prismcompat.h
new file mode 100644
index 000000000000..55541c01752e
--- /dev/null
+++ b/drivers/net/wireless/prism54/prismcompat.h
@@ -0,0 +1,44 @@
1/*
2 * (C) 2004 Margit Schubert-While <margitsw@t-online.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 */
18
19/*
20 * Compatibility header file to aid support of different kernel versions
21 */
22
23#ifdef PRISM54_COMPAT24
24#include "prismcompat24.h"
25#else /* PRISM54_COMPAT24 */
26
27#ifndef _PRISM_COMPAT_H
28#define _PRISM_COMPAT_H
29
30#include <linux/device.h>
31#include <linux/firmware.h>
32#include <linux/config.h>
33#include <linux/moduleparam.h>
34#include <linux/workqueue.h>
35#include <linux/compiler.h>
36
37#ifndef __iomem
38#define __iomem
39#endif
40
41#define PRISM_FW_PDEV &priv->pdev->dev
42
43#endif /* _PRISM_COMPAT_H */
44#endif /* PRISM54_COMPAT24 */
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
new file mode 100644
index 000000000000..6e5bda56b8f8
--- /dev/null
+++ b/drivers/net/wireless/ray_cs.c
@@ -0,0 +1,2957 @@
1/*=============================================================================
2 *
3 * A PCMCIA client driver for the Raylink wireless LAN card.
4 * The starting point for this module was the skeleton.c in the
5 * PCMCIA 2.9.12 package written by David Hinds, dahinds@users.sourceforge.net
6 *
7 *
8 * Copyright (c) 1998 Corey Thomas (corey@world.std.com)
9 *
10 * This driver is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 only of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * It is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 *
23 * Changes:
24 * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/08/2000
25 * - reorganize kmallocs in ray_attach, checking all for failure
26 * and releasing the previous allocations if one fails
27 *
28 * Daniele Bellucci <bellucda@tiscali.it> - 07/10/2003
29 * - Audit copy_to_user in ioctl(SIOCGIWESSID)
30 *
31=============================================================================*/
32
33#include <linux/config.h>
34#include <linux/module.h>
35#include <linux/kernel.h>
36#include <linux/proc_fs.h>
37#include <linux/ptrace.h>
38#include <linux/slab.h>
39#include <linux/string.h>
40#include <linux/timer.h>
41#include <linux/init.h>
42#include <linux/netdevice.h>
43#include <linux/etherdevice.h>
44#include <linux/if_arp.h>
45#include <linux/ioport.h>
46#include <linux/skbuff.h>
47#include <linux/ethtool.h>
48
49#include <pcmcia/version.h>
50#include <pcmcia/cs_types.h>
51#include <pcmcia/cs.h>
52#include <pcmcia/cistpl.h>
53#include <pcmcia/cisreg.h>
54#include <pcmcia/ds.h>
55#include <pcmcia/mem_op.h>
56
57#include <linux/wireless.h>
58
59#include <asm/io.h>
60#include <asm/system.h>
61#include <asm/byteorder.h>
62#include <asm/uaccess.h>
63
64/* Warning : these stuff will slow down the driver... */
65#define WIRELESS_SPY /* Enable spying addresses */
66/* Definitions we need for spy */
67typedef struct iw_statistics iw_stats;
68typedef struct iw_quality iw_qual;
69typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */
70
71#include "rayctl.h"
72#include "ray_cs.h"
73
74/* All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
75 you do not define PCMCIA_DEBUG at all, all the debug code will be
76 left out. If you compile with PCMCIA_DEBUG=0, the debug code will
77 be present but disabled -- but it can then be enabled for specific
78 modules at load time with a 'pc_debug=#' option to insmod.
79*/
80
81#ifdef RAYLINK_DEBUG
82#define PCMCIA_DEBUG RAYLINK_DEBUG
83#endif
84#ifdef PCMCIA_DEBUG
85static int ray_debug;
86static int pc_debug = PCMCIA_DEBUG;
87module_param(pc_debug, int, 0);
88/* #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); */
89#define DEBUG(n, args...) if (pc_debug>(n)) printk(args);
90#else
91#define DEBUG(n, args...)
92#endif
93/** Prototypes based on PCMCIA skeleton driver *******************************/
94static void ray_config(dev_link_t *link);
95static void ray_release(dev_link_t *link);
96static int ray_event(event_t event, int priority, event_callback_args_t *args);
97static dev_link_t *ray_attach(void);
98static void ray_detach(dev_link_t *);
99
100/***** Prototypes indicated by device structure ******************************/
101static int ray_dev_close(struct net_device *dev);
102static int ray_dev_config(struct net_device *dev, struct ifmap *map);
103static struct net_device_stats *ray_get_stats(struct net_device *dev);
104static int ray_dev_init(struct net_device *dev);
105static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
106
107static struct ethtool_ops netdev_ethtool_ops;
108
109static int ray_open(struct net_device *dev);
110static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev);
111static void set_multicast_list(struct net_device *dev);
112static void ray_update_multi_list(struct net_device *dev, int all);
113static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
114 unsigned char *data, int len);
115static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type,
116 unsigned char *data);
117static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len);
118#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */
119static iw_stats * ray_get_wireless_stats(struct net_device * dev);
120#endif /* WIRELESS_EXT > 7 */
121
122/***** Prototypes for raylink functions **************************************/
123static int asc_to_int(char a);
124static void authenticate(ray_dev_t *local);
125static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type);
126static void authenticate_timeout(u_long);
127static int get_free_ccs(ray_dev_t *local);
128static int get_free_tx_ccs(ray_dev_t *local);
129static void init_startup_params(ray_dev_t *local);
130static int parse_addr(char *in_str, UCHAR *out);
131static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, UCHAR type);
132static int ray_init(struct net_device *dev);
133static int interrupt_ecf(ray_dev_t *local, int ccs);
134static void ray_reset(struct net_device *dev);
135static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len);
136static void verify_dl_startup(u_long);
137
138/* Prototypes for interrpt time functions **********************************/
139static irqreturn_t ray_interrupt (int reg, void *dev_id, struct pt_regs *regs);
140static void clear_interrupt(ray_dev_t *local);
141static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
142 unsigned int pkt_addr, int rx_len);
143static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int len);
144static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs __iomem *prcs);
145static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs);
146static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
147 unsigned int pkt_addr, int rx_len);
148static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned int pkt_addr,
149 int rx_len);
150static void associate(ray_dev_t *local);
151
152/* Card command functions */
153static int dl_startup_params(struct net_device *dev);
154static void join_net(u_long local);
155static void start_net(u_long local);
156/* void start_net(ray_dev_t *local); */
157
158/*===========================================================================*/
159/* Parameters that can be set with 'insmod' */
160
161/* ADHOC=0, Infrastructure=1 */
162static int net_type = ADHOC;
163
164/* Hop dwell time in Kus (1024 us units defined by 802.11) */
165static int hop_dwell = 128;
166
167/* Beacon period in Kus */
168static int beacon_period = 256;
169
170/* power save mode (0 = off, 1 = save power) */
171static int psm;
172
173/* String for network's Extended Service Set ID. 32 Characters max */
174static char *essid;
175
176/* Default to encapsulation unless translation requested */
177static int translate = 1;
178
179static int country = USA;
180
181static int sniffer;
182
183static int bc;
184
185/* 48 bit physical card address if overriding card's real physical
186 * address is required. Since IEEE 802.11 addresses are 48 bits
187 * like ethernet, an int can't be used, so a string is used. To
188 * allow use of addresses starting with a decimal digit, the first
189 * character must be a letter and will be ignored. This letter is
190 * followed by up to 12 hex digits which are the address. If less
191 * than 12 digits are used, the address will be left filled with 0's.
192 * Note that bit 0 of the first byte is the broadcast bit, and evil
193 * things will happen if it is not 0 in a card address.
194 */
195static char *phy_addr = NULL;
196
197
198/* The dev_info variable is the "key" that is used to match up this
199 device driver with appropriate cards, through the card configuration
200 database.
201*/
202static dev_info_t dev_info = "ray_cs";
203
204/* A linked list of "instances" of the ray device. Each actual
205 PCMCIA card corresponds to one device instance, and is described
206 by one dev_link_t structure (defined in ds.h).
207*/
208static dev_link_t *dev_list = NULL;
209
210/* A dev_link_t structure has fields for most things that are needed
211 to keep track of a socket, but there will usually be some device
212 specific information that also needs to be kept track of. The
213 'priv' pointer in a dev_link_t structure can be used to point to
214 a device-specific private data structure, like this.
215*/
216static unsigned int ray_mem_speed = 500;
217
218MODULE_AUTHOR("Corey Thomas <corey@world.std.com>");
219MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");
220MODULE_LICENSE("GPL");
221
222module_param(net_type, int, 0);
223module_param(hop_dwell, int, 0);
224module_param(beacon_period, int, 0);
225module_param(psm, int, 0);
226module_param(essid, charp, 0);
227module_param(translate, int, 0);
228module_param(country, int, 0);
229module_param(sniffer, int, 0);
230module_param(bc, int, 0);
231module_param(phy_addr, charp, 0);
232module_param(ray_mem_speed, int, 0);
233
234static UCHAR b5_default_startup_parms[] = {
235 0, 0, /* Adhoc station */
236 'L','I','N','U','X', 0, 0, 0, /* 32 char ESSID */
237 0, 0, 0, 0, 0, 0, 0, 0,
238 0, 0, 0, 0, 0, 0, 0, 0,
239 0, 0, 0, 0, 0, 0, 0, 0,
240 1, 0, /* Active scan, CA Mode */
241 0, 0, 0, 0, 0, 0, /* No default MAC addr */
242 0x7f, 0xff, /* Frag threshold */
243 0x00, 0x80, /* Hop time 128 Kus*/
244 0x01, 0x00, /* Beacon period 256 Kus */
245 0x01, 0x07, 0xa3, /* DTIM, retries, ack timeout*/
246 0x1d, 0x82, 0x4e, /* SIFS, DIFS, PIFS */
247 0x7f, 0xff, /* RTS threshold */
248 0x04, 0xe2, 0x38, 0xA4, /* scan_dwell, max_scan_dwell */
249 0x05, /* assoc resp timeout thresh */
250 0x08, 0x02, 0x08, /* adhoc, infra, super cycle max*/
251 0, /* Promiscuous mode */
252 0x0c, 0x0bd, /* Unique word */
253 0x32, /* Slot time */
254 0xff, 0xff, /* roam-low snr, low snr count */
255 0x05, 0xff, /* Infra, adhoc missed bcn thresh */
256 0x01, 0x0b, 0x4f, /* USA, hop pattern, hop pat length */
257/* b4 - b5 differences start here */
258 0x00, 0x3f, /* CW max */
259 0x00, 0x0f, /* CW min */
260 0x04, 0x08, /* Noise gain, limit offset */
261 0x28, 0x28, /* det rssi, med busy offsets */
262 7, /* det sync thresh */
263 0, 2, 2, /* test mode, min, max */
264 0, /* allow broadcast SSID probe resp */
265 0, 0, /* privacy must start, can join */
266 2, 0, 0, 0, 0, 0, 0, 0 /* basic rate set */
267};
268
269static UCHAR b4_default_startup_parms[] = {
270 0, 0, /* Adhoc station */
271 'L','I','N','U','X', 0, 0, 0, /* 32 char ESSID */
272 0, 0, 0, 0, 0, 0, 0, 0,
273 0, 0, 0, 0, 0, 0, 0, 0,
274 0, 0, 0, 0, 0, 0, 0, 0,
275 1, 0, /* Active scan, CA Mode */
276 0, 0, 0, 0, 0, 0, /* No default MAC addr */
277 0x7f, 0xff, /* Frag threshold */
278 0x02, 0x00, /* Hop time */
279 0x00, 0x01, /* Beacon period */
280 0x01, 0x07, 0xa3, /* DTIM, retries, ack timeout*/
281 0x1d, 0x82, 0xce, /* SIFS, DIFS, PIFS */
282 0x7f, 0xff, /* RTS threshold */
283 0xfb, 0x1e, 0xc7, 0x5c, /* scan_dwell, max_scan_dwell */
284 0x05, /* assoc resp timeout thresh */
285 0x04, 0x02, 0x4, /* adhoc, infra, super cycle max*/
286 0, /* Promiscuous mode */
287 0x0c, 0x0bd, /* Unique word */
288 0x4e, /* Slot time (TBD seems wrong)*/
289 0xff, 0xff, /* roam-low snr, low snr count */
290 0x05, 0xff, /* Infra, adhoc missed bcn thresh */
291 0x01, 0x0b, 0x4e, /* USA, hop pattern, hop pat length */
292/* b4 - b5 differences start here */
293 0x3f, 0x0f, /* CW max, min */
294 0x04, 0x08, /* Noise gain, limit offset */
295 0x28, 0x28, /* det rssi, med busy offsets */
296 7, /* det sync thresh */
297 0, 2, 2 /* test mode, min, max*/
298};
299/*===========================================================================*/
300static unsigned char eth2_llc[] = {0xaa, 0xaa, 3, 0, 0, 0};
301
302static char hop_pattern_length[] = { 1,
303 USA_HOP_MOD, EUROPE_HOP_MOD,
304 JAPAN_HOP_MOD, KOREA_HOP_MOD,
305 SPAIN_HOP_MOD, FRANCE_HOP_MOD,
306 ISRAEL_HOP_MOD, AUSTRALIA_HOP_MOD,
307 JAPAN_TEST_HOP_MOD
308};
309
310static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
311
312/*=============================================================================
313 ray_attach() creates an "instance" of the driver, allocating
314 local data structures for one device. The device is registered
315 with Card Services.
316 The dev_link structure is initialized, but we don't actually
317 configure the card at this point -- we wait until we receive a
318 card insertion event.
319=============================================================================*/
320static dev_link_t *ray_attach(void)
321{
322 client_reg_t client_reg;
323 dev_link_t *link;
324 ray_dev_t *local;
325 int ret;
326 struct net_device *dev;
327
328 DEBUG(1, "ray_attach()\n");
329
330 /* Initialize the dev_link_t structure */
331 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
332
333 if (!link)
334 return NULL;
335
336 /* Allocate space for private device-specific data */
337 dev = alloc_etherdev(sizeof(ray_dev_t));
338
339 if (!dev)
340 goto fail_alloc_dev;
341
342 local = dev->priv;
343
344 memset(link, 0, sizeof(struct dev_link_t));
345
346 /* The io structure describes IO port mapping. None used here */
347 link->io.NumPorts1 = 0;
348 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
349 link->io.IOAddrLines = 5;
350
351 /* Interrupt setup. For PCMCIA, driver takes what's given */
352 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
353 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
354 link->irq.Handler = &ray_interrupt;
355
356 /* General socket configuration */
357 link->conf.Attributes = CONF_ENABLE_IRQ;
358 link->conf.Vcc = 50;
359 link->conf.IntType = INT_MEMORY_AND_IO;
360 link->conf.ConfigIndex = 1;
361 link->conf.Present = PRESENT_OPTION;
362
363 link->priv = dev;
364 link->irq.Instance = dev;
365
366 local->finder = link;
367 local->card_status = CARD_INSERTED;
368 local->authentication_state = UNAUTHENTICATED;
369 local->num_multi = 0;
370 DEBUG(2,"ray_attach link = %p, dev = %p, local = %p, intr = %p\n",
371 link,dev,local,&ray_interrupt);
372
373 /* Raylink entries in the device structure */
374 dev->hard_start_xmit = &ray_dev_start_xmit;
375 dev->set_config = &ray_dev_config;
376 dev->get_stats = &ray_get_stats;
377 dev->do_ioctl = &ray_dev_ioctl;
378 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
379#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */
380 dev->get_wireless_stats = ray_get_wireless_stats;
381#endif
382
383 dev->set_multicast_list = &set_multicast_list;
384
385 DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n");
386 SET_MODULE_OWNER(dev);
387 dev->init = &ray_dev_init;
388 dev->open = &ray_open;
389 dev->stop = &ray_dev_close;
390 netif_stop_queue(dev);
391
392 /* Register with Card Services */
393 link->next = dev_list;
394 dev_list = link;
395 client_reg.dev_info = &dev_info;
396 client_reg.EventMask =
397 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
398 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
399 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
400 client_reg.event_handler = &ray_event;
401 client_reg.Version = 0x0210;
402 client_reg.event_callback_args.client_data = link;
403
404 DEBUG(2,"ray_cs ray_attach calling pcmcia_register_client(...)\n");
405
406 init_timer(&local->timer);
407
408 ret = pcmcia_register_client(&link->handle, &client_reg);
409 if (ret != 0) {
410 printk("ray_cs ray_attach RegisterClient unhappy - detaching\n");
411 cs_error(link->handle, RegisterClient, ret);
412 ray_detach(link);
413 return NULL;
414 }
415 DEBUG(2,"ray_cs ray_attach ending\n");
416 return link;
417
418fail_alloc_dev:
419 kfree(link);
420 return NULL;
421} /* ray_attach */
422/*=============================================================================
423 This deletes a driver "instance". The device is de-registered
424 with Card Services. If it has been released, all local data
425 structures are freed. Otherwise, the structures will be freed
426 when the device is released.
427=============================================================================*/
428static void ray_detach(dev_link_t *link)
429{
430 dev_link_t **linkp;
431
432 DEBUG(1, "ray_detach(0x%p)\n", link);
433
434 /* Locate device structure */
435 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
436 if (*linkp == link) break;
437 if (*linkp == NULL)
438 return;
439
440 /* If the device is currently configured and active, we won't
441 actually delete it yet. Instead, it is marked so that when
442 the release() function is called, that will trigger a proper
443 detach().
444 */
445 if (link->state & DEV_CONFIG)
446 ray_release(link);
447
448 /* Break the link with Card Services */
449 if (link->handle)
450 pcmcia_deregister_client(link->handle);
451
452 /* Unlink device structure, free pieces */
453 *linkp = link->next;
454 if (link->priv) {
455 struct net_device *dev = link->priv;
456 if (link->dev) unregister_netdev(dev);
457 free_netdev(dev);
458 }
459 kfree(link);
460 DEBUG(2,"ray_cs ray_detach ending\n");
461} /* ray_detach */
462/*=============================================================================
463 ray_config() is run after a CARD_INSERTION event
464 is received, to configure the PCMCIA socket, and to make the
465 ethernet device available to the system.
466=============================================================================*/
467#define CS_CHECK(fn, ret) \
468do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
469#define MAX_TUPLE_SIZE 128
470static void ray_config(dev_link_t *link)
471{
472 client_handle_t handle = link->handle;
473 tuple_t tuple;
474 cisparse_t parse;
475 int last_fn = 0, last_ret = 0;
476 int i;
477 u_char buf[MAX_TUPLE_SIZE];
478 win_req_t req;
479 memreq_t mem;
480 struct net_device *dev = (struct net_device *)link->priv;
481 ray_dev_t *local = (ray_dev_t *)dev->priv;
482
483 DEBUG(1, "ray_config(0x%p)\n", link);
484
485 /* This reads the card's CONFIG tuple to find its configuration regs */
486 tuple.DesiredTuple = CISTPL_CONFIG;
487 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
488 tuple.TupleData = buf;
489 tuple.TupleDataMax = MAX_TUPLE_SIZE;
490 tuple.TupleOffset = 0;
491 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
492 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
493 link->conf.ConfigBase = parse.config.base;
494 link->conf.Present = parse.config.rmask[0];
495
496 /* Determine card type and firmware version */
497 buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0;
498 tuple.DesiredTuple = CISTPL_VERS_1;
499 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
500 tuple.TupleData = buf;
501 tuple.TupleDataMax = MAX_TUPLE_SIZE;
502 tuple.TupleOffset = 2;
503 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
504
505 for (i=0; i<tuple.TupleDataLen - 4; i++)
506 if (buf[i] == 0) buf[i] = ' ';
507 printk(KERN_INFO "ray_cs Detected: %s\n",buf);
508
509 /* Configure card */
510 link->state |= DEV_CONFIG;
511
512 /* Now allocate an interrupt line. Note that this does not
513 actually assign a handler to the interrupt.
514 */
515 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
516 dev->irq = link->irq.AssignedIRQ;
517
518 /* This actually configures the PCMCIA socket -- setting up
519 the I/O windows and the interrupt mapping.
520 */
521 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
522
523/*** Set up 32k window for shared memory (transmit and control) ************/
524 req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
525 req.Base = 0;
526 req.Size = 0x8000;
527 req.AccessSpeed = ray_mem_speed;
528 CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
529 mem.CardOffset = 0x0000; mem.Page = 0;
530 CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
531 local->sram = ioremap(req.Base,req.Size);
532
533/*** Set up 16k window for shared memory (receive buffer) ***************/
534 req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
535 req.Base = 0;
536 req.Size = 0x4000;
537 req.AccessSpeed = ray_mem_speed;
538 CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &local->rmem_handle));
539 mem.CardOffset = 0x8000; mem.Page = 0;
540 CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
541 local->rmem = ioremap(req.Base,req.Size);
542
543/*** Set up window for attribute memory ***********************************/
544 req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT;
545 req.Base = 0;
546 req.Size = 0x1000;
547 req.AccessSpeed = ray_mem_speed;
548 CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &local->amem_handle));
549 mem.CardOffset = 0x0000; mem.Page = 0;
550 CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
551 local->amem = ioremap(req.Base,req.Size);
552
553 DEBUG(3,"ray_config sram=%p\n",local->sram);
554 DEBUG(3,"ray_config rmem=%p\n",local->rmem);
555 DEBUG(3,"ray_config amem=%p\n",local->amem);
556 if (ray_init(dev) < 0) {
557 ray_release(link);
558 return;
559 }
560
561 SET_NETDEV_DEV(dev, &handle_to_dev(handle));
562 i = register_netdev(dev);
563 if (i != 0) {
564 printk("ray_config register_netdev() failed\n");
565 ray_release(link);
566 return;
567 }
568
569 strcpy(local->node.dev_name, dev->name);
570 link->dev = &local->node;
571
572 link->state &= ~DEV_CONFIG_PENDING;
573 printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ",
574 dev->name, dev->irq);
575 for (i = 0; i < 6; i++)
576 printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
577
578 return;
579
580cs_failed:
581 cs_error(link->handle, last_fn, last_ret);
582
583 ray_release(link);
584} /* ray_config */
585
586static inline struct ccs __iomem *ccs_base(ray_dev_t *dev)
587{
588 return dev->sram + CCS_BASE;
589}
590
591static inline struct rcs __iomem *rcs_base(ray_dev_t *dev)
592{
593 /*
594 * This looks nonsensical, since there is a separate
595 * RCS_BASE. But the difference between a "struct rcs"
596 * and a "struct ccs" ends up being in the _index_ off
597 * the base, so the base pointer is the same for both
598 * ccs/rcs.
599 */
600 return dev->sram + CCS_BASE;
601}
602
603/*===========================================================================*/
604static int ray_init(struct net_device *dev)
605{
606 int i;
607 UCHAR *p;
608 struct ccs __iomem *pccs;
609 ray_dev_t *local = (ray_dev_t *)dev->priv;
610 dev_link_t *link = local->finder;
611 DEBUG(1, "ray_init(0x%p)\n", dev);
612 if (!(link->state & DEV_PRESENT)) {
613 DEBUG(0,"ray_init - device not present\n");
614 return -1;
615 }
616
617 local->net_type = net_type;
618 local->sta_type = TYPE_STA;
619
620 /* Copy the startup results to local memory */
621 memcpy_fromio(&local->startup_res, local->sram + ECF_TO_HOST_BASE,\
622 sizeof(struct startup_res_6));
623
624 /* Check Power up test status and get mac address from card */
625 if (local->startup_res.startup_word != 0x80) {
626 printk(KERN_INFO "ray_init ERROR card status = %2x\n",
627 local->startup_res.startup_word);
628 local->card_status = CARD_INIT_ERROR;
629 return -1;
630 }
631
632 local->fw_ver = local->startup_res.firmware_version[0];
633 local->fw_bld = local->startup_res.firmware_version[1];
634 local->fw_var = local->startup_res.firmware_version[2];
635 DEBUG(1,"ray_init firmware version %d.%d \n",local->fw_ver, local->fw_bld);
636
637 local->tib_length = 0x20;
638 if ((local->fw_ver == 5) && (local->fw_bld >= 30))
639 local->tib_length = local->startup_res.tib_length;
640 DEBUG(2,"ray_init tib_length = 0x%02x\n", local->tib_length);
641 /* Initialize CCS's to buffer free state */
642 pccs = ccs_base(local);
643 for (i=0; i<NUMBER_OF_CCS; i++) {
644 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
645 }
646 init_startup_params(local);
647
648 /* copy mac address to startup parameters */
649 if (parse_addr(phy_addr, local->sparm.b4.a_mac_addr))
650 {
651 p = local->sparm.b4.a_mac_addr;
652 }
653 else
654 {
655 memcpy(&local->sparm.b4.a_mac_addr,
656 &local->startup_res.station_addr, ADDRLEN);
657 p = local->sparm.b4.a_mac_addr;
658 }
659
660 clear_interrupt(local); /* Clear any interrupt from the card */
661 local->card_status = CARD_AWAITING_PARAM;
662 DEBUG(2,"ray_init ending\n");
663 return 0;
664} /* ray_init */
665/*===========================================================================*/
666/* Download startup parameters to the card and command it to read them */
667static int dl_startup_params(struct net_device *dev)
668{
669 int ccsindex;
670 ray_dev_t *local = (ray_dev_t *)dev->priv;
671 struct ccs __iomem *pccs;
672 dev_link_t *link = local->finder;
673
674 DEBUG(1,"dl_startup_params entered\n");
675 if (!(link->state & DEV_PRESENT)) {
676 DEBUG(2,"ray_cs dl_startup_params - device not present\n");
677 return -1;
678 }
679
680 /* Copy parameters to host to ECF area */
681 if (local->fw_ver == 0x55)
682 memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b4,
683 sizeof(struct b4_startup_params));
684 else
685 memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b5,
686 sizeof(struct b5_startup_params));
687
688
689 /* Fill in the CCS fields for the ECF */
690 if ((ccsindex = get_free_ccs(local)) < 0) return -1;
691 local->dl_param_ccs = ccsindex;
692 pccs = ccs_base(local) + ccsindex;
693 writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd);
694 DEBUG(2,"dl_startup_params start ccsindex = %d\n", local->dl_param_ccs);
695 /* Interrupt the firmware to process the command */
696 if (interrupt_ecf(local, ccsindex)) {
697 printk(KERN_INFO "ray dl_startup_params failed - "
698 "ECF not ready for intr\n");
699 local->card_status = CARD_DL_PARAM_ERROR;
700 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
701 return -2;
702 }
703 local->card_status = CARD_DL_PARAM;
704 /* Start kernel timer to wait for dl startup to complete. */
705 local->timer.expires = jiffies + HZ/2;
706 local->timer.data = (long)local;
707 local->timer.function = &verify_dl_startup;
708 add_timer(&local->timer);
709 DEBUG(2,"ray_cs dl_startup_params started timer for verify_dl_startup\n");
710 return 0;
711} /* dl_startup_params */
712/*===========================================================================*/
713static void init_startup_params(ray_dev_t *local)
714{
715 int i;
716
717 if (country > JAPAN_TEST) country = USA;
718 else
719 if (country < USA) country = USA;
720 /* structure for hop time and beacon period is defined here using
721 * New 802.11D6.1 format. Card firmware is still using old format
722 * until version 6.
723 * Before After
724 * a_hop_time ms byte a_hop_time ms byte
725 * a_hop_time 2s byte a_hop_time ls byte
726 * a_hop_time ls byte a_beacon_period ms byte
727 * a_beacon_period a_beacon_period ls byte
728 *
729 * a_hop_time = uS a_hop_time = KuS
730 * a_beacon_period = hops a_beacon_period = KuS
731 */ /* 64ms = 010000 */
732 if (local->fw_ver == 0x55) {
733 memcpy((UCHAR *)&local->sparm.b4, b4_default_startup_parms,
734 sizeof(struct b4_startup_params));
735 /* Translate sane kus input values to old build 4/5 format */
736 /* i = hop time in uS truncated to 3 bytes */
737 i = (hop_dwell * 1024) & 0xffffff;
738 local->sparm.b4.a_hop_time[0] = (i >> 16) & 0xff;
739 local->sparm.b4.a_hop_time[1] = (i >> 8) & 0xff;
740 local->sparm.b4.a_beacon_period[0] = 0;
741 local->sparm.b4.a_beacon_period[1] =
742 ((beacon_period/hop_dwell) - 1) & 0xff;
743 local->sparm.b4.a_curr_country_code = country;
744 local->sparm.b4.a_hop_pattern_length =
745 hop_pattern_length[(int)country] - 1;
746 if (bc)
747 {
748 local->sparm.b4.a_ack_timeout = 0x50;
749 local->sparm.b4.a_sifs = 0x3f;
750 }
751 }
752 else { /* Version 5 uses real kus values */
753 memcpy((UCHAR *)&local->sparm.b5, b5_default_startup_parms,
754 sizeof(struct b5_startup_params));
755
756 local->sparm.b5.a_hop_time[0] = (hop_dwell >> 8) & 0xff;
757 local->sparm.b5.a_hop_time[1] = hop_dwell & 0xff;
758 local->sparm.b5.a_beacon_period[0] = (beacon_period >> 8) & 0xff;
759 local->sparm.b5.a_beacon_period[1] = beacon_period & 0xff;
760 if (psm)
761 local->sparm.b5.a_power_mgt_state = 1;
762 local->sparm.b5.a_curr_country_code = country;
763 local->sparm.b5.a_hop_pattern_length =
764 hop_pattern_length[(int)country];
765 }
766
767 local->sparm.b4.a_network_type = net_type & 0x01;
768 local->sparm.b4.a_acting_as_ap_status = TYPE_STA;
769
770 if (essid != NULL)
771 strncpy(local->sparm.b4.a_current_ess_id, essid, ESSID_SIZE);
772} /* init_startup_params */
773/*===========================================================================*/
774static void verify_dl_startup(u_long data)
775{
776 ray_dev_t *local = (ray_dev_t *)data;
777 struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
778 UCHAR status;
779 dev_link_t *link = local->finder;
780
781 if (!(link->state & DEV_PRESENT)) {
782 DEBUG(2,"ray_cs verify_dl_startup - device not present\n");
783 return;
784 }
785#ifdef PCMCIA_DEBUG
786 if (pc_debug > 2) {
787 int i;
788 printk(KERN_DEBUG "verify_dl_startup parameters sent via ccs %d:\n",
789 local->dl_param_ccs);
790 for (i=0; i<sizeof(struct b5_startup_params); i++) {
791 printk(" %2x", (unsigned int) readb(local->sram + HOST_TO_ECF_BASE + i));
792 }
793 printk("\n");
794 }
795#endif
796
797 status = readb(&pccs->buffer_status);
798 if (status!= CCS_BUFFER_FREE)
799 {
800 printk(KERN_INFO "Download startup params failed. Status = %d\n",
801 status);
802 local->card_status = CARD_DL_PARAM_ERROR;
803 return;
804 }
805 if (local->sparm.b4.a_network_type == ADHOC)
806 start_net((u_long)local);
807 else
808 join_net((u_long)local);
809
810 return;
811} /* end verify_dl_startup */
812/*===========================================================================*/
813/* Command card to start a network */
814static void start_net(u_long data)
815{
816 ray_dev_t *local = (ray_dev_t *)data;
817 struct ccs __iomem *pccs;
818 int ccsindex;
819 dev_link_t *link = local->finder;
820 if (!(link->state & DEV_PRESENT)) {
821 DEBUG(2,"ray_cs start_net - device not present\n");
822 return;
823 }
824 /* Fill in the CCS fields for the ECF */
825 if ((ccsindex = get_free_ccs(local)) < 0) return;
826 pccs = ccs_base(local) + ccsindex;
827 writeb(CCS_START_NETWORK, &pccs->cmd);
828 writeb(0, &pccs->var.start_network.update_param);
829 /* Interrupt the firmware to process the command */
830 if (interrupt_ecf(local, ccsindex)) {
831 DEBUG(1,"ray start net failed - card not ready for intr\n");
832 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
833 return;
834 }
835 local->card_status = CARD_DOING_ACQ;
836 return;
837} /* end start_net */
838/*===========================================================================*/
839/* Command card to join a network */
840static void join_net(u_long data)
841{
842 ray_dev_t *local = (ray_dev_t *)data;
843
844 struct ccs __iomem *pccs;
845 int ccsindex;
846 dev_link_t *link = local->finder;
847
848 if (!(link->state & DEV_PRESENT)) {
849 DEBUG(2,"ray_cs join_net - device not present\n");
850 return;
851 }
852 /* Fill in the CCS fields for the ECF */
853 if ((ccsindex = get_free_ccs(local)) < 0) return;
854 pccs = ccs_base(local) + ccsindex;
855 writeb(CCS_JOIN_NETWORK, &pccs->cmd);
856 writeb(0, &pccs->var.join_network.update_param);
857 writeb(0, &pccs->var.join_network.net_initiated);
858 /* Interrupt the firmware to process the command */
859 if (interrupt_ecf(local, ccsindex)) {
860 DEBUG(1,"ray join net failed - card not ready for intr\n");
861 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
862 return;
863 }
864 local->card_status = CARD_DOING_ACQ;
865 return;
866}
867/*============================================================================
868 After a card is removed, ray_release() will unregister the net
869 device, and release the PCMCIA configuration. If the device is
870 still open, this will be postponed until it is closed.
871=============================================================================*/
872static void ray_release(dev_link_t *link)
873{
874 struct net_device *dev = link->priv;
875 ray_dev_t *local = dev->priv;
876 int i;
877
878 DEBUG(1, "ray_release(0x%p)\n", link);
879
880 del_timer(&local->timer);
881 link->state &= ~DEV_CONFIG;
882
883 iounmap(local->sram);
884 iounmap(local->rmem);
885 iounmap(local->amem);
886 /* Do bother checking to see if these succeed or not */
887 i = pcmcia_release_window(link->win);
888 if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(link->win) ret = %x\n",i);
889 i = pcmcia_release_window(local->amem_handle);
890 if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);
891 i = pcmcia_release_window(local->rmem_handle);
892 if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);
893 i = pcmcia_release_configuration(link->handle);
894 if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseConfiguration ret = %x\n",i);
895 i = pcmcia_release_irq(link->handle, &link->irq);
896 if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i);
897
898 DEBUG(2,"ray_release ending\n");
899}
900
901/*=============================================================================
902 The card status event handler. Mostly, this schedules other
903 stuff to run after an event is received. A CARD_REMOVAL event
904 also sets some flags to discourage the net drivers from trying
905 to talk to the card any more.
906
907 When a CARD_REMOVAL event is received, we immediately set a flag
908 to block future accesses to this device. All the functions that
909 actually access the device should check this flag to make sure
910 the card is still present.
911=============================================================================*/
912static int ray_event(event_t event, int priority,
913 event_callback_args_t *args)
914{
915 dev_link_t *link = args->client_data;
916 struct net_device *dev = link->priv;
917 ray_dev_t *local = (ray_dev_t *)dev->priv;
918 DEBUG(1, "ray_event(0x%06x)\n", event);
919
920 switch (event) {
921 case CS_EVENT_CARD_REMOVAL:
922 link->state &= ~DEV_PRESENT;
923 netif_device_detach(dev);
924 if (link->state & DEV_CONFIG) {
925 ray_release(link);
926 del_timer(&local->timer);
927 }
928 break;
929 case CS_EVENT_CARD_INSERTION:
930 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
931 ray_config(link);
932 break;
933 case CS_EVENT_PM_SUSPEND:
934 link->state |= DEV_SUSPEND;
935 /* Fall through... */
936 case CS_EVENT_RESET_PHYSICAL:
937 if (link->state & DEV_CONFIG) {
938 if (link->open)
939 netif_device_detach(dev);
940
941 pcmcia_release_configuration(link->handle);
942 }
943 break;
944 case CS_EVENT_PM_RESUME:
945 link->state &= ~DEV_SUSPEND;
946 /* Fall through... */
947 case CS_EVENT_CARD_RESET:
948 if (link->state & DEV_CONFIG) {
949 pcmcia_request_configuration(link->handle, &link->conf);
950 if (link->open) {
951 ray_reset(dev);
952 netif_device_attach(dev);
953 }
954 }
955 break;
956 }
957 return 0;
958 DEBUG(2,"ray_event ending\n");
959} /* ray_event */
960/*===========================================================================*/
961int ray_dev_init(struct net_device *dev)
962{
963#ifdef RAY_IMMEDIATE_INIT
964 int i;
965#endif /* RAY_IMMEDIATE_INIT */
966 ray_dev_t *local = dev->priv;
967 dev_link_t *link = local->finder;
968
969 DEBUG(1,"ray_dev_init(dev=%p)\n",dev);
970 if (!(link->state & DEV_PRESENT)) {
971 DEBUG(2,"ray_dev_init - device not present\n");
972 return -1;
973 }
974#ifdef RAY_IMMEDIATE_INIT
975 /* Download startup parameters */
976 if ( (i = dl_startup_params(dev)) < 0)
977 {
978 printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
979 "returns 0x%x\n",i);
980 return -1;
981 }
982#else /* RAY_IMMEDIATE_INIT */
983 /* Postpone the card init so that we can still configure the card,
984 * for example using the Wireless Extensions. The init will happen
985 * in ray_open() - Jean II */
986 DEBUG(1,"ray_dev_init: postponing card init to ray_open() ; Status = %d\n",
987 local->card_status);
988#endif /* RAY_IMMEDIATE_INIT */
989
990 /* copy mac and broadcast addresses to linux device */
991 memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
992 memset(dev->broadcast, 0xff, ETH_ALEN);
993
994 DEBUG(2,"ray_dev_init ending\n");
995 return 0;
996}
997/*===========================================================================*/
998static int ray_dev_config(struct net_device *dev, struct ifmap *map)
999{
1000 ray_dev_t *local = dev->priv;
1001 dev_link_t *link = local->finder;
1002 /* Dummy routine to satisfy device structure */
1003 DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map);
1004 if (!(link->state & DEV_PRESENT)) {
1005 DEBUG(2,"ray_dev_config - device not present\n");
1006 return -1;
1007 }
1008
1009 return 0;
1010}
1011/*===========================================================================*/
1012static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
1013{
1014 ray_dev_t *local = dev->priv;
1015 dev_link_t *link = local->finder;
1016 short length = skb->len;
1017
1018 if (!(link->state & DEV_PRESENT)) {
1019 DEBUG(2,"ray_dev_start_xmit - device not present\n");
1020 return -1;
1021 }
1022 DEBUG(3,"ray_dev_start_xmit(skb=%p, dev=%p)\n",skb,dev);
1023 if (local->authentication_state == NEED_TO_AUTH) {
1024 DEBUG(0,"ray_cs Sending authentication request.\n");
1025 if (!build_auth_frame (local, local->auth_id, OPEN_AUTH_REQUEST)) {
1026 local->authentication_state = AUTHENTICATED;
1027 netif_stop_queue(dev);
1028 return 1;
1029 }
1030 }
1031
1032 if (length < ETH_ZLEN)
1033 {
1034 skb = skb_padto(skb, ETH_ZLEN);
1035 if (skb == NULL)
1036 return 0;
1037 length = ETH_ZLEN;
1038 }
1039 switch (ray_hw_xmit( skb->data, length, dev, DATA_TYPE)) {
1040 case XMIT_NO_CCS:
1041 case XMIT_NEED_AUTH:
1042 netif_stop_queue(dev);
1043 return 1;
1044 case XMIT_NO_INTR:
1045 case XMIT_MSG_BAD:
1046 case XMIT_OK:
1047 default:
1048 dev->trans_start = jiffies;
1049 dev_kfree_skb(skb);
1050 return 0;
1051 }
1052 return 0;
1053} /* ray_dev_start_xmit */
1054/*===========================================================================*/
1055static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev,
1056 UCHAR msg_type)
1057{
1058 ray_dev_t *local = (ray_dev_t *)dev->priv;
1059 struct ccs __iomem *pccs;
1060 int ccsindex;
1061 int offset;
1062 struct tx_msg __iomem *ptx; /* Address of xmit buffer in PC space */
1063 short int addr; /* Address of xmit buffer in card space */
1064
1065 DEBUG(3,"ray_hw_xmit(data=%p, len=%d, dev=%p)\n",data,len,dev);
1066 if (len + TX_HEADER_LENGTH > TX_BUF_SIZE)
1067 {
1068 printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",len);
1069 return XMIT_MSG_BAD;
1070 }
1071 switch (ccsindex = get_free_tx_ccs(local)) {
1072 case ECCSBUSY:
1073 DEBUG(2,"ray_hw_xmit tx_ccs table busy\n");
1074 case ECCSFULL:
1075 DEBUG(2,"ray_hw_xmit No free tx ccs\n");
1076 case ECARDGONE:
1077 netif_stop_queue(dev);
1078 return XMIT_NO_CCS;
1079 default:
1080 break;
1081 }
1082 addr = TX_BUF_BASE + (ccsindex << 11);
1083
1084 if (msg_type == DATA_TYPE) {
1085 local->stats.tx_bytes += len;
1086 local->stats.tx_packets++;
1087 }
1088
1089 ptx = local->sram + addr;
1090
1091 ray_build_header(local, ptx, msg_type, data);
1092 if (translate) {
1093 offset = translate_frame(local, ptx, data, len);
1094 }
1095 else { /* Encapsulate frame */
1096 /* TBD TIB length will move address of ptx->var */
1097 memcpy_toio(&ptx->var, data, len);
1098 offset = 0;
1099 }
1100
1101 /* fill in the CCS */
1102 pccs = ccs_base(local) + ccsindex;
1103 len += TX_HEADER_LENGTH + offset;
1104 writeb(CCS_TX_REQUEST, &pccs->cmd);
1105 writeb(addr >> 8, &pccs->var.tx_request.tx_data_ptr[0]);
1106 writeb(local->tib_length, &pccs->var.tx_request.tx_data_ptr[1]);
1107 writeb(len >> 8, &pccs->var.tx_request.tx_data_length[0]);
1108 writeb(len & 0xff, &pccs->var.tx_request.tx_data_length[1]);
1109/* TBD still need psm_cam? */
1110 writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode);
1111 writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate);
1112 writeb(0, &pccs->var.tx_request.antenna);
1113 DEBUG(3,"ray_hw_xmit default_tx_rate = 0x%x\n",\
1114 local->net_default_tx_rate);
1115
1116 /* Interrupt the firmware to process the command */
1117 if (interrupt_ecf(local, ccsindex)) {
1118 DEBUG(2,"ray_hw_xmit failed - ECF not ready for intr\n");
1119/* TBD very inefficient to copy packet to buffer, and then not
1120 send it, but the alternative is to queue the messages and that
1121 won't be done for a while. Maybe set tbusy until a CCS is free?
1122*/
1123 writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
1124 return XMIT_NO_INTR;
1125 }
1126 return XMIT_OK;
1127} /* end ray_hw_xmit */
1128/*===========================================================================*/
1129static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, unsigned char *data,
1130 int len)
1131{
1132 unsigned short int proto = ((struct ethhdr *)data)->h_proto;
1133 if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
1134 DEBUG(3,"ray_cs translate_frame DIX II\n");
1135 /* Copy LLC header to card buffer */
1136 memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc));
1137 memcpy_toio( ((void __iomem *)&ptx->var) + sizeof(eth2_llc), (UCHAR *)&proto, 2);
1138 if ((proto == 0xf380) || (proto == 0x3781)) {
1139 /* This is the selective translation table, only 2 entries */
1140 writeb(0xf8, &((struct snaphdr_t __iomem *)ptx->var)->org[3]);
1141 }
1142 /* Copy body of ethernet packet without ethernet header */
1143 memcpy_toio((void __iomem *)&ptx->var + sizeof(struct snaphdr_t), \
1144 data + ETH_HLEN, len - ETH_HLEN);
1145 return (int) sizeof(struct snaphdr_t) - ETH_HLEN;
1146 }
1147 else { /* already 802 type, and proto is length */
1148 DEBUG(3,"ray_cs translate_frame 802\n");
1149 if (proto == 0xffff) { /* evil netware IPX 802.3 without LLC */
1150 DEBUG(3,"ray_cs translate_frame evil IPX\n");
1151 memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
1152 return 0 - ETH_HLEN;
1153 }
1154 memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
1155 return 0 - ETH_HLEN;
1156 }
1157 /* TBD do other frame types */
1158} /* end translate_frame */
1159/*===========================================================================*/
1160static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type,
1161 unsigned char *data)
1162{
1163 writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1);
1164/*** IEEE 802.11 Address field assignments *************
1165 TODS FROMDS addr_1 addr_2 addr_3 addr_4
1166Adhoc 0 0 dest src (terminal) BSSID N/A
1167AP to Terminal 0 1 dest AP(BSSID) source N/A
1168Terminal to AP 1 0 AP(BSSID) src (terminal) dest N/A
1169AP to AP 1 1 dest AP src AP dest source
1170*******************************************************/
1171 if (local->net_type == ADHOC) {
1172 writeb(0, &ptx->mac.frame_ctl_2);
1173 memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, 2 * ADDRLEN);
1174 memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
1175 }
1176 else /* infrastructure */
1177 {
1178 if (local->sparm.b4.a_acting_as_ap_status)
1179 {
1180 writeb(FC2_FROM_DS, &ptx->mac.frame_ctl_2);
1181 memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, ADDRLEN);
1182 memcpy_toio(ptx->mac.addr_2, local->bss_id, 6);
1183 memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_source, ADDRLEN);
1184 }
1185 else /* Terminal */
1186 {
1187 writeb(FC2_TO_DS, &ptx->mac.frame_ctl_2);
1188 memcpy_toio(ptx->mac.addr_1, local->bss_id, ADDRLEN);
1189 memcpy_toio(ptx->mac.addr_2, ((struct ethhdr *)data)->h_source, ADDRLEN);
1190 memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_dest, ADDRLEN);
1191 }
1192 }
1193} /* end encapsulate_frame */
1194
1195
1196/*===========================================================================*/
1197
1198static void netdev_get_drvinfo(struct net_device *dev,
1199 struct ethtool_drvinfo *info)
1200{
1201 strcpy(info->driver, "ray_cs");
1202}
1203
1204static struct ethtool_ops netdev_ethtool_ops = {
1205 .get_drvinfo = netdev_get_drvinfo,
1206};
1207
1208/*====================================================================*/
1209
1210static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1211{
1212 ray_dev_t *local = (ray_dev_t *)dev->priv;
1213 dev_link_t *link = local->finder;
1214 int err = 0;
1215#if WIRELESS_EXT > 7
1216 struct iwreq *wrq = (struct iwreq *) ifr;
1217#endif /* WIRELESS_EXT > 7 */
1218#ifdef WIRELESS_SPY
1219 struct sockaddr address[IW_MAX_SPY];
1220#endif /* WIRELESS_SPY */
1221
1222 if (!(link->state & DEV_PRESENT)) {
1223 DEBUG(2,"ray_dev_ioctl - device not present\n");
1224 return -1;
1225 }
1226 DEBUG(2,"ray_cs IOCTL dev=%p, ifr=%p, cmd = 0x%x\n",dev,ifr,cmd);
1227 /* Validate the command */
1228 switch (cmd)
1229 {
1230#if WIRELESS_EXT > 7
1231 /* --------------- WIRELESS EXTENSIONS --------------- */
1232 /* Get name */
1233 case SIOCGIWNAME:
1234 strcpy(wrq->u.name, "IEEE 802.11-FH");
1235 break;
1236
1237 /* Get frequency/channel */
1238 case SIOCGIWFREQ:
1239 wrq->u.freq.m = local->sparm.b5.a_hop_pattern;
1240 wrq->u.freq.e = 0;
1241 break;
1242
1243 /* Set frequency/channel */
1244 case SIOCSIWFREQ:
1245 /* Reject if card is already initialised */
1246 if(local->card_status != CARD_AWAITING_PARAM)
1247 {
1248 err = -EBUSY;
1249 break;
1250 }
1251
1252 /* Setting by channel number */
1253 if ((wrq->u.freq.m > USA_HOP_MOD) || (wrq->u.freq.e > 0))
1254 err = -EOPNOTSUPP;
1255 else
1256 local->sparm.b5.a_hop_pattern = wrq->u.freq.m;
1257 break;
1258
1259 /* Get current network name (ESSID) */
1260 case SIOCGIWESSID:
1261 if (wrq->u.data.pointer)
1262 {
1263 char essid[IW_ESSID_MAX_SIZE + 1];
1264 /* Get the essid that was set */
1265 memcpy(essid, local->sparm.b5.a_current_ess_id,
1266 IW_ESSID_MAX_SIZE);
1267 essid[IW_ESSID_MAX_SIZE] = '\0';
1268
1269 /* Push it out ! */
1270 wrq->u.data.length = strlen(essid) + 1;
1271 wrq->u.data.flags = 1; /* active */
1272 if (copy_to_user(wrq->u.data.pointer, essid, sizeof(essid)))
1273 err = -EFAULT;
1274 }
1275 break;
1276
1277 /* Set desired network name (ESSID) */
1278 case SIOCSIWESSID:
1279 /* Reject if card is already initialised */
1280 if(local->card_status != CARD_AWAITING_PARAM)
1281 {
1282 err = -EBUSY;
1283 break;
1284 }
1285
1286 if (wrq->u.data.pointer)
1287 {
1288 char card_essid[IW_ESSID_MAX_SIZE + 1];
1289
1290 /* Check if we asked for `any' */
1291 if(wrq->u.data.flags == 0)
1292 {
1293 /* Corey : can you do that ? */
1294 err = -EOPNOTSUPP;
1295 }
1296 else
1297 {
1298 /* Check the size of the string */
1299 if(wrq->u.data.length >
1300 IW_ESSID_MAX_SIZE + 1)
1301 {
1302 err = -E2BIG;
1303 break;
1304 }
1305 if (copy_from_user(card_essid,
1306 wrq->u.data.pointer,
1307 wrq->u.data.length)) {
1308 err = -EFAULT;
1309 break;
1310 }
1311 card_essid[IW_ESSID_MAX_SIZE] = '\0';
1312
1313 /* Set the ESSID in the card */
1314 memcpy(local->sparm.b5.a_current_ess_id, card_essid,
1315 IW_ESSID_MAX_SIZE);
1316 }
1317 }
1318 break;
1319
1320 /* Get current Access Point (BSSID in our case) */
1321 case SIOCGIWAP:
1322 memcpy(wrq->u.ap_addr.sa_data, local->bss_id, ETH_ALEN);
1323 wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
1324 break;
1325
1326 /* Get the current bit-rate */
1327 case SIOCGIWRATE:
1328 if(local->net_default_tx_rate == 3)
1329 wrq->u.bitrate.value = 2000000; /* Hum... */
1330 else
1331 wrq->u.bitrate.value = local->net_default_tx_rate * 500000;
1332 wrq->u.bitrate.fixed = 0; /* We are in auto mode */
1333 break;
1334
1335 /* Set the desired bit-rate */
1336 case SIOCSIWRATE:
1337 /* Check if rate is in range */
1338 if((wrq->u.bitrate.value != 1000000) &&
1339 (wrq->u.bitrate.value != 2000000))
1340 {
1341 err = -EINVAL;
1342 break;
1343 }
1344 /* Hack for 1.5 Mb/s instead of 2 Mb/s */
1345 if((local->fw_ver == 0x55) && /* Please check */
1346 (wrq->u.bitrate.value == 2000000))
1347 local->net_default_tx_rate = 3;
1348 else
1349 local->net_default_tx_rate = wrq->u.bitrate.value/500000;
1350 break;
1351
1352 /* Get the current RTS threshold */
1353 case SIOCGIWRTS:
1354 wrq->u.rts.value = (local->sparm.b5.a_rts_threshold[0] << 8)
1355 + local->sparm.b5.a_rts_threshold[1];
1356#if WIRELESS_EXT > 8
1357 wrq->u.rts.disabled = (wrq->u.rts.value == 32767);
1358#endif /* WIRELESS_EXT > 8 */
1359 wrq->u.rts.fixed = 1;
1360 break;
1361
1362 /* Set the desired RTS threshold */
1363 case SIOCSIWRTS:
1364 {
1365 int rthr = wrq->u.rts.value;
1366
1367 /* Reject if card is already initialised */
1368 if(local->card_status != CARD_AWAITING_PARAM)
1369 {
1370 err = -EBUSY;
1371 break;
1372 }
1373
1374 /* if(wrq->u.rts.fixed == 0) we should complain */
1375#if WIRELESS_EXT > 8
1376 if(wrq->u.rts.disabled)
1377 rthr = 32767;
1378 else
1379#endif /* WIRELESS_EXT > 8 */
1380 if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */
1381 {
1382 err = -EINVAL;
1383 break;
1384 }
1385 local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF;
1386 local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF;
1387 }
1388 break;
1389
1390 /* Get the current fragmentation threshold */
1391 case SIOCGIWFRAG:
1392 wrq->u.frag.value = (local->sparm.b5.a_frag_threshold[0] << 8)
1393 + local->sparm.b5.a_frag_threshold[1];
1394#if WIRELESS_EXT > 8
1395 wrq->u.frag.disabled = (wrq->u.frag.value == 32767);
1396#endif /* WIRELESS_EXT > 8 */
1397 wrq->u.frag.fixed = 1;
1398 break;
1399
1400 /* Set the desired fragmentation threshold */
1401 case SIOCSIWFRAG:
1402 {
1403 int fthr = wrq->u.frag.value;
1404
1405 /* Reject if card is already initialised */
1406 if(local->card_status != CARD_AWAITING_PARAM)
1407 {
1408 err = -EBUSY;
1409 break;
1410 }
1411
1412 /* if(wrq->u.frag.fixed == 0) should complain */
1413#if WIRELESS_EXT > 8
1414 if(wrq->u.frag.disabled)
1415 fthr = 32767;
1416 else
1417#endif /* WIRELESS_EXT > 8 */
1418 if((fthr < 256) || (fthr > 2347)) /* To check out ! */
1419 {
1420 err = -EINVAL;
1421 break;
1422 }
1423 local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF;
1424 local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF;
1425 }
1426 break;
1427
1428#endif /* WIRELESS_EXT > 7 */
1429#if WIRELESS_EXT > 8
1430
1431 /* Get the current mode of operation */
1432 case SIOCGIWMODE:
1433 if(local->sparm.b5.a_network_type)
1434 wrq->u.mode = IW_MODE_INFRA;
1435 else
1436 wrq->u.mode = IW_MODE_ADHOC;
1437 break;
1438
1439 /* Set the current mode of operation */
1440 case SIOCSIWMODE:
1441 {
1442 char card_mode = 1;
1443
1444 /* Reject if card is already initialised */
1445 if(local->card_status != CARD_AWAITING_PARAM)
1446 {
1447 err = -EBUSY;
1448 break;
1449 }
1450
1451 switch (wrq->u.mode)
1452 {
1453 case IW_MODE_ADHOC:
1454 card_mode = 0;
1455 // Fall through
1456 case IW_MODE_INFRA:
1457 local->sparm.b5.a_network_type = card_mode;
1458 break;
1459 default:
1460 err = -EINVAL;
1461 }
1462 }
1463 break;
1464
1465#endif /* WIRELESS_EXT > 8 */
1466#if WIRELESS_EXT > 7
1467 /* ------------------ IWSPY SUPPORT ------------------ */
1468 /* Define the range (variations) of above parameters */
1469 case SIOCGIWRANGE:
1470 /* Basic checking... */
1471 if(wrq->u.data.pointer != (caddr_t) 0)
1472 {
1473 struct iw_range range;
1474 memset((char *) &range, 0, sizeof(struct iw_range));
1475
1476 /* Set the length (very important for backward compatibility) */
1477 wrq->u.data.length = sizeof(struct iw_range);
1478
1479#if WIRELESS_EXT > 10
1480 /* Set the Wireless Extension versions */
1481 range.we_version_compiled = WIRELESS_EXT;
1482 range.we_version_source = 9;
1483#endif /* WIRELESS_EXT > 10 */
1484
1485 /* Set information in the range struct */
1486 range.throughput = 1.1 * 1000 * 1000; /* Put the right number here */
1487 range.num_channels = hop_pattern_length[(int)country];
1488 range.num_frequency = 0;
1489 range.max_qual.qual = 0;
1490 range.max_qual.level = 255; /* What's the correct value ? */
1491 range.max_qual.noise = 255; /* Idem */
1492 range.num_bitrates = 2;
1493 range.bitrate[0] = 1000000; /* 1 Mb/s */
1494 range.bitrate[1] = 2000000; /* 2 Mb/s */
1495
1496 /* Copy structure to the user buffer */
1497 if(copy_to_user(wrq->u.data.pointer, &range,
1498 sizeof(struct iw_range)))
1499 err = -EFAULT;
1500 }
1501 break;
1502
1503#ifdef WIRELESS_SPY
1504 /* Set addresses to spy */
1505 case SIOCSIWSPY:
1506 /* Check the number of addresses */
1507 if(wrq->u.data.length > IW_MAX_SPY)
1508 {
1509 err = -E2BIG;
1510 break;
1511 }
1512 local->spy_number = wrq->u.data.length;
1513
1514 /* If there is some addresses to copy */
1515 if(local->spy_number > 0)
1516 {
1517 int i;
1518
1519 /* Copy addresses to the driver */
1520 if(copy_from_user(address, wrq->u.data.pointer,
1521 sizeof(struct sockaddr) * local->spy_number))
1522 {
1523 err = -EFAULT;
1524 break;
1525 }
1526
1527 /* Copy addresses to the lp structure */
1528 for(i = 0; i < local->spy_number; i++)
1529 memcpy(local->spy_address[i], address[i].sa_data, ETH_ALEN);
1530
1531 /* Reset structure... */
1532 memset(local->spy_stat, 0x00, sizeof(iw_qual) * IW_MAX_SPY);
1533
1534#ifdef DEBUG_IOCTL_INFO
1535 printk(KERN_DEBUG "SetSpy - Set of new addresses is :\n");
1536 for(i = 0; i < local->spy_number; i++)
1537 printk(KERN_DEBUG "%02X:%02X:%02X:%02X:%02X:%02X\n",
1538 local->spy_address[i][0],
1539 local->spy_address[i][1],
1540 local->spy_address[i][2],
1541 local->spy_address[i][3],
1542 local->spy_address[i][4],
1543 local->spy_address[i][5]);
1544#endif /* DEBUG_IOCTL_INFO */
1545 }
1546 break;
1547
1548 /* Get the spy list and spy stats */
1549 case SIOCGIWSPY:
1550 /* Set the number of addresses */
1551 wrq->u.data.length = local->spy_number;
1552
1553 /* If the user want to have the addresses back... */
1554 if((local->spy_number > 0) && (wrq->u.data.pointer != (caddr_t) 0))
1555 {
1556 int i;
1557
1558 /* Copy addresses from the lp structure */
1559 for(i = 0; i < local->spy_number; i++)
1560 {
1561 memcpy(address[i].sa_data, local->spy_address[i], ETH_ALEN);
1562 address[i].sa_family = ARPHRD_ETHER;
1563 }
1564
1565 /* Copy addresses to the user buffer */
1566 if(copy_to_user(wrq->u.data.pointer, address,
1567 sizeof(struct sockaddr) * local->spy_number))
1568 {
1569 err = -EFAULT;
1570 break;
1571 }
1572
1573 /* Copy stats to the user buffer (just after) */
1574 if(copy_to_user(wrq->u.data.pointer +
1575 (sizeof(struct sockaddr) * local->spy_number),
1576 local->spy_stat, sizeof(iw_qual) * local->spy_number))
1577 {
1578 err = -EFAULT;
1579 break;
1580 }
1581
1582 /* Reset updated flags */
1583 for(i = 0; i < local->spy_number; i++)
1584 local->spy_stat[i].updated = 0x0;
1585 } /* if(pointer != NULL) */
1586
1587 break;
1588#endif /* WIRELESS_SPY */
1589
1590 /* ------------------ PRIVATE IOCTL ------------------ */
1591#ifndef SIOCIWFIRSTPRIV
1592#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
1593#endif /* SIOCIWFIRSTPRIV */
1594#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */
1595#define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1 /* Get framing mode */
1596#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */
1597 case SIOCSIPFRAMING:
1598 if(!capable(CAP_NET_ADMIN)) /* For private IOCTLs, we need to check permissions */
1599 {
1600 err = -EPERM;
1601 break;
1602 }
1603 translate = *(wrq->u.name); /* Set framing mode */
1604 break;
1605 case SIOCGIPFRAMING:
1606 *(wrq->u.name) = translate;
1607 break;
1608 case SIOCGIPCOUNTRY:
1609 *(wrq->u.name) = country;
1610 break;
1611 case SIOCGIWPRIV:
1612 /* Export our "private" intercace */
1613 if(wrq->u.data.pointer != (caddr_t) 0)
1614 {
1615 struct iw_priv_args priv[] =
1616 { /* cmd, set_args, get_args, name */
1617 { SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" },
1618 { SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" },
1619 { SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" },
1620 };
1621 /* Set the number of ioctl available */
1622 wrq->u.data.length = 3;
1623 /* Copy structure to the user buffer */
1624 if(copy_to_user(wrq->u.data.pointer, (u_char *) priv,
1625 sizeof(priv)))
1626 err = -EFAULT;
1627 }
1628 break;
1629#endif /* WIRELESS_EXT > 7 */
1630
1631
1632 default:
1633 DEBUG(0,"ray_dev_ioctl cmd = 0x%x\n", cmd);
1634 err = -EOPNOTSUPP;
1635 }
1636 return err;
1637} /* end ray_dev_ioctl */
1638/*===========================================================================*/
1639#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */
1640static iw_stats * ray_get_wireless_stats(struct net_device * dev)
1641{
1642 ray_dev_t * local = (ray_dev_t *) dev->priv;
1643 dev_link_t *link = local->finder;
1644 struct status __iomem *p = local->sram + STATUS_BASE;
1645
1646 if(local == (ray_dev_t *) NULL)
1647 return (iw_stats *) NULL;
1648
1649 local->wstats.status = local->card_status;
1650#ifdef WIRELESS_SPY
1651 if((local->spy_number > 0) && (local->sparm.b5.a_network_type == 0))
1652 {
1653 /* Get it from the first node in spy list */
1654 local->wstats.qual.qual = local->spy_stat[0].qual;
1655 local->wstats.qual.level = local->spy_stat[0].level;
1656 local->wstats.qual.noise = local->spy_stat[0].noise;
1657 local->wstats.qual.updated = local->spy_stat[0].updated;
1658 }
1659#endif /* WIRELESS_SPY */
1660
1661 if((link->state & DEV_PRESENT)) {
1662 local->wstats.qual.noise = readb(&p->rxnoise);
1663 local->wstats.qual.updated |= 4;
1664 }
1665
1666 return &local->wstats;
1667} /* end ray_get_wireless_stats */
1668#endif /* WIRELESS_EXT > 7 */
1669/*===========================================================================*/
1670static int ray_open(struct net_device *dev)
1671{
1672 dev_link_t *link;
1673 ray_dev_t *local = (ray_dev_t *)dev->priv;
1674
1675 DEBUG(1, "ray_open('%s')\n", dev->name);
1676
1677 for (link = dev_list; link; link = link->next)
1678 if (link->priv == dev) break;
1679 if (!DEV_OK(link)) {
1680 return -ENODEV;
1681 }
1682
1683 if (link->open == 0) local->num_multi = 0;
1684 link->open++;
1685
1686 /* If the card is not started, time to start it ! - Jean II */
1687 if(local->card_status == CARD_AWAITING_PARAM) {
1688 int i;
1689
1690 DEBUG(1,"ray_open: doing init now !\n");
1691
1692 /* Download startup parameters */
1693 if ( (i = dl_startup_params(dev)) < 0)
1694 {
1695 printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
1696 "returns 0x%x\n",i);
1697 return -1;
1698 }
1699 }
1700
1701 if (sniffer) netif_stop_queue(dev);
1702 else netif_start_queue(dev);
1703
1704 DEBUG(2,"ray_open ending\n");
1705 return 0;
1706} /* end ray_open */
1707/*===========================================================================*/
1708static int ray_dev_close(struct net_device *dev)
1709{
1710 dev_link_t *link;
1711
1712 DEBUG(1, "ray_dev_close('%s')\n", dev->name);
1713
1714 for (link = dev_list; link; link = link->next)
1715 if (link->priv == dev) break;
1716 if (link == NULL)
1717 return -ENODEV;
1718
1719 link->open--;
1720 netif_stop_queue(dev);
1721
1722 /* In here, we should stop the hardware (stop card from beeing active)
1723 * and set local->card_status to CARD_AWAITING_PARAM, so that while the
1724 * card is closed we can chage its configuration.
1725 * Probably also need a COR reset to get sane state - Jean II */
1726
1727 return 0;
1728} /* end ray_dev_close */
1729/*===========================================================================*/
1730static void ray_reset(struct net_device *dev) {
1731 DEBUG(1,"ray_reset entered\n");
1732 return;
1733}
1734/*===========================================================================*/
1735/* Cause a firmware interrupt if it is ready for one */
1736/* Return nonzero if not ready */
1737static int interrupt_ecf(ray_dev_t *local, int ccs)
1738{
1739 int i = 50;
1740 dev_link_t *link = local->finder;
1741
1742 if (!(link->state & DEV_PRESENT)) {
1743 DEBUG(2,"ray_cs interrupt_ecf - device not present\n");
1744 return -1;
1745 }
1746 DEBUG(2,"interrupt_ecf(local=%p, ccs = 0x%x\n",local,ccs);
1747
1748 while ( i &&
1749 (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) & ECF_INTR_SET))
1750 i--;
1751 if (i == 0) {
1752 DEBUG(2,"ray_cs interrupt_ecf card not ready for interrupt\n");
1753 return -1;
1754 }
1755 /* Fill the mailbox, then kick the card */
1756 writeb(ccs, local->sram + SCB_BASE);
1757 writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET);
1758 return 0;
1759} /* interrupt_ecf */
1760/*===========================================================================*/
1761/* Get next free transmit CCS */
1762/* Return - index of current tx ccs */
1763static int get_free_tx_ccs(ray_dev_t *local)
1764{
1765 int i;
1766 struct ccs __iomem *pccs = ccs_base(local);
1767 dev_link_t *link = local->finder;
1768
1769 if (!(link->state & DEV_PRESENT)) {
1770 DEBUG(2,"ray_cs get_free_tx_ccs - device not present\n");
1771 return ECARDGONE;
1772 }
1773
1774 if (test_and_set_bit(0,&local->tx_ccs_lock)) {
1775 DEBUG(1,"ray_cs tx_ccs_lock busy\n");
1776 return ECCSBUSY;
1777 }
1778
1779 for (i=0; i < NUMBER_OF_TX_CCS; i++) {
1780 if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) {
1781 writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status);
1782 writeb(CCS_END_LIST, &(pccs+i)->link);
1783 local->tx_ccs_lock = 0;
1784 return i;
1785 }
1786 }
1787 local->tx_ccs_lock = 0;
1788 DEBUG(2,"ray_cs ERROR no free tx CCS for raylink card\n");
1789 return ECCSFULL;
1790} /* get_free_tx_ccs */
1791/*===========================================================================*/
1792/* Get next free CCS */
1793/* Return - index of current ccs */
1794static int get_free_ccs(ray_dev_t *local)
1795{
1796 int i;
1797 struct ccs __iomem *pccs = ccs_base(local);
1798 dev_link_t *link = local->finder;
1799
1800 if (!(link->state & DEV_PRESENT)) {
1801 DEBUG(2,"ray_cs get_free_ccs - device not present\n");
1802 return ECARDGONE;
1803 }
1804 if (test_and_set_bit(0,&local->ccs_lock)) {
1805 DEBUG(1,"ray_cs ccs_lock busy\n");
1806 return ECCSBUSY;
1807 }
1808
1809 for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) {
1810 if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) {
1811 writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status);
1812 writeb(CCS_END_LIST, &(pccs+i)->link);
1813 local->ccs_lock = 0;
1814 return i;
1815 }
1816 }
1817 local->ccs_lock = 0;
1818 DEBUG(1,"ray_cs ERROR no free CCS for raylink card\n");
1819 return ECCSFULL;
1820} /* get_free_ccs */
1821/*===========================================================================*/
1822static void authenticate_timeout(u_long data)
1823{
1824 ray_dev_t *local = (ray_dev_t *)data;
1825 del_timer(&local->timer);
1826 printk(KERN_INFO "ray_cs Authentication with access point failed"
1827 " - timeout\n");
1828 join_net((u_long)local);
1829}
1830/*===========================================================================*/
1831static int asc_to_int(char a)
1832{
1833 if (a < '0') return -1;
1834 if (a <= '9') return (a - '0');
1835 if (a < 'A') return -1;
1836 if (a <= 'F') return (10 + a - 'A');
1837 if (a < 'a') return -1;
1838 if (a <= 'f') return (10 + a - 'a');
1839 return -1;
1840}
1841/*===========================================================================*/
1842static int parse_addr(char *in_str, UCHAR *out)
1843{
1844 int len;
1845 int i,j,k;
1846 int status;
1847
1848 if (in_str == NULL) return 0;
1849 if ((len = strlen(in_str)) < 2) return 0;
1850 memset(out, 0, ADDRLEN);
1851
1852 status = 1;
1853 j = len - 1;
1854 if (j > 12) j = 12;
1855 i = 5;
1856
1857 while (j > 0)
1858 {
1859 if ((k = asc_to_int(in_str[j--])) != -1) out[i] = k;
1860 else return 0;
1861
1862 if (j == 0) break;
1863 if ((k = asc_to_int(in_str[j--])) != -1) out[i] += k << 4;
1864 else return 0;
1865 if (!i--) break;
1866 }
1867 return status;
1868}
1869/*===========================================================================*/
1870static struct net_device_stats *ray_get_stats(struct net_device *dev)
1871{
1872 ray_dev_t *local = (ray_dev_t *)dev->priv;
1873 dev_link_t *link = local->finder;
1874 struct status __iomem *p = local->sram + STATUS_BASE;
1875 if (!(link->state & DEV_PRESENT)) {
1876 DEBUG(2,"ray_cs net_device_stats - device not present\n");
1877 return &local->stats;
1878 }
1879 if (readb(&p->mrx_overflow_for_host))
1880 {
1881 local->stats.rx_over_errors += ntohs(readb(&p->mrx_overflow));
1882 writeb(0,&p->mrx_overflow);
1883 writeb(0,&p->mrx_overflow_for_host);
1884 }
1885 if (readb(&p->mrx_checksum_error_for_host))
1886 {
1887 local->stats.rx_crc_errors += ntohs(readb(&p->mrx_checksum_error));
1888 writeb(0,&p->mrx_checksum_error);
1889 writeb(0,&p->mrx_checksum_error_for_host);
1890 }
1891 if (readb(&p->rx_hec_error_for_host))
1892 {
1893 local->stats.rx_frame_errors += ntohs(readb(&p->rx_hec_error));
1894 writeb(0,&p->rx_hec_error);
1895 writeb(0,&p->rx_hec_error_for_host);
1896 }
1897 return &local->stats;
1898}
1899/*===========================================================================*/
1900static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len)
1901{
1902 ray_dev_t *local = (ray_dev_t *)dev->priv;
1903 dev_link_t *link = local->finder;
1904 int ccsindex;
1905 int i;
1906 struct ccs __iomem *pccs;
1907
1908 if (!(link->state & DEV_PRESENT)) {
1909 DEBUG(2,"ray_update_parm - device not present\n");
1910 return;
1911 }
1912
1913 if ((ccsindex = get_free_ccs(local)) < 0)
1914 {
1915 DEBUG(0,"ray_update_parm - No free ccs\n");
1916 return;
1917 }
1918 pccs = ccs_base(local) + ccsindex;
1919 writeb(CCS_UPDATE_PARAMS, &pccs->cmd);
1920 writeb(objid, &pccs->var.update_param.object_id);
1921 writeb(1, &pccs->var.update_param.number_objects);
1922 writeb(0, &pccs->var.update_param.failure_cause);
1923 for (i=0; i<len; i++) {
1924 writeb(value[i], local->sram + HOST_TO_ECF_BASE);
1925 }
1926 /* Interrupt the firmware to process the command */
1927 if (interrupt_ecf(local, ccsindex)) {
1928 DEBUG(0,"ray_cs associate failed - ECF not ready for intr\n");
1929 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
1930 }
1931}
1932/*===========================================================================*/
1933static void ray_update_multi_list(struct net_device *dev, int all)
1934{
1935 struct dev_mc_list *dmi, **dmip;
1936 int ccsindex;
1937 struct ccs __iomem *pccs;
1938 int i = 0;
1939 ray_dev_t *local = (ray_dev_t *)dev->priv;
1940 dev_link_t *link = local->finder;
1941 void __iomem *p = local->sram + HOST_TO_ECF_BASE;
1942
1943 if (!(link->state & DEV_PRESENT)) {
1944 DEBUG(2,"ray_update_multi_list - device not present\n");
1945 return;
1946 }
1947 else
1948 DEBUG(2,"ray_update_multi_list(%p)\n",dev);
1949 if ((ccsindex = get_free_ccs(local)) < 0)
1950 {
1951 DEBUG(1,"ray_update_multi - No free ccs\n");
1952 return;
1953 }
1954 pccs = ccs_base(local) + ccsindex;
1955 writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd);
1956
1957 if (all) {
1958 writeb(0xff, &pccs->var);
1959 local->num_multi = 0xff;
1960 }
1961 else {
1962 /* Copy the kernel's list of MC addresses to card */
1963 for (dmip=&dev->mc_list; (dmi=*dmip)!=NULL; dmip=&dmi->next) {
1964 memcpy_toio(p, dmi->dmi_addr, ETH_ALEN);
1965 DEBUG(1,"ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",dmi->dmi_addr[0],dmi->dmi_addr[1],dmi->dmi_addr[2],dmi->dmi_addr[3],dmi->dmi_addr[4],dmi->dmi_addr[5]);
1966 p += ETH_ALEN;
1967 i++;
1968 }
1969 if (i > 256/ADDRLEN) i = 256/ADDRLEN;
1970 writeb((UCHAR)i, &pccs->var);
1971 DEBUG(1,"ray_cs update_multi %d addresses in list\n", i);
1972 /* Interrupt the firmware to process the command */
1973 local->num_multi = i;
1974 }
1975 if (interrupt_ecf(local, ccsindex)) {
1976 DEBUG(1,"ray_cs update_multi failed - ECF not ready for intr\n");
1977 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
1978 }
1979} /* end ray_update_multi_list */
1980/*===========================================================================*/
1981static void set_multicast_list(struct net_device *dev)
1982{
1983 ray_dev_t *local = (ray_dev_t *)dev->priv;
1984 UCHAR promisc;
1985
1986 DEBUG(2,"ray_cs set_multicast_list(%p)\n",dev);
1987
1988 if (dev->flags & IFF_PROMISC)
1989 {
1990 if (local->sparm.b5.a_promiscuous_mode == 0) {
1991 DEBUG(1,"ray_cs set_multicast_list promisc on\n");
1992 local->sparm.b5.a_promiscuous_mode = 1;
1993 promisc = 1;
1994 ray_update_parm(dev, OBJID_promiscuous_mode, \
1995 &promisc, sizeof(promisc));
1996 }
1997 }
1998 else {
1999 if (local->sparm.b5.a_promiscuous_mode == 1) {
2000 DEBUG(1,"ray_cs set_multicast_list promisc off\n");
2001 local->sparm.b5.a_promiscuous_mode = 0;
2002 promisc = 0;
2003 ray_update_parm(dev, OBJID_promiscuous_mode, \
2004 &promisc, sizeof(promisc));
2005 }
2006 }
2007
2008 if (dev->flags & IFF_ALLMULTI) ray_update_multi_list(dev, 1);
2009 else
2010 {
2011 if (local->num_multi != dev->mc_count) ray_update_multi_list(dev, 0);
2012 }
2013} /* end set_multicast_list */
2014/*=============================================================================
2015 * All routines below here are run at interrupt time.
2016=============================================================================*/
2017static irqreturn_t ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
2018{
2019 struct net_device *dev = (struct net_device *)dev_id;
2020 dev_link_t *link;
2021 ray_dev_t *local;
2022 struct ccs __iomem *pccs;
2023 struct rcs __iomem *prcs;
2024 UCHAR rcsindex;
2025 UCHAR tmp;
2026 UCHAR cmd;
2027 UCHAR status;
2028
2029 if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */
2030 return IRQ_NONE;
2031
2032 DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev);
2033
2034 local = (ray_dev_t *)dev->priv;
2035 link = (dev_link_t *)local->finder;
2036 if ( ! (link->state & DEV_PRESENT) || link->state & DEV_SUSPEND ) {
2037 DEBUG(2,"ray_cs interrupt from device not present or suspended.\n");
2038 return IRQ_NONE;
2039 }
2040 rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index);
2041
2042 if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS))
2043 {
2044 DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex);
2045 clear_interrupt(local);
2046 return IRQ_HANDLED;
2047 }
2048 if (rcsindex < NUMBER_OF_CCS) /* If it's a returned CCS */
2049 {
2050 pccs = ccs_base(local) + rcsindex;
2051 cmd = readb(&pccs->cmd);
2052 status = readb(&pccs->buffer_status);
2053 switch (cmd)
2054 {
2055 case CCS_DOWNLOAD_STARTUP_PARAMS: /* Happens in firmware someday */
2056 del_timer(&local->timer);
2057 if (status == CCS_COMMAND_COMPLETE) {
2058 DEBUG(1,"ray_cs interrupt download_startup_parameters OK\n");
2059 }
2060 else {
2061 DEBUG(1,"ray_cs interrupt download_startup_parameters fail\n");
2062 }
2063 break;
2064 case CCS_UPDATE_PARAMS:
2065 DEBUG(1,"ray_cs interrupt update params done\n");
2066 if (status != CCS_COMMAND_COMPLETE) {
2067 tmp = readb(&pccs->var.update_param.failure_cause);
2068 DEBUG(0,"ray_cs interrupt update params failed - reason %d\n",tmp);
2069 }
2070 break;
2071 case CCS_REPORT_PARAMS:
2072 DEBUG(1,"ray_cs interrupt report params done\n");
2073 break;
2074 case CCS_UPDATE_MULTICAST_LIST: /* Note that this CCS isn't returned */
2075 DEBUG(1,"ray_cs interrupt CCS Update Multicast List done\n");
2076 break;
2077 case CCS_UPDATE_POWER_SAVINGS_MODE:
2078 DEBUG(1,"ray_cs interrupt update power save mode done\n");
2079 break;
2080 case CCS_START_NETWORK:
2081 case CCS_JOIN_NETWORK:
2082 if (status == CCS_COMMAND_COMPLETE) {
2083 if (readb(&pccs->var.start_network.net_initiated) == 1) {
2084 DEBUG(0,"ray_cs interrupt network \"%s\" started\n",\
2085 local->sparm.b4.a_current_ess_id);
2086 }
2087 else {
2088 DEBUG(0,"ray_cs interrupt network \"%s\" joined\n",\
2089 local->sparm.b4.a_current_ess_id);
2090 }
2091 memcpy_fromio(&local->bss_id,pccs->var.start_network.bssid,ADDRLEN);
2092
2093 if (local->fw_ver == 0x55) local->net_default_tx_rate = 3;
2094 else local->net_default_tx_rate =
2095 readb(&pccs->var.start_network.net_default_tx_rate);
2096 local->encryption = readb(&pccs->var.start_network.encryption);
2097 if (!sniffer && (local->net_type == INFRA)
2098 && !(local->sparm.b4.a_acting_as_ap_status)) {
2099 authenticate(local);
2100 }
2101 local->card_status = CARD_ACQ_COMPLETE;
2102 }
2103 else {
2104 local->card_status = CARD_ACQ_FAILED;
2105
2106 del_timer(&local->timer);
2107 local->timer.expires = jiffies + HZ*5;
2108 local->timer.data = (long)local;
2109 if (status == CCS_START_NETWORK) {
2110 DEBUG(0,"ray_cs interrupt network \"%s\" start failed\n",\
2111 local->sparm.b4.a_current_ess_id);
2112 local->timer.function = &start_net;
2113 }
2114 else {
2115 DEBUG(0,"ray_cs interrupt network \"%s\" join failed\n",\
2116 local->sparm.b4.a_current_ess_id);
2117 local->timer.function = &join_net;
2118 }
2119 add_timer(&local->timer);
2120 }
2121 break;
2122 case CCS_START_ASSOCIATION:
2123 if (status == CCS_COMMAND_COMPLETE) {
2124 local->card_status = CARD_ASSOC_COMPLETE;
2125 DEBUG(0,"ray_cs association successful\n");
2126 }
2127 else
2128 {
2129 DEBUG(0,"ray_cs association failed,\n");
2130 local->card_status = CARD_ASSOC_FAILED;
2131 join_net((u_long)local);
2132 }
2133 break;
2134 case CCS_TX_REQUEST:
2135 if (status == CCS_COMMAND_COMPLETE) {
2136 DEBUG(3,"ray_cs interrupt tx request complete\n");
2137 }
2138 else {
2139 DEBUG(1,"ray_cs interrupt tx request failed\n");
2140 }
2141 if (!sniffer) netif_start_queue(dev);
2142 netif_wake_queue(dev);
2143 break;
2144 case CCS_TEST_MEMORY:
2145 DEBUG(1,"ray_cs interrupt mem test done\n");
2146 break;
2147 case CCS_SHUTDOWN:
2148 DEBUG(1,"ray_cs interrupt Unexpected CCS returned - Shutdown\n");
2149 break;
2150 case CCS_DUMP_MEMORY:
2151 DEBUG(1,"ray_cs interrupt dump memory done\n");
2152 break;
2153 case CCS_START_TIMER:
2154 DEBUG(2,"ray_cs interrupt DING - raylink timer expired\n");
2155 break;
2156 default:
2157 DEBUG(1,"ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",\
2158 rcsindex, cmd);
2159 }
2160 writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
2161 }
2162 else /* It's an RCS */
2163 {
2164 prcs = rcs_base(local) + rcsindex;
2165
2166 switch (readb(&prcs->interrupt_id))
2167 {
2168 case PROCESS_RX_PACKET:
2169 ray_rx(dev, local, prcs);
2170 break;
2171 case REJOIN_NET_COMPLETE:
2172 DEBUG(1,"ray_cs interrupt rejoin net complete\n");
2173 local->card_status = CARD_ACQ_COMPLETE;
2174 /* do we need to clear tx buffers CCS's? */
2175 if (local->sparm.b4.a_network_type == ADHOC) {
2176 if (!sniffer) netif_start_queue(dev);
2177 }
2178 else {
2179 memcpy_fromio(&local->bss_id, prcs->var.rejoin_net_complete.bssid, ADDRLEN);
2180 DEBUG(1,"ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n",\
2181 local->bss_id[0], local->bss_id[1], local->bss_id[2],\
2182 local->bss_id[3], local->bss_id[4], local->bss_id[5]);
2183 if (!sniffer) authenticate(local);
2184 }
2185 break;
2186 case ROAMING_INITIATED:
2187 DEBUG(1,"ray_cs interrupt roaming initiated\n");
2188 netif_stop_queue(dev);
2189 local->card_status = CARD_DOING_ACQ;
2190 break;
2191 case JAPAN_CALL_SIGN_RXD:
2192 DEBUG(1,"ray_cs interrupt japan call sign rx\n");
2193 break;
2194 default:
2195 DEBUG(1,"ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",\
2196 rcsindex, (unsigned int) readb(&prcs->interrupt_id));
2197 break;
2198 }
2199 writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
2200 }
2201 clear_interrupt(local);
2202 return IRQ_HANDLED;
2203} /* ray_interrupt */
2204/*===========================================================================*/
2205static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs __iomem *prcs)
2206{
2207 int rx_len;
2208 unsigned int pkt_addr;
2209 void __iomem *pmsg;
2210 DEBUG(4,"ray_rx process rx packet\n");
2211
2212 /* Calculate address of packet within Rx buffer */
2213 pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
2214 + readb(&prcs->var.rx_packet.rx_data_ptr[1])) & RX_BUFF_END;
2215 /* Length of first packet fragment */
2216 rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8)
2217 + readb(&prcs->var.rx_packet.rx_data_length[1]);
2218
2219 local->last_rsl = readb(&prcs->var.rx_packet.rx_sig_lev);
2220 pmsg = local->rmem + pkt_addr;
2221 switch(readb(pmsg))
2222 {
2223 case DATA_TYPE:
2224 DEBUG(4,"ray_rx data type\n");
2225 rx_data(dev, prcs, pkt_addr, rx_len);
2226 break;
2227 case AUTHENTIC_TYPE:
2228 DEBUG(4,"ray_rx authentic type\n");
2229 if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
2230 else rx_authenticate(local, prcs, pkt_addr, rx_len);
2231 break;
2232 case DEAUTHENTIC_TYPE:
2233 DEBUG(4,"ray_rx deauth type\n");
2234 if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
2235 else rx_deauthenticate(local, prcs, pkt_addr, rx_len);
2236 break;
2237 case NULL_MSG_TYPE:
2238 DEBUG(3,"ray_cs rx NULL msg\n");
2239 break;
2240 case BEACON_TYPE:
2241 DEBUG(4,"ray_rx beacon type\n");
2242 if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
2243
2244 copy_from_rx_buff(local, (UCHAR *)&local->last_bcn, pkt_addr,
2245 rx_len < sizeof(struct beacon_rx) ?
2246 rx_len : sizeof(struct beacon_rx));
2247
2248 local->beacon_rxed = 1;
2249 /* Get the statistics so the card counters never overflow */
2250 ray_get_stats(dev);
2251 break;
2252 default:
2253 DEBUG(0,"ray_cs unknown pkt type %2x\n", (unsigned int) readb(pmsg));
2254 break;
2255 }
2256
2257} /* end ray_rx */
2258/*===========================================================================*/
2259static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned int pkt_addr,
2260 int rx_len)
2261{
2262 struct sk_buff *skb = NULL;
2263 struct rcs __iomem *prcslink = prcs;
2264 ray_dev_t *local = dev->priv;
2265 UCHAR *rx_ptr;
2266 int total_len;
2267 int tmp;
2268#ifdef WIRELESS_SPY
2269 int siglev = local->last_rsl;
2270 u_char linksrcaddr[ETH_ALEN]; /* Other end of the wireless link */
2271#endif
2272
2273 if (!sniffer) {
2274 if (translate) {
2275/* TBD length needs fixing for translated header */
2276 if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
2277 rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN))
2278 {
2279 DEBUG(0,"ray_cs invalid packet length %d received \n",rx_len);
2280 return;
2281 }
2282 }
2283 else /* encapsulated ethernet */ {
2284 if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
2285 rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN))
2286 {
2287 DEBUG(0,"ray_cs invalid packet length %d received \n",rx_len);
2288 return;
2289 }
2290 }
2291 }
2292 DEBUG(4,"ray_cs rx_data packet\n");
2293 /* If fragmented packet, verify sizes of fragments add up */
2294 if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
2295 DEBUG(1,"ray_cs rx'ed fragment\n");
2296 tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
2297 + readb(&prcs->var.rx_packet.totalpacketlength[1]);
2298 total_len = tmp;
2299 prcslink = prcs;
2300 do {
2301 tmp -= (readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8)
2302 + readb(&prcslink->var.rx_packet.rx_data_length[1]);
2303 if (readb(&prcslink->var.rx_packet.next_frag_rcs_index) == 0xFF
2304 || tmp < 0) break;
2305 prcslink = rcs_base(local)
2306 + readb(&prcslink->link_field);
2307 } while (1);
2308
2309 if (tmp < 0)
2310 {
2311 DEBUG(0,"ray_cs rx_data fragment lengths don't add up\n");
2312 local->stats.rx_dropped++;
2313 release_frag_chain(local, prcs);
2314 return;
2315 }
2316 }
2317 else { /* Single unfragmented packet */
2318 total_len = rx_len;
2319 }
2320
2321 skb = dev_alloc_skb( total_len+5 );
2322 if (skb == NULL)
2323 {
2324 DEBUG(0,"ray_cs rx_data could not allocate skb\n");
2325 local->stats.rx_dropped++;
2326 if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF)
2327 release_frag_chain(local, prcs);
2328 return;
2329 }
2330 skb_reserve( skb, 2); /* Align IP on 16 byte (TBD check this)*/
2331 skb->dev = dev;
2332
2333 DEBUG(4,"ray_cs rx_data total_len = %x, rx_len = %x\n",total_len,rx_len);
2334
2335/************************/
2336 /* Reserve enough room for the whole damn packet. */
2337 rx_ptr = skb_put( skb, total_len);
2338 /* Copy the whole packet to sk_buff */
2339 rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len);
2340 /* Get source address */
2341#ifdef WIRELESS_SPY
2342 memcpy(linksrcaddr, ((struct mac_header *)skb->data)->addr_2, ETH_ALEN);
2343#endif
2344 /* Now, deal with encapsulation/translation/sniffer */
2345 if (!sniffer) {
2346 if (!translate) {
2347 /* Encapsulated ethernet, so just lop off 802.11 MAC header */
2348/* TBD reserve skb_reserve( skb, RX_MAC_HEADER_LENGTH); */
2349 skb_pull( skb, RX_MAC_HEADER_LENGTH);
2350 }
2351 else {
2352 /* Do translation */
2353 untranslate(local, skb, total_len);
2354 }
2355 }
2356 else
2357 { /* sniffer mode, so just pass whole packet */ };
2358
2359/************************/
2360 /* Now pick up the rest of the fragments if any */
2361 tmp = 17;
2362 if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
2363 prcslink = prcs;
2364 DEBUG(1,"ray_cs rx_data in fragment loop\n");
2365 do {
2366 prcslink = rcs_base(local)
2367 + readb(&prcslink->var.rx_packet.next_frag_rcs_index);
2368 rx_len = (( readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8)
2369 + readb(&prcslink->var.rx_packet.rx_data_length[1]))
2370 & RX_BUFF_END;
2371 pkt_addr = (( readb(&prcslink->var.rx_packet.rx_data_ptr[0]) << 8)
2372 + readb(&prcslink->var.rx_packet.rx_data_ptr[1]))
2373 & RX_BUFF_END;
2374
2375 rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr, rx_len);
2376
2377 } while (tmp-- &&
2378 readb(&prcslink->var.rx_packet.next_frag_rcs_index) != 0xFF);
2379 release_frag_chain(local, prcs);
2380 }
2381
2382 skb->protocol = eth_type_trans(skb,dev);
2383 netif_rx(skb);
2384 dev->last_rx = jiffies;
2385 local->stats.rx_packets++;
2386 local->stats.rx_bytes += total_len;
2387
2388 /* Gather signal strength per address */
2389#ifdef WIRELESS_SPY
2390 /* For the Access Point or the node having started the ad-hoc net
2391 * note : ad-hoc work only in some specific configurations, but we
2392 * kludge in ray_get_wireless_stats... */
2393 if(!memcmp(linksrcaddr, local->bss_id, ETH_ALEN))
2394 {
2395 /* Update statistics */
2396 /*local->wstats.qual.qual = none ? */
2397 local->wstats.qual.level = siglev;
2398 /*local->wstats.qual.noise = none ? */
2399 local->wstats.qual.updated = 0x2;
2400 }
2401 /* Now, for the addresses in the spy list */
2402 {
2403 int i;
2404 /* Look all addresses */
2405 for(i = 0; i < local->spy_number; i++)
2406 /* If match */
2407 if(!memcmp(linksrcaddr, local->spy_address[i], ETH_ALEN))
2408 {
2409 /* Update statistics */
2410 /*local->spy_stat[i].qual = none ? */
2411 local->spy_stat[i].level = siglev;
2412 /*local->spy_stat[i].noise = none ? */
2413 local->spy_stat[i].updated = 0x2;
2414 }
2415 }
2416#endif /* WIRELESS_SPY */
2417} /* end rx_data */
2418/*===========================================================================*/
2419static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
2420{
2421 snaphdr_t *psnap = (snaphdr_t *)(skb->data + RX_MAC_HEADER_LENGTH);
2422 struct mac_header *pmac = (struct mac_header *)skb->data;
2423 unsigned short type = *(unsigned short *)psnap->ethertype;
2424 unsigned int xsap = *(unsigned int *)psnap & 0x00ffffff;
2425 unsigned int org = (*(unsigned int *)psnap->org) & 0x00ffffff;
2426 int delta;
2427 struct ethhdr *peth;
2428 UCHAR srcaddr[ADDRLEN];
2429 UCHAR destaddr[ADDRLEN];
2430
2431 if (pmac->frame_ctl_2 & FC2_FROM_DS) {
2432 if (pmac->frame_ctl_2 & FC2_TO_DS) { /* AP to AP */
2433 memcpy(destaddr, pmac->addr_3, ADDRLEN);
2434 memcpy(srcaddr, ((unsigned char *)pmac->addr_3) + ADDRLEN, ADDRLEN);
2435 } else { /* AP to terminal */
2436 memcpy(destaddr, pmac->addr_1, ADDRLEN);
2437 memcpy(srcaddr, pmac->addr_3, ADDRLEN);
2438 }
2439 } else { /* Terminal to AP */
2440 if (pmac->frame_ctl_2 & FC2_TO_DS) {
2441 memcpy(destaddr, pmac->addr_3, ADDRLEN);
2442 memcpy(srcaddr, pmac->addr_2, ADDRLEN);
2443 } else { /* Adhoc */
2444 memcpy(destaddr, pmac->addr_1, ADDRLEN);
2445 memcpy(srcaddr, pmac->addr_2, ADDRLEN);
2446 }
2447 }
2448
2449#ifdef PCMCIA_DEBUG
2450 if (pc_debug > 3) {
2451 int i;
2452 printk(KERN_DEBUG "skb->data before untranslate");
2453 for (i=0;i<64;i++)
2454 printk("%02x ",skb->data[i]);
2455 printk("\n" KERN_DEBUG "type = %08x, xsap = %08x, org = %08x\n",
2456 type,xsap,org);
2457 printk(KERN_DEBUG "untranslate skb->data = %p\n",skb->data);
2458 }
2459#endif
2460
2461 if ( xsap != SNAP_ID) {
2462 /* not a snap type so leave it alone */
2463 DEBUG(3,"ray_cs untranslate NOT SNAP %x\n", *(unsigned int *)psnap & 0x00ffffff);
2464
2465 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2466 peth = (struct ethhdr *)(skb->data + delta);
2467 peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
2468 }
2469 else { /* Its a SNAP */
2470 if (org == BRIDGE_ENCAP) { /* EtherII and nuke the LLC */
2471 DEBUG(3,"ray_cs untranslate Bridge encap\n");
2472 delta = RX_MAC_HEADER_LENGTH
2473 + sizeof(struct snaphdr_t) - ETH_HLEN;
2474 peth = (struct ethhdr *)(skb->data + delta);
2475 peth->h_proto = type;
2476 }
2477 else {
2478 if (org == RFC1042_ENCAP) {
2479 switch (type) {
2480 case RAY_IPX_TYPE:
2481 case APPLEARP_TYPE:
2482 DEBUG(3,"ray_cs untranslate RFC IPX/AARP\n");
2483 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2484 peth = (struct ethhdr *)(skb->data + delta);
2485 peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
2486 break;
2487 default:
2488 DEBUG(3,"ray_cs untranslate RFC default\n");
2489 delta = RX_MAC_HEADER_LENGTH +
2490 sizeof(struct snaphdr_t) - ETH_HLEN;
2491 peth = (struct ethhdr *)(skb->data + delta);
2492 peth->h_proto = type;
2493 break;
2494 }
2495 }
2496 else {
2497 printk("ray_cs untranslate very confused by packet\n");
2498 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2499 peth = (struct ethhdr *)(skb->data + delta);
2500 peth->h_proto = type;
2501 }
2502 }
2503 }
2504/* TBD reserve skb_reserve(skb, delta); */
2505 skb_pull(skb, delta);
2506 DEBUG(3,"untranslate after skb_pull(%d), skb->data = %p\n",delta,skb->data);
2507 memcpy(peth->h_dest, destaddr, ADDRLEN);
2508 memcpy(peth->h_source, srcaddr, ADDRLEN);
2509#ifdef PCMCIA_DEBUG
2510 if (pc_debug > 3) {
2511 int i;
2512 printk(KERN_DEBUG "skb->data after untranslate:");
2513 for (i=0;i<64;i++)
2514 printk("%02x ",skb->data[i]);
2515 printk("\n");
2516 }
2517#endif
2518} /* end untranslate */
2519/*===========================================================================*/
2520/* Copy data from circular receive buffer to PC memory.
2521 * dest = destination address in PC memory
2522 * pkt_addr = source address in receive buffer
2523 * len = length of packet to copy
2524 */
2525static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int length)
2526{
2527 int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1);
2528 if (wrap_bytes <= 0)
2529 {
2530 memcpy_fromio(dest,local->rmem + pkt_addr,length);
2531 }
2532 else /* Packet wrapped in circular buffer */
2533 {
2534 memcpy_fromio(dest,local->rmem+pkt_addr,length - wrap_bytes);
2535 memcpy_fromio(dest + length - wrap_bytes, local->rmem, wrap_bytes);
2536 }
2537 return length;
2538}
2539/*===========================================================================*/
2540static void release_frag_chain(ray_dev_t *local, struct rcs __iomem * prcs)
2541{
2542 struct rcs __iomem *prcslink = prcs;
2543 int tmp = 17;
2544 unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index);
2545
2546 while (tmp--) {
2547 writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
2548 if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
2549 DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex);
2550 break;
2551 }
2552 prcslink = rcs_base(local) + rcsindex;
2553 rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index);
2554 }
2555 writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
2556}
2557/*===========================================================================*/
2558static void authenticate(ray_dev_t *local)
2559{
2560 dev_link_t *link = local->finder;
2561 DEBUG(0,"ray_cs Starting authentication.\n");
2562 if (!(link->state & DEV_PRESENT)) {
2563 DEBUG(2,"ray_cs authenticate - device not present\n");
2564 return;
2565 }
2566
2567 del_timer(&local->timer);
2568 if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
2569 local->timer.function = &join_net;
2570 }
2571 else {
2572 local->timer.function = &authenticate_timeout;
2573 }
2574 local->timer.expires = jiffies + HZ*2;
2575 local->timer.data = (long)local;
2576 add_timer(&local->timer);
2577 local->authentication_state = AWAITING_RESPONSE;
2578} /* end authenticate */
2579/*===========================================================================*/
2580static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
2581 unsigned int pkt_addr, int rx_len)
2582{
2583 UCHAR buff[256];
2584 struct rx_msg *msg = (struct rx_msg *)buff;
2585
2586 del_timer(&local->timer);
2587
2588 copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
2589 /* if we are trying to get authenticated */
2590 if (local->sparm.b4.a_network_type == ADHOC) {
2591 DEBUG(1,"ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n", msg->var[0],msg->var[1],msg->var[2],msg->var[3],msg->var[4],msg->var[5]);
2592 if (msg->var[2] == 1) {
2593 DEBUG(0,"ray_cs Sending authentication response.\n");
2594 if (!build_auth_frame (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
2595 local->authentication_state = NEED_TO_AUTH;
2596 memcpy(local->auth_id, msg->mac.addr_2, ADDRLEN);
2597 }
2598 }
2599 }
2600 else /* Infrastructure network */
2601 {
2602 if (local->authentication_state == AWAITING_RESPONSE) {
2603 /* Verify authentication sequence #2 and success */
2604 if (msg->var[2] == 2) {
2605 if ((msg->var[3] | msg->var[4]) == 0) {
2606 DEBUG(1,"Authentication successful\n");
2607 local->card_status = CARD_AUTH_COMPLETE;
2608 associate(local);
2609 local->authentication_state = AUTHENTICATED;
2610 }
2611 else {
2612 DEBUG(0,"Authentication refused\n");
2613 local->card_status = CARD_AUTH_REFUSED;
2614 join_net((u_long)local);
2615 local->authentication_state = UNAUTHENTICATED;
2616 }
2617 }
2618 }
2619 }
2620
2621} /* end rx_authenticate */
2622/*===========================================================================*/
2623static void associate(ray_dev_t *local)
2624{
2625 struct ccs __iomem *pccs;
2626 dev_link_t *link = local->finder;
2627 struct net_device *dev = link->priv;
2628 int ccsindex;
2629 if (!(link->state & DEV_PRESENT)) {
2630 DEBUG(2,"ray_cs associate - device not present\n");
2631 return;
2632 }
2633 /* If no tx buffers available, return*/
2634 if ((ccsindex = get_free_ccs(local)) < 0)
2635 {
2636/* TBD should never be here but... what if we are? */
2637 DEBUG(1,"ray_cs associate - No free ccs\n");
2638 return;
2639 }
2640 DEBUG(1,"ray_cs Starting association with access point\n");
2641 pccs = ccs_base(local) + ccsindex;
2642 /* fill in the CCS */
2643 writeb(CCS_START_ASSOCIATION, &pccs->cmd);
2644 /* Interrupt the firmware to process the command */
2645 if (interrupt_ecf(local, ccsindex)) {
2646 DEBUG(1,"ray_cs associate failed - ECF not ready for intr\n");
2647 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
2648
2649 del_timer(&local->timer);
2650 local->timer.expires = jiffies + HZ*2;
2651 local->timer.data = (long)local;
2652 local->timer.function = &join_net;
2653 add_timer(&local->timer);
2654 local->card_status = CARD_ASSOC_FAILED;
2655 return;
2656 }
2657 if (!sniffer) netif_start_queue(dev);
2658
2659} /* end associate */
2660/*===========================================================================*/
2661static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
2662 unsigned int pkt_addr, int rx_len)
2663{
2664/* UCHAR buff[256];
2665 struct rx_msg *msg = (struct rx_msg *)buff;
2666*/
2667 DEBUG(0,"Deauthentication frame received\n");
2668 local->authentication_state = UNAUTHENTICATED;
2669 /* Need to reauthenticate or rejoin depending on reason code */
2670/* copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
2671 */
2672}
2673/*===========================================================================*/
2674static void clear_interrupt(ray_dev_t *local)
2675{
2676 writeb(0, local->amem + CIS_OFFSET + HCS_INTR_OFFSET);
2677}
2678/*===========================================================================*/
2679#ifdef CONFIG_PROC_FS
2680#define MAXDATA (PAGE_SIZE - 80)
2681
2682static char *card_status[] = {
2683 "Card inserted - uninitialized", /* 0 */
2684 "Card not downloaded", /* 1 */
2685 "Waiting for download parameters", /* 2 */
2686 "Card doing acquisition", /* 3 */
2687 "Acquisition complete", /* 4 */
2688 "Authentication complete", /* 5 */
2689 "Association complete", /* 6 */
2690 "???", "???", "???", "???", /* 7 8 9 10 undefined */
2691 "Card init error", /* 11 */
2692 "Download parameters error", /* 12 */
2693 "???", /* 13 */
2694 "Acquisition failed", /* 14 */
2695 "Authentication refused", /* 15 */
2696 "Association failed" /* 16 */
2697};
2698
2699static char *nettype[] = {"Adhoc", "Infra "};
2700static char *framing[] = {"Encapsulation", "Translation"}
2701;
2702/*===========================================================================*/
2703static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len)
2704{
2705/* Print current values which are not available via other means
2706 * eg ifconfig
2707 */
2708 int i;
2709 dev_link_t *link;
2710 struct net_device *dev;
2711 ray_dev_t *local;
2712 UCHAR *p;
2713 struct freq_hop_element *pfh;
2714 UCHAR c[33];
2715
2716 link = dev_list;
2717 if (!link)
2718 return 0;
2719 dev = (struct net_device *)link->priv;
2720 if (!dev)
2721 return 0;
2722 local = (ray_dev_t *)dev->priv;
2723 if (!local)
2724 return 0;
2725
2726 len = 0;
2727
2728 len += sprintf(buf + len, "Raylink Wireless LAN driver status\n");
2729 len += sprintf(buf + len, "%s\n", rcsid);
2730 /* build 4 does not report version, and field is 0x55 after memtest */
2731 len += sprintf(buf + len, "Firmware version = ");
2732 if (local->fw_ver == 0x55)
2733 len += sprintf(buf + len, "4 - Use dump_cis for more details\n");
2734 else
2735 len += sprintf(buf + len, "%2d.%02d.%02d\n",
2736 local->fw_ver, local->fw_bld, local->fw_var);
2737
2738 for (i=0; i<32; i++) c[i] = local->sparm.b5.a_current_ess_id[i];
2739 c[32] = 0;
2740 len += sprintf(buf + len, "%s network ESSID = \"%s\"\n",
2741 nettype[local->sparm.b5.a_network_type], c);
2742
2743 p = local->bss_id;
2744 len += sprintf(buf + len,
2745 "BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
2746 p[0],p[1],p[2],p[3],p[4],p[5]);
2747
2748 len += sprintf(buf + len, "Country code = %d\n",
2749 local->sparm.b5.a_curr_country_code);
2750
2751 i = local->card_status;
2752 if (i < 0) i = 10;
2753 if (i > 16) i = 10;
2754 len += sprintf(buf + len, "Card status = %s\n", card_status[i]);
2755
2756 len += sprintf(buf + len, "Framing mode = %s\n",framing[translate]);
2757
2758 len += sprintf(buf + len, "Last pkt signal lvl = %d\n", local->last_rsl);
2759
2760 if (local->beacon_rxed) {
2761 /* Pull some fields out of last beacon received */
2762 len += sprintf(buf + len, "Beacon Interval = %d Kus\n",
2763 local->last_bcn.beacon_intvl[0]
2764 + 256 * local->last_bcn.beacon_intvl[1]);
2765
2766 p = local->last_bcn.elements;
2767 if (p[0] == C_ESSID_ELEMENT_ID) p += p[1] + 2;
2768 else {
2769 len += sprintf(buf + len, "Parse beacon failed at essid element id = %d\n",p[0]);
2770 return len;
2771 }
2772
2773 if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) {
2774 len += sprintf(buf + len, "Supported rate codes = ");
2775 for (i=2; i<p[1] + 2; i++)
2776 len += sprintf(buf + len, "0x%02x ", p[i]);
2777 len += sprintf(buf + len, "\n");
2778 p += p[1] + 2;
2779 }
2780 else {
2781 len += sprintf(buf + len, "Parse beacon failed at rates element\n");
2782 return len;
2783 }
2784
2785 if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) {
2786 pfh = (struct freq_hop_element *)p;
2787 len += sprintf(buf + len, "Hop dwell = %d Kus\n",
2788 pfh->dwell_time[0] + 256 * pfh->dwell_time[1]);
2789 len += sprintf(buf + len, "Hop set = %d \n", pfh->hop_set);
2790 len += sprintf(buf + len, "Hop pattern = %d \n", pfh->hop_pattern);
2791 len += sprintf(buf + len, "Hop index = %d \n", pfh->hop_index);
2792 p += p[1] + 2;
2793 }
2794 else {
2795 len += sprintf(buf + len, "Parse beacon failed at FH param element\n");
2796 return len;
2797 }
2798 } else {
2799 len += sprintf(buf + len, "No beacons received\n");
2800 }
2801 return len;
2802}
2803
2804#endif
2805/*===========================================================================*/
2806static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
2807{
2808 int addr;
2809 struct ccs __iomem *pccs;
2810 struct tx_msg __iomem *ptx;
2811 int ccsindex;
2812
2813 /* If no tx buffers available, return */
2814 if ((ccsindex = get_free_tx_ccs(local)) < 0)
2815 {
2816 DEBUG(1,"ray_cs send authenticate - No free tx ccs\n");
2817 return -1;
2818 }
2819
2820 pccs = ccs_base(local) + ccsindex;
2821
2822 /* Address in card space */
2823 addr = TX_BUF_BASE + (ccsindex << 11);
2824 /* fill in the CCS */
2825 writeb(CCS_TX_REQUEST, &pccs->cmd);
2826 writeb(addr >> 8, pccs->var.tx_request.tx_data_ptr);
2827 writeb(0x20, pccs->var.tx_request.tx_data_ptr + 1);
2828 writeb(TX_AUTHENTICATE_LENGTH_MSB, pccs->var.tx_request.tx_data_length);
2829 writeb(TX_AUTHENTICATE_LENGTH_LSB,pccs->var.tx_request.tx_data_length + 1);
2830 writeb(0, &pccs->var.tx_request.pow_sav_mode);
2831
2832 ptx = local->sram + addr;
2833 /* fill in the mac header */
2834 writeb(PROTOCOL_VER | AUTHENTIC_TYPE, &ptx->mac.frame_ctl_1);
2835 writeb(0, &ptx->mac.frame_ctl_2);
2836
2837 memcpy_toio(ptx->mac.addr_1, dest, ADDRLEN);
2838 memcpy_toio(ptx->mac.addr_2, local->sparm.b4.a_mac_addr, ADDRLEN);
2839 memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
2840
2841 /* Fill in msg body with protocol 00 00, sequence 01 00 ,status 00 00 */
2842 memset_io(ptx->var, 0, 6);
2843 writeb(auth_type & 0xff, ptx->var + 2);
2844
2845 /* Interrupt the firmware to process the command */
2846 if (interrupt_ecf(local, ccsindex)) {
2847 DEBUG(1,"ray_cs send authentication request failed - ECF not ready for intr\n");
2848 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
2849 return -1;
2850 }
2851 return 0;
2852} /* End build_auth_frame */
2853
2854/*===========================================================================*/
2855#ifdef CONFIG_PROC_FS
2856static void raycs_write(const char *name, write_proc_t *w, void *data)
2857{
2858 struct proc_dir_entry * entry = create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
2859 if (entry) {
2860 entry->write_proc = w;
2861 entry->data = data;
2862 }
2863}
2864
2865static int write_essid(struct file *file, const char __user *buffer, unsigned long count, void *data)
2866{
2867 static char proc_essid[33];
2868 int len = count;
2869
2870 if (len > 32)
2871 len = 32;
2872 memset(proc_essid, 0, 33);
2873 if (copy_from_user(proc_essid, buffer, len))
2874 return -EFAULT;
2875 essid = proc_essid;
2876 return count;
2877}
2878
2879static int write_int(struct file *file, const char __user *buffer, unsigned long count, void *data)
2880{
2881 static char proc_number[10];
2882 char *p;
2883 int nr, len;
2884
2885 if (!count)
2886 return 0;
2887
2888 if (count > 9)
2889 return -EINVAL;
2890 if (copy_from_user(proc_number, buffer, count))
2891 return -EFAULT;
2892 p = proc_number;
2893 nr = 0;
2894 len = count;
2895 do {
2896 unsigned int c = *p - '0';
2897 if (c > 9)
2898 return -EINVAL;
2899 nr = nr*10 + c;
2900 p++;
2901 } while (--len);
2902 *(int *)data = nr;
2903 return count;
2904}
2905#endif
2906
2907static struct pcmcia_driver ray_driver = {
2908 .owner = THIS_MODULE,
2909 .drv = {
2910 .name = "ray_cs",
2911 },
2912 .attach = ray_attach,
2913 .detach = ray_detach,
2914};
2915
2916static int __init init_ray_cs(void)
2917{
2918 int rc;
2919
2920 DEBUG(1, "%s\n", rcsid);
2921 rc = pcmcia_register_driver(&ray_driver);
2922 DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",rc);
2923
2924#ifdef CONFIG_PROC_FS
2925 proc_mkdir("driver/ray_cs", NULL);
2926
2927 create_proc_info_entry("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_read);
2928 raycs_write("driver/ray_cs/essid", write_essid, NULL);
2929 raycs_write("driver/ray_cs/net_type", write_int, &net_type);
2930 raycs_write("driver/ray_cs/translate", write_int, &translate);
2931#endif
2932 if (translate != 0) translate = 1;
2933 return 0;
2934} /* init_ray_cs */
2935
2936/*===========================================================================*/
2937
2938static void __exit exit_ray_cs(void)
2939{
2940 DEBUG(0, "ray_cs: cleanup_module\n");
2941
2942#ifdef CONFIG_PROC_FS
2943 remove_proc_entry("driver/ray_cs/ray_cs", NULL);
2944 remove_proc_entry("driver/ray_cs/essid", NULL);
2945 remove_proc_entry("driver/ray_cs/net_type", NULL);
2946 remove_proc_entry("driver/ray_cs/translate", NULL);
2947 remove_proc_entry("driver/ray_cs", NULL);
2948#endif
2949
2950 pcmcia_unregister_driver(&ray_driver);
2951 BUG_ON(dev_list != NULL);
2952} /* exit_ray_cs */
2953
2954module_init(init_ray_cs);
2955module_exit(exit_ray_cs);
2956
2957/*===========================================================================*/
diff --git a/drivers/net/wireless/ray_cs.h b/drivers/net/wireless/ray_cs.h
new file mode 100644
index 000000000000..c77afa14fa86
--- /dev/null
+++ b/drivers/net/wireless/ray_cs.h
@@ -0,0 +1,78 @@
1/* Raytheon wireless LAN PCMCIA card driver for Linux
2 A PCMCIA client driver for the Raylink wireless network card
3 Written by Corey Thomas
4*/
5
6#ifndef RAYLINK_H
7
8struct beacon_rx {
9 struct mac_header mac;
10 UCHAR timestamp[8];
11 UCHAR beacon_intvl[2];
12 UCHAR capability[2];
13 UCHAR elements[sizeof(struct essid_element)
14 + sizeof(struct rates_element)
15 + sizeof(struct freq_hop_element)
16 + sizeof(struct japan_call_sign_element)
17 + sizeof(struct tim_element)];
18};
19
20/* Return values for get_free{,_tx}_ccs */
21#define ECCSFULL (-1)
22#define ECCSBUSY (-2)
23#define ECARDGONE (-3)
24
25typedef struct ray_dev_t {
26 int card_status;
27 int authentication_state;
28 dev_node_t node;
29 window_handle_t amem_handle; /* handle to window for attribute memory */
30 window_handle_t rmem_handle; /* handle to window for rx buffer on card */
31 void __iomem *sram; /* pointer to beginning of shared RAM */
32 void __iomem *amem; /* pointer to attribute mem window */
33 void __iomem *rmem; /* pointer to receive buffer window */
34 dev_link_t *finder; /* pointer back to dev_link_t for card */
35 struct timer_list timer;
36 long tx_ccs_lock;
37 long ccs_lock;
38 int dl_param_ccs;
39 union {
40 struct b4_startup_params b4;
41 struct b5_startup_params b5;
42 } sparm;
43 int timeout_flag;
44 UCHAR supported_rates[8];
45 UCHAR japan_call_sign[12];
46 struct startup_res_6 startup_res;
47 int num_multi;
48 /* Network parameters from start/join */
49 UCHAR bss_id[6];
50 UCHAR auth_id[6];
51 UCHAR net_default_tx_rate;
52 UCHAR encryption;
53 struct net_device_stats stats;
54
55 UCHAR net_type;
56 UCHAR sta_type;
57 UCHAR fw_ver;
58 UCHAR fw_bld;
59 UCHAR fw_var;
60 UCHAR ASIC_version;
61 UCHAR assoc_id[2];
62 UCHAR tib_length;
63 UCHAR last_rsl;
64 int beacon_rxed;
65 struct beacon_rx last_bcn;
66#ifdef WIRELESS_EXT
67 iw_stats wstats; /* Wireless specific stats */
68#endif
69#ifdef WIRELESS_SPY
70 int spy_number; /* Number of addresses to spy */
71 mac_addr spy_address[IW_MAX_SPY + 1]; /* The addresses to spy */
72 iw_qual spy_stat[IW_MAX_SPY + 1]; /* Statistics gathered */
73#endif /* WIRELESS_SPY */
74
75} ray_dev_t;
76/*****************************************************************************/
77
78#endif /* RAYLINK_H */
diff --git a/drivers/net/wireless/rayctl.h b/drivers/net/wireless/rayctl.h
new file mode 100644
index 000000000000..49d9b267bc0f
--- /dev/null
+++ b/drivers/net/wireless/rayctl.h
@@ -0,0 +1,732 @@
1#ifndef RAYLINK_H
2
3typedef unsigned char UCHAR;
4
5/****** IEEE 802.11 constants ************************************************/
6#define ADDRLEN 6
7/* Frame control 1 bit fields */
8#define PROTOCOL_VER 0x00
9#define DATA_TYPE 0x08
10#define ASSOC_REQ_TYPE 0x00
11#define ASSOC_RESP_TYPE 0x10
12#define REASSOC_REQ_TYPE 0x20
13#define REASSOC_RESP_TYPE 0x30
14#define NULL_MSG_TYPE 0x48
15#define BEACON_TYPE 0x80
16#define DISASSOC_TYPE 0xA0
17#define PSPOLL_TYPE 0xA4
18#define AUTHENTIC_TYPE 0xB0
19#define DEAUTHENTIC_TYPE 0xC0
20/* Frame control 2 bit fields */
21#define FC2_TO_DS 0x01
22#define FC2_FROM_DS 0x02
23#define FC2_MORE_FRAG 0x04
24#define FC2_RETRY 0x08
25#define FC2_PSM 0x10
26#define FC2_MORE_DATA 0x20
27#define FC2_WEP 0x40
28#define FC2_ORDER 0x80
29/*****************************************************************************/
30/* 802.11 element ID's and lengths */
31#define C_BP_CAPABILITY_ESS 0x01
32#define C_BP_CAPABILITY_IBSS 0x02
33#define C_BP_CAPABILITY_CF_POLLABLE 0x04
34#define C_BP_CAPABILITY_CF_POLL_REQUEST 0x08
35#define C_BP_CAPABILITY_PRIVACY 0x10
36
37#define C_ESSID_ELEMENT_ID 0
38#define C_ESSID_ELEMENT_MAX_LENGTH 32
39
40#define C_SUPPORTED_RATES_ELEMENT_ID 1
41#define C_SUPPORTED_RATES_ELEMENT_LENGTH 2
42
43#define C_FH_PARAM_SET_ELEMENT_ID 2
44#define C_FH_PARAM_SET_ELEMENT_LNGTH 5
45
46#define C_CF_PARAM_SET_ELEMENT_ID 4
47#define C_CF_PARAM_SET_ELEMENT_LNGTH 6
48
49#define C_TIM_ELEMENT_ID 5
50#define C_TIM_BITMAP_LENGTH 251
51#define C_TIM_BMCAST_BIT 0x01
52
53#define C_IBSS_ELEMENT_ID 6
54#define C_IBSS_ELEMENT_LENGTH 2
55
56#define C_JAPAN_CALL_SIGN_ELEMENT_ID 51
57#define C_JAPAN_CALL_SIGN_ELEMENT_LNGTH 12
58
59#define C_DISASSOC_REASON_CODE_LEN 2
60#define C_DISASSOC_REASON_CODE_DEFAULT 8
61
62#define C_CRC_LEN 4
63#define C_NUM_SUPPORTED_RATES 8
64/****** IEEE 802.11 mac header for type data packets *************************/
65struct mac_header {
66 UCHAR frame_ctl_1;
67 UCHAR frame_ctl_2;
68 UCHAR duration_lsb;
69 UCHAR duration_msb;
70 UCHAR addr_1[ADDRLEN];
71 UCHAR addr_2[ADDRLEN];
72 UCHAR addr_3[ADDRLEN];
73 UCHAR seq_frag_num[2];
74/* UCHAR addr_4[ADDRLEN]; *//* only present for AP to AP (TO DS and FROM DS */
75};
76/****** IEEE 802.11 frame element structures *********************************/
77struct essid_element
78{
79 UCHAR id;
80 UCHAR length;
81 UCHAR text[C_ESSID_ELEMENT_MAX_LENGTH];
82};
83struct rates_element
84{
85 UCHAR id;
86 UCHAR length;
87 UCHAR value[8];
88};
89struct freq_hop_element
90{
91 UCHAR id;
92 UCHAR length;
93 UCHAR dwell_time[2];
94 UCHAR hop_set;
95 UCHAR hop_pattern;
96 UCHAR hop_index;
97};
98struct tim_element
99{
100 UCHAR id;
101 UCHAR length;
102 UCHAR dtim_count;
103 UCHAR dtim_period;
104 UCHAR bitmap_control;
105 UCHAR tim[C_TIM_BITMAP_LENGTH];
106};
107struct ibss_element
108{
109 UCHAR id;
110 UCHAR length;
111 UCHAR atim_window[2];
112};
113struct japan_call_sign_element
114{
115 UCHAR id;
116 UCHAR length;
117 UCHAR call_sign[12];
118};
119/****** Beacon message structures ********************************************/
120/* .elements is a large lump of max size because elements are variable size */
121struct infra_beacon
122{
123 UCHAR timestamp[8];
124 UCHAR beacon_intvl[2];
125 UCHAR capability[2];
126 UCHAR elements[sizeof(struct essid_element)
127 + sizeof(struct rates_element)
128 + sizeof(struct freq_hop_element)
129 + sizeof(struct japan_call_sign_element)
130 + sizeof(struct tim_element)];
131};
132struct adhoc_beacon
133{
134 UCHAR timestamp[8];
135 UCHAR beacon_intvl[2];
136 UCHAR capability[2];
137 UCHAR elements[sizeof(struct essid_element)
138 + sizeof(struct rates_element)
139 + sizeof(struct freq_hop_element)
140 + sizeof(struct japan_call_sign_element)
141 + sizeof(struct ibss_element)];
142};
143/*****************************************************************************/
144/*****************************************************************************/
145/* #define C_MAC_HDR_2_WEP 0x40 */
146/* TX/RX CCS constants */
147#define TX_HEADER_LENGTH 0x1C
148#define RX_MAC_HEADER_LENGTH 0x18
149#define TX_AUTHENTICATE_LENGTH (TX_HEADER_LENGTH + 6)
150#define TX_AUTHENTICATE_LENGTH_MSB (TX_AUTHENTICATE_LENGTH >> 8)
151#define TX_AUTHENTICATE_LENGTH_LSB (TX_AUTHENTICATE_LENGTH & 0xff)
152#define TX_DEAUTHENTICATE_LENGTH (TX_HEADER_LENGTH + 2)
153#define TX_DEAUTHENTICATE_LENGTH_MSB (TX_AUTHENTICATE_LENGTH >> 8)
154#define TX_DEAUTHENTICATE_LENGTH_LSB (TX_AUTHENTICATE_LENGTH & 0xff)
155#define FCS_LEN 4
156
157#define ADHOC 0
158#define INFRA 1
159
160#define TYPE_STA 0
161#define TYPE_AP 1
162
163#define PASSIVE_SCAN 1
164#define ACTIVE_SCAN 1
165
166#define PSM_CAM 0
167
168/* Country codes */
169#define USA 1
170#define EUROPE 2
171#define JAPAN 3
172#define KOREA 4
173#define SPAIN 5
174#define FRANCE 6
175#define ISRAEL 7
176#define AUSTRALIA 8
177#define JAPAN_TEST 9
178
179/* Hop pattern lengths */
180#define USA_HOP_MOD 79
181#define EUROPE_HOP_MOD 79
182#define JAPAN_HOP_MOD 23
183#define KOREA_HOP_MOD 23
184#define SPAIN_HOP_MOD 27
185#define FRANCE_HOP_MOD 35
186#define ISRAEL_HOP_MOD 35
187#define AUSTRALIA_HOP_MOD 47
188#define JAPAN_TEST_HOP_MOD 23
189
190#define ESSID_SIZE 32
191/**********************************************************************/
192/* CIS Register Constants */
193#define CIS_OFFSET 0x0f00
194/* Configuration Option Register (0x0F00) */
195#define COR_OFFSET 0x00
196#define COR_SOFT_RESET 0x80
197#define COR_LEVEL_IRQ 0x40
198#define COR_CONFIG_NUM 0x01
199#define COR_DEFAULT (COR_LEVEL_IRQ | COR_CONFIG_NUM)
200
201/* Card Configuration and Status Register (0x0F01) */
202#define CCSR_OFFSET 0x01
203#define CCSR_HOST_INTR_PENDING 0x01
204#define CCSR_POWER_DOWN 0x04
205
206/* HCS Interrupt Register (0x0F05) */
207#define HCS_INTR_OFFSET 0x05
208/* #define HCS_INTR_OFFSET 0x0A */
209#define HCS_INTR_CLEAR 0x00
210
211/* ECF Interrupt Register (0x0F06) */
212#define ECF_INTR_OFFSET 0x06
213/* #define ECF_INTR_OFFSET 0x0C */
214#define ECF_INTR_SET 0x01
215
216/* Authorization Register 0 (0x0F08) */
217#define AUTH_0_ON 0x57
218
219/* Authorization Register 1 (0x0F09) */
220#define AUTH_1_ON 0x82
221
222/* Program Mode Register (0x0F0A) */
223#define PC2PM 0x02
224#define PC2CAL 0x10
225#define PC2MLSE 0x20
226
227/* PC Test Mode Register (0x0F0B) */
228#define PC_TEST_MODE 0x08
229
230/* Frequency Control Word (0x0F10) */
231/* Range 0x02 - 0xA6 */
232
233/* Test Mode Control 1-4 (0x0F14 - 0x0F17) */
234
235/**********************************************************************/
236
237/* Shared RAM Area */
238#define SCB_BASE 0x0000
239#define STATUS_BASE 0x0100
240#define HOST_TO_ECF_BASE 0x0200
241#define ECF_TO_HOST_BASE 0x0300
242#define CCS_BASE 0x0400
243#define RCS_BASE 0x0800
244#define INFRA_TIM_BASE 0x0C00
245#define SSID_LIST_BASE 0x0D00
246#define TX_BUF_BASE 0x1000
247#define RX_BUF_BASE 0x8000
248
249#define NUMBER_OF_CCS 64
250#define NUMBER_OF_RCS 64
251/*#define NUMBER_OF_TX_CCS 14 */
252#define NUMBER_OF_TX_CCS 14
253
254#define TX_BUF_SIZE (2048 - sizeof(struct tx_msg))
255#define RX_BUFF_END 0x3FFF
256/* Values for buffer_status */
257#define CCS_BUFFER_FREE 0
258#define CCS_BUFFER_BUSY 1
259#define CCS_COMMAND_COMPLETE 2
260#define CCS_COMMAND_FAILED 3
261
262/* Values for cmd */
263#define CCS_DOWNLOAD_STARTUP_PARAMS 1
264#define CCS_UPDATE_PARAMS 2
265#define CCS_REPORT_PARAMS 3
266#define CCS_UPDATE_MULTICAST_LIST 4
267#define CCS_UPDATE_POWER_SAVINGS_MODE 5
268#define CCS_START_NETWORK 6
269#define CCS_JOIN_NETWORK 7
270#define CCS_START_ASSOCIATION 8
271#define CCS_TX_REQUEST 9
272#define CCS_TEST_MEMORY 0xa
273#define CCS_SHUTDOWN 0xb
274#define CCS_DUMP_MEMORY 0xc
275#define CCS_START_TIMER 0xe
276#define CCS_LAST_CMD CCS_START_TIMER
277
278/* Values for link field */
279#define CCS_END_LIST 0xff
280
281/* values for buffer_status field */
282#define RCS_BUFFER_FREE 0
283#define RCS_BUFFER_BUSY 1
284#define RCS_COMPLETE 2
285#define RCS_FAILED 3
286#define RCS_BUFFER_RELEASE 0xFF
287
288/* values for interrupt_id field */
289#define PROCESS_RX_PACKET 0x80 /* */
290#define REJOIN_NET_COMPLETE 0x81 /* RCS ID: Rejoin Net Complete */
291#define ROAMING_INITIATED 0x82 /* RCS ID: Roaming Initiated */
292#define JAPAN_CALL_SIGN_RXD 0x83 /* RCS ID: New Japan Call Sign */
293
294/*****************************************************************************/
295/* Memory types for dump memory command */
296#define C_MEM_PROG 0
297#define C_MEM_XDATA 1
298#define C_MEM_SFR 2
299#define C_MEM_IDATA 3
300
301/*** Return values for hw_xmit **********/
302#define XMIT_OK (0)
303#define XMIT_MSG_BAD (-1)
304#define XMIT_NO_CCS (-2)
305#define XMIT_NO_INTR (-3)
306#define XMIT_NEED_AUTH (-4)
307
308/*** Values for card status */
309#define CARD_INSERTED (0)
310
311#define CARD_AWAITING_PARAM (1)
312#define CARD_INIT_ERROR (11)
313
314#define CARD_DL_PARAM (2)
315#define CARD_DL_PARAM_ERROR (12)
316
317#define CARD_DOING_ACQ (3)
318
319#define CARD_ACQ_COMPLETE (4)
320#define CARD_ACQ_FAILED (14)
321
322#define CARD_AUTH_COMPLETE (5)
323#define CARD_AUTH_REFUSED (15)
324
325#define CARD_ASSOC_COMPLETE (6)
326#define CARD_ASSOC_FAILED (16)
327
328/*** Values for authentication_state ***********************************/
329#define UNAUTHENTICATED (0)
330#define AWAITING_RESPONSE (1)
331#define AUTHENTICATED (2)
332#define NEED_TO_AUTH (3)
333
334/*** Values for authentication type ************************************/
335#define OPEN_AUTH_REQUEST (1)
336#define OPEN_AUTH_RESPONSE (2)
337#define BROADCAST_DEAUTH (0xc0)
338/*** Values for timer functions ****************************************/
339#define TODO_NOTHING (0)
340#define TODO_VERIFY_DL_START (-1)
341#define TODO_START_NET (-2)
342#define TODO_JOIN_NET (-3)
343#define TODO_AUTHENTICATE_TIMEOUT (-4)
344#define TODO_SEND_CCS (-5)
345/***********************************************************************/
346/* Parameter passing structure for update/report parameter CCS's */
347struct object_id {
348 void *object_addr;
349 unsigned char object_length;
350};
351
352#define OBJID_network_type 0
353#define OBJID_acting_as_ap_status 1
354#define OBJID_current_ess_id 2
355#define OBJID_scanning_mode 3
356#define OBJID_power_mgt_state 4
357#define OBJID_mac_address 5
358#define OBJID_frag_threshold 6
359#define OBJID_hop_time 7
360#define OBJID_beacon_period 8
361#define OBJID_dtim_period 9
362#define OBJID_retry_max 10
363#define OBJID_ack_timeout 11
364#define OBJID_sifs 12
365#define OBJID_difs 13
366#define OBJID_pifs 14
367#define OBJID_rts_threshold 15
368#define OBJID_scan_dwell_time 16
369#define OBJID_max_scan_dwell_time 17
370#define OBJID_assoc_resp_timeout 18
371#define OBJID_adhoc_scan_cycle_max 19
372#define OBJID_infra_scan_cycle_max 20
373#define OBJID_infra_super_cycle_max 21
374#define OBJID_promiscuous_mode 22
375#define OBJID_unique_word 23
376#define OBJID_slot_time 24
377#define OBJID_roaming_low_snr 25
378#define OBJID_low_snr_count_thresh 26
379#define OBJID_infra_missed_bcn 27
380#define OBJID_adhoc_missed_bcn 28
381#define OBJID_curr_country_code 29
382#define OBJID_hop_pattern 30
383#define OBJID_reserved 31
384#define OBJID_cw_max_msb 32
385#define OBJID_cw_min_msb 33
386#define OBJID_noise_filter_gain 34
387#define OBJID_noise_limit_offset 35
388#define OBJID_det_rssi_thresh_offset 36
389#define OBJID_med_busy_thresh_offset 37
390#define OBJID_det_sync_thresh 38
391#define OBJID_test_mode 39
392#define OBJID_test_min_chan_num 40
393#define OBJID_test_max_chan_num 41
394#define OBJID_allow_bcast_ID_prbrsp 42
395#define OBJID_privacy_must_start 43
396#define OBJID_privacy_can_join 44
397#define OBJID_basic_rate_set 45
398
399/**** Configuration/Status/Control Area ***************************/
400/* System Control Block (SCB) Area
401 * Located at Shared RAM offset 0
402 */
403struct scb {
404 UCHAR ccs_index;
405 UCHAR rcs_index;
406};
407
408/****** Status area at Shared RAM offset 0x0100 ******************************/
409struct status {
410 UCHAR mrx_overflow_for_host; /* 0=ECF may write, 1=host may write*/
411 UCHAR mrx_checksum_error_for_host; /* 0=ECF may write, 1=host may write*/
412 UCHAR rx_hec_error_for_host; /* 0=ECF may write, 1=host may write*/
413 UCHAR reserved1;
414 short mrx_overflow; /* ECF increments on rx overflow */
415 short mrx_checksum_error; /* ECF increments on rx CRC error */
416 short rx_hec_error; /* ECF incs on mac header CRC error */
417 UCHAR rxnoise; /* Average RSL measurement */
418};
419
420/****** Host-to-ECF Data Area at Shared RAM offset 0x200 *********************/
421struct host_to_ecf_area {
422
423};
424
425/****** ECF-to-Host Data Area at Shared RAM offset 0x0300 ********************/
426struct startup_res_518 {
427 UCHAR startup_word;
428 UCHAR station_addr[ADDRLEN];
429 UCHAR calc_prog_chksum;
430 UCHAR calc_cis_chksum;
431 UCHAR ecf_spare[7];
432 UCHAR japan_call_sign[12];
433};
434
435struct startup_res_6 {
436 UCHAR startup_word;
437 UCHAR station_addr[ADDRLEN];
438 UCHAR reserved;
439 UCHAR supp_rates[8];
440 UCHAR japan_call_sign[12];
441 UCHAR calc_prog_chksum;
442 UCHAR calc_cis_chksum;
443 UCHAR firmware_version[3];
444 UCHAR asic_version;
445 UCHAR tib_length;
446};
447
448struct start_join_net_params {
449 UCHAR net_type;
450 UCHAR ssid[ESSID_SIZE];
451 UCHAR reserved;
452 UCHAR privacy_can_join;
453};
454
455/****** Command Control Structure area at Shared ram offset 0x0400 ***********/
456/* Structures for command specific parameters (ccs.var) */
457struct update_param_cmd {
458 UCHAR object_id;
459 UCHAR number_objects;
460 UCHAR failure_cause;
461};
462struct report_param_cmd {
463 UCHAR object_id;
464 UCHAR number_objects;
465 UCHAR failure_cause;
466 UCHAR length;
467};
468struct start_network_cmd {
469 UCHAR update_param;
470 UCHAR bssid[ADDRLEN];
471 UCHAR net_initiated;
472 UCHAR net_default_tx_rate;
473 UCHAR encryption;
474};
475struct join_network_cmd {
476 UCHAR update_param;
477 UCHAR bssid[ADDRLEN];
478 UCHAR net_initiated;
479 UCHAR net_default_tx_rate;
480 UCHAR encryption;
481};
482struct tx_requested_cmd {
483
484 UCHAR tx_data_ptr[2];
485 UCHAR tx_data_length[2];
486 UCHAR host_reserved[2];
487 UCHAR reserved[3];
488 UCHAR tx_rate;
489 UCHAR pow_sav_mode;
490 UCHAR retries;
491 UCHAR antenna;
492};
493struct tx_requested_cmd_4 {
494
495 UCHAR tx_data_ptr[2];
496 UCHAR tx_data_length[2];
497 UCHAR dest_addr[ADDRLEN];
498 UCHAR pow_sav_mode;
499 UCHAR retries;
500 UCHAR station_id;
501};
502struct memory_dump_cmd {
503 UCHAR memory_type;
504 UCHAR memory_ptr[2];
505 UCHAR length;
506};
507struct update_association_cmd {
508 UCHAR status;
509 UCHAR aid[2];
510};
511struct start_timer_cmd {
512 UCHAR duration[2];
513};
514
515struct ccs {
516 UCHAR buffer_status; /* 0 = buffer free, 1 = buffer busy */
517 /* 2 = command complete, 3 = failed */
518 UCHAR cmd; /* command to ECF */
519 UCHAR link; /* link to next CCS, FF=end of list */
520 /* command specific parameters */
521 union {
522 char reserved[13];
523 struct update_param_cmd update_param;
524 struct report_param_cmd report_param;
525 UCHAR nummulticast;
526 UCHAR mode;
527 struct start_network_cmd start_network;
528 struct join_network_cmd join_network;
529 struct tx_requested_cmd tx_request;
530 struct memory_dump_cmd memory_dump;
531 struct update_association_cmd update_assoc;
532 struct start_timer_cmd start_timer;
533 } var;
534};
535
536/*****************************************************************************/
537/* Transmit buffer structures */
538struct tib_structure {
539 UCHAR ccs_index;
540 UCHAR psm;
541 UCHAR pass_fail;
542 UCHAR retry_count;
543 UCHAR max_retries;
544 UCHAR frags_remaining;
545 UCHAR no_rb;
546 UCHAR rts_reqd;
547 UCHAR csma_tx_cntrl_2;
548 UCHAR sifs_tx_cntrl_2;
549 UCHAR tx_dma_addr_1[2];
550 UCHAR tx_dma_addr_2[2];
551 UCHAR var_dur_2mhz[2];
552 UCHAR var_dur_1mhz[2];
553 UCHAR max_dur_2mhz[2];
554 UCHAR max_dur_1mhz[2];
555 UCHAR hdr_len;
556 UCHAR max_frag_len[2];
557 UCHAR var_len[2];
558 UCHAR phy_hdr_4;
559 UCHAR mac_hdr_1;
560 UCHAR mac_hdr_2;
561 UCHAR sid[2];
562};
563
564struct phy_header {
565 UCHAR sfd[2];
566 UCHAR hdr_3;
567 UCHAR hdr_4;
568};
569struct rx_msg {
570 struct mac_header mac;
571 UCHAR var[1];
572};
573
574struct tx_msg {
575 struct tib_structure tib;
576 struct phy_header phy;
577 struct mac_header mac;
578 UCHAR var[1];
579};
580
581/****** ECF Receive Control Stucture (RCS) Area at Shared RAM offset 0x0800 */
582/* Structures for command specific parameters (rcs.var) */
583struct rx_packet_cmd {
584 UCHAR rx_data_ptr[2];
585 UCHAR rx_data_length[2];
586 UCHAR rx_sig_lev;
587 UCHAR next_frag_rcs_index;
588 UCHAR totalpacketlength[2];
589};
590struct rejoin_net_cmplt_cmd {
591 UCHAR reserved;
592 UCHAR bssid[ADDRLEN];
593};
594struct japan_call_sign_rxd {
595 UCHAR rxd_call_sign[8];
596 UCHAR reserved[5];
597};
598
599struct rcs {
600 UCHAR buffer_status;
601 UCHAR interrupt_id;
602 UCHAR link_field;
603 /* command specific parameters */
604 union {
605 UCHAR reserved[13];
606 struct rx_packet_cmd rx_packet;
607 struct rejoin_net_cmplt_cmd rejoin_net_complete;
608 struct japan_call_sign_rxd japan_call_sign;
609 } var;
610};
611
612/****** Startup parameter structures for both versions of firmware ***********/
613struct b4_startup_params {
614 UCHAR a_network_type; /* C_ADHOC, C_INFRA */
615 UCHAR a_acting_as_ap_status; /* C_TYPE_STA, C_TYPE_AP */
616 UCHAR a_current_ess_id[ESSID_SIZE]; /* Null terminated unless 32 long */
617 UCHAR a_scanning_mode; /* passive 0, active 1 */
618 UCHAR a_power_mgt_state; /* CAM 0, */
619 UCHAR a_mac_addr[ADDRLEN]; /* */
620 UCHAR a_frag_threshold[2]; /* 512 */
621 UCHAR a_hop_time[2]; /* 16k * 2**n, n=0-4 in Kus */
622 UCHAR a_beacon_period[2]; /* n * a_hop_time in Kus */
623 UCHAR a_dtim_period; /* in beacons */
624 UCHAR a_retry_max; /* */
625 UCHAR a_ack_timeout; /* */
626 UCHAR a_sifs; /* */
627 UCHAR a_difs; /* */
628 UCHAR a_pifs; /* */
629 UCHAR a_rts_threshold[2]; /* */
630 UCHAR a_scan_dwell_time[2]; /* */
631 UCHAR a_max_scan_dwell_time[2]; /* */
632 UCHAR a_assoc_resp_timeout_thresh; /* */
633 UCHAR a_adhoc_scan_cycle_max; /* */
634 UCHAR a_infra_scan_cycle_max; /* */
635 UCHAR a_infra_super_scan_cycle_max; /* */
636 UCHAR a_promiscuous_mode; /* */
637 UCHAR a_unique_word[2]; /* */
638 UCHAR a_slot_time; /* */
639 UCHAR a_roaming_low_snr_thresh; /* */
640 UCHAR a_low_snr_count_thresh; /* */
641 UCHAR a_infra_missed_bcn_thresh; /* */
642 UCHAR a_adhoc_missed_bcn_thresh; /* */
643 UCHAR a_curr_country_code; /* C_USA */
644 UCHAR a_hop_pattern; /* */
645 UCHAR a_hop_pattern_length; /* */
646/* b4 - b5 differences start here */
647 UCHAR a_cw_max; /* */
648 UCHAR a_cw_min; /* */
649 UCHAR a_noise_filter_gain; /* */
650 UCHAR a_noise_limit_offset; /* */
651 UCHAR a_det_rssi_thresh_offset; /* */
652 UCHAR a_med_busy_thresh_offset; /* */
653 UCHAR a_det_sync_thresh; /* */
654 UCHAR a_test_mode; /* */
655 UCHAR a_test_min_chan_num; /* */
656 UCHAR a_test_max_chan_num; /* */
657 UCHAR a_rx_tx_delay; /* */
658 UCHAR a_current_bss_id[ADDRLEN]; /* */
659 UCHAR a_hop_set; /* */
660};
661struct b5_startup_params {
662 UCHAR a_network_type; /* C_ADHOC, C_INFRA */
663 UCHAR a_acting_as_ap_status; /* C_TYPE_STA, C_TYPE_AP */
664 UCHAR a_current_ess_id[ESSID_SIZE]; /* Null terminated unless 32 long */
665 UCHAR a_scanning_mode; /* passive 0, active 1 */
666 UCHAR a_power_mgt_state; /* CAM 0, */
667 UCHAR a_mac_addr[ADDRLEN]; /* */
668 UCHAR a_frag_threshold[2]; /* 512 */
669 UCHAR a_hop_time[2]; /* 16k * 2**n, n=0-4 in Kus */
670 UCHAR a_beacon_period[2]; /* n * a_hop_time in Kus */
671 UCHAR a_dtim_period; /* in beacons */
672 UCHAR a_retry_max; /* 4 */
673 UCHAR a_ack_timeout; /* */
674 UCHAR a_sifs; /* */
675 UCHAR a_difs; /* */
676 UCHAR a_pifs; /* */
677 UCHAR a_rts_threshold[2]; /* */
678 UCHAR a_scan_dwell_time[2]; /* */
679 UCHAR a_max_scan_dwell_time[2]; /* */
680 UCHAR a_assoc_resp_timeout_thresh; /* */
681 UCHAR a_adhoc_scan_cycle_max; /* */
682 UCHAR a_infra_scan_cycle_max; /* */
683 UCHAR a_infra_super_scan_cycle_max; /* */
684 UCHAR a_promiscuous_mode; /* */
685 UCHAR a_unique_word[2]; /* */
686 UCHAR a_slot_time; /* */
687 UCHAR a_roaming_low_snr_thresh; /* */
688 UCHAR a_low_snr_count_thresh; /* */
689 UCHAR a_infra_missed_bcn_thresh; /* */
690 UCHAR a_adhoc_missed_bcn_thresh; /* */
691 UCHAR a_curr_country_code; /* C_USA */
692 UCHAR a_hop_pattern; /* */
693 UCHAR a_hop_pattern_length; /* */
694/* b4 - b5 differences start here */
695 UCHAR a_cw_max[2]; /* */
696 UCHAR a_cw_min[2]; /* */
697 UCHAR a_noise_filter_gain; /* */
698 UCHAR a_noise_limit_offset; /* */
699 UCHAR a_det_rssi_thresh_offset; /* */
700 UCHAR a_med_busy_thresh_offset; /* */
701 UCHAR a_det_sync_thresh; /* */
702 UCHAR a_test_mode; /* */
703 UCHAR a_test_min_chan_num; /* */
704 UCHAR a_test_max_chan_num; /* */
705 UCHAR a_allow_bcast_SSID_probe_rsp;
706 UCHAR a_privacy_must_start;
707 UCHAR a_privacy_can_join;
708 UCHAR a_basic_rate_set[8];
709};
710
711/*****************************************************************************/
712#define RAY_IOCG_PARMS (SIOCDEVPRIVATE)
713#define RAY_IOCS_PARMS (SIOCDEVPRIVATE + 1)
714#define RAY_DO_CMD (SIOCDEVPRIVATE + 2)
715
716/****** ethernet <-> 802.11 translation **************************************/
717typedef struct snaphdr_t
718{
719 UCHAR dsap;
720 UCHAR ssap;
721 UCHAR ctrl;
722 UCHAR org[3];
723 UCHAR ethertype[2];
724} snaphdr_t;
725
726#define BRIDGE_ENCAP 0xf80000
727#define RFC1042_ENCAP 0
728#define SNAP_ID 0x0003aaaa
729#define RAY_IPX_TYPE 0x8137
730#define APPLEARP_TYPE 0x80f3
731/*****************************************************************************/
732#endif /* #ifndef RAYLINK_H */
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
new file mode 100644
index 000000000000..ec8cf29ffced
--- /dev/null
+++ b/drivers/net/wireless/strip.c
@@ -0,0 +1,2843 @@
1/*
2 * Copyright 1996 The Board of Trustees of The Leland Stanford
3 * Junior University. All Rights Reserved.
4 *
5 * Permission to use, copy, modify, and distribute this
6 * software and its documentation for any purpose and without
7 * fee is hereby granted, provided that the above copyright
8 * notice appear in all copies. Stanford University
9 * makes no representations about the suitability of this
10 * software for any purpose. It is provided "as is" without
11 * express or implied warranty.
12 *
13 * strip.c This module implements Starmode Radio IP (STRIP)
14 * for kernel-based devices like TTY. It interfaces between a
15 * raw TTY, and the kernel's INET protocol layers (via DDI).
16 *
17 * Version: @(#)strip.c 1.3 July 1997
18 *
19 * Author: Stuart Cheshire <cheshire@cs.stanford.edu>
20 *
21 * Fixes: v0.9 12th Feb 1996 (SC)
22 * New byte stuffing (2+6 run-length encoding)
23 * New watchdog timer task
24 * New Protocol key (SIP0)
25 *
26 * v0.9.1 3rd March 1996 (SC)
27 * Changed to dynamic device allocation -- no more compile
28 * time (or boot time) limit on the number of STRIP devices.
29 *
30 * v0.9.2 13th March 1996 (SC)
31 * Uses arp cache lookups (but doesn't send arp packets yet)
32 *
33 * v0.9.3 17th April 1996 (SC)
34 * Fixed bug where STR_ERROR flag was getting set unneccessarily
35 * (causing otherwise good packets to be unneccessarily dropped)
36 *
37 * v0.9.4 27th April 1996 (SC)
38 * First attempt at using "&COMMAND" Starmode AT commands
39 *
40 * v0.9.5 29th May 1996 (SC)
41 * First attempt at sending (unicast) ARP packets
42 *
43 * v0.9.6 5th June 1996 (Elliot)
44 * Put "message level" tags in every "printk" statement
45 *
46 * v0.9.7 13th June 1996 (laik)
47 * Added support for the /proc fs
48 *
49 * v0.9.8 July 1996 (Mema)
50 * Added packet logging
51 *
52 * v1.0 November 1996 (SC)
53 * Fixed (severe) memory leaks in the /proc fs code
54 * Fixed race conditions in the logging code
55 *
56 * v1.1 January 1997 (SC)
57 * Deleted packet logging (use tcpdump instead)
58 * Added support for Metricom Firmware v204 features
59 * (like message checksums)
60 *
61 * v1.2 January 1997 (SC)
62 * Put portables list back in
63 *
64 * v1.3 July 1997 (SC)
65 * Made STRIP driver set the radio's baud rate automatically.
66 * It is no longer necessarily to manually set the radio's
67 * rate permanently to 115200 -- the driver handles setting
68 * the rate automatically.
69 */
70
71#ifdef MODULE
72static const char StripVersion[] = "1.3A-STUART.CHESHIRE-MODULAR";
73#else
74static const char StripVersion[] = "1.3A-STUART.CHESHIRE";
75#endif
76
77#define TICKLE_TIMERS 0
78#define EXT_COUNTERS 1
79
80
81/************************************************************************/
82/* Header files */
83
84#include <linux/config.h>
85#include <linux/kernel.h>
86#include <linux/module.h>
87#include <linux/init.h>
88#include <linux/bitops.h>
89#include <asm/system.h>
90#include <asm/uaccess.h>
91
92# include <linux/ctype.h>
93#include <linux/string.h>
94#include <linux/mm.h>
95#include <linux/interrupt.h>
96#include <linux/in.h>
97#include <linux/tty.h>
98#include <linux/errno.h>
99#include <linux/netdevice.h>
100#include <linux/inetdevice.h>
101#include <linux/etherdevice.h>
102#include <linux/skbuff.h>
103#include <linux/if_arp.h>
104#include <linux/if_strip.h>
105#include <linux/proc_fs.h>
106#include <linux/seq_file.h>
107#include <linux/serial.h>
108#include <linux/serialP.h>
109#include <linux/rcupdate.h>
110#include <net/arp.h>
111
112#include <linux/ip.h>
113#include <linux/tcp.h>
114#include <linux/time.h>
115
116
117/************************************************************************/
118/* Useful structures and definitions */
119
120/*
121 * A MetricomKey identifies the protocol being carried inside a Metricom
122 * Starmode packet.
123 */
124
125typedef union {
126 __u8 c[4];
127 __u32 l;
128} MetricomKey;
129
130/*
131 * An IP address can be viewed as four bytes in memory (which is what it is) or as
132 * a single 32-bit long (which is convenient for assignment, equality testing etc.)
133 */
134
135typedef union {
136 __u8 b[4];
137 __u32 l;
138} IPaddr;
139
140/*
141 * A MetricomAddressString is used to hold a printable representation of
142 * a Metricom address.
143 */
144
145typedef struct {
146 __u8 c[24];
147} MetricomAddressString;
148
149/* Encapsulation can expand packet of size x to 65/64x + 1
150 * Sent packet looks like "<CR>*<address>*<key><encaps payload><CR>"
151 * 1 1 1-18 1 4 ? 1
152 * eg. <CR>*0000-1234*SIP0<encaps payload><CR>
153 * We allow 31 bytes for the stars, the key, the address and the <CR>s
154 */
155#define STRIP_ENCAP_SIZE(X) (32 + (X)*65L/64L)
156
157/*
158 * A STRIP_Header is never really sent over the radio, but making a dummy
159 * header for internal use within the kernel that looks like an Ethernet
160 * header makes certain other software happier. For example, tcpdump
161 * already understands Ethernet headers.
162 */
163
164typedef struct {
165 MetricomAddress dst_addr; /* Destination address, e.g. "0000-1234" */
166 MetricomAddress src_addr; /* Source address, e.g. "0000-5678" */
167 unsigned short protocol; /* The protocol type, using Ethernet codes */
168} STRIP_Header;
169
170typedef struct {
171 char c[60];
172} MetricomNode;
173
174#define NODE_TABLE_SIZE 32
175typedef struct {
176 struct timeval timestamp;
177 int num_nodes;
178 MetricomNode node[NODE_TABLE_SIZE];
179} MetricomNodeTable;
180
181enum { FALSE = 0, TRUE = 1 };
182
183/*
184 * Holds the radio's firmware version.
185 */
186typedef struct {
187 char c[50];
188} FirmwareVersion;
189
190/*
191 * Holds the radio's serial number.
192 */
193typedef struct {
194 char c[18];
195} SerialNumber;
196
197/*
198 * Holds the radio's battery voltage.
199 */
200typedef struct {
201 char c[11];
202} BatteryVoltage;
203
204typedef struct {
205 char c[8];
206} char8;
207
208enum {
209 NoStructure = 0, /* Really old firmware */
210 StructuredMessages = 1, /* Parsable AT response msgs */
211 ChecksummedMessages = 2 /* Parsable AT response msgs with checksums */
212} FirmwareLevel;
213
214struct strip {
215 int magic;
216 /*
217 * These are pointers to the malloc()ed frame buffers.
218 */
219
220 unsigned char *rx_buff; /* buffer for received IP packet */
221 unsigned char *sx_buff; /* buffer for received serial data */
222 int sx_count; /* received serial data counter */
223 int sx_size; /* Serial buffer size */
224 unsigned char *tx_buff; /* transmitter buffer */
225 unsigned char *tx_head; /* pointer to next byte to XMIT */
226 int tx_left; /* bytes left in XMIT queue */
227 int tx_size; /* Serial buffer size */
228
229 /*
230 * STRIP interface statistics.
231 */
232
233 unsigned long rx_packets; /* inbound frames counter */
234 unsigned long tx_packets; /* outbound frames counter */
235 unsigned long rx_errors; /* Parity, etc. errors */
236 unsigned long tx_errors; /* Planned stuff */
237 unsigned long rx_dropped; /* No memory for skb */
238 unsigned long tx_dropped; /* When MTU change */
239 unsigned long rx_over_errors; /* Frame bigger then STRIP buf. */
240
241 unsigned long pps_timer; /* Timer to determine pps */
242 unsigned long rx_pps_count; /* Counter to determine pps */
243 unsigned long tx_pps_count; /* Counter to determine pps */
244 unsigned long sx_pps_count; /* Counter to determine pps */
245 unsigned long rx_average_pps; /* rx packets per second * 8 */
246 unsigned long tx_average_pps; /* tx packets per second * 8 */
247 unsigned long sx_average_pps; /* sent packets per second * 8 */
248
249#ifdef EXT_COUNTERS
250 unsigned long rx_bytes; /* total received bytes */
251 unsigned long tx_bytes; /* total received bytes */
252 unsigned long rx_rbytes; /* bytes thru radio i/f */
253 unsigned long tx_rbytes; /* bytes thru radio i/f */
254 unsigned long rx_sbytes; /* tot bytes thru serial i/f */
255 unsigned long tx_sbytes; /* tot bytes thru serial i/f */
256 unsigned long rx_ebytes; /* tot stat/err bytes */
257 unsigned long tx_ebytes; /* tot stat/err bytes */
258#endif
259
260 /*
261 * Internal variables.
262 */
263
264 struct list_head list; /* Linked list of devices */
265
266 int discard; /* Set if serial error */
267 int working; /* Is radio working correctly? */
268 int firmware_level; /* Message structuring level */
269 int next_command; /* Next periodic command */
270 unsigned int user_baud; /* The user-selected baud rate */
271 int mtu; /* Our mtu (to spot changes!) */
272 long watchdog_doprobe; /* Next time to test the radio */
273 long watchdog_doreset; /* Time to do next reset */
274 long gratuitous_arp; /* Time to send next ARP refresh */
275 long arp_interval; /* Next ARP interval */
276 struct timer_list idle_timer; /* For periodic wakeup calls */
277 MetricomAddress true_dev_addr; /* True address of radio */
278 int manual_dev_addr; /* Hack: See note below */
279
280 FirmwareVersion firmware_version; /* The radio's firmware version */
281 SerialNumber serial_number; /* The radio's serial number */
282 BatteryVoltage battery_voltage; /* The radio's battery voltage */
283
284 /*
285 * Other useful structures.
286 */
287
288 struct tty_struct *tty; /* ptr to TTY structure */
289 struct net_device *dev; /* Our device structure */
290
291 /*
292 * Neighbour radio records
293 */
294
295 MetricomNodeTable portables;
296 MetricomNodeTable poletops;
297};
298
299/*
300 * Note: manual_dev_addr hack
301 *
302 * It is not possible to change the hardware address of a Metricom radio,
303 * or to send packets with a user-specified hardware source address, thus
304 * trying to manually set a hardware source address is a questionable
305 * thing to do. However, if the user *does* manually set the hardware
306 * source address of a STRIP interface, then the kernel will believe it,
307 * and use it in certain places. For example, the hardware address listed
308 * by ifconfig will be the manual address, not the true one.
309 * (Both addresses are listed in /proc/net/strip.)
310 * Also, ARP packets will be sent out giving the user-specified address as
311 * the source address, not the real address. This is dangerous, because
312 * it means you won't receive any replies -- the ARP replies will go to
313 * the specified address, which will be some other radio. The case where
314 * this is useful is when that other radio is also connected to the same
315 * machine. This allows you to connect a pair of radios to one machine,
316 * and to use one exclusively for inbound traffic, and the other
317 * exclusively for outbound traffic. Pretty neat, huh?
318 *
319 * Here's the full procedure to set this up:
320 *
321 * 1. "slattach" two interfaces, e.g. st0 for outgoing packets,
322 * and st1 for incoming packets
323 *
324 * 2. "ifconfig" st0 (outbound radio) to have the hardware address
325 * which is the real hardware address of st1 (inbound radio).
326 * Now when it sends out packets, it will masquerade as st1, and
327 * replies will be sent to that radio, which is exactly what we want.
328 *
329 * 3. Set the route table entry ("route add default ..." or
330 * "route add -net ...", as appropriate) to send packets via the st0
331 * interface (outbound radio). Do not add any route which sends packets
332 * out via the st1 interface -- that radio is for inbound traffic only.
333 *
334 * 4. "ifconfig" st1 (inbound radio) to have hardware address zero.
335 * This tells the STRIP driver to "shut down" that interface and not
336 * send any packets through it. In particular, it stops sending the
337 * periodic gratuitous ARP packets that a STRIP interface normally sends.
338 * Also, when packets arrive on that interface, it will search the
339 * interface list to see if there is another interface who's manual
340 * hardware address matches its own real address (i.e. st0 in this
341 * example) and if so it will transfer ownership of the skbuff to
342 * that interface, so that it looks to the kernel as if the packet
343 * arrived on that interface. This is necessary because when the
344 * kernel sends an ARP packet on st0, it expects to get a reply on
345 * st0, and if it sees the reply come from st1 then it will ignore
346 * it (to be accurate, it puts the entry in the ARP table, but
347 * labelled in such a way that st0 can't use it).
348 *
349 * Thanks to Petros Maniatis for coming up with the idea of splitting
350 * inbound and outbound traffic between two interfaces, which turned
351 * out to be really easy to implement, even if it is a bit of a hack.
352 *
353 * Having set a manual address on an interface, you can restore it
354 * to automatic operation (where the address is automatically kept
355 * consistent with the real address of the radio) by setting a manual
356 * address of all ones, e.g. "ifconfig st0 hw strip FFFFFFFFFFFF"
357 * This 'turns off' manual override mode for the device address.
358 *
359 * Note: The IEEE 802 headers reported in tcpdump will show the *real*
360 * radio addresses the packets were sent and received from, so that you
361 * can see what is really going on with packets, and which interfaces
362 * they are really going through.
363 */
364
365
366/************************************************************************/
367/* Constants */
368
369/*
370 * CommandString1 works on all radios
371 * Other CommandStrings are only used with firmware that provides structured responses.
372 *
373 * ats319=1 Enables Info message for node additions and deletions
374 * ats319=2 Enables Info message for a new best node
375 * ats319=4 Enables checksums
376 * ats319=8 Enables ACK messages
377 */
378
379static const int MaxCommandStringLength = 32;
380static const int CompatibilityCommand = 1;
381
382static const char CommandString0[] = "*&COMMAND*ATS319=7"; /* Turn on checksums & info messages */
383static const char CommandString1[] = "*&COMMAND*ATS305?"; /* Query radio name */
384static const char CommandString2[] = "*&COMMAND*ATS325?"; /* Query battery voltage */
385static const char CommandString3[] = "*&COMMAND*ATS300?"; /* Query version information */
386static const char CommandString4[] = "*&COMMAND*ATS311?"; /* Query poletop list */
387static const char CommandString5[] = "*&COMMAND*AT~LA"; /* Query portables list */
388typedef struct {
389 const char *string;
390 long length;
391} StringDescriptor;
392
393static const StringDescriptor CommandString[] = {
394 {CommandString0, sizeof(CommandString0) - 1},
395 {CommandString1, sizeof(CommandString1) - 1},
396 {CommandString2, sizeof(CommandString2) - 1},
397 {CommandString3, sizeof(CommandString3) - 1},
398 {CommandString4, sizeof(CommandString4) - 1},
399 {CommandString5, sizeof(CommandString5) - 1}
400};
401
402#define GOT_ALL_RADIO_INFO(S) \
403 ((S)->firmware_version.c[0] && \
404 (S)->battery_voltage.c[0] && \
405 memcmp(&(S)->true_dev_addr, zero_address.c, sizeof(zero_address)))
406
407static const char hextable[16] = "0123456789ABCDEF";
408
409static const MetricomAddress zero_address;
410static const MetricomAddress broadcast_address =
411 { {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} };
412
413static const MetricomKey SIP0Key = { "SIP0" };
414static const MetricomKey ARP0Key = { "ARP0" };
415static const MetricomKey ATR_Key = { "ATR " };
416static const MetricomKey ACK_Key = { "ACK_" };
417static const MetricomKey INF_Key = { "INF_" };
418static const MetricomKey ERR_Key = { "ERR_" };
419
420static const long MaxARPInterval = 60 * HZ; /* One minute */
421
422/*
423 * Maximum Starmode packet length is 1183 bytes. Allowing 4 bytes for
424 * protocol key, 4 bytes for checksum, one byte for CR, and 65/64 expansion
425 * for STRIP encoding, that translates to a maximum payload MTU of 1155.
426 * Note: A standard NFS 1K data packet is a total of 0x480 (1152) bytes
427 * long, including IP header, UDP header, and NFS header. Setting the STRIP
428 * MTU to 1152 allows us to send default sized NFS packets without fragmentation.
429 */
430static const unsigned short MAX_SEND_MTU = 1152;
431static const unsigned short MAX_RECV_MTU = 1500; /* Hoping for Ethernet sized packets in the future! */
432static const unsigned short DEFAULT_STRIP_MTU = 1152;
433static const int STRIP_MAGIC = 0x5303;
434static const long LongTime = 0x7FFFFFFF;
435
436/************************************************************************/
437/* Global variables */
438
439static LIST_HEAD(strip_list);
440static DEFINE_SPINLOCK(strip_lock);
441
442/************************************************************************/
443/* Macros */
444
445/* Returns TRUE if text T begins with prefix P */
446#define has_prefix(T,L,P) (((L) >= sizeof(P)-1) && !strncmp((T), (P), sizeof(P)-1))
447
448/* Returns TRUE if text T of length L is equal to string S */
449#define text_equal(T,L,S) (((L) == sizeof(S)-1) && !strncmp((T), (S), sizeof(S)-1))
450
451#define READHEX(X) ((X)>='0' && (X)<='9' ? (X)-'0' : \
452 (X)>='a' && (X)<='f' ? (X)-'a'+10 : \
453 (X)>='A' && (X)<='F' ? (X)-'A'+10 : 0 )
454
455#define READHEX16(X) ((__u16)(READHEX(X)))
456
457#define READDEC(X) ((X)>='0' && (X)<='9' ? (X)-'0' : 0)
458
459#define ARRAY_END(X) (&((X)[ARRAY_SIZE(X)]))
460
461#define JIFFIE_TO_SEC(X) ((X) / HZ)
462
463
464/************************************************************************/
465/* Utility routines */
466
467static int arp_query(unsigned char *haddr, u32 paddr,
468 struct net_device *dev)
469{
470 struct neighbour *neighbor_entry;
471
472 neighbor_entry = neigh_lookup(&arp_tbl, &paddr, dev);
473
474 if (neighbor_entry != NULL) {
475 neighbor_entry->used = jiffies;
476 if (neighbor_entry->nud_state & NUD_VALID) {
477 memcpy(haddr, neighbor_entry->ha, dev->addr_len);
478 return 1;
479 }
480 }
481 return 0;
482}
483
484static void DumpData(char *msg, struct strip *strip_info, __u8 * ptr,
485 __u8 * end)
486{
487 static const int MAX_DumpData = 80;
488 __u8 pkt_text[MAX_DumpData], *p = pkt_text;
489
490 *p++ = '\"';
491
492 while (ptr < end && p < &pkt_text[MAX_DumpData - 4]) {
493 if (*ptr == '\\') {
494 *p++ = '\\';
495 *p++ = '\\';
496 } else {
497 if (*ptr >= 32 && *ptr <= 126) {
498 *p++ = *ptr;
499 } else {
500 sprintf(p, "\\%02X", *ptr);
501 p += 3;
502 }
503 }
504 ptr++;
505 }
506
507 if (ptr == end)
508 *p++ = '\"';
509 *p++ = 0;
510
511 printk(KERN_INFO "%s: %-13s%s\n", strip_info->dev->name, msg, pkt_text);
512}
513
514
515/************************************************************************/
516/* Byte stuffing/unstuffing routines */
517
518/* Stuffing scheme:
519 * 00 Unused (reserved character)
520 * 01-3F Run of 2-64 different characters
521 * 40-7F Run of 1-64 different characters plus a single zero at the end
522 * 80-BF Run of 1-64 of the same character
523 * C0-FF Run of 1-64 zeroes (ASCII 0)
524 */
525
526typedef enum {
527 Stuff_Diff = 0x00,
528 Stuff_DiffZero = 0x40,
529 Stuff_Same = 0x80,
530 Stuff_Zero = 0xC0,
531 Stuff_NoCode = 0xFF, /* Special code, meaning no code selected */
532
533 Stuff_CodeMask = 0xC0,
534 Stuff_CountMask = 0x3F,
535 Stuff_MaxCount = 0x3F,
536 Stuff_Magic = 0x0D /* The value we are eliminating */
537} StuffingCode;
538
539/* StuffData encodes the data starting at "src" for "length" bytes.
540 * It writes it to the buffer pointed to by "dst" (which must be at least
541 * as long as 1 + 65/64 of the input length). The output may be up to 1.6%
542 * larger than the input for pathological input, but will usually be smaller.
543 * StuffData returns the new value of the dst pointer as its result.
544 * "code_ptr_ptr" points to a "__u8 *" which is used to hold encoding state
545 * between calls, allowing an encoded packet to be incrementally built up
546 * from small parts. On the first call, the "__u8 *" pointed to should be
547 * initialized to NULL; between subsequent calls the calling routine should
548 * leave the value alone and simply pass it back unchanged so that the
549 * encoder can recover its current state.
550 */
551
552#define StuffData_FinishBlock(X) \
553(*code_ptr = (X) ^ Stuff_Magic, code = Stuff_NoCode)
554
555static __u8 *StuffData(__u8 * src, __u32 length, __u8 * dst,
556 __u8 ** code_ptr_ptr)
557{
558 __u8 *end = src + length;
559 __u8 *code_ptr = *code_ptr_ptr;
560 __u8 code = Stuff_NoCode, count = 0;
561
562 if (!length)
563 return (dst);
564
565 if (code_ptr) {
566 /*
567 * Recover state from last call, if applicable
568 */
569 code = (*code_ptr ^ Stuff_Magic) & Stuff_CodeMask;
570 count = (*code_ptr ^ Stuff_Magic) & Stuff_CountMask;
571 }
572
573 while (src < end) {
574 switch (code) {
575 /* Stuff_NoCode: If no current code, select one */
576 case Stuff_NoCode:
577 /* Record where we're going to put this code */
578 code_ptr = dst++;
579 count = 0; /* Reset the count (zero means one instance) */
580 /* Tentatively start a new block */
581 if (*src == 0) {
582 code = Stuff_Zero;
583 src++;
584 } else {
585 code = Stuff_Same;
586 *dst++ = *src++ ^ Stuff_Magic;
587 }
588 /* Note: We optimistically assume run of same -- */
589 /* which will be fixed later in Stuff_Same */
590 /* if it turns out not to be true. */
591 break;
592
593 /* Stuff_Zero: We already have at least one zero encoded */
594 case Stuff_Zero:
595 /* If another zero, count it, else finish this code block */
596 if (*src == 0) {
597 count++;
598 src++;
599 } else {
600 StuffData_FinishBlock(Stuff_Zero + count);
601 }
602 break;
603
604 /* Stuff_Same: We already have at least one byte encoded */
605 case Stuff_Same:
606 /* If another one the same, count it */
607 if ((*src ^ Stuff_Magic) == code_ptr[1]) {
608 count++;
609 src++;
610 break;
611 }
612 /* else, this byte does not match this block. */
613 /* If we already have two or more bytes encoded, finish this code block */
614 if (count) {
615 StuffData_FinishBlock(Stuff_Same + count);
616 break;
617 }
618 /* else, we only have one so far, so switch to Stuff_Diff code */
619 code = Stuff_Diff;
620 /* and fall through to Stuff_Diff case below
621 * Note cunning cleverness here: case Stuff_Diff compares
622 * the current character with the previous two to see if it
623 * has a run of three the same. Won't this be an error if
624 * there aren't two previous characters stored to compare with?
625 * No. Because we know the current character is *not* the same
626 * as the previous one, the first test below will necessarily
627 * fail and the send half of the "if" won't be executed.
628 */
629
630 /* Stuff_Diff: We have at least two *different* bytes encoded */
631 case Stuff_Diff:
632 /* If this is a zero, must encode a Stuff_DiffZero, and begin a new block */
633 if (*src == 0) {
634 StuffData_FinishBlock(Stuff_DiffZero +
635 count);
636 }
637 /* else, if we have three in a row, it is worth starting a Stuff_Same block */
638 else if ((*src ^ Stuff_Magic) == dst[-1]
639 && dst[-1] == dst[-2]) {
640 /* Back off the last two characters we encoded */
641 code += count - 2;
642 /* Note: "Stuff_Diff + 0" is an illegal code */
643 if (code == Stuff_Diff + 0) {
644 code = Stuff_Same + 0;
645 }
646 StuffData_FinishBlock(code);
647 code_ptr = dst - 2;
648 /* dst[-1] already holds the correct value */
649 count = 2; /* 2 means three bytes encoded */
650 code = Stuff_Same;
651 }
652 /* else, another different byte, so add it to the block */
653 else {
654 *dst++ = *src ^ Stuff_Magic;
655 count++;
656 }
657 src++; /* Consume the byte */
658 break;
659 }
660 if (count == Stuff_MaxCount) {
661 StuffData_FinishBlock(code + count);
662 }
663 }
664 if (code == Stuff_NoCode) {
665 *code_ptr_ptr = NULL;
666 } else {
667 *code_ptr_ptr = code_ptr;
668 StuffData_FinishBlock(code + count);
669 }
670 return (dst);
671}
672
673/*
674 * UnStuffData decodes the data at "src", up to (but not including) "end".
675 * It writes the decoded data into the buffer pointed to by "dst", up to a
676 * maximum of "dst_length", and returns the new value of "src" so that a
677 * follow-on call can read more data, continuing from where the first left off.
678 *
679 * There are three types of results:
680 * 1. The source data runs out before extracting "dst_length" bytes:
681 * UnStuffData returns NULL to indicate failure.
682 * 2. The source data produces exactly "dst_length" bytes:
683 * UnStuffData returns new_src = end to indicate that all bytes were consumed.
684 * 3. "dst_length" bytes are extracted, with more remaining.
685 * UnStuffData returns new_src < end to indicate that there are more bytes
686 * to be read.
687 *
688 * Note: The decoding may be destructive, in that it may alter the source
689 * data in the process of decoding it (this is necessary to allow a follow-on
690 * call to resume correctly).
691 */
692
693static __u8 *UnStuffData(__u8 * src, __u8 * end, __u8 * dst,
694 __u32 dst_length)
695{
696 __u8 *dst_end = dst + dst_length;
697 /* Sanity check */
698 if (!src || !end || !dst || !dst_length)
699 return (NULL);
700 while (src < end && dst < dst_end) {
701 int count = (*src ^ Stuff_Magic) & Stuff_CountMask;
702 switch ((*src ^ Stuff_Magic) & Stuff_CodeMask) {
703 case Stuff_Diff:
704 if (src + 1 + count >= end)
705 return (NULL);
706 do {
707 *dst++ = *++src ^ Stuff_Magic;
708 }
709 while (--count >= 0 && dst < dst_end);
710 if (count < 0)
711 src += 1;
712 else {
713 if (count == 0)
714 *src = Stuff_Same ^ Stuff_Magic;
715 else
716 *src =
717 (Stuff_Diff +
718 count) ^ Stuff_Magic;
719 }
720 break;
721 case Stuff_DiffZero:
722 if (src + 1 + count >= end)
723 return (NULL);
724 do {
725 *dst++ = *++src ^ Stuff_Magic;
726 }
727 while (--count >= 0 && dst < dst_end);
728 if (count < 0)
729 *src = Stuff_Zero ^ Stuff_Magic;
730 else
731 *src =
732 (Stuff_DiffZero + count) ^ Stuff_Magic;
733 break;
734 case Stuff_Same:
735 if (src + 1 >= end)
736 return (NULL);
737 do {
738 *dst++ = src[1] ^ Stuff_Magic;
739 }
740 while (--count >= 0 && dst < dst_end);
741 if (count < 0)
742 src += 2;
743 else
744 *src = (Stuff_Same + count) ^ Stuff_Magic;
745 break;
746 case Stuff_Zero:
747 do {
748 *dst++ = 0;
749 }
750 while (--count >= 0 && dst < dst_end);
751 if (count < 0)
752 src += 1;
753 else
754 *src = (Stuff_Zero + count) ^ Stuff_Magic;
755 break;
756 }
757 }
758 if (dst < dst_end)
759 return (NULL);
760 else
761 return (src);
762}
763
764
765/************************************************************************/
766/* General routines for STRIP */
767
768/*
769 * get_baud returns the current baud rate, as one of the constants defined in
770 * termbits.h
771 * If the user has issued a baud rate override using the 'setserial' command
772 * and the logical current rate is set to 38.4, then the true baud rate
773 * currently in effect (57.6 or 115.2) is returned.
774 */
775static unsigned int get_baud(struct tty_struct *tty)
776{
777 if (!tty || !tty->termios)
778 return (0);
779 if ((tty->termios->c_cflag & CBAUD) == B38400 && tty->driver_data) {
780 struct async_struct *info =
781 (struct async_struct *) tty->driver_data;
782 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
783 return (B57600);
784 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
785 return (B115200);
786 }
787 return (tty->termios->c_cflag & CBAUD);
788}
789
790/*
791 * set_baud sets the baud rate to the rate defined by baudcode
792 * Note: The rate B38400 should be avoided, because the user may have
793 * issued a 'setserial' speed override to map that to a different speed.
794 * We could achieve a true rate of 38400 if we needed to by cancelling
795 * any user speed override that is in place, but that might annoy the
796 * user, so it is simplest to just avoid using 38400.
797 */
798static void set_baud(struct tty_struct *tty, unsigned int baudcode)
799{
800 struct termios old_termios = *(tty->termios);
801 tty->termios->c_cflag &= ~CBAUD; /* Clear the old baud setting */
802 tty->termios->c_cflag |= baudcode; /* Set the new baud setting */
803 tty->driver->set_termios(tty, &old_termios);
804}
805
806/*
807 * Convert a string to a Metricom Address.
808 */
809
810#define IS_RADIO_ADDRESS(p) ( \
811 isdigit((p)[0]) && isdigit((p)[1]) && isdigit((p)[2]) && isdigit((p)[3]) && \
812 (p)[4] == '-' && \
813 isdigit((p)[5]) && isdigit((p)[6]) && isdigit((p)[7]) && isdigit((p)[8]) )
814
815static int string_to_radio_address(MetricomAddress * addr, __u8 * p)
816{
817 if (!IS_RADIO_ADDRESS(p))
818 return (1);
819 addr->c[0] = 0;
820 addr->c[1] = 0;
821 addr->c[2] = READHEX(p[0]) << 4 | READHEX(p[1]);
822 addr->c[3] = READHEX(p[2]) << 4 | READHEX(p[3]);
823 addr->c[4] = READHEX(p[5]) << 4 | READHEX(p[6]);
824 addr->c[5] = READHEX(p[7]) << 4 | READHEX(p[8]);
825 return (0);
826}
827
828/*
829 * Convert a Metricom Address to a string.
830 */
831
832static __u8 *radio_address_to_string(const MetricomAddress * addr,
833 MetricomAddressString * p)
834{
835 sprintf(p->c, "%02X%02X-%02X%02X", addr->c[2], addr->c[3],
836 addr->c[4], addr->c[5]);
837 return (p->c);
838}
839
840/*
841 * Note: Must make sure sx_size is big enough to receive a stuffed
842 * MAX_RECV_MTU packet. Additionally, we also want to ensure that it's
843 * big enough to receive a large radio neighbour list (currently 4K).
844 */
845
846static int allocate_buffers(struct strip *strip_info, int mtu)
847{
848 struct net_device *dev = strip_info->dev;
849 int sx_size = max_t(int, STRIP_ENCAP_SIZE(MAX_RECV_MTU), 4096);
850 int tx_size = STRIP_ENCAP_SIZE(mtu) + MaxCommandStringLength;
851 __u8 *r = kmalloc(MAX_RECV_MTU, GFP_ATOMIC);
852 __u8 *s = kmalloc(sx_size, GFP_ATOMIC);
853 __u8 *t = kmalloc(tx_size, GFP_ATOMIC);
854 if (r && s && t) {
855 strip_info->rx_buff = r;
856 strip_info->sx_buff = s;
857 strip_info->tx_buff = t;
858 strip_info->sx_size = sx_size;
859 strip_info->tx_size = tx_size;
860 strip_info->mtu = dev->mtu = mtu;
861 return (1);
862 }
863 if (r)
864 kfree(r);
865 if (s)
866 kfree(s);
867 if (t)
868 kfree(t);
869 return (0);
870}
871
872/*
873 * MTU has been changed by the IP layer.
874 * We could be in
875 * an upcall from the tty driver, or in an ip packet queue.
876 */
877static int strip_change_mtu(struct net_device *dev, int new_mtu)
878{
879 struct strip *strip_info = netdev_priv(dev);
880 int old_mtu = strip_info->mtu;
881 unsigned char *orbuff = strip_info->rx_buff;
882 unsigned char *osbuff = strip_info->sx_buff;
883 unsigned char *otbuff = strip_info->tx_buff;
884
885 if (new_mtu > MAX_SEND_MTU) {
886 printk(KERN_ERR
887 "%s: MTU exceeds maximum allowable (%d), MTU change cancelled.\n",
888 strip_info->dev->name, MAX_SEND_MTU);
889 return -EINVAL;
890 }
891
892 spin_lock_bh(&strip_lock);
893 if (!allocate_buffers(strip_info, new_mtu)) {
894 printk(KERN_ERR "%s: unable to grow strip buffers, MTU change cancelled.\n",
895 strip_info->dev->name);
896 spin_unlock_bh(&strip_lock);
897 return -ENOMEM;
898 }
899
900 if (strip_info->sx_count) {
901 if (strip_info->sx_count <= strip_info->sx_size)
902 memcpy(strip_info->sx_buff, osbuff,
903 strip_info->sx_count);
904 else {
905 strip_info->discard = strip_info->sx_count;
906 strip_info->rx_over_errors++;
907 }
908 }
909
910 if (strip_info->tx_left) {
911 if (strip_info->tx_left <= strip_info->tx_size)
912 memcpy(strip_info->tx_buff, strip_info->tx_head,
913 strip_info->tx_left);
914 else {
915 strip_info->tx_left = 0;
916 strip_info->tx_dropped++;
917 }
918 }
919 strip_info->tx_head = strip_info->tx_buff;
920 spin_unlock_bh(&strip_lock);
921
922 printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n",
923 strip_info->dev->name, old_mtu, strip_info->mtu);
924
925 if (orbuff)
926 kfree(orbuff);
927 if (osbuff)
928 kfree(osbuff);
929 if (otbuff)
930 kfree(otbuff);
931
932 return 0;
933}
934
935static void strip_unlock(struct strip *strip_info)
936{
937 /*
938 * Set the timer to go off in one second.
939 */
940 strip_info->idle_timer.expires = jiffies + 1 * HZ;
941 add_timer(&strip_info->idle_timer);
942 netif_wake_queue(strip_info->dev);
943}
944
945
946
947/*
948 * If the time is in the near future, time_delta prints the number of
949 * seconds to go into the buffer and returns the address of the buffer.
950 * If the time is not in the near future, it returns the address of the
951 * string "Not scheduled" The buffer must be long enough to contain the
952 * ascii representation of the number plus 9 charactes for the " seconds"
953 * and the null character.
954 */
955#ifdef CONFIG_PROC_FS
956static char *time_delta(char buffer[], long time)
957{
958 time -= jiffies;
959 if (time > LongTime / 2)
960 return ("Not scheduled");
961 if (time < 0)
962 time = 0; /* Don't print negative times */
963 sprintf(buffer, "%ld seconds", time / HZ);
964 return (buffer);
965}
966
967/* get Nth element of the linked list */
968static struct strip *strip_get_idx(loff_t pos)
969{
970 struct list_head *l;
971 int i = 0;
972
973 list_for_each_rcu(l, &strip_list) {
974 if (pos == i)
975 return list_entry(l, struct strip, list);
976 ++i;
977 }
978 return NULL;
979}
980
981static void *strip_seq_start(struct seq_file *seq, loff_t *pos)
982{
983 rcu_read_lock();
984 return *pos ? strip_get_idx(*pos - 1) : SEQ_START_TOKEN;
985}
986
987static void *strip_seq_next(struct seq_file *seq, void *v, loff_t *pos)
988{
989 struct list_head *l;
990 struct strip *s;
991
992 ++*pos;
993 if (v == SEQ_START_TOKEN)
994 return strip_get_idx(1);
995
996 s = v;
997 l = &s->list;
998 list_for_each_continue_rcu(l, &strip_list) {
999 return list_entry(l, struct strip, list);
1000 }
1001 return NULL;
1002}
1003
1004static void strip_seq_stop(struct seq_file *seq, void *v)
1005{
1006 rcu_read_unlock();
1007}
1008
1009static void strip_seq_neighbours(struct seq_file *seq,
1010 const MetricomNodeTable * table,
1011 const char *title)
1012{
1013 /* We wrap this in a do/while loop, so if the table changes */
1014 /* while we're reading it, we just go around and try again. */
1015 struct timeval t;
1016
1017 do {
1018 int i;
1019 t = table->timestamp;
1020 if (table->num_nodes)
1021 seq_printf(seq, "\n %s\n", title);
1022 for (i = 0; i < table->num_nodes; i++) {
1023 MetricomNode node;
1024
1025 spin_lock_bh(&strip_lock);
1026 node = table->node[i];
1027 spin_unlock_bh(&strip_lock);
1028 seq_printf(seq, " %s\n", node.c);
1029 }
1030 } while (table->timestamp.tv_sec != t.tv_sec
1031 || table->timestamp.tv_usec != t.tv_usec);
1032}
1033
1034/*
1035 * This function prints radio status information via the seq_file
1036 * interface. The interface takes care of buffer size and over
1037 * run issues.
1038 *
1039 * The buffer in seq_file is PAGESIZE (4K)
1040 * so this routine should never print more or it will get truncated.
1041 * With the maximum of 32 portables and 32 poletops
1042 * reported, the routine outputs 3107 bytes into the buffer.
1043 */
1044static void strip_seq_status_info(struct seq_file *seq,
1045 const struct strip *strip_info)
1046{
1047 char temp[32];
1048 MetricomAddressString addr_string;
1049
1050 /* First, we must copy all of our data to a safe place, */
1051 /* in case a serial interrupt comes in and changes it. */
1052 int tx_left = strip_info->tx_left;
1053 unsigned long rx_average_pps = strip_info->rx_average_pps;
1054 unsigned long tx_average_pps = strip_info->tx_average_pps;
1055 unsigned long sx_average_pps = strip_info->sx_average_pps;
1056 int working = strip_info->working;
1057 int firmware_level = strip_info->firmware_level;
1058 long watchdog_doprobe = strip_info->watchdog_doprobe;
1059 long watchdog_doreset = strip_info->watchdog_doreset;
1060 long gratuitous_arp = strip_info->gratuitous_arp;
1061 long arp_interval = strip_info->arp_interval;
1062 FirmwareVersion firmware_version = strip_info->firmware_version;
1063 SerialNumber serial_number = strip_info->serial_number;
1064 BatteryVoltage battery_voltage = strip_info->battery_voltage;
1065 char *if_name = strip_info->dev->name;
1066 MetricomAddress true_dev_addr = strip_info->true_dev_addr;
1067 MetricomAddress dev_dev_addr =
1068 *(MetricomAddress *) strip_info->dev->dev_addr;
1069 int manual_dev_addr = strip_info->manual_dev_addr;
1070#ifdef EXT_COUNTERS
1071 unsigned long rx_bytes = strip_info->rx_bytes;
1072 unsigned long tx_bytes = strip_info->tx_bytes;
1073 unsigned long rx_rbytes = strip_info->rx_rbytes;
1074 unsigned long tx_rbytes = strip_info->tx_rbytes;
1075 unsigned long rx_sbytes = strip_info->rx_sbytes;
1076 unsigned long tx_sbytes = strip_info->tx_sbytes;
1077 unsigned long rx_ebytes = strip_info->rx_ebytes;
1078 unsigned long tx_ebytes = strip_info->tx_ebytes;
1079#endif
1080
1081 seq_printf(seq, "\nInterface name\t\t%s\n", if_name);
1082 seq_printf(seq, " Radio working:\t\t%s\n", working ? "Yes" : "No");
1083 radio_address_to_string(&true_dev_addr, &addr_string);
1084 seq_printf(seq, " Radio address:\t\t%s\n", addr_string.c);
1085 if (manual_dev_addr) {
1086 radio_address_to_string(&dev_dev_addr, &addr_string);
1087 seq_printf(seq, " Device address:\t%s\n", addr_string.c);
1088 }
1089 seq_printf(seq, " Firmware version:\t%s", !working ? "Unknown" :
1090 !firmware_level ? "Should be upgraded" :
1091 firmware_version.c);
1092 if (firmware_level >= ChecksummedMessages)
1093 seq_printf(seq, " (Checksums Enabled)");
1094 seq_printf(seq, "\n");
1095 seq_printf(seq, " Serial number:\t\t%s\n", serial_number.c);
1096 seq_printf(seq, " Battery voltage:\t%s\n", battery_voltage.c);
1097 seq_printf(seq, " Transmit queue (bytes):%d\n", tx_left);
1098 seq_printf(seq, " Receive packet rate: %ld packets per second\n",
1099 rx_average_pps / 8);
1100 seq_printf(seq, " Transmit packet rate: %ld packets per second\n",
1101 tx_average_pps / 8);
1102 seq_printf(seq, " Sent packet rate: %ld packets per second\n",
1103 sx_average_pps / 8);
1104 seq_printf(seq, " Next watchdog probe:\t%s\n",
1105 time_delta(temp, watchdog_doprobe));
1106 seq_printf(seq, " Next watchdog reset:\t%s\n",
1107 time_delta(temp, watchdog_doreset));
1108 seq_printf(seq, " Next gratuitous ARP:\t");
1109
1110 if (!memcmp
1111 (strip_info->dev->dev_addr, zero_address.c,
1112 sizeof(zero_address)))
1113 seq_printf(seq, "Disabled\n");
1114 else {
1115 seq_printf(seq, "%s\n", time_delta(temp, gratuitous_arp));
1116 seq_printf(seq, " Next ARP interval:\t%ld seconds\n",
1117 JIFFIE_TO_SEC(arp_interval));
1118 }
1119
1120 if (working) {
1121#ifdef EXT_COUNTERS
1122 seq_printf(seq, "\n");
1123 seq_printf(seq,
1124 " Total bytes: \trx:\t%lu\ttx:\t%lu\n",
1125 rx_bytes, tx_bytes);
1126 seq_printf(seq,
1127 " thru radio: \trx:\t%lu\ttx:\t%lu\n",
1128 rx_rbytes, tx_rbytes);
1129 seq_printf(seq,
1130 " thru serial port: \trx:\t%lu\ttx:\t%lu\n",
1131 rx_sbytes, tx_sbytes);
1132 seq_printf(seq,
1133 " Total stat/err bytes:\trx:\t%lu\ttx:\t%lu\n",
1134 rx_ebytes, tx_ebytes);
1135#endif
1136 strip_seq_neighbours(seq, &strip_info->poletops,
1137 "Poletops:");
1138 strip_seq_neighbours(seq, &strip_info->portables,
1139 "Portables:");
1140 }
1141}
1142
1143/*
1144 * This function is exports status information from the STRIP driver through
1145 * the /proc file system.
1146 */
1147static int strip_seq_show(struct seq_file *seq, void *v)
1148{
1149 if (v == SEQ_START_TOKEN)
1150 seq_printf(seq, "strip_version: %s\n", StripVersion);
1151 else
1152 strip_seq_status_info(seq, (const struct strip *)v);
1153 return 0;
1154}
1155
1156
1157static struct seq_operations strip_seq_ops = {
1158 .start = strip_seq_start,
1159 .next = strip_seq_next,
1160 .stop = strip_seq_stop,
1161 .show = strip_seq_show,
1162};
1163
1164static int strip_seq_open(struct inode *inode, struct file *file)
1165{
1166 return seq_open(file, &strip_seq_ops);
1167}
1168
1169static struct file_operations strip_seq_fops = {
1170 .owner = THIS_MODULE,
1171 .open = strip_seq_open,
1172 .read = seq_read,
1173 .llseek = seq_lseek,
1174 .release = seq_release,
1175};
1176#endif
1177
1178
1179
1180/************************************************************************/
1181/* Sending routines */
1182
1183static void ResetRadio(struct strip *strip_info)
1184{
1185 struct tty_struct *tty = strip_info->tty;
1186 static const char init[] = "ate0q1dt**starmode\r**";
1187 StringDescriptor s = { init, sizeof(init) - 1 };
1188
1189 /*
1190 * If the radio isn't working anymore,
1191 * we should clear the old status information.
1192 */
1193 if (strip_info->working) {
1194 printk(KERN_INFO "%s: No response: Resetting radio.\n",
1195 strip_info->dev->name);
1196 strip_info->firmware_version.c[0] = '\0';
1197 strip_info->serial_number.c[0] = '\0';
1198 strip_info->battery_voltage.c[0] = '\0';
1199 strip_info->portables.num_nodes = 0;
1200 do_gettimeofday(&strip_info->portables.timestamp);
1201 strip_info->poletops.num_nodes = 0;
1202 do_gettimeofday(&strip_info->poletops.timestamp);
1203 }
1204
1205 strip_info->pps_timer = jiffies;
1206 strip_info->rx_pps_count = 0;
1207 strip_info->tx_pps_count = 0;
1208 strip_info->sx_pps_count = 0;
1209 strip_info->rx_average_pps = 0;
1210 strip_info->tx_average_pps = 0;
1211 strip_info->sx_average_pps = 0;
1212
1213 /* Mark radio address as unknown */
1214 *(MetricomAddress *) & strip_info->true_dev_addr = zero_address;
1215 if (!strip_info->manual_dev_addr)
1216 *(MetricomAddress *) strip_info->dev->dev_addr =
1217 zero_address;
1218 strip_info->working = FALSE;
1219 strip_info->firmware_level = NoStructure;
1220 strip_info->next_command = CompatibilityCommand;
1221 strip_info->watchdog_doprobe = jiffies + 10 * HZ;
1222 strip_info->watchdog_doreset = jiffies + 1 * HZ;
1223
1224 /* If the user has selected a baud rate above 38.4 see what magic we have to do */
1225 if (strip_info->user_baud > B38400) {
1226 /*
1227 * Subtle stuff: Pay attention :-)
1228 * If the serial port is currently at the user's selected (>38.4) rate,
1229 * then we temporarily switch to 19.2 and issue the ATS304 command
1230 * to tell the radio to switch to the user's selected rate.
1231 * If the serial port is not currently at that rate, that means we just
1232 * issued the ATS304 command last time through, so this time we restore
1233 * the user's selected rate and issue the normal starmode reset string.
1234 */
1235 if (strip_info->user_baud == get_baud(tty)) {
1236 static const char b0[] = "ate0q1s304=57600\r";
1237 static const char b1[] = "ate0q1s304=115200\r";
1238 static const StringDescriptor baudstring[2] =
1239 { {b0, sizeof(b0) - 1}
1240 , {b1, sizeof(b1) - 1}
1241 };
1242 set_baud(tty, B19200);
1243 if (strip_info->user_baud == B57600)
1244 s = baudstring[0];
1245 else if (strip_info->user_baud == B115200)
1246 s = baudstring[1];
1247 else
1248 s = baudstring[1]; /* For now */
1249 } else
1250 set_baud(tty, strip_info->user_baud);
1251 }
1252
1253 tty->driver->write(tty, s.string, s.length);
1254#ifdef EXT_COUNTERS
1255 strip_info->tx_ebytes += s.length;
1256#endif
1257}
1258
1259/*
1260 * Called by the driver when there's room for more data. If we have
1261 * more packets to send, we send them here.
1262 */
1263
1264static void strip_write_some_more(struct tty_struct *tty)
1265{
1266 struct strip *strip_info = (struct strip *) tty->disc_data;
1267
1268 /* First make sure we're connected. */
1269 if (!strip_info || strip_info->magic != STRIP_MAGIC ||
1270 !netif_running(strip_info->dev))
1271 return;
1272
1273 if (strip_info->tx_left > 0) {
1274 int num_written =
1275 tty->driver->write(tty, strip_info->tx_head,
1276 strip_info->tx_left);
1277 strip_info->tx_left -= num_written;
1278 strip_info->tx_head += num_written;
1279#ifdef EXT_COUNTERS
1280 strip_info->tx_sbytes += num_written;
1281#endif
1282 } else { /* Else start transmission of another packet */
1283
1284 tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
1285 strip_unlock(strip_info);
1286 }
1287}
1288
1289static __u8 *add_checksum(__u8 * buffer, __u8 * end)
1290{
1291 __u16 sum = 0;
1292 __u8 *p = buffer;
1293 while (p < end)
1294 sum += *p++;
1295 end[3] = hextable[sum & 0xF];
1296 sum >>= 4;
1297 end[2] = hextable[sum & 0xF];
1298 sum >>= 4;
1299 end[1] = hextable[sum & 0xF];
1300 sum >>= 4;
1301 end[0] = hextable[sum & 0xF];
1302 return (end + 4);
1303}
1304
1305static unsigned char *strip_make_packet(unsigned char *buffer,
1306 struct strip *strip_info,
1307 struct sk_buff *skb)
1308{
1309 __u8 *ptr = buffer;
1310 __u8 *stuffstate = NULL;
1311 STRIP_Header *header = (STRIP_Header *) skb->data;
1312 MetricomAddress haddr = header->dst_addr;
1313 int len = skb->len - sizeof(STRIP_Header);
1314 MetricomKey key;
1315
1316 /*HexDump("strip_make_packet", strip_info, skb->data, skb->data + skb->len); */
1317
1318 if (header->protocol == htons(ETH_P_IP))
1319 key = SIP0Key;
1320 else if (header->protocol == htons(ETH_P_ARP))
1321 key = ARP0Key;
1322 else {
1323 printk(KERN_ERR
1324 "%s: strip_make_packet: Unknown packet type 0x%04X\n",
1325 strip_info->dev->name, ntohs(header->protocol));
1326 return (NULL);
1327 }
1328
1329 if (len > strip_info->mtu) {
1330 printk(KERN_ERR
1331 "%s: Dropping oversized transmit packet: %d bytes\n",
1332 strip_info->dev->name, len);
1333 return (NULL);
1334 }
1335
1336 /*
1337 * If we're sending to ourselves, discard the packet.
1338 * (Metricom radios choke if they try to send a packet to their own address.)
1339 */
1340 if (!memcmp(haddr.c, strip_info->true_dev_addr.c, sizeof(haddr))) {
1341 printk(KERN_ERR "%s: Dropping packet addressed to self\n",
1342 strip_info->dev->name);
1343 return (NULL);
1344 }
1345
1346 /*
1347 * If this is a broadcast packet, send it to our designated Metricom
1348 * 'broadcast hub' radio (First byte of address being 0xFF means broadcast)
1349 */
1350 if (haddr.c[0] == 0xFF) {
1351 u32 brd = 0;
1352 struct in_device *in_dev;
1353
1354 rcu_read_lock();
1355 in_dev = __in_dev_get(strip_info->dev);
1356 if (in_dev == NULL) {
1357 rcu_read_unlock();
1358 return NULL;
1359 }
1360 if (in_dev->ifa_list)
1361 brd = in_dev->ifa_list->ifa_broadcast;
1362 rcu_read_unlock();
1363
1364 /* arp_query returns 1 if it succeeds in looking up the address, 0 if it fails */
1365 if (!arp_query(haddr.c, brd, strip_info->dev)) {
1366 printk(KERN_ERR
1367 "%s: Unable to send packet (no broadcast hub configured)\n",
1368 strip_info->dev->name);
1369 return (NULL);
1370 }
1371 /*
1372 * If we are the broadcast hub, don't bother sending to ourselves.
1373 * (Metricom radios choke if they try to send a packet to their own address.)
1374 */
1375 if (!memcmp
1376 (haddr.c, strip_info->true_dev_addr.c, sizeof(haddr)))
1377 return (NULL);
1378 }
1379
1380 *ptr++ = 0x0D;
1381 *ptr++ = '*';
1382 *ptr++ = hextable[haddr.c[2] >> 4];
1383 *ptr++ = hextable[haddr.c[2] & 0xF];
1384 *ptr++ = hextable[haddr.c[3] >> 4];
1385 *ptr++ = hextable[haddr.c[3] & 0xF];
1386 *ptr++ = '-';
1387 *ptr++ = hextable[haddr.c[4] >> 4];
1388 *ptr++ = hextable[haddr.c[4] & 0xF];
1389 *ptr++ = hextable[haddr.c[5] >> 4];
1390 *ptr++ = hextable[haddr.c[5] & 0xF];
1391 *ptr++ = '*';
1392 *ptr++ = key.c[0];
1393 *ptr++ = key.c[1];
1394 *ptr++ = key.c[2];
1395 *ptr++ = key.c[3];
1396
1397 ptr =
1398 StuffData(skb->data + sizeof(STRIP_Header), len, ptr,
1399 &stuffstate);
1400
1401 if (strip_info->firmware_level >= ChecksummedMessages)
1402 ptr = add_checksum(buffer + 1, ptr);
1403
1404 *ptr++ = 0x0D;
1405 return (ptr);
1406}
1407
1408static void strip_send(struct strip *strip_info, struct sk_buff *skb)
1409{
1410 MetricomAddress haddr;
1411 unsigned char *ptr = strip_info->tx_buff;
1412 int doreset = (long) jiffies - strip_info->watchdog_doreset >= 0;
1413 int doprobe = (long) jiffies - strip_info->watchdog_doprobe >= 0
1414 && !doreset;
1415 u32 addr, brd;
1416
1417 /*
1418 * 1. If we have a packet, encapsulate it and put it in the buffer
1419 */
1420 if (skb) {
1421 char *newptr = strip_make_packet(ptr, strip_info, skb);
1422 strip_info->tx_pps_count++;
1423 if (!newptr)
1424 strip_info->tx_dropped++;
1425 else {
1426 ptr = newptr;
1427 strip_info->sx_pps_count++;
1428 strip_info->tx_packets++; /* Count another successful packet */
1429#ifdef EXT_COUNTERS
1430 strip_info->tx_bytes += skb->len;
1431 strip_info->tx_rbytes += ptr - strip_info->tx_buff;
1432#endif
1433 /*DumpData("Sending:", strip_info, strip_info->tx_buff, ptr); */
1434 /*HexDump("Sending", strip_info, strip_info->tx_buff, ptr); */
1435 }
1436 }
1437
1438 /*
1439 * 2. If it is time for another tickle, tack it on, after the packet
1440 */
1441 if (doprobe) {
1442 StringDescriptor ts = CommandString[strip_info->next_command];
1443#if TICKLE_TIMERS
1444 {
1445 struct timeval tv;
1446 do_gettimeofday(&tv);
1447 printk(KERN_INFO "**** Sending tickle string %d at %02d.%06d\n",
1448 strip_info->next_command, tv.tv_sec % 100,
1449 tv.tv_usec);
1450 }
1451#endif
1452 if (ptr == strip_info->tx_buff)
1453 *ptr++ = 0x0D;
1454
1455 *ptr++ = '*'; /* First send "**" to provoke an error message */
1456 *ptr++ = '*';
1457
1458 /* Then add the command */
1459 memcpy(ptr, ts.string, ts.length);
1460
1461 /* Add a checksum ? */
1462 if (strip_info->firmware_level < ChecksummedMessages)
1463 ptr += ts.length;
1464 else
1465 ptr = add_checksum(ptr, ptr + ts.length);
1466
1467 *ptr++ = 0x0D; /* Terminate the command with a <CR> */
1468
1469 /* Cycle to next periodic command? */
1470 if (strip_info->firmware_level >= StructuredMessages)
1471 if (++strip_info->next_command >=
1472 ARRAY_SIZE(CommandString))
1473 strip_info->next_command = 0;
1474#ifdef EXT_COUNTERS
1475 strip_info->tx_ebytes += ts.length;
1476#endif
1477 strip_info->watchdog_doprobe = jiffies + 10 * HZ;
1478 strip_info->watchdog_doreset = jiffies + 1 * HZ;
1479 /*printk(KERN_INFO "%s: Routine radio test.\n", strip_info->dev->name); */
1480 }
1481
1482 /*
1483 * 3. Set up the strip_info ready to send the data (if any).
1484 */
1485 strip_info->tx_head = strip_info->tx_buff;
1486 strip_info->tx_left = ptr - strip_info->tx_buff;
1487 strip_info->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
1488
1489 /*
1490 * 4. Debugging check to make sure we're not overflowing the buffer.
1491 */
1492 if (strip_info->tx_size - strip_info->tx_left < 20)
1493 printk(KERN_ERR "%s: Sending%5d bytes;%5d bytes free.\n",
1494 strip_info->dev->name, strip_info->tx_left,
1495 strip_info->tx_size - strip_info->tx_left);
1496
1497 /*
1498 * 5. If watchdog has expired, reset the radio. Note: if there's data waiting in
1499 * the buffer, strip_write_some_more will send it after the reset has finished
1500 */
1501 if (doreset) {
1502 ResetRadio(strip_info);
1503 return;
1504 }
1505
1506 if (1) {
1507 struct in_device *in_dev;
1508
1509 brd = addr = 0;
1510 rcu_read_lock();
1511 in_dev = __in_dev_get(strip_info->dev);
1512 if (in_dev) {
1513 if (in_dev->ifa_list) {
1514 brd = in_dev->ifa_list->ifa_broadcast;
1515 addr = in_dev->ifa_list->ifa_local;
1516 }
1517 }
1518 rcu_read_unlock();
1519 }
1520
1521
1522 /*
1523 * 6. If it is time for a periodic ARP, queue one up to be sent.
1524 * We only do this if:
1525 * 1. The radio is working
1526 * 2. It's time to send another periodic ARP
1527 * 3. We really know what our address is (and it is not manually set to zero)
1528 * 4. We have a designated broadcast address configured
1529 * If we queue up an ARP packet when we don't have a designated broadcast
1530 * address configured, then the packet will just have to be discarded in
1531 * strip_make_packet. This is not fatal, but it causes misleading information
1532 * to be displayed in tcpdump. tcpdump will report that periodic APRs are
1533 * being sent, when in fact they are not, because they are all being dropped
1534 * in the strip_make_packet routine.
1535 */
1536 if (strip_info->working
1537 && (long) jiffies - strip_info->gratuitous_arp >= 0
1538 && memcmp(strip_info->dev->dev_addr, zero_address.c,
1539 sizeof(zero_address))
1540 && arp_query(haddr.c, brd, strip_info->dev)) {
1541 /*printk(KERN_INFO "%s: Sending gratuitous ARP with interval %ld\n",
1542 strip_info->dev->name, strip_info->arp_interval / HZ); */
1543 strip_info->gratuitous_arp =
1544 jiffies + strip_info->arp_interval;
1545 strip_info->arp_interval *= 2;
1546 if (strip_info->arp_interval > MaxARPInterval)
1547 strip_info->arp_interval = MaxARPInterval;
1548 if (addr)
1549 arp_send(ARPOP_REPLY, ETH_P_ARP, addr, /* Target address of ARP packet is our address */
1550 strip_info->dev, /* Device to send packet on */
1551 addr, /* Source IP address this ARP packet comes from */
1552 NULL, /* Destination HW address is NULL (broadcast it) */
1553 strip_info->dev->dev_addr, /* Source HW address is our HW address */
1554 strip_info->dev->dev_addr); /* Target HW address is our HW address (redundant) */
1555 }
1556
1557 /*
1558 * 7. All ready. Start the transmission
1559 */
1560 strip_write_some_more(strip_info->tty);
1561}
1562
1563/* Encapsulate a datagram and kick it into a TTY queue. */
1564static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
1565{
1566 struct strip *strip_info = netdev_priv(dev);
1567
1568 if (!netif_running(dev)) {
1569 printk(KERN_ERR "%s: xmit call when iface is down\n",
1570 dev->name);
1571 return (1);
1572 }
1573
1574 netif_stop_queue(dev);
1575
1576 del_timer(&strip_info->idle_timer);
1577
1578
1579 if (jiffies - strip_info->pps_timer > HZ) {
1580 unsigned long t = jiffies - strip_info->pps_timer;
1581 unsigned long rx_pps_count = (strip_info->rx_pps_count * HZ * 8 + t / 2) / t;
1582 unsigned long tx_pps_count = (strip_info->tx_pps_count * HZ * 8 + t / 2) / t;
1583 unsigned long sx_pps_count = (strip_info->sx_pps_count * HZ * 8 + t / 2) / t;
1584
1585 strip_info->pps_timer = jiffies;
1586 strip_info->rx_pps_count = 0;
1587 strip_info->tx_pps_count = 0;
1588 strip_info->sx_pps_count = 0;
1589
1590 strip_info->rx_average_pps = (strip_info->rx_average_pps + rx_pps_count + 1) / 2;
1591 strip_info->tx_average_pps = (strip_info->tx_average_pps + tx_pps_count + 1) / 2;
1592 strip_info->sx_average_pps = (strip_info->sx_average_pps + sx_pps_count + 1) / 2;
1593
1594 if (rx_pps_count / 8 >= 10)
1595 printk(KERN_INFO "%s: WARNING: Receiving %ld packets per second.\n",
1596 strip_info->dev->name, rx_pps_count / 8);
1597 if (tx_pps_count / 8 >= 10)
1598 printk(KERN_INFO "%s: WARNING: Tx %ld packets per second.\n",
1599 strip_info->dev->name, tx_pps_count / 8);
1600 if (sx_pps_count / 8 >= 10)
1601 printk(KERN_INFO "%s: WARNING: Sending %ld packets per second.\n",
1602 strip_info->dev->name, sx_pps_count / 8);
1603 }
1604
1605 spin_lock_bh(&strip_lock);
1606
1607 strip_send(strip_info, skb);
1608
1609 spin_unlock_bh(&strip_lock);
1610
1611 if (skb)
1612 dev_kfree_skb(skb);
1613 return 0;
1614}
1615
1616/*
1617 * IdleTask periodically calls strip_xmit, so even when we have no IP packets
1618 * to send for an extended period of time, the watchdog processing still gets
1619 * done to ensure that the radio stays in Starmode
1620 */
1621
1622static void strip_IdleTask(unsigned long parameter)
1623{
1624 strip_xmit(NULL, (struct net_device *) parameter);
1625}
1626
1627/*
1628 * Create the MAC header for an arbitrary protocol layer
1629 *
1630 * saddr!=NULL means use this specific address (n/a for Metricom)
1631 * saddr==NULL means use default device source address
1632 * daddr!=NULL means use this destination address
1633 * daddr==NULL means leave destination address alone
1634 * (e.g. unresolved arp -- kernel will call
1635 * rebuild_header later to fill in the address)
1636 */
1637
1638static int strip_header(struct sk_buff *skb, struct net_device *dev,
1639 unsigned short type, void *daddr, void *saddr,
1640 unsigned len)
1641{
1642 struct strip *strip_info = netdev_priv(dev);
1643 STRIP_Header *header = (STRIP_Header *) skb_push(skb, sizeof(STRIP_Header));
1644
1645 /*printk(KERN_INFO "%s: strip_header 0x%04X %s\n", dev->name, type,
1646 type == ETH_P_IP ? "IP" : type == ETH_P_ARP ? "ARP" : ""); */
1647
1648 header->src_addr = strip_info->true_dev_addr;
1649 header->protocol = htons(type);
1650
1651 /*HexDump("strip_header", netdev_priv(dev), skb->data, skb->data + skb->len); */
1652
1653 if (!daddr)
1654 return (-dev->hard_header_len);
1655
1656 header->dst_addr = *(MetricomAddress *) daddr;
1657 return (dev->hard_header_len);
1658}
1659
1660/*
1661 * Rebuild the MAC header. This is called after an ARP
1662 * (or in future other address resolution) has completed on this
1663 * sk_buff. We now let ARP fill in the other fields.
1664 * I think this should return zero if packet is ready to send,
1665 * or non-zero if it needs more time to do an address lookup
1666 */
1667
1668static int strip_rebuild_header(struct sk_buff *skb)
1669{
1670#ifdef CONFIG_INET
1671 STRIP_Header *header = (STRIP_Header *) skb->data;
1672
1673 /* Arp find returns zero if if knows the address, */
1674 /* or if it doesn't know the address it sends an ARP packet and returns non-zero */
1675 return arp_find(header->dst_addr.c, skb) ? 1 : 0;
1676#else
1677 return 0;
1678#endif
1679}
1680
1681
1682/************************************************************************/
1683/* Receiving routines */
1684
1685static int strip_receive_room(struct tty_struct *tty)
1686{
1687 return 0x10000; /* We can handle an infinite amount of data. :-) */
1688}
1689
1690/*
1691 * This function parses the response to the ATS300? command,
1692 * extracting the radio version and serial number.
1693 */
1694static void get_radio_version(struct strip *strip_info, __u8 * ptr, __u8 * end)
1695{
1696 __u8 *p, *value_begin, *value_end;
1697 int len;
1698
1699 /* Determine the beginning of the second line of the payload */
1700 p = ptr;
1701 while (p < end && *p != 10)
1702 p++;
1703 if (p >= end)
1704 return;
1705 p++;
1706 value_begin = p;
1707
1708 /* Determine the end of line */
1709 while (p < end && *p != 10)
1710 p++;
1711 if (p >= end)
1712 return;
1713 value_end = p;
1714 p++;
1715
1716 len = value_end - value_begin;
1717 len = min_t(int, len, sizeof(FirmwareVersion) - 1);
1718 if (strip_info->firmware_version.c[0] == 0)
1719 printk(KERN_INFO "%s: Radio Firmware: %.*s\n",
1720 strip_info->dev->name, len, value_begin);
1721 sprintf(strip_info->firmware_version.c, "%.*s", len, value_begin);
1722
1723 /* Look for the first colon */
1724 while (p < end && *p != ':')
1725 p++;
1726 if (p >= end)
1727 return;
1728 /* Skip over the space */
1729 p += 2;
1730 len = sizeof(SerialNumber) - 1;
1731 if (p + len <= end) {
1732 sprintf(strip_info->serial_number.c, "%.*s", len, p);
1733 } else {
1734 printk(KERN_DEBUG
1735 "STRIP: radio serial number shorter (%zd) than expected (%d)\n",
1736 end - p, len);
1737 }
1738}
1739
1740/*
1741 * This function parses the response to the ATS325? command,
1742 * extracting the radio battery voltage.
1743 */
1744static void get_radio_voltage(struct strip *strip_info, __u8 * ptr, __u8 * end)
1745{
1746 int len;
1747
1748 len = sizeof(BatteryVoltage) - 1;
1749 if (ptr + len <= end) {
1750 sprintf(strip_info->battery_voltage.c, "%.*s", len, ptr);
1751 } else {
1752 printk(KERN_DEBUG
1753 "STRIP: radio voltage string shorter (%zd) than expected (%d)\n",
1754 end - ptr, len);
1755 }
1756}
1757
1758/*
1759 * This function parses the responses to the AT~LA and ATS311 commands,
1760 * which list the radio's neighbours.
1761 */
1762static void get_radio_neighbours(MetricomNodeTable * table, __u8 * ptr, __u8 * end)
1763{
1764 table->num_nodes = 0;
1765 while (ptr < end && table->num_nodes < NODE_TABLE_SIZE) {
1766 MetricomNode *node = &table->node[table->num_nodes++];
1767 char *dst = node->c, *limit = dst + sizeof(*node) - 1;
1768 while (ptr < end && *ptr <= 32)
1769 ptr++;
1770 while (ptr < end && dst < limit && *ptr != 10)
1771 *dst++ = *ptr++;
1772 *dst++ = 0;
1773 while (ptr < end && ptr[-1] != 10)
1774 ptr++;
1775 }
1776 do_gettimeofday(&table->timestamp);
1777}
1778
1779static int get_radio_address(struct strip *strip_info, __u8 * p)
1780{
1781 MetricomAddress addr;
1782
1783 if (string_to_radio_address(&addr, p))
1784 return (1);
1785
1786 /* See if our radio address has changed */
1787 if (memcmp(strip_info->true_dev_addr.c, addr.c, sizeof(addr))) {
1788 MetricomAddressString addr_string;
1789 radio_address_to_string(&addr, &addr_string);
1790 printk(KERN_INFO "%s: Radio address = %s\n",
1791 strip_info->dev->name, addr_string.c);
1792 strip_info->true_dev_addr = addr;
1793 if (!strip_info->manual_dev_addr)
1794 *(MetricomAddress *) strip_info->dev->dev_addr =
1795 addr;
1796 /* Give the radio a few seconds to get its head straight, then send an arp */
1797 strip_info->gratuitous_arp = jiffies + 15 * HZ;
1798 strip_info->arp_interval = 1 * HZ;
1799 }
1800 return (0);
1801}
1802
1803static int verify_checksum(struct strip *strip_info)
1804{
1805 __u8 *p = strip_info->sx_buff;
1806 __u8 *end = strip_info->sx_buff + strip_info->sx_count - 4;
1807 u_short sum =
1808 (READHEX16(end[0]) << 12) | (READHEX16(end[1]) << 8) |
1809 (READHEX16(end[2]) << 4) | (READHEX16(end[3]));
1810 while (p < end)
1811 sum -= *p++;
1812 if (sum == 0 && strip_info->firmware_level == StructuredMessages) {
1813 strip_info->firmware_level = ChecksummedMessages;
1814 printk(KERN_INFO "%s: Radio provides message checksums\n",
1815 strip_info->dev->name);
1816 }
1817 return (sum == 0);
1818}
1819
1820static void RecvErr(char *msg, struct strip *strip_info)
1821{
1822 __u8 *ptr = strip_info->sx_buff;
1823 __u8 *end = strip_info->sx_buff + strip_info->sx_count;
1824 DumpData(msg, strip_info, ptr, end);
1825 strip_info->rx_errors++;
1826}
1827
1828static void RecvErr_Message(struct strip *strip_info, __u8 * sendername,
1829 const __u8 * msg, u_long len)
1830{
1831 if (has_prefix(msg, len, "001")) { /* Not in StarMode! */
1832 RecvErr("Error Msg:", strip_info);
1833 printk(KERN_INFO "%s: Radio %s is not in StarMode\n",
1834 strip_info->dev->name, sendername);
1835 }
1836
1837 else if (has_prefix(msg, len, "002")) { /* Remap handle */
1838 /* We ignore "Remap handle" messages for now */
1839 }
1840
1841 else if (has_prefix(msg, len, "003")) { /* Can't resolve name */
1842 RecvErr("Error Msg:", strip_info);
1843 printk(KERN_INFO "%s: Destination radio name is unknown\n",
1844 strip_info->dev->name);
1845 }
1846
1847 else if (has_prefix(msg, len, "004")) { /* Name too small or missing */
1848 strip_info->watchdog_doreset = jiffies + LongTime;
1849#if TICKLE_TIMERS
1850 {
1851 struct timeval tv;
1852 do_gettimeofday(&tv);
1853 printk(KERN_INFO
1854 "**** Got ERR_004 response at %02d.%06d\n",
1855 tv.tv_sec % 100, tv.tv_usec);
1856 }
1857#endif
1858 if (!strip_info->working) {
1859 strip_info->working = TRUE;
1860 printk(KERN_INFO "%s: Radio now in starmode\n",
1861 strip_info->dev->name);
1862 /*
1863 * If the radio has just entered a working state, we should do our first
1864 * probe ASAP, so that we find out our radio address etc. without delay.
1865 */
1866 strip_info->watchdog_doprobe = jiffies;
1867 }
1868 if (strip_info->firmware_level == NoStructure && sendername) {
1869 strip_info->firmware_level = StructuredMessages;
1870 strip_info->next_command = 0; /* Try to enable checksums ASAP */
1871 printk(KERN_INFO
1872 "%s: Radio provides structured messages\n",
1873 strip_info->dev->name);
1874 }
1875 if (strip_info->firmware_level >= StructuredMessages) {
1876 /*
1877 * If this message has a valid checksum on the end, then the call to verify_checksum
1878 * will elevate the firmware_level to ChecksummedMessages for us. (The actual return
1879 * code from verify_checksum is ignored here.)
1880 */
1881 verify_checksum(strip_info);
1882 /*
1883 * If the radio has structured messages but we don't yet have all our information about it,
1884 * we should do probes without delay, until we have gathered all the information
1885 */
1886 if (!GOT_ALL_RADIO_INFO(strip_info))
1887 strip_info->watchdog_doprobe = jiffies;
1888 }
1889 }
1890
1891 else if (has_prefix(msg, len, "005")) /* Bad count specification */
1892 RecvErr("Error Msg:", strip_info);
1893
1894 else if (has_prefix(msg, len, "006")) /* Header too big */
1895 RecvErr("Error Msg:", strip_info);
1896
1897 else if (has_prefix(msg, len, "007")) { /* Body too big */
1898 RecvErr("Error Msg:", strip_info);
1899 printk(KERN_ERR
1900 "%s: Error! Packet size too big for radio.\n",
1901 strip_info->dev->name);
1902 }
1903
1904 else if (has_prefix(msg, len, "008")) { /* Bad character in name */
1905 RecvErr("Error Msg:", strip_info);
1906 printk(KERN_ERR
1907 "%s: Radio name contains illegal character\n",
1908 strip_info->dev->name);
1909 }
1910
1911 else if (has_prefix(msg, len, "009")) /* No count or line terminator */
1912 RecvErr("Error Msg:", strip_info);
1913
1914 else if (has_prefix(msg, len, "010")) /* Invalid checksum */
1915 RecvErr("Error Msg:", strip_info);
1916
1917 else if (has_prefix(msg, len, "011")) /* Checksum didn't match */
1918 RecvErr("Error Msg:", strip_info);
1919
1920 else if (has_prefix(msg, len, "012")) /* Failed to transmit packet */
1921 RecvErr("Error Msg:", strip_info);
1922
1923 else
1924 RecvErr("Error Msg:", strip_info);
1925}
1926
1927static void process_AT_response(struct strip *strip_info, __u8 * ptr,
1928 __u8 * end)
1929{
1930 u_long len;
1931 __u8 *p = ptr;
1932 while (p < end && p[-1] != 10)
1933 p++; /* Skip past first newline character */
1934 /* Now ptr points to the AT command, and p points to the text of the response. */
1935 len = p - ptr;
1936
1937#if TICKLE_TIMERS
1938 {
1939 struct timeval tv;
1940 do_gettimeofday(&tv);
1941 printk(KERN_INFO "**** Got AT response %.7s at %02d.%06d\n",
1942 ptr, tv.tv_sec % 100, tv.tv_usec);
1943 }
1944#endif
1945
1946 if (has_prefix(ptr, len, "ATS300?"))
1947 get_radio_version(strip_info, p, end);
1948 else if (has_prefix(ptr, len, "ATS305?"))
1949 get_radio_address(strip_info, p);
1950 else if (has_prefix(ptr, len, "ATS311?"))
1951 get_radio_neighbours(&strip_info->poletops, p, end);
1952 else if (has_prefix(ptr, len, "ATS319=7"))
1953 verify_checksum(strip_info);
1954 else if (has_prefix(ptr, len, "ATS325?"))
1955 get_radio_voltage(strip_info, p, end);
1956 else if (has_prefix(ptr, len, "AT~LA"))
1957 get_radio_neighbours(&strip_info->portables, p, end);
1958 else
1959 RecvErr("Unknown AT Response:", strip_info);
1960}
1961
1962static void process_ACK(struct strip *strip_info, __u8 * ptr, __u8 * end)
1963{
1964 /* Currently we don't do anything with ACKs from the radio */
1965}
1966
1967static void process_Info(struct strip *strip_info, __u8 * ptr, __u8 * end)
1968{
1969 if (ptr + 16 > end)
1970 RecvErr("Bad Info Msg:", strip_info);
1971}
1972
1973static struct net_device *get_strip_dev(struct strip *strip_info)
1974{
1975 /* If our hardware address is *manually set* to zero, and we know our */
1976 /* real radio hardware address, try to find another strip device that has been */
1977 /* manually set to that address that we can 'transfer ownership' of this packet to */
1978 if (strip_info->manual_dev_addr &&
1979 !memcmp(strip_info->dev->dev_addr, zero_address.c,
1980 sizeof(zero_address))
1981 && memcmp(&strip_info->true_dev_addr, zero_address.c,
1982 sizeof(zero_address))) {
1983 struct net_device *dev;
1984 read_lock_bh(&dev_base_lock);
1985 dev = dev_base;
1986 while (dev) {
1987 if (dev->type == strip_info->dev->type &&
1988 !memcmp(dev->dev_addr,
1989 &strip_info->true_dev_addr,
1990 sizeof(MetricomAddress))) {
1991 printk(KERN_INFO
1992 "%s: Transferred packet ownership to %s.\n",
1993 strip_info->dev->name, dev->name);
1994 read_unlock_bh(&dev_base_lock);
1995 return (dev);
1996 }
1997 dev = dev->next;
1998 }
1999 read_unlock_bh(&dev_base_lock);
2000 }
2001 return (strip_info->dev);
2002}
2003
2004/*
2005 * Send one completely decapsulated datagram to the next layer.
2006 */
2007
2008static void deliver_packet(struct strip *strip_info, STRIP_Header * header,
2009 __u16 packetlen)
2010{
2011 struct sk_buff *skb = dev_alloc_skb(sizeof(STRIP_Header) + packetlen);
2012 if (!skb) {
2013 printk(KERN_ERR "%s: memory squeeze, dropping packet.\n",
2014 strip_info->dev->name);
2015 strip_info->rx_dropped++;
2016 } else {
2017 memcpy(skb_put(skb, sizeof(STRIP_Header)), header,
2018 sizeof(STRIP_Header));
2019 memcpy(skb_put(skb, packetlen), strip_info->rx_buff,
2020 packetlen);
2021 skb->dev = get_strip_dev(strip_info);
2022 skb->protocol = header->protocol;
2023 skb->mac.raw = skb->data;
2024
2025 /* Having put a fake header on the front of the sk_buff for the */
2026 /* benefit of tools like tcpdump, skb_pull now 'consumes' that */
2027 /* fake header before we hand the packet up to the next layer. */
2028 skb_pull(skb, sizeof(STRIP_Header));
2029
2030 /* Finally, hand the packet up to the next layer (e.g. IP or ARP, etc.) */
2031 strip_info->rx_packets++;
2032 strip_info->rx_pps_count++;
2033#ifdef EXT_COUNTERS
2034 strip_info->rx_bytes += packetlen;
2035#endif
2036 skb->dev->last_rx = jiffies;
2037 netif_rx(skb);
2038 }
2039}
2040
2041static void process_IP_packet(struct strip *strip_info,
2042 STRIP_Header * header, __u8 * ptr,
2043 __u8 * end)
2044{
2045 __u16 packetlen;
2046
2047 /* Decode start of the IP packet header */
2048 ptr = UnStuffData(ptr, end, strip_info->rx_buff, 4);
2049 if (!ptr) {
2050 RecvErr("IP Packet too short", strip_info);
2051 return;
2052 }
2053
2054 packetlen = ((__u16) strip_info->rx_buff[2] << 8) | strip_info->rx_buff[3];
2055
2056 if (packetlen > MAX_RECV_MTU) {
2057 printk(KERN_INFO "%s: Dropping oversized received IP packet: %d bytes\n",
2058 strip_info->dev->name, packetlen);
2059 strip_info->rx_dropped++;
2060 return;
2061 }
2062
2063 /*printk(KERN_INFO "%s: Got %d byte IP packet\n", strip_info->dev->name, packetlen); */
2064
2065 /* Decode remainder of the IP packet */
2066 ptr =
2067 UnStuffData(ptr, end, strip_info->rx_buff + 4, packetlen - 4);
2068 if (!ptr) {
2069 RecvErr("IP Packet too short", strip_info);
2070 return;
2071 }
2072
2073 if (ptr < end) {
2074 RecvErr("IP Packet too long", strip_info);
2075 return;
2076 }
2077
2078 header->protocol = htons(ETH_P_IP);
2079
2080 deliver_packet(strip_info, header, packetlen);
2081}
2082
2083static void process_ARP_packet(struct strip *strip_info,
2084 STRIP_Header * header, __u8 * ptr,
2085 __u8 * end)
2086{
2087 __u16 packetlen;
2088 struct arphdr *arphdr = (struct arphdr *) strip_info->rx_buff;
2089
2090 /* Decode start of the ARP packet */
2091 ptr = UnStuffData(ptr, end, strip_info->rx_buff, 8);
2092 if (!ptr) {
2093 RecvErr("ARP Packet too short", strip_info);
2094 return;
2095 }
2096
2097 packetlen = 8 + (arphdr->ar_hln + arphdr->ar_pln) * 2;
2098
2099 if (packetlen > MAX_RECV_MTU) {
2100 printk(KERN_INFO
2101 "%s: Dropping oversized received ARP packet: %d bytes\n",
2102 strip_info->dev->name, packetlen);
2103 strip_info->rx_dropped++;
2104 return;
2105 }
2106
2107 /*printk(KERN_INFO "%s: Got %d byte ARP %s\n",
2108 strip_info->dev->name, packetlen,
2109 ntohs(arphdr->ar_op) == ARPOP_REQUEST ? "request" : "reply"); */
2110
2111 /* Decode remainder of the ARP packet */
2112 ptr =
2113 UnStuffData(ptr, end, strip_info->rx_buff + 8, packetlen - 8);
2114 if (!ptr) {
2115 RecvErr("ARP Packet too short", strip_info);
2116 return;
2117 }
2118
2119 if (ptr < end) {
2120 RecvErr("ARP Packet too long", strip_info);
2121 return;
2122 }
2123
2124 header->protocol = htons(ETH_P_ARP);
2125
2126 deliver_packet(strip_info, header, packetlen);
2127}
2128
2129/*
2130 * process_text_message processes a <CR>-terminated block of data received
2131 * from the radio that doesn't begin with a '*' character. All normal
2132 * Starmode communication messages with the radio begin with a '*',
2133 * so any text that does not indicates a serial port error, a radio that
2134 * is in Hayes command mode instead of Starmode, or a radio with really
2135 * old firmware that doesn't frame its Starmode responses properly.
2136 */
2137static void process_text_message(struct strip *strip_info)
2138{
2139 __u8 *msg = strip_info->sx_buff;
2140 int len = strip_info->sx_count;
2141
2142 /* Check for anything that looks like it might be our radio name */
2143 /* (This is here for backwards compatibility with old firmware) */
2144 if (len == 9 && get_radio_address(strip_info, msg) == 0)
2145 return;
2146
2147 if (text_equal(msg, len, "OK"))
2148 return; /* Ignore 'OK' responses from prior commands */
2149 if (text_equal(msg, len, "ERROR"))
2150 return; /* Ignore 'ERROR' messages */
2151 if (has_prefix(msg, len, "ate0q1"))
2152 return; /* Ignore character echo back from the radio */
2153
2154 /* Catch other error messages */
2155 /* (This is here for backwards compatibility with old firmware) */
2156 if (has_prefix(msg, len, "ERR_")) {
2157 RecvErr_Message(strip_info, NULL, &msg[4], len - 4);
2158 return;
2159 }
2160
2161 RecvErr("No initial *", strip_info);
2162}
2163
2164/*
2165 * process_message processes a <CR>-terminated block of data received
2166 * from the radio. If the radio is not in Starmode or has old firmware,
2167 * it may be a line of text in response to an AT command. Ideally, with
2168 * a current radio that's properly in Starmode, all data received should
2169 * be properly framed and checksummed radio message blocks, containing
2170 * either a starmode packet, or a other communication from the radio
2171 * firmware, like "INF_" Info messages and &COMMAND responses.
2172 */
2173static void process_message(struct strip *strip_info)
2174{
2175 STRIP_Header header = { zero_address, zero_address, 0 };
2176 __u8 *ptr = strip_info->sx_buff;
2177 __u8 *end = strip_info->sx_buff + strip_info->sx_count;
2178 __u8 sendername[32], *sptr = sendername;
2179 MetricomKey key;
2180
2181 /*HexDump("Receiving", strip_info, ptr, end); */
2182
2183 /* Check for start of address marker, and then skip over it */
2184 if (*ptr == '*')
2185 ptr++;
2186 else {
2187 process_text_message(strip_info);
2188 return;
2189 }
2190
2191 /* Copy out the return address */
2192 while (ptr < end && *ptr != '*'
2193 && sptr < ARRAY_END(sendername) - 1)
2194 *sptr++ = *ptr++;
2195 *sptr = 0; /* Null terminate the sender name */
2196
2197 /* Check for end of address marker, and skip over it */
2198 if (ptr >= end || *ptr != '*') {
2199 RecvErr("No second *", strip_info);
2200 return;
2201 }
2202 ptr++; /* Skip the second '*' */
2203
2204 /* If the sender name is "&COMMAND", ignore this 'packet' */
2205 /* (This is here for backwards compatibility with old firmware) */
2206 if (!strcmp(sendername, "&COMMAND")) {
2207 strip_info->firmware_level = NoStructure;
2208 strip_info->next_command = CompatibilityCommand;
2209 return;
2210 }
2211
2212 if (ptr + 4 > end) {
2213 RecvErr("No proto key", strip_info);
2214 return;
2215 }
2216
2217 /* Get the protocol key out of the buffer */
2218 key.c[0] = *ptr++;
2219 key.c[1] = *ptr++;
2220 key.c[2] = *ptr++;
2221 key.c[3] = *ptr++;
2222
2223 /* If we're using checksums, verify the checksum at the end of the packet */
2224 if (strip_info->firmware_level >= ChecksummedMessages) {
2225 end -= 4; /* Chop the last four bytes off the packet (they're the checksum) */
2226 if (ptr > end) {
2227 RecvErr("Missing Checksum", strip_info);
2228 return;
2229 }
2230 if (!verify_checksum(strip_info)) {
2231 RecvErr("Bad Checksum", strip_info);
2232 return;
2233 }
2234 }
2235
2236 /*printk(KERN_INFO "%s: Got packet from \"%s\".\n", strip_info->dev->name, sendername); */
2237
2238 /*
2239 * Fill in (pseudo) source and destination addresses in the packet.
2240 * We assume that the destination address was our address (the radio does not
2241 * tell us this). If the radio supplies a source address, then we use it.
2242 */
2243 header.dst_addr = strip_info->true_dev_addr;
2244 string_to_radio_address(&header.src_addr, sendername);
2245
2246#ifdef EXT_COUNTERS
2247 if (key.l == SIP0Key.l) {
2248 strip_info->rx_rbytes += (end - ptr);
2249 process_IP_packet(strip_info, &header, ptr, end);
2250 } else if (key.l == ARP0Key.l) {
2251 strip_info->rx_rbytes += (end - ptr);
2252 process_ARP_packet(strip_info, &header, ptr, end);
2253 } else if (key.l == ATR_Key.l) {
2254 strip_info->rx_ebytes += (end - ptr);
2255 process_AT_response(strip_info, ptr, end);
2256 } else if (key.l == ACK_Key.l) {
2257 strip_info->rx_ebytes += (end - ptr);
2258 process_ACK(strip_info, ptr, end);
2259 } else if (key.l == INF_Key.l) {
2260 strip_info->rx_ebytes += (end - ptr);
2261 process_Info(strip_info, ptr, end);
2262 } else if (key.l == ERR_Key.l) {
2263 strip_info->rx_ebytes += (end - ptr);
2264 RecvErr_Message(strip_info, sendername, ptr, end - ptr);
2265 } else
2266 RecvErr("Unrecognized protocol key", strip_info);
2267#else
2268 if (key.l == SIP0Key.l)
2269 process_IP_packet(strip_info, &header, ptr, end);
2270 else if (key.l == ARP0Key.l)
2271 process_ARP_packet(strip_info, &header, ptr, end);
2272 else if (key.l == ATR_Key.l)
2273 process_AT_response(strip_info, ptr, end);
2274 else if (key.l == ACK_Key.l)
2275 process_ACK(strip_info, ptr, end);
2276 else if (key.l == INF_Key.l)
2277 process_Info(strip_info, ptr, end);
2278 else if (key.l == ERR_Key.l)
2279 RecvErr_Message(strip_info, sendername, ptr, end - ptr);
2280 else
2281 RecvErr("Unrecognized protocol key", strip_info);
2282#endif
2283}
2284
2285#define TTYERROR(X) ((X) == TTY_BREAK ? "Break" : \
2286 (X) == TTY_FRAME ? "Framing Error" : \
2287 (X) == TTY_PARITY ? "Parity Error" : \
2288 (X) == TTY_OVERRUN ? "Hardware Overrun" : "Unknown Error")
2289
2290/*
2291 * Handle the 'receiver data ready' interrupt.
2292 * This function is called by the 'tty_io' module in the kernel when
2293 * a block of STRIP data has been received, which can now be decapsulated
2294 * and sent on to some IP layer for further processing.
2295 */
2296
2297static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
2298 char *fp, int count)
2299{
2300 struct strip *strip_info = (struct strip *) tty->disc_data;
2301 const unsigned char *end = cp + count;
2302
2303 if (!strip_info || strip_info->magic != STRIP_MAGIC
2304 || !netif_running(strip_info->dev))
2305 return;
2306
2307 spin_lock_bh(&strip_lock);
2308#if 0
2309 {
2310 struct timeval tv;
2311 do_gettimeofday(&tv);
2312 printk(KERN_INFO
2313 "**** strip_receive_buf: %3d bytes at %02d.%06d\n",
2314 count, tv.tv_sec % 100, tv.tv_usec);
2315 }
2316#endif
2317
2318#ifdef EXT_COUNTERS
2319 strip_info->rx_sbytes += count;
2320#endif
2321
2322 /* Read the characters out of the buffer */
2323 while (cp < end) {
2324 if (fp && *fp)
2325 printk(KERN_INFO "%s: %s on serial port\n",
2326 strip_info->dev->name, TTYERROR(*fp));
2327 if (fp && *fp++ && !strip_info->discard) { /* If there's a serial error, record it */
2328 /* If we have some characters in the buffer, discard them */
2329 strip_info->discard = strip_info->sx_count;
2330 strip_info->rx_errors++;
2331 }
2332
2333 /* Leading control characters (CR, NL, Tab, etc.) are ignored */
2334 if (strip_info->sx_count > 0 || *cp >= ' ') {
2335 if (*cp == 0x0D) { /* If end of packet, decide what to do with it */
2336 if (strip_info->sx_count > 3000)
2337 printk(KERN_INFO
2338 "%s: Cut a %d byte packet (%zd bytes remaining)%s\n",
2339 strip_info->dev->name,
2340 strip_info->sx_count,
2341 end - cp - 1,
2342 strip_info->
2343 discard ? " (discarded)" :
2344 "");
2345 if (strip_info->sx_count >
2346 strip_info->sx_size) {
2347 strip_info->rx_over_errors++;
2348 printk(KERN_INFO
2349 "%s: sx_buff overflow (%d bytes total)\n",
2350 strip_info->dev->name,
2351 strip_info->sx_count);
2352 } else if (strip_info->discard)
2353 printk(KERN_INFO
2354 "%s: Discarding bad packet (%d/%d)\n",
2355 strip_info->dev->name,
2356 strip_info->discard,
2357 strip_info->sx_count);
2358 else
2359 process_message(strip_info);
2360 strip_info->discard = 0;
2361 strip_info->sx_count = 0;
2362 } else {
2363 /* Make sure we have space in the buffer */
2364 if (strip_info->sx_count <
2365 strip_info->sx_size)
2366 strip_info->sx_buff[strip_info->
2367 sx_count] =
2368 *cp;
2369 strip_info->sx_count++;
2370 }
2371 }
2372 cp++;
2373 }
2374 spin_unlock_bh(&strip_lock);
2375}
2376
2377
2378/************************************************************************/
2379/* General control routines */
2380
2381static int set_mac_address(struct strip *strip_info,
2382 MetricomAddress * addr)
2383{
2384 /*
2385 * We're using a manually specified address if the address is set
2386 * to anything other than all ones. Setting the address to all ones
2387 * disables manual mode and goes back to automatic address determination
2388 * (tracking the true address that the radio has).
2389 */
2390 strip_info->manual_dev_addr =
2391 memcmp(addr->c, broadcast_address.c,
2392 sizeof(broadcast_address));
2393 if (strip_info->manual_dev_addr)
2394 *(MetricomAddress *) strip_info->dev->dev_addr = *addr;
2395 else
2396 *(MetricomAddress *) strip_info->dev->dev_addr =
2397 strip_info->true_dev_addr;
2398 return 0;
2399}
2400
2401static int strip_set_mac_address(struct net_device *dev, void *addr)
2402{
2403 struct strip *strip_info = netdev_priv(dev);
2404 struct sockaddr *sa = addr;
2405 printk(KERN_INFO "%s: strip_set_dev_mac_address called\n", dev->name);
2406 set_mac_address(strip_info, (MetricomAddress *) sa->sa_data);
2407 return 0;
2408}
2409
2410static struct net_device_stats *strip_get_stats(struct net_device *dev)
2411{
2412 struct strip *strip_info = netdev_priv(dev);
2413 static struct net_device_stats stats;
2414
2415 memset(&stats, 0, sizeof(struct net_device_stats));
2416
2417 stats.rx_packets = strip_info->rx_packets;
2418 stats.tx_packets = strip_info->tx_packets;
2419 stats.rx_dropped = strip_info->rx_dropped;
2420 stats.tx_dropped = strip_info->tx_dropped;
2421 stats.tx_errors = strip_info->tx_errors;
2422 stats.rx_errors = strip_info->rx_errors;
2423 stats.rx_over_errors = strip_info->rx_over_errors;
2424 return (&stats);
2425}
2426
2427
2428/************************************************************************/
2429/* Opening and closing */
2430
2431/*
2432 * Here's the order things happen:
2433 * When the user runs "slattach -p strip ..."
2434 * 1. The TTY module calls strip_open
2435 * 2. strip_open calls strip_alloc
2436 * 3. strip_alloc calls register_netdev
2437 * 4. register_netdev calls strip_dev_init
2438 * 5. then strip_open finishes setting up the strip_info
2439 *
2440 * When the user runs "ifconfig st<x> up address netmask ..."
2441 * 6. strip_open_low gets called
2442 *
2443 * When the user runs "ifconfig st<x> down"
2444 * 7. strip_close_low gets called
2445 *
2446 * When the user kills the slattach process
2447 * 8. strip_close gets called
2448 * 9. strip_close calls dev_close
2449 * 10. if the device is still up, then dev_close calls strip_close_low
2450 * 11. strip_close calls strip_free
2451 */
2452
2453/* Open the low-level part of the STRIP channel. Easy! */
2454
2455static int strip_open_low(struct net_device *dev)
2456{
2457 struct strip *strip_info = netdev_priv(dev);
2458
2459 if (strip_info->tty == NULL)
2460 return (-ENODEV);
2461
2462 if (!allocate_buffers(strip_info, dev->mtu))
2463 return (-ENOMEM);
2464
2465 strip_info->sx_count = 0;
2466 strip_info->tx_left = 0;
2467
2468 strip_info->discard = 0;
2469 strip_info->working = FALSE;
2470 strip_info->firmware_level = NoStructure;
2471 strip_info->next_command = CompatibilityCommand;
2472 strip_info->user_baud = get_baud(strip_info->tty);
2473
2474 printk(KERN_INFO "%s: Initializing Radio.\n",
2475 strip_info->dev->name);
2476 ResetRadio(strip_info);
2477 strip_info->idle_timer.expires = jiffies + 1 * HZ;
2478 add_timer(&strip_info->idle_timer);
2479 netif_wake_queue(dev);
2480 return (0);
2481}
2482
2483
2484/*
2485 * Close the low-level part of the STRIP channel. Easy!
2486 */
2487
2488static int strip_close_low(struct net_device *dev)
2489{
2490 struct strip *strip_info = netdev_priv(dev);
2491
2492 if (strip_info->tty == NULL)
2493 return -EBUSY;
2494 strip_info->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
2495
2496 netif_stop_queue(dev);
2497
2498 /*
2499 * Free all STRIP frame buffers.
2500 */
2501 if (strip_info->rx_buff) {
2502 kfree(strip_info->rx_buff);
2503 strip_info->rx_buff = NULL;
2504 }
2505 if (strip_info->sx_buff) {
2506 kfree(strip_info->sx_buff);
2507 strip_info->sx_buff = NULL;
2508 }
2509 if (strip_info->tx_buff) {
2510 kfree(strip_info->tx_buff);
2511 strip_info->tx_buff = NULL;
2512 }
2513 del_timer(&strip_info->idle_timer);
2514 return 0;
2515}
2516
2517/*
2518 * This routine is called by DDI when the
2519 * (dynamically assigned) device is registered
2520 */
2521
2522static void strip_dev_setup(struct net_device *dev)
2523{
2524 /*
2525 * Finish setting up the DEVICE info.
2526 */
2527
2528 SET_MODULE_OWNER(dev);
2529
2530 dev->trans_start = 0;
2531 dev->last_rx = 0;
2532 dev->tx_queue_len = 30; /* Drop after 30 frames queued */
2533
2534 dev->flags = 0;
2535 dev->mtu = DEFAULT_STRIP_MTU;
2536 dev->type = ARPHRD_METRICOM; /* dtang */
2537 dev->hard_header_len = sizeof(STRIP_Header);
2538 /*
2539 * dev->priv Already holds a pointer to our struct strip
2540 */
2541
2542 *(MetricomAddress *) & dev->broadcast = broadcast_address;
2543 dev->dev_addr[0] = 0;
2544 dev->addr_len = sizeof(MetricomAddress);
2545
2546 /*
2547 * Pointers to interface service routines.
2548 */
2549
2550 dev->open = strip_open_low;
2551 dev->stop = strip_close_low;
2552 dev->hard_start_xmit = strip_xmit;
2553 dev->hard_header = strip_header;
2554 dev->rebuild_header = strip_rebuild_header;
2555 dev->set_mac_address = strip_set_mac_address;
2556 dev->get_stats = strip_get_stats;
2557 dev->change_mtu = strip_change_mtu;
2558}
2559
2560/*
2561 * Free a STRIP channel.
2562 */
2563
2564static void strip_free(struct strip *strip_info)
2565{
2566 spin_lock_bh(&strip_lock);
2567 list_del_rcu(&strip_info->list);
2568 spin_unlock_bh(&strip_lock);
2569
2570 strip_info->magic = 0;
2571
2572 free_netdev(strip_info->dev);
2573}
2574
2575
2576/*
2577 * Allocate a new free STRIP channel
2578 */
2579static struct strip *strip_alloc(void)
2580{
2581 struct list_head *n;
2582 struct net_device *dev;
2583 struct strip *strip_info;
2584
2585 dev = alloc_netdev(sizeof(struct strip), "st%d",
2586 strip_dev_setup);
2587
2588 if (!dev)
2589 return NULL; /* If no more memory, return */
2590
2591
2592 strip_info = dev->priv;
2593 strip_info->dev = dev;
2594
2595 strip_info->magic = STRIP_MAGIC;
2596 strip_info->tty = NULL;
2597
2598 strip_info->gratuitous_arp = jiffies + LongTime;
2599 strip_info->arp_interval = 0;
2600 init_timer(&strip_info->idle_timer);
2601 strip_info->idle_timer.data = (long) dev;
2602 strip_info->idle_timer.function = strip_IdleTask;
2603
2604
2605 spin_lock_bh(&strip_lock);
2606 rescan:
2607 /*
2608 * Search the list to find where to put our new entry
2609 * (and in the process decide what channel number it is
2610 * going to be)
2611 */
2612 list_for_each(n, &strip_list) {
2613 struct strip *s = hlist_entry(n, struct strip, list);
2614
2615 if (s->dev->base_addr == dev->base_addr) {
2616 ++dev->base_addr;
2617 goto rescan;
2618 }
2619 }
2620
2621 sprintf(dev->name, "st%ld", dev->base_addr);
2622
2623 list_add_tail_rcu(&strip_info->list, &strip_list);
2624 spin_unlock_bh(&strip_lock);
2625
2626 return strip_info;
2627}
2628
2629/*
2630 * Open the high-level part of the STRIP channel.
2631 * This function is called by the TTY module when the
2632 * STRIP line discipline is called for. Because we are
2633 * sure the tty line exists, we only have to link it to
2634 * a free STRIP channel...
2635 */
2636
2637static int strip_open(struct tty_struct *tty)
2638{
2639 struct strip *strip_info = (struct strip *) tty->disc_data;
2640
2641 /*
2642 * First make sure we're not already connected.
2643 */
2644
2645 if (strip_info && strip_info->magic == STRIP_MAGIC)
2646 return -EEXIST;
2647
2648 /*
2649 * OK. Find a free STRIP channel to use.
2650 */
2651 if ((strip_info = strip_alloc()) == NULL)
2652 return -ENFILE;
2653
2654 /*
2655 * Register our newly created device so it can be ifconfig'd
2656 * strip_dev_init() will be called as a side-effect
2657 */
2658
2659 if (register_netdev(strip_info->dev) != 0) {
2660 printk(KERN_ERR "strip: register_netdev() failed.\n");
2661 strip_free(strip_info);
2662 return -ENFILE;
2663 }
2664
2665 strip_info->tty = tty;
2666 tty->disc_data = strip_info;
2667 if (tty->driver->flush_buffer)
2668 tty->driver->flush_buffer(tty);
2669
2670 /*
2671 * Restore default settings
2672 */
2673
2674 strip_info->dev->type = ARPHRD_METRICOM; /* dtang */
2675
2676 /*
2677 * Set tty options
2678 */
2679
2680 tty->termios->c_iflag |= IGNBRK | IGNPAR; /* Ignore breaks and parity errors. */
2681 tty->termios->c_cflag |= CLOCAL; /* Ignore modem control signals. */
2682 tty->termios->c_cflag &= ~HUPCL; /* Don't close on hup */
2683
2684 printk(KERN_INFO "STRIP: device \"%s\" activated\n",
2685 strip_info->dev->name);
2686
2687 /*
2688 * Done. We have linked the TTY line to a channel.
2689 */
2690 return (strip_info->dev->base_addr);
2691}
2692
2693/*
2694 * Close down a STRIP channel.
2695 * This means flushing out any pending queues, and then restoring the
2696 * TTY line discipline to what it was before it got hooked to STRIP
2697 * (which usually is TTY again).
2698 */
2699
2700static void strip_close(struct tty_struct *tty)
2701{
2702 struct strip *strip_info = (struct strip *) tty->disc_data;
2703
2704 /*
2705 * First make sure we're connected.
2706 */
2707
2708 if (!strip_info || strip_info->magic != STRIP_MAGIC)
2709 return;
2710
2711 unregister_netdev(strip_info->dev);
2712
2713 tty->disc_data = NULL;
2714 strip_info->tty = NULL;
2715 printk(KERN_INFO "STRIP: device \"%s\" closed down\n",
2716 strip_info->dev->name);
2717 strip_free(strip_info);
2718 tty->disc_data = NULL;
2719}
2720
2721
2722/************************************************************************/
2723/* Perform I/O control calls on an active STRIP channel. */
2724
2725static int strip_ioctl(struct tty_struct *tty, struct file *file,
2726 unsigned int cmd, unsigned long arg)
2727{
2728 struct strip *strip_info = (struct strip *) tty->disc_data;
2729
2730 /*
2731 * First make sure we're connected.
2732 */
2733
2734 if (!strip_info || strip_info->magic != STRIP_MAGIC)
2735 return -EINVAL;
2736
2737 switch (cmd) {
2738 case SIOCGIFNAME:
2739 if(copy_to_user((void __user *) arg, strip_info->dev->name, strlen(strip_info->dev->name) + 1))
2740 return -EFAULT;
2741 break;
2742 case SIOCSIFHWADDR:
2743 {
2744 MetricomAddress addr;
2745 //printk(KERN_INFO "%s: SIOCSIFHWADDR\n", strip_info->dev->name);
2746 if(copy_from_user(&addr, (void __user *) arg, sizeof(MetricomAddress)))
2747 return -EFAULT;
2748 return set_mac_address(strip_info, &addr);
2749 }
2750 /*
2751 * Allow stty to read, but not set, the serial port
2752 */
2753
2754 case TCGETS:
2755 case TCGETA:
2756 return n_tty_ioctl(tty, file, cmd, arg);
2757 break;
2758 default:
2759 return -ENOIOCTLCMD;
2760 break;
2761 }
2762 return 0;
2763}
2764
2765
2766/************************************************************************/
2767/* Initialization */
2768
2769static struct tty_ldisc strip_ldisc = {
2770 .magic = TTY_LDISC_MAGIC,
2771 .name = "strip",
2772 .owner = THIS_MODULE,
2773 .open = strip_open,
2774 .close = strip_close,
2775 .ioctl = strip_ioctl,
2776 .receive_buf = strip_receive_buf,
2777 .receive_room = strip_receive_room,
2778 .write_wakeup = strip_write_some_more,
2779};
2780
2781/*
2782 * Initialize the STRIP driver.
2783 * This routine is called at boot time, to bootstrap the multi-channel
2784 * STRIP driver
2785 */
2786
2787static char signon[] __initdata =
2788 KERN_INFO "STRIP: Version %s (unlimited channels)\n";
2789
2790static int __init strip_init_driver(void)
2791{
2792 int status;
2793
2794 printk(signon, StripVersion);
2795
2796
2797 /*
2798 * Fill in our line protocol discipline, and register it
2799 */
2800 if ((status = tty_register_ldisc(N_STRIP, &strip_ldisc)))
2801 printk(KERN_ERR "STRIP: can't register line discipline (err = %d)\n",
2802 status);
2803
2804 /*
2805 * Register the status file with /proc
2806 */
2807 proc_net_fops_create("strip", S_IFREG | S_IRUGO, &strip_seq_fops);
2808
2809 return status;
2810}
2811
2812module_init(strip_init_driver);
2813
2814static const char signoff[] __exitdata =
2815 KERN_INFO "STRIP: Module Unloaded\n";
2816
2817static void __exit strip_exit_driver(void)
2818{
2819 int i;
2820 struct list_head *p,*n;
2821
2822 /* module ref count rules assure that all entries are unregistered */
2823 list_for_each_safe(p, n, &strip_list) {
2824 struct strip *s = list_entry(p, struct strip, list);
2825 strip_free(s);
2826 }
2827
2828 /* Unregister with the /proc/net file here. */
2829 proc_net_remove("strip");
2830
2831 if ((i = tty_register_ldisc(N_STRIP, NULL)))
2832 printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);
2833
2834 printk(signoff);
2835}
2836
2837module_exit(strip_exit_driver);
2838
2839MODULE_AUTHOR("Stuart Cheshire <cheshire@cs.stanford.edu>");
2840MODULE_DESCRIPTION("Starmode Radio IP (STRIP) Device Driver");
2841MODULE_LICENSE("Dual BSD/GPL");
2842
2843MODULE_SUPPORTED_DEVICE("Starmode Radio IP (STRIP) modem");
diff --git a/drivers/net/wireless/todo.txt b/drivers/net/wireless/todo.txt
new file mode 100644
index 000000000000..32234018de72
--- /dev/null
+++ b/drivers/net/wireless/todo.txt
@@ -0,0 +1,15 @@
1 Wireless Todo
2 -------------
3
41) Bring other kernel Wireless LAN drivers here
5 Completed
6
72) Bring new Wireless LAN driver not yet in the kernel there
8 See my web page for details
9 In particular : HostAP
10
113) Misc
12 o Mark wavelan, wavelan_cs, netwave_cs drivers as obsolete
13 o Maybe arlan.c, ray_cs.c and strip.c also deserve to be obsolete
14
15 Jean II
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
new file mode 100644
index 000000000000..7a5e20a17890
--- /dev/null
+++ b/drivers/net/wireless/wavelan.c
@@ -0,0 +1,4452 @@
1/*
2 * WaveLAN ISA driver
3 *
4 * Jean II - HPLB '96
5 *
6 * Reorganisation and extension of the driver.
7 * Original copyright follows (also see the end of this file).
8 * See wavelan.p.h for details.
9 *
10 *
11 *
12 * AT&T GIS (nee NCR) WaveLAN card:
13 * An Ethernet-like radio transceiver
14 * controlled by an Intel 82586 coprocessor.
15 */
16
17#include "wavelan.p.h" /* Private header */
18
19/************************* MISC SUBROUTINES **************************/
20/*
21 * Subroutines which won't fit in one of the following category
22 * (WaveLAN modem or i82586)
23 */
24
25/*------------------------------------------------------------------*/
26/*
27 * Translate irq number to PSA irq parameter
28 */
29static u8 wv_irq_to_psa(int irq)
30{
31 if (irq < 0 || irq >= NELS(irqvals))
32 return 0;
33
34 return irqvals[irq];
35}
36
37/*------------------------------------------------------------------*/
38/*
39 * Translate PSA irq parameter to irq number
40 */
41static int __init wv_psa_to_irq(u8 irqval)
42{
43 int irq;
44
45 for (irq = 0; irq < NELS(irqvals); irq++)
46 if (irqvals[irq] == irqval)
47 return irq;
48
49 return -1;
50}
51
52#ifdef STRUCT_CHECK
53/*------------------------------------------------------------------*/
54/*
55 * Sanity routine to verify the sizes of the various WaveLAN interface
56 * structures.
57 */
58static char *wv_struct_check(void)
59{
60#define SC(t,s,n) if (sizeof(t) != s) return(n);
61
62 SC(psa_t, PSA_SIZE, "psa_t");
63 SC(mmw_t, MMW_SIZE, "mmw_t");
64 SC(mmr_t, MMR_SIZE, "mmr_t");
65 SC(ha_t, HA_SIZE, "ha_t");
66
67#undef SC
68
69 return ((char *) NULL);
70} /* wv_struct_check */
71#endif /* STRUCT_CHECK */
72
73/********************* HOST ADAPTER SUBROUTINES *********************/
74/*
75 * Useful subroutines to manage the WaveLAN ISA interface
76 *
77 * One major difference with the PCMCIA hardware (except the port mapping)
78 * is that we have to keep the state of the Host Control Register
79 * because of the interrupt enable & bus size flags.
80 */
81
82/*------------------------------------------------------------------*/
83/*
84 * Read from card's Host Adaptor Status Register.
85 */
86static inline u16 hasr_read(unsigned long ioaddr)
87{
88 return (inw(HASR(ioaddr)));
89} /* hasr_read */
90
91/*------------------------------------------------------------------*/
92/*
93 * Write to card's Host Adapter Command Register.
94 */
95static inline void hacr_write(unsigned long ioaddr, u16 hacr)
96{
97 outw(hacr, HACR(ioaddr));
98} /* hacr_write */
99
100/*------------------------------------------------------------------*/
101/*
102 * Write to card's Host Adapter Command Register. Include a delay for
103 * those times when it is needed.
104 */
105static inline void hacr_write_slow(unsigned long ioaddr, u16 hacr)
106{
107 hacr_write(ioaddr, hacr);
108 /* delay might only be needed sometimes */
109 mdelay(1);
110} /* hacr_write_slow */
111
112/*------------------------------------------------------------------*/
113/*
114 * Set the channel attention bit.
115 */
116static inline void set_chan_attn(unsigned long ioaddr, u16 hacr)
117{
118 hacr_write(ioaddr, hacr | HACR_CA);
119} /* set_chan_attn */
120
121/*------------------------------------------------------------------*/
122/*
123 * Reset, and then set host adaptor into default mode.
124 */
125static inline void wv_hacr_reset(unsigned long ioaddr)
126{
127 hacr_write_slow(ioaddr, HACR_RESET);
128 hacr_write(ioaddr, HACR_DEFAULT);
129} /* wv_hacr_reset */
130
131/*------------------------------------------------------------------*/
132/*
133 * Set the I/O transfer over the ISA bus to 8-bit mode
134 */
135static inline void wv_16_off(unsigned long ioaddr, u16 hacr)
136{
137 hacr &= ~HACR_16BITS;
138 hacr_write(ioaddr, hacr);
139} /* wv_16_off */
140
141/*------------------------------------------------------------------*/
142/*
143 * Set the I/O transfer over the ISA bus to 8-bit mode
144 */
145static inline void wv_16_on(unsigned long ioaddr, u16 hacr)
146{
147 hacr |= HACR_16BITS;
148 hacr_write(ioaddr, hacr);
149} /* wv_16_on */
150
151/*------------------------------------------------------------------*/
152/*
153 * Disable interrupts on the WaveLAN hardware.
154 * (called by wv_82586_stop())
155 */
156static inline void wv_ints_off(struct net_device * dev)
157{
158 net_local *lp = (net_local *) dev->priv;
159 unsigned long ioaddr = dev->base_addr;
160
161 lp->hacr &= ~HACR_INTRON;
162 hacr_write(ioaddr, lp->hacr);
163} /* wv_ints_off */
164
165/*------------------------------------------------------------------*/
166/*
167 * Enable interrupts on the WaveLAN hardware.
168 * (called by wv_hw_reset())
169 */
170static inline void wv_ints_on(struct net_device * dev)
171{
172 net_local *lp = (net_local *) dev->priv;
173 unsigned long ioaddr = dev->base_addr;
174
175 lp->hacr |= HACR_INTRON;
176 hacr_write(ioaddr, lp->hacr);
177} /* wv_ints_on */
178
179/******************* MODEM MANAGEMENT SUBROUTINES *******************/
180/*
181 * Useful subroutines to manage the modem of the WaveLAN
182 */
183
184/*------------------------------------------------------------------*/
185/*
186 * Read the Parameter Storage Area from the WaveLAN card's memory
187 */
188/*
189 * Read bytes from the PSA.
190 */
191static void psa_read(unsigned long ioaddr, u16 hacr, int o, /* offset in PSA */
192 u8 * b, /* buffer to fill */
193 int n)
194{ /* size to read */
195 wv_16_off(ioaddr, hacr);
196
197 while (n-- > 0) {
198 outw(o, PIOR2(ioaddr));
199 o++;
200 *b++ = inb(PIOP2(ioaddr));
201 }
202
203 wv_16_on(ioaddr, hacr);
204} /* psa_read */
205
206/*------------------------------------------------------------------*/
207/*
208 * Write the Parameter Storage Area to the WaveLAN card's memory.
209 */
210static void psa_write(unsigned long ioaddr, u16 hacr, int o, /* Offset in PSA */
211 u8 * b, /* Buffer in memory */
212 int n)
213{ /* Length of buffer */
214 int count = 0;
215
216 wv_16_off(ioaddr, hacr);
217
218 while (n-- > 0) {
219 outw(o, PIOR2(ioaddr));
220 o++;
221
222 outb(*b, PIOP2(ioaddr));
223 b++;
224
225 /* Wait for the memory to finish its write cycle */
226 count = 0;
227 while ((count++ < 100) &&
228 (hasr_read(ioaddr) & HASR_PSA_BUSY)) mdelay(1);
229 }
230
231 wv_16_on(ioaddr, hacr);
232} /* psa_write */
233
234#ifdef SET_PSA_CRC
235/*------------------------------------------------------------------*/
236/*
237 * Calculate the PSA CRC
238 * Thanks to Valster, Nico <NVALSTER@wcnd.nl.lucent.com> for the code
239 * NOTE: By specifying a length including the CRC position the
240 * returned value should be zero. (i.e. a correct checksum in the PSA)
241 *
242 * The Windows drivers don't use the CRC, but the AP and the PtP tool
243 * depend on it.
244 */
245static inline u16 psa_crc(u8 * psa, /* The PSA */
246 int size)
247{ /* Number of short for CRC */
248 int byte_cnt; /* Loop on the PSA */
249 u16 crc_bytes = 0; /* Data in the PSA */
250 int bit_cnt; /* Loop on the bits of the short */
251
252 for (byte_cnt = 0; byte_cnt < size; byte_cnt++) {
253 crc_bytes ^= psa[byte_cnt]; /* Its an xor */
254
255 for (bit_cnt = 1; bit_cnt < 9; bit_cnt++) {
256 if (crc_bytes & 0x0001)
257 crc_bytes = (crc_bytes >> 1) ^ 0xA001;
258 else
259 crc_bytes >>= 1;
260 }
261 }
262
263 return crc_bytes;
264} /* psa_crc */
265#endif /* SET_PSA_CRC */
266
267/*------------------------------------------------------------------*/
268/*
269 * update the checksum field in the Wavelan's PSA
270 */
271static void update_psa_checksum(struct net_device * dev, unsigned long ioaddr, u16 hacr)
272{
273#ifdef SET_PSA_CRC
274 psa_t psa;
275 u16 crc;
276
277 /* read the parameter storage area */
278 psa_read(ioaddr, hacr, 0, (unsigned char *) &psa, sizeof(psa));
279
280 /* update the checksum */
281 crc = psa_crc((unsigned char *) &psa,
282 sizeof(psa) - sizeof(psa.psa_crc[0]) -
283 sizeof(psa.psa_crc[1])
284 - sizeof(psa.psa_crc_status));
285
286 psa.psa_crc[0] = crc & 0xFF;
287 psa.psa_crc[1] = (crc & 0xFF00) >> 8;
288
289 /* Write it ! */
290 psa_write(ioaddr, hacr, (char *) &psa.psa_crc - (char *) &psa,
291 (unsigned char *) &psa.psa_crc, 2);
292
293#ifdef DEBUG_IOCTL_INFO
294 printk(KERN_DEBUG "%s: update_psa_checksum(): crc = 0x%02x%02x\n",
295 dev->name, psa.psa_crc[0], psa.psa_crc[1]);
296
297 /* Check again (luxury !) */
298 crc = psa_crc((unsigned char *) &psa,
299 sizeof(psa) - sizeof(psa.psa_crc_status));
300
301 if (crc != 0)
302 printk(KERN_WARNING
303 "%s: update_psa_checksum(): CRC does not agree with PSA data (even after recalculating)\n",
304 dev->name);
305#endif /* DEBUG_IOCTL_INFO */
306#endif /* SET_PSA_CRC */
307} /* update_psa_checksum */
308
309/*------------------------------------------------------------------*/
310/*
311 * Write 1 byte to the MMC.
312 */
313static inline void mmc_out(unsigned long ioaddr, u16 o, u8 d)
314{
315 int count = 0;
316
317 /* Wait for MMC to go idle */
318 while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY))
319 udelay(10);
320
321 outw((u16) (((u16) d << 8) | (o << 1) | 1), MMCR(ioaddr));
322}
323
324/*------------------------------------------------------------------*/
325/*
326 * Routine to write bytes to the Modem Management Controller.
327 * We start at the end because it is the way it should be!
328 */
329static inline void mmc_write(unsigned long ioaddr, u8 o, u8 * b, int n)
330{
331 o += n;
332 b += n;
333
334 while (n-- > 0)
335 mmc_out(ioaddr, --o, *(--b));
336} /* mmc_write */
337
338/*------------------------------------------------------------------*/
339/*
340 * Read a byte from the MMC.
341 * Optimised version for 1 byte, avoid using memory.
342 */
343static inline u8 mmc_in(unsigned long ioaddr, u16 o)
344{
345 int count = 0;
346
347 while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY))
348 udelay(10);
349 outw(o << 1, MMCR(ioaddr));
350
351 while ((count++ < 100) && (inw(HASR(ioaddr)) & HASR_MMC_BUSY))
352 udelay(10);
353 return (u8) (inw(MMCR(ioaddr)) >> 8);
354}
355
356/*------------------------------------------------------------------*/
357/*
358 * Routine to read bytes from the Modem Management Controller.
359 * The implementation is complicated by a lack of address lines,
360 * which prevents decoding of the low-order bit.
361 * (code has just been moved in the above function)
362 * We start at the end because it is the way it should be!
363 */
364static inline void mmc_read(unsigned long ioaddr, u8 o, u8 * b, int n)
365{
366 o += n;
367 b += n;
368
369 while (n-- > 0)
370 *(--b) = mmc_in(ioaddr, --o);
371} /* mmc_read */
372
373/*------------------------------------------------------------------*/
374/*
375 * Get the type of encryption available.
376 */
377static inline int mmc_encr(unsigned long ioaddr)
378{ /* I/O port of the card */
379 int temp;
380
381 temp = mmc_in(ioaddr, mmroff(0, mmr_des_avail));
382 if ((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES))
383 return 0;
384 else
385 return temp;
386}
387
388/*------------------------------------------------------------------*/
389/*
390 * Wait for the frequency EEPROM to complete a command.
391 * I hope this one will be optimally inlined.
392 */
393static inline void fee_wait(unsigned long ioaddr, /* I/O port of the card */
394 int delay, /* Base delay to wait for */
395 int number)
396{ /* Number of time to wait */
397 int count = 0; /* Wait only a limited time */
398
399 while ((count++ < number) &&
400 (mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
401 MMR_FEE_STATUS_BUSY)) udelay(delay);
402}
403
404/*------------------------------------------------------------------*/
405/*
406 * Read bytes from the Frequency EEPROM (frequency select cards).
407 */
408static void fee_read(unsigned long ioaddr, /* I/O port of the card */
409 u16 o, /* destination offset */
410 u16 * b, /* data buffer */
411 int n)
412{ /* number of registers */
413 b += n; /* Position at the end of the area */
414
415 /* Write the address */
416 mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n - 1);
417
418 /* Loop on all buffer */
419 while (n-- > 0) {
420 /* Write the read command */
421 mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
422 MMW_FEE_CTRL_READ);
423
424 /* Wait until EEPROM is ready (should be quick). */
425 fee_wait(ioaddr, 10, 100);
426
427 /* Read the value. */
428 *--b = ((mmc_in(ioaddr, mmroff(0, mmr_fee_data_h)) << 8) |
429 mmc_in(ioaddr, mmroff(0, mmr_fee_data_l)));
430 }
431}
432
433#ifdef WIRELESS_EXT /* if the wireless extension exists in the kernel */
434
435/*------------------------------------------------------------------*/
436/*
437 * Write bytes from the Frequency EEPROM (frequency select cards).
438 * This is a bit complicated, because the frequency EEPROM has to
439 * be unprotected and the write enabled.
440 * Jean II
441 */
442static void fee_write(unsigned long ioaddr, /* I/O port of the card */
443 u16 o, /* destination offset */
444 u16 * b, /* data buffer */
445 int n)
446{ /* number of registers */
447 b += n; /* Position at the end of the area. */
448
449#ifdef EEPROM_IS_PROTECTED /* disabled */
450#ifdef DOESNT_SEEM_TO_WORK /* disabled */
451 /* Ask to read the protected register */
452 mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRREAD);
453
454 fee_wait(ioaddr, 10, 100);
455
456 /* Read the protected register. */
457 printk("Protected 2: %02X-%02X\n",
458 mmc_in(ioaddr, mmroff(0, mmr_fee_data_h)),
459 mmc_in(ioaddr, mmroff(0, mmr_fee_data_l)));
460#endif /* DOESNT_SEEM_TO_WORK */
461
462 /* Enable protected register. */
463 mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
464 mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PREN);
465
466 fee_wait(ioaddr, 10, 100);
467
468 /* Unprotect area. */
469 mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n);
470 mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
471#ifdef DOESNT_SEEM_TO_WORK /* disabled */
472 /* or use: */
473 mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRCLEAR);
474#endif /* DOESNT_SEEM_TO_WORK */
475
476 fee_wait(ioaddr, 10, 100);
477#endif /* EEPROM_IS_PROTECTED */
478
479 /* Write enable. */
480 mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
481 mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WREN);
482
483 fee_wait(ioaddr, 10, 100);
484
485 /* Write the EEPROM address. */
486 mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), o + n - 1);
487
488 /* Loop on all buffer */
489 while (n-- > 0) {
490 /* Write the value. */
491 mmc_out(ioaddr, mmwoff(0, mmw_fee_data_h), (*--b) >> 8);
492 mmc_out(ioaddr, mmwoff(0, mmw_fee_data_l), *b & 0xFF);
493
494 /* Write the write command. */
495 mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
496 MMW_FEE_CTRL_WRITE);
497
498 /* WaveLAN documentation says to wait at least 10 ms for EEBUSY = 0 */
499 mdelay(10);
500 fee_wait(ioaddr, 10, 100);
501 }
502
503 /* Write disable. */
504 mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_DS);
505 mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WDS);
506
507 fee_wait(ioaddr, 10, 100);
508
509#ifdef EEPROM_IS_PROTECTED /* disabled */
510 /* Reprotect EEPROM. */
511 mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x00);
512 mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
513
514 fee_wait(ioaddr, 10, 100);
515#endif /* EEPROM_IS_PROTECTED */
516}
517#endif /* WIRELESS_EXT */
518
519/************************ I82586 SUBROUTINES *************************/
520/*
521 * Useful subroutines to manage the Ethernet controller
522 */
523
524/*------------------------------------------------------------------*/
525/*
526 * Read bytes from the on-board RAM.
527 * Why does inlining this function make it fail?
528 */
529static /*inline */ void obram_read(unsigned long ioaddr,
530 u16 o, u8 * b, int n)
531{
532 outw(o, PIOR1(ioaddr));
533 insw(PIOP1(ioaddr), (unsigned short *) b, (n + 1) >> 1);
534}
535
536/*------------------------------------------------------------------*/
537/*
538 * Write bytes to the on-board RAM.
539 */
540static inline void obram_write(unsigned long ioaddr, u16 o, u8 * b, int n)
541{
542 outw(o, PIOR1(ioaddr));
543 outsw(PIOP1(ioaddr), (unsigned short *) b, (n + 1) >> 1);
544}
545
546/*------------------------------------------------------------------*/
547/*
548 * Acknowledge the reading of the status issued by the i82586.
549 */
550static void wv_ack(struct net_device * dev)
551{
552 net_local *lp = (net_local *) dev->priv;
553 unsigned long ioaddr = dev->base_addr;
554 u16 scb_cs;
555 int i;
556
557 obram_read(ioaddr, scboff(OFFSET_SCB, scb_status),
558 (unsigned char *) &scb_cs, sizeof(scb_cs));
559 scb_cs &= SCB_ST_INT;
560
561 if (scb_cs == 0)
562 return;
563
564 obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
565 (unsigned char *) &scb_cs, sizeof(scb_cs));
566
567 set_chan_attn(ioaddr, lp->hacr);
568
569 for (i = 1000; i > 0; i--) {
570 obram_read(ioaddr, scboff(OFFSET_SCB, scb_command),
571 (unsigned char *) &scb_cs, sizeof(scb_cs));
572 if (scb_cs == 0)
573 break;
574
575 udelay(10);
576 }
577 udelay(100);
578
579#ifdef DEBUG_CONFIG_ERROR
580 if (i <= 0)
581 printk(KERN_INFO
582 "%s: wv_ack(): board not accepting command.\n",
583 dev->name);
584#endif
585}
586
587/*------------------------------------------------------------------*/
588/*
589 * Set channel attention bit and busy wait until command has
590 * completed, then acknowledge completion of the command.
591 */
592static inline int wv_synchronous_cmd(struct net_device * dev, const char *str)
593{
594 net_local *lp = (net_local *) dev->priv;
595 unsigned long ioaddr = dev->base_addr;
596 u16 scb_cmd;
597 ach_t cb;
598 int i;
599
600 scb_cmd = SCB_CMD_CUC & SCB_CMD_CUC_GO;
601 obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
602 (unsigned char *) &scb_cmd, sizeof(scb_cmd));
603
604 set_chan_attn(ioaddr, lp->hacr);
605
606 for (i = 1000; i > 0; i--) {
607 obram_read(ioaddr, OFFSET_CU, (unsigned char *) &cb,
608 sizeof(cb));
609 if (cb.ac_status & AC_SFLD_C)
610 break;
611
612 udelay(10);
613 }
614 udelay(100);
615
616 if (i <= 0 || !(cb.ac_status & AC_SFLD_OK)) {
617#ifdef DEBUG_CONFIG_ERROR
618 printk(KERN_INFO "%s: %s failed; status = 0x%x\n",
619 dev->name, str, cb.ac_status);
620#endif
621#ifdef DEBUG_I82586_SHOW
622 wv_scb_show(ioaddr);
623#endif
624 return -1;
625 }
626
627 /* Ack the status */
628 wv_ack(dev);
629
630 return 0;
631}
632
633/*------------------------------------------------------------------*/
634/*
635 * Configuration commands completion interrupt.
636 * Check if done, and if OK.
637 */
638static inline int
639wv_config_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp)
640{
641 unsigned short mcs_addr;
642 unsigned short status;
643 int ret;
644
645#ifdef DEBUG_INTERRUPT_TRACE
646 printk(KERN_DEBUG "%s: ->wv_config_complete()\n", dev->name);
647#endif
648
649 mcs_addr = lp->tx_first_in_use + sizeof(ac_tx_t) + sizeof(ac_nop_t)
650 + sizeof(tbd_t) + sizeof(ac_cfg_t) + sizeof(ac_ias_t);
651
652 /* Read the status of the last command (set mc list). */
653 obram_read(ioaddr, acoff(mcs_addr, ac_status),
654 (unsigned char *) &status, sizeof(status));
655
656 /* If not completed -> exit */
657 if ((status & AC_SFLD_C) == 0)
658 ret = 0; /* Not ready to be scrapped */
659 else {
660#ifdef DEBUG_CONFIG_ERROR
661 unsigned short cfg_addr;
662 unsigned short ias_addr;
663
664 /* Check mc_config command */
665 if ((status & AC_SFLD_OK) != AC_SFLD_OK)
666 printk(KERN_INFO
667 "%s: wv_config_complete(): set_multicast_address failed; status = 0x%x\n",
668 dev->name, status);
669
670 /* check ia-config command */
671 ias_addr = mcs_addr - sizeof(ac_ias_t);
672 obram_read(ioaddr, acoff(ias_addr, ac_status),
673 (unsigned char *) &status, sizeof(status));
674 if ((status & AC_SFLD_OK) != AC_SFLD_OK)
675 printk(KERN_INFO
676 "%s: wv_config_complete(): set_MAC_address failed; status = 0x%x\n",
677 dev->name, status);
678
679 /* Check config command. */
680 cfg_addr = ias_addr - sizeof(ac_cfg_t);
681 obram_read(ioaddr, acoff(cfg_addr, ac_status),
682 (unsigned char *) &status, sizeof(status));
683 if ((status & AC_SFLD_OK) != AC_SFLD_OK)
684 printk(KERN_INFO
685 "%s: wv_config_complete(): configure failed; status = 0x%x\n",
686 dev->name, status);
687#endif /* DEBUG_CONFIG_ERROR */
688
689 ret = 1; /* Ready to be scrapped */
690 }
691
692#ifdef DEBUG_INTERRUPT_TRACE
693 printk(KERN_DEBUG "%s: <-wv_config_complete() - %d\n", dev->name,
694 ret);
695#endif
696 return ret;
697}
698
699/*------------------------------------------------------------------*/
700/*
701 * Command completion interrupt.
702 * Reclaim as many freed tx buffers as we can.
703 * (called in wavelan_interrupt()).
704 * Note : the spinlock is already grabbed for us.
705 */
706static int wv_complete(struct net_device * dev, unsigned long ioaddr, net_local * lp)
707{
708 int nreaped = 0;
709
710#ifdef DEBUG_INTERRUPT_TRACE
711 printk(KERN_DEBUG "%s: ->wv_complete()\n", dev->name);
712#endif
713
714 /* Loop on all the transmit buffers */
715 while (lp->tx_first_in_use != I82586NULL) {
716 unsigned short tx_status;
717
718 /* Read the first transmit buffer */
719 obram_read(ioaddr, acoff(lp->tx_first_in_use, ac_status),
720 (unsigned char *) &tx_status,
721 sizeof(tx_status));
722
723 /* If not completed -> exit */
724 if ((tx_status & AC_SFLD_C) == 0)
725 break;
726
727 /* Hack for reconfiguration */
728 if (tx_status == 0xFFFF)
729 if (!wv_config_complete(dev, ioaddr, lp))
730 break; /* Not completed */
731
732 /* We now remove this buffer */
733 nreaped++;
734 --lp->tx_n_in_use;
735
736/*
737if (lp->tx_n_in_use > 0)
738 printk("%c", "0123456789abcdefghijk"[lp->tx_n_in_use]);
739*/
740
741 /* Was it the last one? */
742 if (lp->tx_n_in_use <= 0)
743 lp->tx_first_in_use = I82586NULL;
744 else {
745 /* Next one in the chain */
746 lp->tx_first_in_use += TXBLOCKZ;
747 if (lp->tx_first_in_use >=
748 OFFSET_CU +
749 NTXBLOCKS * TXBLOCKZ) lp->tx_first_in_use -=
750 NTXBLOCKS * TXBLOCKZ;
751 }
752
753 /* Hack for reconfiguration */
754 if (tx_status == 0xFFFF)
755 continue;
756
757 /* Now, check status of the finished command */
758 if (tx_status & AC_SFLD_OK) {
759 int ncollisions;
760
761 lp->stats.tx_packets++;
762 ncollisions = tx_status & AC_SFLD_MAXCOL;
763 lp->stats.collisions += ncollisions;
764#ifdef DEBUG_TX_INFO
765 if (ncollisions > 0)
766 printk(KERN_DEBUG
767 "%s: wv_complete(): tx completed after %d collisions.\n",
768 dev->name, ncollisions);
769#endif
770 } else {
771 lp->stats.tx_errors++;
772 if (tx_status & AC_SFLD_S10) {
773 lp->stats.tx_carrier_errors++;
774#ifdef DEBUG_TX_FAIL
775 printk(KERN_DEBUG
776 "%s: wv_complete(): tx error: no CS.\n",
777 dev->name);
778#endif
779 }
780 if (tx_status & AC_SFLD_S9) {
781 lp->stats.tx_carrier_errors++;
782#ifdef DEBUG_TX_FAIL
783 printk(KERN_DEBUG
784 "%s: wv_complete(): tx error: lost CTS.\n",
785 dev->name);
786#endif
787 }
788 if (tx_status & AC_SFLD_S8) {
789 lp->stats.tx_fifo_errors++;
790#ifdef DEBUG_TX_FAIL
791 printk(KERN_DEBUG
792 "%s: wv_complete(): tx error: slow DMA.\n",
793 dev->name);
794#endif
795 }
796 if (tx_status & AC_SFLD_S6) {
797 lp->stats.tx_heartbeat_errors++;
798#ifdef DEBUG_TX_FAIL
799 printk(KERN_DEBUG
800 "%s: wv_complete(): tx error: heart beat.\n",
801 dev->name);
802#endif
803 }
804 if (tx_status & AC_SFLD_S5) {
805 lp->stats.tx_aborted_errors++;
806#ifdef DEBUG_TX_FAIL
807 printk(KERN_DEBUG
808 "%s: wv_complete(): tx error: too many collisions.\n",
809 dev->name);
810#endif
811 }
812 }
813
814#ifdef DEBUG_TX_INFO
815 printk(KERN_DEBUG
816 "%s: wv_complete(): tx completed, tx_status 0x%04x\n",
817 dev->name, tx_status);
818#endif
819 }
820
821#ifdef DEBUG_INTERRUPT_INFO
822 if (nreaped > 1)
823 printk(KERN_DEBUG "%s: wv_complete(): reaped %d\n",
824 dev->name, nreaped);
825#endif
826
827 /*
828 * Inform upper layers.
829 */
830 if (lp->tx_n_in_use < NTXBLOCKS - 1) {
831 netif_wake_queue(dev);
832 }
833#ifdef DEBUG_INTERRUPT_TRACE
834 printk(KERN_DEBUG "%s: <-wv_complete()\n", dev->name);
835#endif
836 return nreaped;
837}
838
839/*------------------------------------------------------------------*/
840/*
841 * Reconfigure the i82586, or at least ask for it.
842 * Because wv_82586_config uses a transmission buffer, we must do it
843 * when we are sure that there is one left, so we do it now
844 * or in wavelan_packet_xmit() (I can't find any better place,
845 * wavelan_interrupt is not an option), so you may experience
846 * delays sometimes.
847 */
848static inline void wv_82586_reconfig(struct net_device * dev)
849{
850 net_local *lp = (net_local *) dev->priv;
851 unsigned long flags;
852
853 /* Arm the flag, will be cleard in wv_82586_config() */
854 lp->reconfig_82586 = 1;
855
856 /* Check if we can do it now ! */
857 if((netif_running(dev)) && !(netif_queue_stopped(dev))) {
858 spin_lock_irqsave(&lp->spinlock, flags);
859 /* May fail */
860 wv_82586_config(dev);
861 spin_unlock_irqrestore(&lp->spinlock, flags);
862 }
863 else {
864#ifdef DEBUG_CONFIG_INFO
865 printk(KERN_DEBUG
866 "%s: wv_82586_reconfig(): delayed (state = %lX)\n",
867 dev->name, dev->state);
868#endif
869 }
870}
871
872/********************* DEBUG & INFO SUBROUTINES *********************/
873/*
874 * This routine is used in the code to show information for debugging.
875 * Most of the time, it dumps the contents of hardware structures.
876 */
877
878#ifdef DEBUG_PSA_SHOW
879/*------------------------------------------------------------------*/
880/*
881 * Print the formatted contents of the Parameter Storage Area.
882 */
883static void wv_psa_show(psa_t * p)
884{
885 printk(KERN_DEBUG "##### WaveLAN PSA contents: #####\n");
886 printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n",
887 p->psa_io_base_addr_1,
888 p->psa_io_base_addr_2,
889 p->psa_io_base_addr_3, p->psa_io_base_addr_4);
890 printk(KERN_DEBUG "psa_rem_boot_addr_1: 0x%02X %02X %02X\n",
891 p->psa_rem_boot_addr_1,
892 p->psa_rem_boot_addr_2, p->psa_rem_boot_addr_3);
893 printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params);
894 printk("psa_int_req_no: %d\n", p->psa_int_req_no);
895#ifdef DEBUG_SHOW_UNUSED
896 printk(KERN_DEBUG
897 "psa_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
898 p->psa_unused0[0], p->psa_unused0[1], p->psa_unused0[2],
899 p->psa_unused0[3], p->psa_unused0[4], p->psa_unused0[5],
900 p->psa_unused0[6]);
901#endif /* DEBUG_SHOW_UNUSED */
902 printk(KERN_DEBUG
903 "psa_univ_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x\n",
904 p->psa_univ_mac_addr[0], p->psa_univ_mac_addr[1],
905 p->psa_univ_mac_addr[2], p->psa_univ_mac_addr[3],
906 p->psa_univ_mac_addr[4], p->psa_univ_mac_addr[5]);
907 printk(KERN_DEBUG
908 "psa_local_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x\n",
909 p->psa_local_mac_addr[0], p->psa_local_mac_addr[1],
910 p->psa_local_mac_addr[2], p->psa_local_mac_addr[3],
911 p->psa_local_mac_addr[4], p->psa_local_mac_addr[5]);
912 printk(KERN_DEBUG "psa_univ_local_sel: %d, ",
913 p->psa_univ_local_sel);
914 printk("psa_comp_number: %d, ", p->psa_comp_number);
915 printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set);
916 printk(KERN_DEBUG "psa_feature_select/decay_prm: 0x%02x, ",
917 p->psa_feature_select);
918 printk("psa_subband/decay_update_prm: %d\n", p->psa_subband);
919 printk(KERN_DEBUG "psa_quality_thr: 0x%02x, ", p->psa_quality_thr);
920 printk("psa_mod_delay: 0x%02x\n", p->psa_mod_delay);
921 printk(KERN_DEBUG "psa_nwid: 0x%02x%02x, ", p->psa_nwid[0],
922 p->psa_nwid[1]);
923 printk("psa_nwid_select: %d\n", p->psa_nwid_select);
924 printk(KERN_DEBUG "psa_encryption_select: %d, ",
925 p->psa_encryption_select);
926 printk
927 ("psa_encryption_key[]: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
928 p->psa_encryption_key[0], p->psa_encryption_key[1],
929 p->psa_encryption_key[2], p->psa_encryption_key[3],
930 p->psa_encryption_key[4], p->psa_encryption_key[5],
931 p->psa_encryption_key[6], p->psa_encryption_key[7]);
932 printk(KERN_DEBUG "psa_databus_width: %d\n", p->psa_databus_width);
933 printk(KERN_DEBUG "psa_call_code/auto_squelch: 0x%02x, ",
934 p->psa_call_code[0]);
935 printk
936 ("psa_call_code[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
937 p->psa_call_code[0], p->psa_call_code[1], p->psa_call_code[2],
938 p->psa_call_code[3], p->psa_call_code[4], p->psa_call_code[5],
939 p->psa_call_code[6], p->psa_call_code[7]);
940#ifdef DEBUG_SHOW_UNUSED
941 printk(KERN_DEBUG "psa_reserved[]: %02X:%02X:%02X:%02X\n",
942 p->psa_reserved[0],
943 p->psa_reserved[1], p->psa_reserved[2], p->psa_reserved[3]);
944#endif /* DEBUG_SHOW_UNUSED */
945 printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status);
946 printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]);
947 printk("psa_crc_status: 0x%02x\n", p->psa_crc_status);
948} /* wv_psa_show */
949#endif /* DEBUG_PSA_SHOW */
950
951#ifdef DEBUG_MMC_SHOW
952/*------------------------------------------------------------------*/
953/*
954 * Print the formatted status of the Modem Management Controller.
955 * This function needs to be completed.
956 */
957static void wv_mmc_show(struct net_device * dev)
958{
959 unsigned long ioaddr = dev->base_addr;
960 net_local *lp = (net_local *) dev->priv;
961 mmr_t m;
962
963 /* Basic check */
964 if (hasr_read(ioaddr) & HASR_NO_CLK) {
965 printk(KERN_WARNING
966 "%s: wv_mmc_show: modem not connected\n",
967 dev->name);
968 return;
969 }
970
971 /* Read the mmc */
972 mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1);
973 mmc_read(ioaddr, 0, (u8 *) & m, sizeof(m));
974 mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
975
976#ifdef WIRELESS_EXT /* if wireless extension exists in the kernel */
977 /* Don't forget to update statistics */
978 lp->wstats.discard.nwid +=
979 (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
980#endif /* WIRELESS_EXT */
981
982 printk(KERN_DEBUG "##### WaveLAN modem status registers: #####\n");
983#ifdef DEBUG_SHOW_UNUSED
984 printk(KERN_DEBUG
985 "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
986 m.mmr_unused0[0], m.mmr_unused0[1], m.mmr_unused0[2],
987 m.mmr_unused0[3], m.mmr_unused0[4], m.mmr_unused0[5],
988 m.mmr_unused0[6], m.mmr_unused0[7]);
989#endif /* DEBUG_SHOW_UNUSED */
990 printk(KERN_DEBUG "Encryption algorithm: %02X - Status: %02X\n",
991 m.mmr_des_avail, m.mmr_des_status);
992#ifdef DEBUG_SHOW_UNUSED
993 printk(KERN_DEBUG "mmc_unused1[]: %02X:%02X:%02X:%02X:%02X\n",
994 m.mmr_unused1[0],
995 m.mmr_unused1[1],
996 m.mmr_unused1[2], m.mmr_unused1[3], m.mmr_unused1[4]);
997#endif /* DEBUG_SHOW_UNUSED */
998 printk(KERN_DEBUG "dce_status: 0x%x [%s%s%s%s]\n",
999 m.mmr_dce_status,
1000 (m.
1001 mmr_dce_status & MMR_DCE_STATUS_RX_BUSY) ?
1002 "energy detected," : "",
1003 (m.
1004 mmr_dce_status & MMR_DCE_STATUS_LOOPT_IND) ?
1005 "loop test indicated," : "",
1006 (m.
1007 mmr_dce_status & MMR_DCE_STATUS_TX_BUSY) ?
1008 "transmitter on," : "",
1009 (m.
1010 mmr_dce_status & MMR_DCE_STATUS_JBR_EXPIRED) ?
1011 "jabber timer expired," : "");
1012 printk(KERN_DEBUG "Dsp ID: %02X\n", m.mmr_dsp_id);
1013#ifdef DEBUG_SHOW_UNUSED
1014 printk(KERN_DEBUG "mmc_unused2[]: %02X:%02X\n",
1015 m.mmr_unused2[0], m.mmr_unused2[1]);
1016#endif /* DEBUG_SHOW_UNUSED */
1017 printk(KERN_DEBUG "# correct_nwid: %d, # wrong_nwid: %d\n",
1018 (m.mmr_correct_nwid_h << 8) | m.mmr_correct_nwid_l,
1019 (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l);
1020 printk(KERN_DEBUG "thr_pre_set: 0x%x [current signal %s]\n",
1021 m.mmr_thr_pre_set & MMR_THR_PRE_SET,
1022 (m.
1023 mmr_thr_pre_set & MMR_THR_PRE_SET_CUR) ? "above" :
1024 "below");
1025 printk(KERN_DEBUG "signal_lvl: %d [%s], ",
1026 m.mmr_signal_lvl & MMR_SIGNAL_LVL,
1027 (m.
1028 mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) ? "new msg" :
1029 "no new msg");
1030 printk("silence_lvl: %d [%s], ",
1031 m.mmr_silence_lvl & MMR_SILENCE_LVL,
1032 (m.
1033 mmr_silence_lvl & MMR_SILENCE_LVL_VALID) ? "update done" :
1034 "no new update");
1035 printk("sgnl_qual: 0x%x [%s]\n", m.mmr_sgnl_qual & MMR_SGNL_QUAL,
1036 (m.
1037 mmr_sgnl_qual & MMR_SGNL_QUAL_ANT) ? "Antenna 1" :
1038 "Antenna 0");
1039#ifdef DEBUG_SHOW_UNUSED
1040 printk(KERN_DEBUG "netw_id_l: %x\n", m.mmr_netw_id_l);
1041#endif /* DEBUG_SHOW_UNUSED */
1042} /* wv_mmc_show */
1043#endif /* DEBUG_MMC_SHOW */
1044
1045#ifdef DEBUG_I82586_SHOW
1046/*------------------------------------------------------------------*/
1047/*
1048 * Print the last block of the i82586 memory.
1049 */
1050static void wv_scb_show(unsigned long ioaddr)
1051{
1052 scb_t scb;
1053
1054 obram_read(ioaddr, OFFSET_SCB, (unsigned char *) &scb,
1055 sizeof(scb));
1056
1057 printk(KERN_DEBUG "##### WaveLAN system control block: #####\n");
1058
1059 printk(KERN_DEBUG "status: ");
1060 printk("stat 0x%x[%s%s%s%s] ",
1061 (scb.
1062 scb_status & (SCB_ST_CX | SCB_ST_FR | SCB_ST_CNA |
1063 SCB_ST_RNR)) >> 12,
1064 (scb.
1065 scb_status & SCB_ST_CX) ? "command completion interrupt," :
1066 "", (scb.scb_status & SCB_ST_FR) ? "frame received," : "",
1067 (scb.
1068 scb_status & SCB_ST_CNA) ? "command unit not active," : "",
1069 (scb.
1070 scb_status & SCB_ST_RNR) ? "receiving unit not ready," :
1071 "");
1072 printk("cus 0x%x[%s%s%s] ", (scb.scb_status & SCB_ST_CUS) >> 8,
1073 ((scb.scb_status & SCB_ST_CUS) ==
1074 SCB_ST_CUS_IDLE) ? "idle" : "",
1075 ((scb.scb_status & SCB_ST_CUS) ==
1076 SCB_ST_CUS_SUSP) ? "suspended" : "",
1077 ((scb.scb_status & SCB_ST_CUS) ==
1078 SCB_ST_CUS_ACTV) ? "active" : "");
1079 printk("rus 0x%x[%s%s%s%s]\n", (scb.scb_status & SCB_ST_RUS) >> 4,
1080 ((scb.scb_status & SCB_ST_RUS) ==
1081 SCB_ST_RUS_IDLE) ? "idle" : "",
1082 ((scb.scb_status & SCB_ST_RUS) ==
1083 SCB_ST_RUS_SUSP) ? "suspended" : "",
1084 ((scb.scb_status & SCB_ST_RUS) ==
1085 SCB_ST_RUS_NRES) ? "no resources" : "",
1086 ((scb.scb_status & SCB_ST_RUS) ==
1087 SCB_ST_RUS_RDY) ? "ready" : "");
1088
1089 printk(KERN_DEBUG "command: ");
1090 printk("ack 0x%x[%s%s%s%s] ",
1091 (scb.
1092 scb_command & (SCB_CMD_ACK_CX | SCB_CMD_ACK_FR |
1093 SCB_CMD_ACK_CNA | SCB_CMD_ACK_RNR)) >> 12,
1094 (scb.
1095 scb_command & SCB_CMD_ACK_CX) ? "ack cmd completion," : "",
1096 (scb.
1097 scb_command & SCB_CMD_ACK_FR) ? "ack frame received," : "",
1098 (scb.
1099 scb_command & SCB_CMD_ACK_CNA) ? "ack CU not active," : "",
1100 (scb.
1101 scb_command & SCB_CMD_ACK_RNR) ? "ack RU not ready," : "");
1102 printk("cuc 0x%x[%s%s%s%s%s] ",
1103 (scb.scb_command & SCB_CMD_CUC) >> 8,
1104 ((scb.scb_command & SCB_CMD_CUC) ==
1105 SCB_CMD_CUC_NOP) ? "nop" : "",
1106 ((scb.scb_command & SCB_CMD_CUC) ==
1107 SCB_CMD_CUC_GO) ? "start cbl_offset" : "",
1108 ((scb.scb_command & SCB_CMD_CUC) ==
1109 SCB_CMD_CUC_RES) ? "resume execution" : "",
1110 ((scb.scb_command & SCB_CMD_CUC) ==
1111 SCB_CMD_CUC_SUS) ? "suspend execution" : "",
1112 ((scb.scb_command & SCB_CMD_CUC) ==
1113 SCB_CMD_CUC_ABT) ? "abort execution" : "");
1114 printk("ruc 0x%x[%s%s%s%s%s]\n",
1115 (scb.scb_command & SCB_CMD_RUC) >> 4,
1116 ((scb.scb_command & SCB_CMD_RUC) ==
1117 SCB_CMD_RUC_NOP) ? "nop" : "",
1118 ((scb.scb_command & SCB_CMD_RUC) ==
1119 SCB_CMD_RUC_GO) ? "start rfa_offset" : "",
1120 ((scb.scb_command & SCB_CMD_RUC) ==
1121 SCB_CMD_RUC_RES) ? "resume reception" : "",
1122 ((scb.scb_command & SCB_CMD_RUC) ==
1123 SCB_CMD_RUC_SUS) ? "suspend reception" : "",
1124 ((scb.scb_command & SCB_CMD_RUC) ==
1125 SCB_CMD_RUC_ABT) ? "abort reception" : "");
1126
1127 printk(KERN_DEBUG "cbl_offset 0x%x ", scb.scb_cbl_offset);
1128 printk("rfa_offset 0x%x\n", scb.scb_rfa_offset);
1129
1130 printk(KERN_DEBUG "crcerrs %d ", scb.scb_crcerrs);
1131 printk("alnerrs %d ", scb.scb_alnerrs);
1132 printk("rscerrs %d ", scb.scb_rscerrs);
1133 printk("ovrnerrs %d\n", scb.scb_ovrnerrs);
1134}
1135
1136/*------------------------------------------------------------------*/
1137/*
1138 * Print the formatted status of the i82586's receive unit.
1139 */
1140static void wv_ru_show(struct net_device * dev)
1141{
1142 /* net_local *lp = (net_local *) dev->priv; */
1143
1144 printk(KERN_DEBUG
1145 "##### WaveLAN i82586 receiver unit status: #####\n");
1146 printk(KERN_DEBUG "ru:");
1147 /*
1148 * Not implemented yet
1149 */
1150 printk("\n");
1151} /* wv_ru_show */
1152
1153/*------------------------------------------------------------------*/
1154/*
1155 * Display info about one control block of the i82586 memory.
1156 */
1157static void wv_cu_show_one(struct net_device * dev, net_local * lp, int i, u16 p)
1158{
1159 unsigned long ioaddr;
1160 ac_tx_t actx;
1161
1162 ioaddr = dev->base_addr;
1163
1164 printk("%d: 0x%x:", i, p);
1165
1166 obram_read(ioaddr, p, (unsigned char *) &actx, sizeof(actx));
1167 printk(" status=0x%x,", actx.tx_h.ac_status);
1168 printk(" command=0x%x,", actx.tx_h.ac_command);
1169
1170 /*
1171 {
1172 tbd_t tbd;
1173
1174 obram_read(ioaddr, actx.tx_tbd_offset, (unsigned char *)&tbd, sizeof(tbd));
1175 printk(" tbd_status=0x%x,", tbd.tbd_status);
1176 }
1177 */
1178
1179 printk("|");
1180}
1181
1182/*------------------------------------------------------------------*/
1183/*
1184 * Print status of the command unit of the i82586.
1185 */
1186static void wv_cu_show(struct net_device * dev)
1187{
1188 net_local *lp = (net_local *) dev->priv;
1189 unsigned int i;
1190 u16 p;
1191
1192 printk(KERN_DEBUG
1193 "##### WaveLAN i82586 command unit status: #####\n");
1194
1195 printk(KERN_DEBUG);
1196 for (i = 0, p = lp->tx_first_in_use; i < NTXBLOCKS; i++) {
1197 wv_cu_show_one(dev, lp, i, p);
1198
1199 p += TXBLOCKZ;
1200 if (p >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ)
1201 p -= NTXBLOCKS * TXBLOCKZ;
1202 }
1203 printk("\n");
1204}
1205#endif /* DEBUG_I82586_SHOW */
1206
1207#ifdef DEBUG_DEVICE_SHOW
1208/*------------------------------------------------------------------*/
1209/*
1210 * Print the formatted status of the WaveLAN PCMCIA device driver.
1211 */
1212static void wv_dev_show(struct net_device * dev)
1213{
1214 printk(KERN_DEBUG "dev:");
1215 printk(" state=%lX,", dev->state);
1216 printk(" trans_start=%ld,", dev->trans_start);
1217 printk(" flags=0x%x,", dev->flags);
1218 printk("\n");
1219} /* wv_dev_show */
1220
1221/*------------------------------------------------------------------*/
1222/*
1223 * Print the formatted status of the WaveLAN PCMCIA device driver's
1224 * private information.
1225 */
1226static void wv_local_show(struct net_device * dev)
1227{
1228 net_local *lp;
1229
1230 lp = (net_local *) dev->priv;
1231
1232 printk(KERN_DEBUG "local:");
1233 printk(" tx_n_in_use=%d,", lp->tx_n_in_use);
1234 printk(" hacr=0x%x,", lp->hacr);
1235 printk(" rx_head=0x%x,", lp->rx_head);
1236 printk(" rx_last=0x%x,", lp->rx_last);
1237 printk(" tx_first_free=0x%x,", lp->tx_first_free);
1238 printk(" tx_first_in_use=0x%x,", lp->tx_first_in_use);
1239 printk("\n");
1240} /* wv_local_show */
1241#endif /* DEBUG_DEVICE_SHOW */
1242
1243#if defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO)
1244/*------------------------------------------------------------------*/
1245/*
1246 * Dump packet header (and content if necessary) on the screen
1247 */
1248static inline void wv_packet_info(u8 * p, /* Packet to dump */
1249 int length, /* Length of the packet */
1250 char *msg1, /* Name of the device */
1251 char *msg2)
1252{ /* Name of the function */
1253 int i;
1254 int maxi;
1255
1256 printk(KERN_DEBUG
1257 "%s: %s(): dest %02X:%02X:%02X:%02X:%02X:%02X, length %d\n",
1258 msg1, msg2, p[0], p[1], p[2], p[3], p[4], p[5], length);
1259 printk(KERN_DEBUG
1260 "%s: %s(): src %02X:%02X:%02X:%02X:%02X:%02X, type 0x%02X%02X\n",
1261 msg1, msg2, p[6], p[7], p[8], p[9], p[10], p[11], p[12],
1262 p[13]);
1263
1264#ifdef DEBUG_PACKET_DUMP
1265
1266 printk(KERN_DEBUG "data=\"");
1267
1268 if ((maxi = length) > DEBUG_PACKET_DUMP)
1269 maxi = DEBUG_PACKET_DUMP;
1270 for (i = 14; i < maxi; i++)
1271 if (p[i] >= ' ' && p[i] <= '~')
1272 printk(" %c", p[i]);
1273 else
1274 printk("%02X", p[i]);
1275 if (maxi < length)
1276 printk("..");
1277 printk("\"\n");
1278 printk(KERN_DEBUG "\n");
1279#endif /* DEBUG_PACKET_DUMP */
1280}
1281#endif /* defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO) */
1282
1283/*------------------------------------------------------------------*/
1284/*
1285 * This is the information which is displayed by the driver at startup.
1286 * There are lots of flags for configuring it to your liking.
1287 */
1288static inline void wv_init_info(struct net_device * dev)
1289{
1290 short ioaddr = dev->base_addr;
1291 net_local *lp = (net_local *) dev->priv;
1292 psa_t psa;
1293 int i;
1294
1295 /* Read the parameter storage area */
1296 psa_read(ioaddr, lp->hacr, 0, (unsigned char *) &psa, sizeof(psa));
1297
1298#ifdef DEBUG_PSA_SHOW
1299 wv_psa_show(&psa);
1300#endif
1301#ifdef DEBUG_MMC_SHOW
1302 wv_mmc_show(dev);
1303#endif
1304#ifdef DEBUG_I82586_SHOW
1305 wv_cu_show(dev);
1306#endif
1307
1308#ifdef DEBUG_BASIC_SHOW
1309 /* Now, let's go for the basic stuff. */
1310 printk(KERN_NOTICE "%s: WaveLAN at %#x,", dev->name, ioaddr);
1311 for (i = 0; i < WAVELAN_ADDR_SIZE; i++)
1312 printk("%s%02X", (i == 0) ? " " : ":", dev->dev_addr[i]);
1313 printk(", IRQ %d", dev->irq);
1314
1315 /* Print current network ID. */
1316 if (psa.psa_nwid_select)
1317 printk(", nwid 0x%02X-%02X", psa.psa_nwid[0],
1318 psa.psa_nwid[1]);
1319 else
1320 printk(", nwid off");
1321
1322 /* If 2.00 card */
1323 if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
1324 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
1325 unsigned short freq;
1326
1327 /* Ask the EEPROM to read the frequency from the first area. */
1328 fee_read(ioaddr, 0x00, &freq, 1);
1329
1330 /* Print frequency */
1331 printk(", 2.00, %ld", (freq >> 6) + 2400L);
1332
1333 /* Hack! */
1334 if (freq & 0x20)
1335 printk(".5");
1336 } else {
1337 printk(", PC");
1338 switch (psa.psa_comp_number) {
1339 case PSA_COMP_PC_AT_915:
1340 case PSA_COMP_PC_AT_2400:
1341 printk("-AT");
1342 break;
1343 case PSA_COMP_PC_MC_915:
1344 case PSA_COMP_PC_MC_2400:
1345 printk("-MC");
1346 break;
1347 case PSA_COMP_PCMCIA_915:
1348 printk("MCIA");
1349 break;
1350 default:
1351 printk("?");
1352 }
1353 printk(", ");
1354 switch (psa.psa_subband) {
1355 case PSA_SUBBAND_915:
1356 printk("915");
1357 break;
1358 case PSA_SUBBAND_2425:
1359 printk("2425");
1360 break;
1361 case PSA_SUBBAND_2460:
1362 printk("2460");
1363 break;
1364 case PSA_SUBBAND_2484:
1365 printk("2484");
1366 break;
1367 case PSA_SUBBAND_2430_5:
1368 printk("2430.5");
1369 break;
1370 default:
1371 printk("?");
1372 }
1373 }
1374
1375 printk(" MHz\n");
1376#endif /* DEBUG_BASIC_SHOW */
1377
1378#ifdef DEBUG_VERSION_SHOW
1379 /* Print version information */
1380 printk(KERN_NOTICE "%s", version);
1381#endif
1382} /* wv_init_info */
1383
1384/********************* IOCTL, STATS & RECONFIG *********************/
1385/*
1386 * We found here routines that are called by Linux on different
1387 * occasions after the configuration and not for transmitting data
1388 * These may be called when the user use ifconfig, /proc/net/dev
1389 * or wireless extensions
1390 */
1391
1392/*------------------------------------------------------------------*/
1393/*
1394 * Get the current Ethernet statistics. This may be called with the
1395 * card open or closed.
1396 * Used when the user read /proc/net/dev
1397 */
1398static en_stats *wavelan_get_stats(struct net_device * dev)
1399{
1400#ifdef DEBUG_IOCTL_TRACE
1401 printk(KERN_DEBUG "%s: <>wavelan_get_stats()\n", dev->name);
1402#endif
1403
1404 return (&((net_local *) dev->priv)->stats);
1405}
1406
1407/*------------------------------------------------------------------*/
1408/*
1409 * Set or clear the multicast filter for this adaptor.
1410 * num_addrs == -1 Promiscuous mode, receive all packets
1411 * num_addrs == 0 Normal mode, clear multicast list
1412 * num_addrs > 0 Multicast mode, receive normal and MC packets,
1413 * and do best-effort filtering.
1414 */
1415static void wavelan_set_multicast_list(struct net_device * dev)
1416{
1417 net_local *lp = (net_local *) dev->priv;
1418
1419#ifdef DEBUG_IOCTL_TRACE
1420 printk(KERN_DEBUG "%s: ->wavelan_set_multicast_list()\n",
1421 dev->name);
1422#endif
1423
1424#ifdef DEBUG_IOCTL_INFO
1425 printk(KERN_DEBUG
1426 "%s: wavelan_set_multicast_list(): setting Rx mode %02X to %d addresses.\n",
1427 dev->name, dev->flags, dev->mc_count);
1428#endif
1429
1430 /* Are we asking for promiscuous mode,
1431 * or all multicast addresses (we don't have that!)
1432 * or too many multicast addresses for the hardware filter? */
1433 if ((dev->flags & IFF_PROMISC) ||
1434 (dev->flags & IFF_ALLMULTI) ||
1435 (dev->mc_count > I82586_MAX_MULTICAST_ADDRESSES)) {
1436 /*
1437 * Enable promiscuous mode: receive all packets.
1438 */
1439 if (!lp->promiscuous) {
1440 lp->promiscuous = 1;
1441 lp->mc_count = 0;
1442
1443 wv_82586_reconfig(dev);
1444
1445 /* Tell the kernel that we are doing a really bad job. */
1446 dev->flags |= IFF_PROMISC;
1447 }
1448 } else
1449 /* Are there multicast addresses to send? */
1450 if (dev->mc_list != (struct dev_mc_list *) NULL) {
1451 /*
1452 * Disable promiscuous mode, but receive all packets
1453 * in multicast list
1454 */
1455#ifdef MULTICAST_AVOID
1456 if (lp->promiscuous || (dev->mc_count != lp->mc_count))
1457#endif
1458 {
1459 lp->promiscuous = 0;
1460 lp->mc_count = dev->mc_count;
1461
1462 wv_82586_reconfig(dev);
1463 }
1464 } else {
1465 /*
1466 * Switch to normal mode: disable promiscuous mode and
1467 * clear the multicast list.
1468 */
1469 if (lp->promiscuous || lp->mc_count == 0) {
1470 lp->promiscuous = 0;
1471 lp->mc_count = 0;
1472
1473 wv_82586_reconfig(dev);
1474 }
1475 }
1476#ifdef DEBUG_IOCTL_TRACE
1477 printk(KERN_DEBUG "%s: <-wavelan_set_multicast_list()\n",
1478 dev->name);
1479#endif
1480}
1481
1482/*------------------------------------------------------------------*/
1483/*
1484 * This function doesn't exist.
1485 * (Note : it was a nice way to test the reconfigure stuff...)
1486 */
1487#ifdef SET_MAC_ADDRESS
1488static int wavelan_set_mac_address(struct net_device * dev, void *addr)
1489{
1490 struct sockaddr *mac = addr;
1491
1492 /* Copy the address. */
1493 memcpy(dev->dev_addr, mac->sa_data, WAVELAN_ADDR_SIZE);
1494
1495 /* Reconfigure the beast. */
1496 wv_82586_reconfig(dev);
1497
1498 return 0;
1499}
1500#endif /* SET_MAC_ADDRESS */
1501
1502#ifdef WIRELESS_EXT /* if wireless extensions exist in the kernel */
1503
1504/*------------------------------------------------------------------*/
1505/*
1506 * Frequency setting (for hardware capable of it)
1507 * It's a bit complicated and you don't really want to look into it.
1508 * (called in wavelan_ioctl)
1509 */
1510static inline int wv_set_frequency(unsigned long ioaddr, /* I/O port of the card */
1511 iw_freq * frequency)
1512{
1513 const int BAND_NUM = 10; /* Number of bands */
1514 long freq = 0L; /* offset to 2.4 GHz in .5 MHz */
1515#ifdef DEBUG_IOCTL_INFO
1516 int i;
1517#endif
1518
1519 /* Setting by frequency */
1520 /* Theoretically, you may set any frequency between
1521 * the two limits with a 0.5 MHz precision. In practice,
1522 * I don't want you to have trouble with local regulations.
1523 */
1524 if ((frequency->e == 1) &&
1525 (frequency->m >= (int) 2.412e8)
1526 && (frequency->m <= (int) 2.487e8)) {
1527 freq = ((frequency->m / 10000) - 24000L) / 5;
1528 }
1529
1530 /* Setting by channel (same as wfreqsel) */
1531 /* Warning: each channel is 22 MHz wide, so some of the channels
1532 * will interfere. */
1533 if ((frequency->e == 0) && (frequency->m < BAND_NUM)) {
1534 /* Get frequency offset. */
1535 freq = channel_bands[frequency->m] >> 1;
1536 }
1537
1538 /* Verify that the frequency is allowed. */
1539 if (freq != 0L) {
1540 u16 table[10]; /* Authorized frequency table */
1541
1542 /* Read the frequency table. */
1543 fee_read(ioaddr, 0x71, table, 10);
1544
1545#ifdef DEBUG_IOCTL_INFO
1546 printk(KERN_DEBUG "Frequency table: ");
1547 for (i = 0; i < 10; i++) {
1548 printk(" %04X", table[i]);
1549 }
1550 printk("\n");
1551#endif
1552
1553 /* Look in the table to see whether the frequency is allowed. */
1554 if (!(table[9 - ((freq - 24) / 16)] &
1555 (1 << ((freq - 24) % 16)))) return -EINVAL; /* not allowed */
1556 } else
1557 return -EINVAL;
1558
1559 /* if we get a usable frequency */
1560 if (freq != 0L) {
1561 unsigned short area[16];
1562 unsigned short dac[2];
1563 unsigned short area_verify[16];
1564 unsigned short dac_verify[2];
1565 /* Corresponding gain (in the power adjust value table)
1566 * See AT&T WaveLAN Data Manual, REF 407-024689/E, page 3-8
1567 * and WCIN062D.DOC, page 6.2.9. */
1568 unsigned short power_limit[] = { 40, 80, 120, 160, 0 };
1569 int power_band = 0; /* Selected band */
1570 unsigned short power_adjust; /* Correct value */
1571
1572 /* Search for the gain. */
1573 power_band = 0;
1574 while ((freq > power_limit[power_band]) &&
1575 (power_limit[++power_band] != 0));
1576
1577 /* Read the first area. */
1578 fee_read(ioaddr, 0x00, area, 16);
1579
1580 /* Read the DAC. */
1581 fee_read(ioaddr, 0x60, dac, 2);
1582
1583 /* Read the new power adjust value. */
1584 fee_read(ioaddr, 0x6B - (power_band >> 1), &power_adjust,
1585 1);
1586 if (power_band & 0x1)
1587 power_adjust >>= 8;
1588 else
1589 power_adjust &= 0xFF;
1590
1591#ifdef DEBUG_IOCTL_INFO
1592 printk(KERN_DEBUG "WaveLAN EEPROM Area 1: ");
1593 for (i = 0; i < 16; i++) {
1594 printk(" %04X", area[i]);
1595 }
1596 printk("\n");
1597
1598 printk(KERN_DEBUG "WaveLAN EEPROM DAC: %04X %04X\n",
1599 dac[0], dac[1]);
1600#endif
1601
1602 /* Frequency offset (for info only) */
1603 area[0] = ((freq << 5) & 0xFFE0) | (area[0] & 0x1F);
1604
1605 /* Receiver Principle main divider coefficient */
1606 area[3] = (freq >> 1) + 2400L - 352L;
1607 area[2] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
1608
1609 /* Transmitter Main divider coefficient */
1610 area[13] = (freq >> 1) + 2400L;
1611 area[12] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
1612
1613 /* Other parts of the area are flags, bit streams or unused. */
1614
1615 /* Set the value in the DAC. */
1616 dac[1] = ((power_adjust >> 1) & 0x7F) | (dac[1] & 0xFF80);
1617 dac[0] = ((power_adjust & 0x1) << 4) | (dac[0] & 0xFFEF);
1618
1619 /* Write the first area. */
1620 fee_write(ioaddr, 0x00, area, 16);
1621
1622 /* Write the DAC. */
1623 fee_write(ioaddr, 0x60, dac, 2);
1624
1625 /* We now should verify here that the writing of the EEPROM went OK. */
1626
1627 /* Reread the first area. */
1628 fee_read(ioaddr, 0x00, area_verify, 16);
1629
1630 /* Reread the DAC. */
1631 fee_read(ioaddr, 0x60, dac_verify, 2);
1632
1633 /* Compare. */
1634 if (memcmp(area, area_verify, 16 * 2) ||
1635 memcmp(dac, dac_verify, 2 * 2)) {
1636#ifdef DEBUG_IOCTL_ERROR
1637 printk(KERN_INFO
1638 "WaveLAN: wv_set_frequency: unable to write new frequency to EEPROM(?).\n");
1639#endif
1640 return -EOPNOTSUPP;
1641 }
1642
1643 /* We must download the frequency parameters to the
1644 * synthesizers (from the EEPROM - area 1)
1645 * Note: as the EEPROM is automatically decremented, we set the end
1646 * if the area... */
1647 mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x0F);
1648 mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
1649 MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
1650
1651 /* Wait until the download is finished. */
1652 fee_wait(ioaddr, 100, 100);
1653
1654 /* We must now download the power adjust value (gain) to
1655 * the synthesizers (from the EEPROM - area 7 - DAC). */
1656 mmc_out(ioaddr, mmwoff(0, mmw_fee_addr), 0x61);
1657 mmc_out(ioaddr, mmwoff(0, mmw_fee_ctrl),
1658 MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
1659
1660 /* Wait for the download to finish. */
1661 fee_wait(ioaddr, 100, 100);
1662
1663#ifdef DEBUG_IOCTL_INFO
1664 /* Verification of what we have done */
1665
1666 printk(KERN_DEBUG "WaveLAN EEPROM Area 1: ");
1667 for (i = 0; i < 16; i++) {
1668 printk(" %04X", area_verify[i]);
1669 }
1670 printk("\n");
1671
1672 printk(KERN_DEBUG "WaveLAN EEPROM DAC: %04X %04X\n",
1673 dac_verify[0], dac_verify[1]);
1674#endif
1675
1676 return 0;
1677 } else
1678 return -EINVAL; /* Bah, never get there... */
1679}
1680
1681/*------------------------------------------------------------------*/
1682/*
1683 * Give the list of available frequencies.
1684 */
1685static inline int wv_frequency_list(unsigned long ioaddr, /* I/O port of the card */
1686 iw_freq * list, /* List of frequencies to fill */
1687 int max)
1688{ /* Maximum number of frequencies */
1689 u16 table[10]; /* Authorized frequency table */
1690 long freq = 0L; /* offset to 2.4 GHz in .5 MHz + 12 MHz */
1691 int i; /* index in the table */
1692 int c = 0; /* Channel number */
1693
1694 /* Read the frequency table. */
1695 fee_read(ioaddr, 0x71 /* frequency table */ , table, 10);
1696
1697 /* Check all frequencies. */
1698 i = 0;
1699 for (freq = 0; freq < 150; freq++)
1700 /* Look in the table if the frequency is allowed */
1701 if (table[9 - (freq / 16)] & (1 << (freq % 16))) {
1702 /* Compute approximate channel number */
1703 while ((((channel_bands[c] >> 1) - 24) < freq) &&
1704 (c < NELS(channel_bands)))
1705 c++;
1706 list[i].i = c; /* Set the list index */
1707
1708 /* put in the list */
1709 list[i].m = (((freq + 24) * 5) + 24000L) * 10000;
1710 list[i++].e = 1;
1711
1712 /* Check number. */
1713 if (i >= max)
1714 return (i);
1715 }
1716
1717 return (i);
1718}
1719
1720#ifdef IW_WIRELESS_SPY
1721/*------------------------------------------------------------------*/
1722/*
1723 * Gather wireless spy statistics: for each packet, compare the source
1724 * address with our list, and if they match, get the statistics.
1725 * Sorry, but this function really needs the wireless extensions.
1726 */
1727static inline void wl_spy_gather(struct net_device * dev,
1728 u8 * mac, /* MAC address */
1729 u8 * stats) /* Statistics to gather */
1730{
1731 struct iw_quality wstats;
1732
1733 wstats.qual = stats[2] & MMR_SGNL_QUAL;
1734 wstats.level = stats[0] & MMR_SIGNAL_LVL;
1735 wstats.noise = stats[1] & MMR_SILENCE_LVL;
1736 wstats.updated = 0x7;
1737
1738 /* Update spy records */
1739 wireless_spy_update(dev, mac, &wstats);
1740}
1741#endif /* IW_WIRELESS_SPY */
1742
1743#ifdef HISTOGRAM
1744/*------------------------------------------------------------------*/
1745/*
1746 * This function calculates a histogram of the signal level.
1747 * As the noise is quite constant, it's like doing it on the SNR.
1748 * We have defined a set of interval (lp->his_range), and each time
1749 * the level goes in that interval, we increment the count (lp->his_sum).
1750 * With this histogram you may detect if one WaveLAN is really weak,
1751 * or you may also calculate the mean and standard deviation of the level.
1752 */
1753static inline void wl_his_gather(struct net_device * dev, u8 * stats)
1754{ /* Statistics to gather */
1755 net_local *lp = (net_local *) dev->priv;
1756 u8 level = stats[0] & MMR_SIGNAL_LVL;
1757 int i;
1758
1759 /* Find the correct interval. */
1760 i = 0;
1761 while ((i < (lp->his_number - 1))
1762 && (level >= lp->his_range[i++]));
1763
1764 /* Increment interval counter. */
1765 (lp->his_sum[i])++;
1766}
1767#endif /* HISTOGRAM */
1768
1769/*------------------------------------------------------------------*/
1770/*
1771 * Wireless Handler : get protocol name
1772 */
1773static int wavelan_get_name(struct net_device *dev,
1774 struct iw_request_info *info,
1775 union iwreq_data *wrqu,
1776 char *extra)
1777{
1778 strcpy(wrqu->name, "WaveLAN");
1779 return 0;
1780}
1781
1782/*------------------------------------------------------------------*/
1783/*
1784 * Wireless Handler : set NWID
1785 */
1786static int wavelan_set_nwid(struct net_device *dev,
1787 struct iw_request_info *info,
1788 union iwreq_data *wrqu,
1789 char *extra)
1790{
1791 unsigned long ioaddr = dev->base_addr;
1792 net_local *lp = (net_local *) dev->priv; /* lp is not unused */
1793 psa_t psa;
1794 mm_t m;
1795 unsigned long flags;
1796 int ret = 0;
1797
1798 /* Disable interrupts and save flags. */
1799 spin_lock_irqsave(&lp->spinlock, flags);
1800
1801 /* Set NWID in WaveLAN. */
1802 if (!wrqu->nwid.disabled) {
1803 /* Set NWID in psa */
1804 psa.psa_nwid[0] = (wrqu->nwid.value & 0xFF00) >> 8;
1805 psa.psa_nwid[1] = wrqu->nwid.value & 0xFF;
1806 psa.psa_nwid_select = 0x01;
1807 psa_write(ioaddr, lp->hacr,
1808 (char *) psa.psa_nwid - (char *) &psa,
1809 (unsigned char *) psa.psa_nwid, 3);
1810
1811 /* Set NWID in mmc. */
1812 m.w.mmw_netw_id_l = psa.psa_nwid[1];
1813 m.w.mmw_netw_id_h = psa.psa_nwid[0];
1814 mmc_write(ioaddr,
1815 (char *) &m.w.mmw_netw_id_l -
1816 (char *) &m,
1817 (unsigned char *) &m.w.mmw_netw_id_l, 2);
1818 mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), 0x00);
1819 } else {
1820 /* Disable NWID in the psa. */
1821 psa.psa_nwid_select = 0x00;
1822 psa_write(ioaddr, lp->hacr,
1823 (char *) &psa.psa_nwid_select -
1824 (char *) &psa,
1825 (unsigned char *) &psa.psa_nwid_select,
1826 1);
1827
1828 /* Disable NWID in the mmc (no filtering). */
1829 mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel),
1830 MMW_LOOPT_SEL_DIS_NWID);
1831 }
1832 /* update the Wavelan checksum */
1833 update_psa_checksum(dev, ioaddr, lp->hacr);
1834
1835 /* Enable interrupts and restore flags. */
1836 spin_unlock_irqrestore(&lp->spinlock, flags);
1837
1838 return ret;
1839}
1840
1841/*------------------------------------------------------------------*/
1842/*
1843 * Wireless Handler : get NWID
1844 */
1845static int wavelan_get_nwid(struct net_device *dev,
1846 struct iw_request_info *info,
1847 union iwreq_data *wrqu,
1848 char *extra)
1849{
1850 unsigned long ioaddr = dev->base_addr;
1851 net_local *lp = (net_local *) dev->priv; /* lp is not unused */
1852 psa_t psa;
1853 unsigned long flags;
1854 int ret = 0;
1855
1856 /* Disable interrupts and save flags. */
1857 spin_lock_irqsave(&lp->spinlock, flags);
1858
1859 /* Read the NWID. */
1860 psa_read(ioaddr, lp->hacr,
1861 (char *) psa.psa_nwid - (char *) &psa,
1862 (unsigned char *) psa.psa_nwid, 3);
1863 wrqu->nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
1864 wrqu->nwid.disabled = !(psa.psa_nwid_select);
1865 wrqu->nwid.fixed = 1; /* Superfluous */
1866
1867 /* Enable interrupts and restore flags. */
1868 spin_unlock_irqrestore(&lp->spinlock, flags);
1869
1870 return ret;
1871}
1872
1873/*------------------------------------------------------------------*/
1874/*
1875 * Wireless Handler : set frequency
1876 */
1877static int wavelan_set_freq(struct net_device *dev,
1878 struct iw_request_info *info,
1879 union iwreq_data *wrqu,
1880 char *extra)
1881{
1882 unsigned long ioaddr = dev->base_addr;
1883 net_local *lp = (net_local *) dev->priv; /* lp is not unused */
1884 unsigned long flags;
1885 int ret;
1886
1887 /* Disable interrupts and save flags. */
1888 spin_lock_irqsave(&lp->spinlock, flags);
1889
1890 /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
1891 if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
1892 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
1893 ret = wv_set_frequency(ioaddr, &(wrqu->freq));
1894 else
1895 ret = -EOPNOTSUPP;
1896
1897 /* Enable interrupts and restore flags. */
1898 spin_unlock_irqrestore(&lp->spinlock, flags);
1899
1900 return ret;
1901}
1902
1903/*------------------------------------------------------------------*/
1904/*
1905 * Wireless Handler : get frequency
1906 */
1907static int wavelan_get_freq(struct net_device *dev,
1908 struct iw_request_info *info,
1909 union iwreq_data *wrqu,
1910 char *extra)
1911{
1912 unsigned long ioaddr = dev->base_addr;
1913 net_local *lp = (net_local *) dev->priv; /* lp is not unused */
1914 psa_t psa;
1915 unsigned long flags;
1916 int ret = 0;
1917
1918 /* Disable interrupts and save flags. */
1919 spin_lock_irqsave(&lp->spinlock, flags);
1920
1921 /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable).
1922 * Does it work for everybody, especially old cards? */
1923 if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
1924 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
1925 unsigned short freq;
1926
1927 /* Ask the EEPROM to read the frequency from the first area. */
1928 fee_read(ioaddr, 0x00, &freq, 1);
1929 wrqu->freq.m = ((freq >> 5) * 5 + 24000L) * 10000;
1930 wrqu->freq.e = 1;
1931 } else {
1932 psa_read(ioaddr, lp->hacr,
1933 (char *) &psa.psa_subband - (char *) &psa,
1934 (unsigned char *) &psa.psa_subband, 1);
1935
1936 if (psa.psa_subband <= 4) {
1937 wrqu->freq.m = fixed_bands[psa.psa_subband];
1938 wrqu->freq.e = (psa.psa_subband != 0);
1939 } else
1940 ret = -EOPNOTSUPP;
1941 }
1942
1943 /* Enable interrupts and restore flags. */
1944 spin_unlock_irqrestore(&lp->spinlock, flags);
1945
1946 return ret;
1947}
1948
1949/*------------------------------------------------------------------*/
1950/*
1951 * Wireless Handler : set level threshold
1952 */
1953static int wavelan_set_sens(struct net_device *dev,
1954 struct iw_request_info *info,
1955 union iwreq_data *wrqu,
1956 char *extra)
1957{
1958 unsigned long ioaddr = dev->base_addr;
1959 net_local *lp = (net_local *) dev->priv; /* lp is not unused */
1960 psa_t psa;
1961 unsigned long flags;
1962 int ret = 0;
1963
1964 /* Disable interrupts and save flags. */
1965 spin_lock_irqsave(&lp->spinlock, flags);
1966
1967 /* Set the level threshold. */
1968 /* We should complain loudly if wrqu->sens.fixed = 0, because we
1969 * can't set auto mode... */
1970 psa.psa_thr_pre_set = wrqu->sens.value & 0x3F;
1971 psa_write(ioaddr, lp->hacr,
1972 (char *) &psa.psa_thr_pre_set - (char *) &psa,
1973 (unsigned char *) &psa.psa_thr_pre_set, 1);
1974 /* update the Wavelan checksum */
1975 update_psa_checksum(dev, ioaddr, lp->hacr);
1976 mmc_out(ioaddr, mmwoff(0, mmw_thr_pre_set),
1977 psa.psa_thr_pre_set);
1978
1979 /* Enable interrupts and restore flags. */
1980 spin_unlock_irqrestore(&lp->spinlock, flags);
1981
1982 return ret;
1983}
1984
1985/*------------------------------------------------------------------*/
1986/*
1987 * Wireless Handler : get level threshold
1988 */
1989static int wavelan_get_sens(struct net_device *dev,
1990 struct iw_request_info *info,
1991 union iwreq_data *wrqu,
1992 char *extra)
1993{
1994 unsigned long ioaddr = dev->base_addr;
1995 net_local *lp = (net_local *) dev->priv; /* lp is not unused */
1996 psa_t psa;
1997 unsigned long flags;
1998 int ret = 0;
1999
2000 /* Disable interrupts and save flags. */
2001 spin_lock_irqsave(&lp->spinlock, flags);
2002
2003 /* Read the level threshold. */
2004 psa_read(ioaddr, lp->hacr,
2005 (char *) &psa.psa_thr_pre_set - (char *) &psa,
2006 (unsigned char *) &psa.psa_thr_pre_set, 1);
2007 wrqu->sens.value = psa.psa_thr_pre_set & 0x3F;
2008 wrqu->sens.fixed = 1;
2009
2010 /* Enable interrupts and restore flags. */
2011 spin_unlock_irqrestore(&lp->spinlock, flags);
2012
2013 return ret;
2014}
2015
2016/*------------------------------------------------------------------*/
2017/*
2018 * Wireless Handler : set encryption key
2019 */
2020static int wavelan_set_encode(struct net_device *dev,
2021 struct iw_request_info *info,
2022 union iwreq_data *wrqu,
2023 char *extra)
2024{
2025 unsigned long ioaddr = dev->base_addr;
2026 net_local *lp = (net_local *) dev->priv; /* lp is not unused */
2027 unsigned long flags;
2028 psa_t psa;
2029 int ret = 0;
2030
2031 /* Disable interrupts and save flags. */
2032 spin_lock_irqsave(&lp->spinlock, flags);
2033
2034 /* Check if capable of encryption */
2035 if (!mmc_encr(ioaddr)) {
2036 ret = -EOPNOTSUPP;
2037 }
2038
2039 /* Check the size of the key */
2040 if((wrqu->encoding.length != 8) && (wrqu->encoding.length != 0)) {
2041 ret = -EINVAL;
2042 }
2043
2044 if(!ret) {
2045 /* Basic checking... */
2046 if (wrqu->encoding.length == 8) {
2047 /* Copy the key in the driver */
2048 memcpy(psa.psa_encryption_key, extra,
2049 wrqu->encoding.length);
2050 psa.psa_encryption_select = 1;
2051
2052 psa_write(ioaddr, lp->hacr,
2053 (char *) &psa.psa_encryption_select -
2054 (char *) &psa,
2055 (unsigned char *) &psa.
2056 psa_encryption_select, 8 + 1);
2057
2058 mmc_out(ioaddr, mmwoff(0, mmw_encr_enable),
2059 MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);
2060 mmc_write(ioaddr, mmwoff(0, mmw_encr_key),
2061 (unsigned char *) &psa.
2062 psa_encryption_key, 8);
2063 }
2064
2065 /* disable encryption */
2066 if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
2067 psa.psa_encryption_select = 0;
2068 psa_write(ioaddr, lp->hacr,
2069 (char *) &psa.psa_encryption_select -
2070 (char *) &psa,
2071 (unsigned char *) &psa.
2072 psa_encryption_select, 1);
2073
2074 mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), 0);
2075 }
2076 /* update the Wavelan checksum */
2077 update_psa_checksum(dev, ioaddr, lp->hacr);
2078 }
2079
2080 /* Enable interrupts and restore flags. */
2081 spin_unlock_irqrestore(&lp->spinlock, flags);
2082
2083 return ret;
2084}
2085
2086/*------------------------------------------------------------------*/
2087/*
2088 * Wireless Handler : get encryption key
2089 */
2090static int wavelan_get_encode(struct net_device *dev,
2091 struct iw_request_info *info,
2092 union iwreq_data *wrqu,
2093 char *extra)
2094{
2095 unsigned long ioaddr = dev->base_addr;
2096 net_local *lp = (net_local *) dev->priv; /* lp is not unused */
2097 psa_t psa;
2098 unsigned long flags;
2099 int ret = 0;
2100
2101 /* Disable interrupts and save flags. */
2102 spin_lock_irqsave(&lp->spinlock, flags);
2103
2104 /* Check if encryption is available */
2105 if (!mmc_encr(ioaddr)) {
2106 ret = -EOPNOTSUPP;
2107 } else {
2108 /* Read the encryption key */
2109 psa_read(ioaddr, lp->hacr,
2110 (char *) &psa.psa_encryption_select -
2111 (char *) &psa,
2112 (unsigned char *) &psa.
2113 psa_encryption_select, 1 + 8);
2114
2115 /* encryption is enabled ? */
2116 if (psa.psa_encryption_select)
2117 wrqu->encoding.flags = IW_ENCODE_ENABLED;
2118 else
2119 wrqu->encoding.flags = IW_ENCODE_DISABLED;
2120 wrqu->encoding.flags |= mmc_encr(ioaddr);
2121
2122 /* Copy the key to the user buffer */
2123 wrqu->encoding.length = 8;
2124 memcpy(extra, psa.psa_encryption_key, wrqu->encoding.length);
2125 }
2126
2127 /* Enable interrupts and restore flags. */
2128 spin_unlock_irqrestore(&lp->spinlock, flags);
2129
2130 return ret;
2131}
2132
2133/*------------------------------------------------------------------*/
2134/*
2135 * Wireless Handler : get range info
2136 */
2137static int wavelan_get_range(struct net_device *dev,
2138 struct iw_request_info *info,
2139 union iwreq_data *wrqu,
2140 char *extra)
2141{
2142 unsigned long ioaddr = dev->base_addr;
2143 net_local *lp = (net_local *) dev->priv; /* lp is not unused */
2144 struct iw_range *range = (struct iw_range *) extra;
2145 unsigned long flags;
2146 int ret = 0;
2147
2148 /* Set the length (very important for backward compatibility) */
2149 wrqu->data.length = sizeof(struct iw_range);
2150
2151 /* Set all the info we don't care or don't know about to zero */
2152 memset(range, 0, sizeof(struct iw_range));
2153
2154 /* Set the Wireless Extension versions */
2155 range->we_version_compiled = WIRELESS_EXT;
2156 range->we_version_source = 9;
2157
2158 /* Set information in the range struct. */
2159 range->throughput = 1.6 * 1000 * 1000; /* don't argue on this ! */
2160 range->min_nwid = 0x0000;
2161 range->max_nwid = 0xFFFF;
2162
2163 range->sensitivity = 0x3F;
2164 range->max_qual.qual = MMR_SGNL_QUAL;
2165 range->max_qual.level = MMR_SIGNAL_LVL;
2166 range->max_qual.noise = MMR_SILENCE_LVL;
2167 range->avg_qual.qual = MMR_SGNL_QUAL; /* Always max */
2168 /* Need to get better values for those two */
2169 range->avg_qual.level = 30;
2170 range->avg_qual.noise = 8;
2171
2172 range->num_bitrates = 1;
2173 range->bitrate[0] = 2000000; /* 2 Mb/s */
2174
2175 /* Event capability (kernel + driver) */
2176 range->event_capa[0] = (IW_EVENT_CAPA_MASK(0x8B02) |
2177 IW_EVENT_CAPA_MASK(0x8B04));
2178 range->event_capa[1] = IW_EVENT_CAPA_K_1;
2179
2180 /* Disable interrupts and save flags. */
2181 spin_lock_irqsave(&lp->spinlock, flags);
2182
2183 /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
2184 if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
2185 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
2186 range->num_channels = 10;
2187 range->num_frequency = wv_frequency_list(ioaddr, range->freq,
2188 IW_MAX_FREQUENCIES);
2189 } else
2190 range->num_channels = range->num_frequency = 0;
2191
2192 /* Encryption supported ? */
2193 if (mmc_encr(ioaddr)) {
2194 range->encoding_size[0] = 8; /* DES = 64 bits key */
2195 range->num_encoding_sizes = 1;
2196 range->max_encoding_tokens = 1; /* Only one key possible */
2197 } else {
2198 range->num_encoding_sizes = 0;
2199 range->max_encoding_tokens = 0;
2200 }
2201
2202 /* Enable interrupts and restore flags. */
2203 spin_unlock_irqrestore(&lp->spinlock, flags);
2204
2205 return ret;
2206}
2207
2208/*------------------------------------------------------------------*/
2209/*
2210 * Wireless Private Handler : set quality threshold
2211 */
2212static int wavelan_set_qthr(struct net_device *dev,
2213 struct iw_request_info *info,
2214 union iwreq_data *wrqu,
2215 char *extra)
2216{
2217 unsigned long ioaddr = dev->base_addr;
2218 net_local *lp = (net_local *) dev->priv; /* lp is not unused */
2219 psa_t psa;
2220 unsigned long flags;
2221
2222 /* Disable interrupts and save flags. */
2223 spin_lock_irqsave(&lp->spinlock, flags);
2224
2225 psa.psa_quality_thr = *(extra) & 0x0F;
2226 psa_write(ioaddr, lp->hacr,
2227 (char *) &psa.psa_quality_thr - (char *) &psa,
2228 (unsigned char *) &psa.psa_quality_thr, 1);
2229 /* update the Wavelan checksum */
2230 update_psa_checksum(dev, ioaddr, lp->hacr);
2231 mmc_out(ioaddr, mmwoff(0, mmw_quality_thr),
2232 psa.psa_quality_thr);
2233
2234 /* Enable interrupts and restore flags. */
2235 spin_unlock_irqrestore(&lp->spinlock, flags);
2236
2237 return 0;
2238}
2239
2240/*------------------------------------------------------------------*/
2241/*
2242 * Wireless Private Handler : get quality threshold
2243 */
2244static int wavelan_get_qthr(struct net_device *dev,
2245 struct iw_request_info *info,
2246 union iwreq_data *wrqu,
2247 char *extra)
2248{
2249 unsigned long ioaddr = dev->base_addr;
2250 net_local *lp = (net_local *) dev->priv; /* lp is not unused */
2251 psa_t psa;
2252 unsigned long flags;
2253
2254 /* Disable interrupts and save flags. */
2255 spin_lock_irqsave(&lp->spinlock, flags);
2256
2257 psa_read(ioaddr, lp->hacr,
2258 (char *) &psa.psa_quality_thr - (char *) &psa,
2259 (unsigned char *) &psa.psa_quality_thr, 1);
2260 *(extra) = psa.psa_quality_thr & 0x0F;
2261
2262 /* Enable interrupts and restore flags. */
2263 spin_unlock_irqrestore(&lp->spinlock, flags);
2264
2265 return 0;
2266}
2267
2268#ifdef HISTOGRAM
2269/*------------------------------------------------------------------*/
2270/*
2271 * Wireless Private Handler : set histogram
2272 */
2273static int wavelan_set_histo(struct net_device *dev,
2274 struct iw_request_info *info,
2275 union iwreq_data *wrqu,
2276 char *extra)
2277{
2278 net_local *lp = (net_local *) dev->priv; /* lp is not unused */
2279
2280 /* Check the number of intervals. */
2281 if (wrqu->data.length > 16) {
2282 return(-E2BIG);
2283 }
2284
2285 /* Disable histo while we copy the addresses.
2286 * As we don't disable interrupts, we need to do this */
2287 lp->his_number = 0;
2288
2289 /* Are there ranges to copy? */
2290 if (wrqu->data.length > 0) {
2291 /* Copy interval ranges to the driver */
2292 memcpy(lp->his_range, extra, wrqu->data.length);
2293
2294 {
2295 int i;
2296 printk(KERN_DEBUG "Histo :");
2297 for(i = 0; i < wrqu->data.length; i++)
2298 printk(" %d", lp->his_range[i]);
2299 printk("\n");
2300 }
2301
2302 /* Reset result structure. */
2303 memset(lp->his_sum, 0x00, sizeof(long) * 16);
2304 }
2305
2306 /* Now we can set the number of ranges */
2307 lp->his_number = wrqu->data.length;
2308
2309 return(0);
2310}
2311
2312/*------------------------------------------------------------------*/
2313/*
2314 * Wireless Private Handler : get histogram
2315 */
2316static int wavelan_get_histo(struct net_device *dev,
2317 struct iw_request_info *info,
2318 union iwreq_data *wrqu,
2319 char *extra)
2320{
2321 net_local *lp = (net_local *) dev->priv; /* lp is not unused */
2322
2323 /* Set the number of intervals. */
2324 wrqu->data.length = lp->his_number;
2325
2326 /* Give back the distribution statistics */
2327 if(lp->his_number > 0)
2328 memcpy(extra, lp->his_sum, sizeof(long) * lp->his_number);
2329
2330 return(0);
2331}
2332#endif /* HISTOGRAM */
2333
2334/*------------------------------------------------------------------*/
2335/*
2336 * Structures to export the Wireless Handlers
2337 */
2338
2339static const iw_handler wavelan_handler[] =
2340{
2341 NULL, /* SIOCSIWNAME */
2342 wavelan_get_name, /* SIOCGIWNAME */
2343 wavelan_set_nwid, /* SIOCSIWNWID */
2344 wavelan_get_nwid, /* SIOCGIWNWID */
2345 wavelan_set_freq, /* SIOCSIWFREQ */
2346 wavelan_get_freq, /* SIOCGIWFREQ */
2347 NULL, /* SIOCSIWMODE */
2348 NULL, /* SIOCGIWMODE */
2349 wavelan_set_sens, /* SIOCSIWSENS */
2350 wavelan_get_sens, /* SIOCGIWSENS */
2351 NULL, /* SIOCSIWRANGE */
2352 wavelan_get_range, /* SIOCGIWRANGE */
2353 NULL, /* SIOCSIWPRIV */
2354 NULL, /* SIOCGIWPRIV */
2355 NULL, /* SIOCSIWSTATS */
2356 NULL, /* SIOCGIWSTATS */
2357 iw_handler_set_spy, /* SIOCSIWSPY */
2358 iw_handler_get_spy, /* SIOCGIWSPY */
2359 iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
2360 iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
2361 NULL, /* SIOCSIWAP */
2362 NULL, /* SIOCGIWAP */
2363 NULL, /* -- hole -- */
2364 NULL, /* SIOCGIWAPLIST */
2365 NULL, /* -- hole -- */
2366 NULL, /* -- hole -- */
2367 NULL, /* SIOCSIWESSID */
2368 NULL, /* SIOCGIWESSID */
2369 NULL, /* SIOCSIWNICKN */
2370 NULL, /* SIOCGIWNICKN */
2371 NULL, /* -- hole -- */
2372 NULL, /* -- hole -- */
2373 NULL, /* SIOCSIWRATE */
2374 NULL, /* SIOCGIWRATE */
2375 NULL, /* SIOCSIWRTS */
2376 NULL, /* SIOCGIWRTS */
2377 NULL, /* SIOCSIWFRAG */
2378 NULL, /* SIOCGIWFRAG */
2379 NULL, /* SIOCSIWTXPOW */
2380 NULL, /* SIOCGIWTXPOW */
2381 NULL, /* SIOCSIWRETRY */
2382 NULL, /* SIOCGIWRETRY */
2383 /* Bummer ! Why those are only at the end ??? */
2384 wavelan_set_encode, /* SIOCSIWENCODE */
2385 wavelan_get_encode, /* SIOCGIWENCODE */
2386};
2387
2388static const iw_handler wavelan_private_handler[] =
2389{
2390 wavelan_set_qthr, /* SIOCIWFIRSTPRIV */
2391 wavelan_get_qthr, /* SIOCIWFIRSTPRIV + 1 */
2392#ifdef HISTOGRAM
2393 wavelan_set_histo, /* SIOCIWFIRSTPRIV + 2 */
2394 wavelan_get_histo, /* SIOCIWFIRSTPRIV + 3 */
2395#endif /* HISTOGRAM */
2396};
2397
2398static const struct iw_priv_args wavelan_private_args[] = {
2399/*{ cmd, set_args, get_args, name } */
2400 { SIOCSIPQTHR, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setqualthr" },
2401 { SIOCGIPQTHR, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getqualthr" },
2402 { SIOCSIPHISTO, IW_PRIV_TYPE_BYTE | 16, 0, "sethisto" },
2403 { SIOCGIPHISTO, 0, IW_PRIV_TYPE_INT | 16, "gethisto" },
2404};
2405
2406static const struct iw_handler_def wavelan_handler_def =
2407{
2408 .num_standard = sizeof(wavelan_handler)/sizeof(iw_handler),
2409 .num_private = sizeof(wavelan_private_handler)/sizeof(iw_handler),
2410 .num_private_args = sizeof(wavelan_private_args)/sizeof(struct iw_priv_args),
2411 .standard = wavelan_handler,
2412 .private = wavelan_private_handler,
2413 .private_args = wavelan_private_args,
2414 .get_wireless_stats = wavelan_get_wireless_stats,
2415};
2416
2417/*------------------------------------------------------------------*/
2418/*
2419 * Get wireless statistics.
2420 * Called by /proc/net/wireless
2421 */
2422static iw_stats *wavelan_get_wireless_stats(struct net_device * dev)
2423{
2424 unsigned long ioaddr = dev->base_addr;
2425 net_local *lp = (net_local *) dev->priv;
2426 mmr_t m;
2427 iw_stats *wstats;
2428 unsigned long flags;
2429
2430#ifdef DEBUG_IOCTL_TRACE
2431 printk(KERN_DEBUG "%s: ->wavelan_get_wireless_stats()\n",
2432 dev->name);
2433#endif
2434
2435 /* Check */
2436 if (lp == (net_local *) NULL)
2437 return (iw_stats *) NULL;
2438
2439 /* Disable interrupts and save flags. */
2440 spin_lock_irqsave(&lp->spinlock, flags);
2441
2442 wstats = &lp->wstats;
2443
2444 /* Get data from the mmc. */
2445 mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1);
2446
2447 mmc_read(ioaddr, mmroff(0, mmr_dce_status), &m.mmr_dce_status, 1);
2448 mmc_read(ioaddr, mmroff(0, mmr_wrong_nwid_l), &m.mmr_wrong_nwid_l,
2449 2);
2450 mmc_read(ioaddr, mmroff(0, mmr_thr_pre_set), &m.mmr_thr_pre_set,
2451 4);
2452
2453 mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
2454
2455 /* Copy data to wireless stuff. */
2456 wstats->status = m.mmr_dce_status & MMR_DCE_STATUS;
2457 wstats->qual.qual = m.mmr_sgnl_qual & MMR_SGNL_QUAL;
2458 wstats->qual.level = m.mmr_signal_lvl & MMR_SIGNAL_LVL;
2459 wstats->qual.noise = m.mmr_silence_lvl & MMR_SILENCE_LVL;
2460 wstats->qual.updated = (((m. mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 7)
2461 | ((m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 6)
2462 | ((m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) >> 5));
2463 wstats->discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
2464 wstats->discard.code = 0L;
2465 wstats->discard.misc = 0L;
2466
2467 /* Enable interrupts and restore flags. */
2468 spin_unlock_irqrestore(&lp->spinlock, flags);
2469
2470#ifdef DEBUG_IOCTL_TRACE
2471 printk(KERN_DEBUG "%s: <-wavelan_get_wireless_stats()\n",
2472 dev->name);
2473#endif
2474 return &lp->wstats;
2475}
2476#endif /* WIRELESS_EXT */
2477
2478/************************* PACKET RECEPTION *************************/
2479/*
2480 * This part deals with receiving the packets.
2481 * The interrupt handler gets an interrupt when a packet has been
2482 * successfully received and calls this part.
2483 */
2484
2485/*------------------------------------------------------------------*/
2486/*
2487 * This routine does the actual copying of data (including the Ethernet
2488 * header structure) from the WaveLAN card to an sk_buff chain that
2489 * will be passed up to the network interface layer. NOTE: we
2490 * currently don't handle trailer protocols (neither does the rest of
2491 * the network interface), so if that is needed, it will (at least in
2492 * part) be added here. The contents of the receive ring buffer are
2493 * copied to a message chain that is then passed to the kernel.
2494 *
2495 * Note: if any errors occur, the packet is "dropped on the floor".
2496 * (called by wv_packet_rcv())
2497 */
2498static inline void
2499wv_packet_read(struct net_device * dev, u16 buf_off, int sksize)
2500{
2501 net_local *lp = (net_local *) dev->priv;
2502 unsigned long ioaddr = dev->base_addr;
2503 struct sk_buff *skb;
2504
2505#ifdef DEBUG_RX_TRACE
2506 printk(KERN_DEBUG "%s: ->wv_packet_read(0x%X, %d)\n",
2507 dev->name, buf_off, sksize);
2508#endif
2509
2510 /* Allocate buffer for the data */
2511 if ((skb = dev_alloc_skb(sksize)) == (struct sk_buff *) NULL) {
2512#ifdef DEBUG_RX_ERROR
2513 printk(KERN_INFO
2514 "%s: wv_packet_read(): could not alloc_skb(%d, GFP_ATOMIC).\n",
2515 dev->name, sksize);
2516#endif
2517 lp->stats.rx_dropped++;
2518 return;
2519 }
2520
2521 skb->dev = dev;
2522
2523 /* Copy the packet to the buffer. */
2524 obram_read(ioaddr, buf_off, skb_put(skb, sksize), sksize);
2525 skb->protocol = eth_type_trans(skb, dev);
2526
2527#ifdef DEBUG_RX_INFO
2528 wv_packet_info(skb->mac.raw, sksize, dev->name, "wv_packet_read");
2529#endif /* DEBUG_RX_INFO */
2530
2531 /* Statistics-gathering and associated stuff.
2532 * It seem a bit messy with all the define, but it's really
2533 * simple... */
2534 if (
2535#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
2536 (lp->spy_data.spy_number > 0) ||
2537#endif /* IW_WIRELESS_SPY */
2538#ifdef HISTOGRAM
2539 (lp->his_number > 0) ||
2540#endif /* HISTOGRAM */
2541 0) {
2542 u8 stats[3]; /* signal level, noise level, signal quality */
2543
2544 /* Read signal level, silence level and signal quality bytes */
2545 /* Note: in the PCMCIA hardware, these are part of the frame.
2546 * It seems that for the ISA hardware, it's nowhere to be
2547 * found in the frame, so I'm obliged to do this (it has a
2548 * side effect on /proc/net/wireless).
2549 * Any ideas?
2550 */
2551 mmc_out(ioaddr, mmwoff(0, mmw_freeze), 1);
2552 mmc_read(ioaddr, mmroff(0, mmr_signal_lvl), stats, 3);
2553 mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
2554
2555#ifdef DEBUG_RX_INFO
2556 printk(KERN_DEBUG
2557 "%s: wv_packet_read(): Signal level %d/63, Silence level %d/63, signal quality %d/16\n",
2558 dev->name, stats[0] & 0x3F, stats[1] & 0x3F,
2559 stats[2] & 0x0F);
2560#endif
2561
2562 /* Spying stuff */
2563#ifdef IW_WIRELESS_SPY
2564 wl_spy_gather(dev, skb->mac.raw + WAVELAN_ADDR_SIZE,
2565 stats);
2566#endif /* IW_WIRELESS_SPY */
2567#ifdef HISTOGRAM
2568 wl_his_gather(dev, stats);
2569#endif /* HISTOGRAM */
2570 }
2571
2572 /*
2573 * Hand the packet to the network module.
2574 */
2575 netif_rx(skb);
2576
2577 /* Keep statistics up to date */
2578 dev->last_rx = jiffies;
2579 lp->stats.rx_packets++;
2580 lp->stats.rx_bytes += sksize;
2581
2582#ifdef DEBUG_RX_TRACE
2583 printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
2584#endif
2585}
2586
2587/*------------------------------------------------------------------*/
2588/*
2589 * Transfer as many packets as we can
2590 * from the device RAM.
2591 * (called in wavelan_interrupt()).
2592 * Note : the spinlock is already grabbed for us.
2593 */
2594static inline void wv_receive(struct net_device * dev)
2595{
2596 unsigned long ioaddr = dev->base_addr;
2597 net_local *lp = (net_local *) dev->priv;
2598 fd_t fd;
2599 rbd_t rbd;
2600 int nreaped = 0;
2601
2602#ifdef DEBUG_RX_TRACE
2603 printk(KERN_DEBUG "%s: ->wv_receive()\n", dev->name);
2604#endif
2605
2606 /* Loop on each received packet. */
2607 for (;;) {
2608 obram_read(ioaddr, lp->rx_head, (unsigned char *) &fd,
2609 sizeof(fd));
2610
2611 /* Note about the status :
2612 * It start up to be 0 (the value we set). Then, when the RU
2613 * grab the buffer to prepare for reception, it sets the
2614 * FD_STATUS_B flag. When the RU has finished receiving the
2615 * frame, it clears FD_STATUS_B, set FD_STATUS_C to indicate
2616 * completion and set the other flags to indicate the eventual
2617 * errors. FD_STATUS_OK indicates that the reception was OK.
2618 */
2619
2620 /* If the current frame is not complete, we have reached the end. */
2621 if ((fd.fd_status & FD_STATUS_C) != FD_STATUS_C)
2622 break; /* This is how we exit the loop. */
2623
2624 nreaped++;
2625
2626 /* Check whether frame was correctly received. */
2627 if ((fd.fd_status & FD_STATUS_OK) == FD_STATUS_OK) {
2628 /* Does the frame contain a pointer to the data? Let's check. */
2629 if (fd.fd_rbd_offset != I82586NULL) {
2630 /* Read the receive buffer descriptor */
2631 obram_read(ioaddr, fd.fd_rbd_offset,
2632 (unsigned char *) &rbd,
2633 sizeof(rbd));
2634
2635#ifdef DEBUG_RX_ERROR
2636 if ((rbd.rbd_status & RBD_STATUS_EOF) !=
2637 RBD_STATUS_EOF) printk(KERN_INFO
2638 "%s: wv_receive(): missing EOF flag.\n",
2639 dev->name);
2640
2641 if ((rbd.rbd_status & RBD_STATUS_F) !=
2642 RBD_STATUS_F) printk(KERN_INFO
2643 "%s: wv_receive(): missing F flag.\n",
2644 dev->name);
2645#endif /* DEBUG_RX_ERROR */
2646
2647 /* Read the packet and transmit to Linux */
2648 wv_packet_read(dev, rbd.rbd_bufl,
2649 rbd.
2650 rbd_status &
2651 RBD_STATUS_ACNT);
2652 }
2653#ifdef DEBUG_RX_ERROR
2654 else /* if frame has no data */
2655 printk(KERN_INFO
2656 "%s: wv_receive(): frame has no data.\n",
2657 dev->name);
2658#endif
2659 } else { /* If reception was no successful */
2660
2661 lp->stats.rx_errors++;
2662
2663#ifdef DEBUG_RX_INFO
2664 printk(KERN_DEBUG
2665 "%s: wv_receive(): frame not received successfully (%X).\n",
2666 dev->name, fd.fd_status);
2667#endif
2668
2669#ifdef DEBUG_RX_ERROR
2670 if ((fd.fd_status & FD_STATUS_S6) != 0)
2671 printk(KERN_INFO
2672 "%s: wv_receive(): no EOF flag.\n",
2673 dev->name);
2674#endif
2675
2676 if ((fd.fd_status & FD_STATUS_S7) != 0) {
2677 lp->stats.rx_length_errors++;
2678#ifdef DEBUG_RX_FAIL
2679 printk(KERN_DEBUG
2680 "%s: wv_receive(): frame too short.\n",
2681 dev->name);
2682#endif
2683 }
2684
2685 if ((fd.fd_status & FD_STATUS_S8) != 0) {
2686 lp->stats.rx_over_errors++;
2687#ifdef DEBUG_RX_FAIL
2688 printk(KERN_DEBUG
2689 "%s: wv_receive(): rx DMA overrun.\n",
2690 dev->name);
2691#endif
2692 }
2693
2694 if ((fd.fd_status & FD_STATUS_S9) != 0) {
2695 lp->stats.rx_fifo_errors++;
2696#ifdef DEBUG_RX_FAIL
2697 printk(KERN_DEBUG
2698 "%s: wv_receive(): ran out of resources.\n",
2699 dev->name);
2700#endif
2701 }
2702
2703 if ((fd.fd_status & FD_STATUS_S10) != 0) {
2704 lp->stats.rx_frame_errors++;
2705#ifdef DEBUG_RX_FAIL
2706 printk(KERN_DEBUG
2707 "%s: wv_receive(): alignment error.\n",
2708 dev->name);
2709#endif
2710 }
2711
2712 if ((fd.fd_status & FD_STATUS_S11) != 0) {
2713 lp->stats.rx_crc_errors++;
2714#ifdef DEBUG_RX_FAIL
2715 printk(KERN_DEBUG
2716 "%s: wv_receive(): CRC error.\n",
2717 dev->name);
2718#endif
2719 }
2720 }
2721
2722 fd.fd_status = 0;
2723 obram_write(ioaddr, fdoff(lp->rx_head, fd_status),
2724 (unsigned char *) &fd.fd_status,
2725 sizeof(fd.fd_status));
2726
2727 fd.fd_command = FD_COMMAND_EL;
2728 obram_write(ioaddr, fdoff(lp->rx_head, fd_command),
2729 (unsigned char *) &fd.fd_command,
2730 sizeof(fd.fd_command));
2731
2732 fd.fd_command = 0;
2733 obram_write(ioaddr, fdoff(lp->rx_last, fd_command),
2734 (unsigned char *) &fd.fd_command,
2735 sizeof(fd.fd_command));
2736
2737 lp->rx_last = lp->rx_head;
2738 lp->rx_head = fd.fd_link_offset;
2739 } /* for(;;) -> loop on all frames */
2740
2741#ifdef DEBUG_RX_INFO
2742 if (nreaped > 1)
2743 printk(KERN_DEBUG "%s: wv_receive(): reaped %d\n",
2744 dev->name, nreaped);
2745#endif
2746#ifdef DEBUG_RX_TRACE
2747 printk(KERN_DEBUG "%s: <-wv_receive()\n", dev->name);
2748#endif
2749}
2750
2751/*********************** PACKET TRANSMISSION ***********************/
2752/*
2753 * This part deals with sending packets through the WaveLAN.
2754 *
2755 */
2756
2757/*------------------------------------------------------------------*/
2758/*
2759 * This routine fills in the appropriate registers and memory
2760 * locations on the WaveLAN card and starts the card off on
2761 * the transmit.
2762 *
2763 * The principle:
2764 * Each block contains a transmit command, a NOP command,
2765 * a transmit block descriptor and a buffer.
2766 * The CU read the transmit block which point to the tbd,
2767 * read the tbd and the content of the buffer.
2768 * When it has finish with it, it goes to the next command
2769 * which in our case is the NOP. The NOP points on itself,
2770 * so the CU stop here.
2771 * When we add the next block, we modify the previous nop
2772 * to make it point on the new tx command.
2773 * Simple, isn't it ?
2774 *
2775 * (called in wavelan_packet_xmit())
2776 */
2777static inline int wv_packet_write(struct net_device * dev, void *buf, short length)
2778{
2779 net_local *lp = (net_local *) dev->priv;
2780 unsigned long ioaddr = dev->base_addr;
2781 unsigned short txblock;
2782 unsigned short txpred;
2783 unsigned short tx_addr;
2784 unsigned short nop_addr;
2785 unsigned short tbd_addr;
2786 unsigned short buf_addr;
2787 ac_tx_t tx;
2788 ac_nop_t nop;
2789 tbd_t tbd;
2790 int clen = length;
2791 unsigned long flags;
2792
2793#ifdef DEBUG_TX_TRACE
2794 printk(KERN_DEBUG "%s: ->wv_packet_write(%d)\n", dev->name,
2795 length);
2796#endif
2797
2798 spin_lock_irqsave(&lp->spinlock, flags);
2799
2800 /* Check nothing bad has happened */
2801 if (lp->tx_n_in_use == (NTXBLOCKS - 1)) {
2802#ifdef DEBUG_TX_ERROR
2803 printk(KERN_INFO "%s: wv_packet_write(): Tx queue full.\n",
2804 dev->name);
2805#endif
2806 spin_unlock_irqrestore(&lp->spinlock, flags);
2807 return 1;
2808 }
2809
2810 /* Calculate addresses of next block and previous block. */
2811 txblock = lp->tx_first_free;
2812 txpred = txblock - TXBLOCKZ;
2813 if (txpred < OFFSET_CU)
2814 txpred += NTXBLOCKS * TXBLOCKZ;
2815 lp->tx_first_free += TXBLOCKZ;
2816 if (lp->tx_first_free >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ)
2817 lp->tx_first_free -= NTXBLOCKS * TXBLOCKZ;
2818
2819 lp->tx_n_in_use++;
2820
2821 /* Calculate addresses of the different parts of the block. */
2822 tx_addr = txblock;
2823 nop_addr = tx_addr + sizeof(tx);
2824 tbd_addr = nop_addr + sizeof(nop);
2825 buf_addr = tbd_addr + sizeof(tbd);
2826
2827 /*
2828 * Transmit command
2829 */
2830 tx.tx_h.ac_status = 0;
2831 obram_write(ioaddr, toff(ac_tx_t, tx_addr, tx_h.ac_status),
2832 (unsigned char *) &tx.tx_h.ac_status,
2833 sizeof(tx.tx_h.ac_status));
2834
2835 /*
2836 * NOP command
2837 */
2838 nop.nop_h.ac_status = 0;
2839 obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status),
2840 (unsigned char *) &nop.nop_h.ac_status,
2841 sizeof(nop.nop_h.ac_status));
2842 nop.nop_h.ac_link = nop_addr;
2843 obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link),
2844 (unsigned char *) &nop.nop_h.ac_link,
2845 sizeof(nop.nop_h.ac_link));
2846
2847 /*
2848 * Transmit buffer descriptor
2849 */
2850 tbd.tbd_status = TBD_STATUS_EOF | (TBD_STATUS_ACNT & clen);
2851 tbd.tbd_next_bd_offset = I82586NULL;
2852 tbd.tbd_bufl = buf_addr;
2853 tbd.tbd_bufh = 0;
2854 obram_write(ioaddr, tbd_addr, (unsigned char *) &tbd, sizeof(tbd));
2855
2856 /*
2857 * Data
2858 */
2859 obram_write(ioaddr, buf_addr, buf, length);
2860
2861 /*
2862 * Overwrite the predecessor NOP link
2863 * so that it points to this txblock.
2864 */
2865 nop_addr = txpred + sizeof(tx);
2866 nop.nop_h.ac_status = 0;
2867 obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status),
2868 (unsigned char *) &nop.nop_h.ac_status,
2869 sizeof(nop.nop_h.ac_status));
2870 nop.nop_h.ac_link = txblock;
2871 obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link),
2872 (unsigned char *) &nop.nop_h.ac_link,
2873 sizeof(nop.nop_h.ac_link));
2874
2875 /* Make sure the watchdog will keep quiet for a while */
2876 dev->trans_start = jiffies;
2877
2878 /* Keep stats up to date. */
2879 lp->stats.tx_bytes += length;
2880
2881 if (lp->tx_first_in_use == I82586NULL)
2882 lp->tx_first_in_use = txblock;
2883
2884 if (lp->tx_n_in_use < NTXBLOCKS - 1)
2885 netif_wake_queue(dev);
2886
2887 spin_unlock_irqrestore(&lp->spinlock, flags);
2888
2889#ifdef DEBUG_TX_INFO
2890 wv_packet_info((u8 *) buf, length, dev->name,
2891 "wv_packet_write");
2892#endif /* DEBUG_TX_INFO */
2893
2894#ifdef DEBUG_TX_TRACE
2895 printk(KERN_DEBUG "%s: <-wv_packet_write()\n", dev->name);
2896#endif
2897
2898 return 0;
2899}
2900
2901/*------------------------------------------------------------------*/
2902/*
2903 * This routine is called when we want to send a packet (NET3 callback)
2904 * In this routine, we check if the harware is ready to accept
2905 * the packet. We also prevent reentrance. Then we call the function
2906 * to send the packet.
2907 */
2908static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev)
2909{
2910 net_local *lp = (net_local *) dev->priv;
2911 unsigned long flags;
2912
2913#ifdef DEBUG_TX_TRACE
2914 printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name,
2915 (unsigned) skb);
2916#endif
2917
2918 /*
2919 * Block a timer-based transmit from overlapping.
2920 * In other words, prevent reentering this routine.
2921 */
2922 netif_stop_queue(dev);
2923
2924 /* If somebody has asked to reconfigure the controller,
2925 * we can do it now.
2926 */
2927 if (lp->reconfig_82586) {
2928 spin_lock_irqsave(&lp->spinlock, flags);
2929 wv_82586_config(dev);
2930 spin_unlock_irqrestore(&lp->spinlock, flags);
2931 /* Check that we can continue */
2932 if (lp->tx_n_in_use == (NTXBLOCKS - 1))
2933 return 1;
2934 }
2935#ifdef DEBUG_TX_ERROR
2936 if (skb->next)
2937 printk(KERN_INFO "skb has next\n");
2938#endif
2939
2940 /* Do we need some padding? */
2941 /* Note : on wireless the propagation time is in the order of 1us,
2942 * and we don't have the Ethernet specific requirement of beeing
2943 * able to detect collisions, therefore in theory we don't really
2944 * need to pad. Jean II */
2945 if (skb->len < ETH_ZLEN) {
2946 skb = skb_padto(skb, ETH_ZLEN);
2947 if (skb == NULL)
2948 return 0;
2949 }
2950
2951 /* Write packet on the card */
2952 if(wv_packet_write(dev, skb->data, skb->len))
2953 return 1; /* We failed */
2954
2955 dev_kfree_skb(skb);
2956
2957#ifdef DEBUG_TX_TRACE
2958 printk(KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name);
2959#endif
2960 return 0;
2961}
2962
2963/*********************** HARDWARE CONFIGURATION ***********************/
2964/*
2965 * This part does the real job of starting and configuring the hardware.
2966 */
2967
2968/*--------------------------------------------------------------------*/
2969/*
2970 * Routine to initialize the Modem Management Controller.
2971 * (called by wv_hw_reset())
2972 */
2973static inline int wv_mmc_init(struct net_device * dev)
2974{
2975 unsigned long ioaddr = dev->base_addr;
2976 net_local *lp = (net_local *) dev->priv;
2977 psa_t psa;
2978 mmw_t m;
2979 int configured;
2980
2981#ifdef DEBUG_CONFIG_TRACE
2982 printk(KERN_DEBUG "%s: ->wv_mmc_init()\n", dev->name);
2983#endif
2984
2985 /* Read the parameter storage area. */
2986 psa_read(ioaddr, lp->hacr, 0, (unsigned char *) &psa, sizeof(psa));
2987
2988#ifdef USE_PSA_CONFIG
2989 configured = psa.psa_conf_status & 1;
2990#else
2991 configured = 0;
2992#endif
2993
2994 /* Is the PSA is not configured */
2995 if (!configured) {
2996 /* User will be able to configure NWID later (with iwconfig). */
2997 psa.psa_nwid[0] = 0;
2998 psa.psa_nwid[1] = 0;
2999
3000 /* no NWID checking since NWID is not set */
3001 psa.psa_nwid_select = 0;
3002
3003 /* Disable encryption */
3004 psa.psa_encryption_select = 0;
3005
3006 /* Set to standard values:
3007 * 0x04 for AT,
3008 * 0x01 for MCA,
3009 * 0x04 for PCMCIA and 2.00 card (AT&T 407-024689/E document)
3010 */
3011 if (psa.psa_comp_number & 1)
3012 psa.psa_thr_pre_set = 0x01;
3013 else
3014 psa.psa_thr_pre_set = 0x04;
3015 psa.psa_quality_thr = 0x03;
3016
3017 /* It is configured */
3018 psa.psa_conf_status |= 1;
3019
3020#ifdef USE_PSA_CONFIG
3021 /* Write the psa. */
3022 psa_write(ioaddr, lp->hacr,
3023 (char *) psa.psa_nwid - (char *) &psa,
3024 (unsigned char *) psa.psa_nwid, 4);
3025 psa_write(ioaddr, lp->hacr,
3026 (char *) &psa.psa_thr_pre_set - (char *) &psa,
3027 (unsigned char *) &psa.psa_thr_pre_set, 1);
3028 psa_write(ioaddr, lp->hacr,
3029 (char *) &psa.psa_quality_thr - (char *) &psa,
3030 (unsigned char *) &psa.psa_quality_thr, 1);
3031 psa_write(ioaddr, lp->hacr,
3032 (char *) &psa.psa_conf_status - (char *) &psa,
3033 (unsigned char *) &psa.psa_conf_status, 1);
3034 /* update the Wavelan checksum */
3035 update_psa_checksum(dev, ioaddr, lp->hacr);
3036#endif
3037 }
3038
3039 /* Zero the mmc structure. */
3040 memset(&m, 0x00, sizeof(m));
3041
3042 /* Copy PSA info to the mmc. */
3043 m.mmw_netw_id_l = psa.psa_nwid[1];
3044 m.mmw_netw_id_h = psa.psa_nwid[0];
3045
3046 if (psa.psa_nwid_select & 1)
3047 m.mmw_loopt_sel = 0x00;
3048 else
3049 m.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID;
3050
3051 memcpy(&m.mmw_encr_key, &psa.psa_encryption_key,
3052 sizeof(m.mmw_encr_key));
3053
3054 if (psa.psa_encryption_select)
3055 m.mmw_encr_enable =
3056 MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE;
3057 else
3058 m.mmw_encr_enable = 0;
3059
3060 m.mmw_thr_pre_set = psa.psa_thr_pre_set & 0x3F;
3061 m.mmw_quality_thr = psa.psa_quality_thr & 0x0F;
3062
3063 /*
3064 * Set default modem control parameters.
3065 * See NCR document 407-0024326 Rev. A.
3066 */
3067 m.mmw_jabber_enable = 0x01;
3068 m.mmw_freeze = 0;
3069 m.mmw_anten_sel = MMW_ANTEN_SEL_ALG_EN;
3070 m.mmw_ifs = 0x20;
3071 m.mmw_mod_delay = 0x04;
3072 m.mmw_jam_time = 0x38;
3073
3074 m.mmw_des_io_invert = 0;
3075 m.mmw_decay_prm = 0;
3076 m.mmw_decay_updat_prm = 0;
3077
3078 /* Write all info to MMC. */
3079 mmc_write(ioaddr, 0, (u8 *) & m, sizeof(m));
3080
3081 /* The following code starts the modem of the 2.00 frequency
3082 * selectable cards at power on. It's not strictly needed for the
3083 * following boots.
3084 * The original patch was by Joe Finney for the PCMCIA driver, but
3085 * I've cleaned it up a bit and added documentation.
3086 * Thanks to Loeke Brederveld from Lucent for the info.
3087 */
3088
3089 /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable)
3090 * Does it work for everybody, especially old cards? */
3091 /* Note: WFREQSEL verifies that it is able to read a sensible
3092 * frequency from EEPROM (address 0x00) and that MMR_FEE_STATUS_ID
3093 * is 0xA (Xilinx version) or 0xB (Ariadne version).
3094 * My test is more crude but does work. */
3095 if (!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
3096 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
3097 /* We must download the frequency parameters to the
3098 * synthesizers (from the EEPROM - area 1)
3099 * Note: as the EEPROM is automatically decremented, we set the end
3100 * if the area... */
3101 m.mmw_fee_addr = 0x0F;
3102 m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
3103 mmc_write(ioaddr, (char *) &m.mmw_fee_ctrl - (char *) &m,
3104 (unsigned char *) &m.mmw_fee_ctrl, 2);
3105
3106 /* Wait until the download is finished. */
3107 fee_wait(ioaddr, 100, 100);
3108
3109#ifdef DEBUG_CONFIG_INFO
3110 /* The frequency was in the last word downloaded. */
3111 mmc_read(ioaddr, (char *) &m.mmw_fee_data_l - (char *) &m,
3112 (unsigned char *) &m.mmw_fee_data_l, 2);
3113
3114 /* Print some info for the user. */
3115 printk(KERN_DEBUG
3116 "%s: WaveLAN 2.00 recognised (frequency select). Current frequency = %ld\n",
3117 dev->name,
3118 ((m.
3119 mmw_fee_data_h << 4) | (m.mmw_fee_data_l >> 4)) *
3120 5 / 2 + 24000L);
3121#endif
3122
3123 /* We must now download the power adjust value (gain) to
3124 * the synthesizers (from the EEPROM - area 7 - DAC). */
3125 m.mmw_fee_addr = 0x61;
3126 m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
3127 mmc_write(ioaddr, (char *) &m.mmw_fee_ctrl - (char *) &m,
3128 (unsigned char *) &m.mmw_fee_ctrl, 2);
3129
3130 /* Wait until the download is finished. */
3131 }
3132 /* if 2.00 card */
3133#ifdef DEBUG_CONFIG_TRACE
3134 printk(KERN_DEBUG "%s: <-wv_mmc_init()\n", dev->name);
3135#endif
3136 return 0;
3137}
3138
3139/*------------------------------------------------------------------*/
3140/*
3141 * Construct the fd and rbd structures.
3142 * Start the receive unit.
3143 * (called by wv_hw_reset())
3144 */
3145static inline int wv_ru_start(struct net_device * dev)
3146{
3147 net_local *lp = (net_local *) dev->priv;
3148 unsigned long ioaddr = dev->base_addr;
3149 u16 scb_cs;
3150 fd_t fd;
3151 rbd_t rbd;
3152 u16 rx;
3153 u16 rx_next;
3154 int i;
3155
3156#ifdef DEBUG_CONFIG_TRACE
3157 printk(KERN_DEBUG "%s: ->wv_ru_start()\n", dev->name);
3158#endif
3159
3160 obram_read(ioaddr, scboff(OFFSET_SCB, scb_status),
3161 (unsigned char *) &scb_cs, sizeof(scb_cs));
3162 if ((scb_cs & SCB_ST_RUS) == SCB_ST_RUS_RDY)
3163 return 0;
3164
3165 lp->rx_head = OFFSET_RU;
3166
3167 for (i = 0, rx = lp->rx_head; i < NRXBLOCKS; i++, rx = rx_next) {
3168 rx_next =
3169 (i == NRXBLOCKS - 1) ? lp->rx_head : rx + RXBLOCKZ;
3170
3171 fd.fd_status = 0;
3172 fd.fd_command = (i == NRXBLOCKS - 1) ? FD_COMMAND_EL : 0;
3173 fd.fd_link_offset = rx_next;
3174 fd.fd_rbd_offset = rx + sizeof(fd);
3175 obram_write(ioaddr, rx, (unsigned char *) &fd, sizeof(fd));
3176
3177 rbd.rbd_status = 0;
3178 rbd.rbd_next_rbd_offset = I82586NULL;
3179 rbd.rbd_bufl = rx + sizeof(fd) + sizeof(rbd);
3180 rbd.rbd_bufh = 0;
3181 rbd.rbd_el_size = RBD_EL | (RBD_SIZE & MAXDATAZ);
3182 obram_write(ioaddr, rx + sizeof(fd),
3183 (unsigned char *) &rbd, sizeof(rbd));
3184
3185 lp->rx_last = rx;
3186 }
3187
3188 obram_write(ioaddr, scboff(OFFSET_SCB, scb_rfa_offset),
3189 (unsigned char *) &lp->rx_head, sizeof(lp->rx_head));
3190
3191 scb_cs = SCB_CMD_RUC_GO;
3192 obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
3193 (unsigned char *) &scb_cs, sizeof(scb_cs));
3194
3195 set_chan_attn(ioaddr, lp->hacr);
3196
3197 for (i = 1000; i > 0; i--) {
3198 obram_read(ioaddr, scboff(OFFSET_SCB, scb_command),
3199 (unsigned char *) &scb_cs, sizeof(scb_cs));
3200 if (scb_cs == 0)
3201 break;
3202
3203 udelay(10);
3204 }
3205
3206 if (i <= 0) {
3207#ifdef DEBUG_CONFIG_ERROR
3208 printk(KERN_INFO
3209 "%s: wavelan_ru_start(): board not accepting command.\n",
3210 dev->name);
3211#endif
3212 return -1;
3213 }
3214#ifdef DEBUG_CONFIG_TRACE
3215 printk(KERN_DEBUG "%s: <-wv_ru_start()\n", dev->name);
3216#endif
3217 return 0;
3218}
3219
3220/*------------------------------------------------------------------*/
3221/*
3222 * Initialise the transmit blocks.
3223 * Start the command unit executing the NOP
3224 * self-loop of the first transmit block.
3225 *
3226 * Here we create the list of send buffers used to transmit packets
3227 * between the PC and the command unit. For each buffer, we create a
3228 * buffer descriptor (pointing on the buffer), a transmit command
3229 * (pointing to the buffer descriptor) and a NOP command.
3230 * The transmit command is linked to the NOP, and the NOP to itself.
3231 * When we will have finished executing the transmit command, we will
3232 * then loop on the NOP. By releasing the NOP link to a new command,
3233 * we may send another buffer.
3234 *
3235 * (called by wv_hw_reset())
3236 */
3237static inline int wv_cu_start(struct net_device * dev)
3238{
3239 net_local *lp = (net_local *) dev->priv;
3240 unsigned long ioaddr = dev->base_addr;
3241 int i;
3242 u16 txblock;
3243 u16 first_nop;
3244 u16 scb_cs;
3245
3246#ifdef DEBUG_CONFIG_TRACE
3247 printk(KERN_DEBUG "%s: ->wv_cu_start()\n", dev->name);
3248#endif
3249
3250 lp->tx_first_free = OFFSET_CU;
3251 lp->tx_first_in_use = I82586NULL;
3252
3253 for (i = 0, txblock = OFFSET_CU;
3254 i < NTXBLOCKS; i++, txblock += TXBLOCKZ) {
3255 ac_tx_t tx;
3256 ac_nop_t nop;
3257 tbd_t tbd;
3258 unsigned short tx_addr;
3259 unsigned short nop_addr;
3260 unsigned short tbd_addr;
3261 unsigned short buf_addr;
3262
3263 tx_addr = txblock;
3264 nop_addr = tx_addr + sizeof(tx);
3265 tbd_addr = nop_addr + sizeof(nop);
3266 buf_addr = tbd_addr + sizeof(tbd);
3267
3268 tx.tx_h.ac_status = 0;
3269 tx.tx_h.ac_command = acmd_transmit | AC_CFLD_I;
3270 tx.tx_h.ac_link = nop_addr;
3271 tx.tx_tbd_offset = tbd_addr;
3272 obram_write(ioaddr, tx_addr, (unsigned char *) &tx,
3273 sizeof(tx));
3274
3275 nop.nop_h.ac_status = 0;
3276 nop.nop_h.ac_command = acmd_nop;
3277 nop.nop_h.ac_link = nop_addr;
3278 obram_write(ioaddr, nop_addr, (unsigned char *) &nop,
3279 sizeof(nop));
3280
3281 tbd.tbd_status = TBD_STATUS_EOF;
3282 tbd.tbd_next_bd_offset = I82586NULL;
3283 tbd.tbd_bufl = buf_addr;
3284 tbd.tbd_bufh = 0;
3285 obram_write(ioaddr, tbd_addr, (unsigned char *) &tbd,
3286 sizeof(tbd));
3287 }
3288
3289 first_nop =
3290 OFFSET_CU + (NTXBLOCKS - 1) * TXBLOCKZ + sizeof(ac_tx_t);
3291 obram_write(ioaddr, scboff(OFFSET_SCB, scb_cbl_offset),
3292 (unsigned char *) &first_nop, sizeof(first_nop));
3293
3294 scb_cs = SCB_CMD_CUC_GO;
3295 obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
3296 (unsigned char *) &scb_cs, sizeof(scb_cs));
3297
3298 set_chan_attn(ioaddr, lp->hacr);
3299
3300 for (i = 1000; i > 0; i--) {
3301 obram_read(ioaddr, scboff(OFFSET_SCB, scb_command),
3302 (unsigned char *) &scb_cs, sizeof(scb_cs));
3303 if (scb_cs == 0)
3304 break;
3305
3306 udelay(10);
3307 }
3308
3309 if (i <= 0) {
3310#ifdef DEBUG_CONFIG_ERROR
3311 printk(KERN_INFO
3312 "%s: wavelan_cu_start(): board not accepting command.\n",
3313 dev->name);
3314#endif
3315 return -1;
3316 }
3317
3318 lp->tx_n_in_use = 0;
3319 netif_start_queue(dev);
3320#ifdef DEBUG_CONFIG_TRACE
3321 printk(KERN_DEBUG "%s: <-wv_cu_start()\n", dev->name);
3322#endif
3323 return 0;
3324}
3325
3326/*------------------------------------------------------------------*/
3327/*
3328 * This routine does a standard configuration of the WaveLAN
3329 * controller (i82586).
3330 *
3331 * It initialises the scp, iscp and scb structure
3332 * The first two are just pointers to the next.
3333 * The last one is used for basic configuration and for basic
3334 * communication (interrupt status).
3335 *
3336 * (called by wv_hw_reset())
3337 */
3338static inline int wv_82586_start(struct net_device * dev)
3339{
3340 net_local *lp = (net_local *) dev->priv;
3341 unsigned long ioaddr = dev->base_addr;
3342 scp_t scp; /* system configuration pointer */
3343 iscp_t iscp; /* intermediate scp */
3344 scb_t scb; /* system control block */
3345 ach_t cb; /* Action command header */
3346 u8 zeroes[512];
3347 int i;
3348
3349#ifdef DEBUG_CONFIG_TRACE
3350 printk(KERN_DEBUG "%s: ->wv_82586_start()\n", dev->name);
3351#endif
3352
3353 /*
3354 * Clear the onboard RAM.
3355 */
3356 memset(&zeroes[0], 0x00, sizeof(zeroes));
3357 for (i = 0; i < I82586_MEMZ; i += sizeof(zeroes))
3358 obram_write(ioaddr, i, &zeroes[0], sizeof(zeroes));
3359
3360 /*
3361 * Construct the command unit structures:
3362 * scp, iscp, scb, cb.
3363 */
3364 memset(&scp, 0x00, sizeof(scp));
3365 scp.scp_sysbus = SCP_SY_16BBUS;
3366 scp.scp_iscpl = OFFSET_ISCP;
3367 obram_write(ioaddr, OFFSET_SCP, (unsigned char *) &scp,
3368 sizeof(scp));
3369
3370 memset(&iscp, 0x00, sizeof(iscp));
3371 iscp.iscp_busy = 1;
3372 iscp.iscp_offset = OFFSET_SCB;
3373 obram_write(ioaddr, OFFSET_ISCP, (unsigned char *) &iscp,
3374 sizeof(iscp));
3375
3376 /* Our first command is to reset the i82586. */
3377 memset(&scb, 0x00, sizeof(scb));
3378 scb.scb_command = SCB_CMD_RESET;
3379 scb.scb_cbl_offset = OFFSET_CU;
3380 scb.scb_rfa_offset = OFFSET_RU;
3381 obram_write(ioaddr, OFFSET_SCB, (unsigned char *) &scb,
3382 sizeof(scb));
3383
3384 set_chan_attn(ioaddr, lp->hacr);
3385
3386 /* Wait for command to finish. */
3387 for (i = 1000; i > 0; i--) {
3388 obram_read(ioaddr, OFFSET_ISCP, (unsigned char *) &iscp,
3389 sizeof(iscp));
3390
3391 if (iscp.iscp_busy == (unsigned short) 0)
3392 break;
3393
3394 udelay(10);
3395 }
3396
3397 if (i <= 0) {
3398#ifdef DEBUG_CONFIG_ERROR
3399 printk(KERN_INFO
3400 "%s: wv_82586_start(): iscp_busy timeout.\n",
3401 dev->name);
3402#endif
3403 return -1;
3404 }
3405
3406 /* Check command completion. */
3407 for (i = 15; i > 0; i--) {
3408 obram_read(ioaddr, OFFSET_SCB, (unsigned char *) &scb,
3409 sizeof(scb));
3410
3411 if (scb.scb_status == (SCB_ST_CX | SCB_ST_CNA))
3412 break;
3413
3414 udelay(10);
3415 }
3416
3417 if (i <= 0) {
3418#ifdef DEBUG_CONFIG_ERROR
3419 printk(KERN_INFO
3420 "%s: wv_82586_start(): status: expected 0x%02x, got 0x%02x.\n",
3421 dev->name, SCB_ST_CX | SCB_ST_CNA, scb.scb_status);
3422#endif
3423 return -1;
3424 }
3425
3426 wv_ack(dev);
3427
3428 /* Set the action command header. */
3429 memset(&cb, 0x00, sizeof(cb));
3430 cb.ac_command = AC_CFLD_EL | (AC_CFLD_CMD & acmd_diagnose);
3431 cb.ac_link = OFFSET_CU;
3432 obram_write(ioaddr, OFFSET_CU, (unsigned char *) &cb, sizeof(cb));
3433
3434 if (wv_synchronous_cmd(dev, "diag()") == -1)
3435 return -1;
3436
3437 obram_read(ioaddr, OFFSET_CU, (unsigned char *) &cb, sizeof(cb));
3438 if (cb.ac_status & AC_SFLD_FAIL) {
3439#ifdef DEBUG_CONFIG_ERROR
3440 printk(KERN_INFO
3441 "%s: wv_82586_start(): i82586 Self Test failed.\n",
3442 dev->name);
3443#endif
3444 return -1;
3445 }
3446#ifdef DEBUG_I82586_SHOW
3447 wv_scb_show(ioaddr);
3448#endif
3449
3450#ifdef DEBUG_CONFIG_TRACE
3451 printk(KERN_DEBUG "%s: <-wv_82586_start()\n", dev->name);
3452#endif
3453 return 0;
3454}
3455
3456/*------------------------------------------------------------------*/
3457/*
3458 * This routine does a standard configuration of the WaveLAN
3459 * controller (i82586).
3460 *
3461 * This routine is a violent hack. We use the first free transmit block
3462 * to make our configuration. In the buffer area, we create the three
3463 * configuration commands (linked). We make the previous NOP point to
3464 * the beginning of the buffer instead of the tx command. After, we go
3465 * as usual to the NOP command.
3466 * Note that only the last command (mc_set) will generate an interrupt.
3467 *
3468 * (called by wv_hw_reset(), wv_82586_reconfig(), wavelan_packet_xmit())
3469 */
3470static void wv_82586_config(struct net_device * dev)
3471{
3472 net_local *lp = (net_local *) dev->priv;
3473 unsigned long ioaddr = dev->base_addr;
3474 unsigned short txblock;
3475 unsigned short txpred;
3476 unsigned short tx_addr;
3477 unsigned short nop_addr;
3478 unsigned short tbd_addr;
3479 unsigned short cfg_addr;
3480 unsigned short ias_addr;
3481 unsigned short mcs_addr;
3482 ac_tx_t tx;
3483 ac_nop_t nop;
3484 ac_cfg_t cfg; /* Configure action */
3485 ac_ias_t ias; /* IA-setup action */
3486 ac_mcs_t mcs; /* Multicast setup */
3487 struct dev_mc_list *dmi;
3488
3489#ifdef DEBUG_CONFIG_TRACE
3490 printk(KERN_DEBUG "%s: ->wv_82586_config()\n", dev->name);
3491#endif
3492
3493 /* Check nothing bad has happened */
3494 if (lp->tx_n_in_use == (NTXBLOCKS - 1)) {
3495#ifdef DEBUG_CONFIG_ERROR
3496 printk(KERN_INFO "%s: wv_82586_config(): Tx queue full.\n",
3497 dev->name);
3498#endif
3499 return;
3500 }
3501
3502 /* Calculate addresses of next block and previous block. */
3503 txblock = lp->tx_first_free;
3504 txpred = txblock - TXBLOCKZ;
3505 if (txpred < OFFSET_CU)
3506 txpred += NTXBLOCKS * TXBLOCKZ;
3507 lp->tx_first_free += TXBLOCKZ;
3508 if (lp->tx_first_free >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ)
3509 lp->tx_first_free -= NTXBLOCKS * TXBLOCKZ;
3510
3511 lp->tx_n_in_use++;
3512
3513 /* Calculate addresses of the different parts of the block. */
3514 tx_addr = txblock;
3515 nop_addr = tx_addr + sizeof(tx);
3516 tbd_addr = nop_addr + sizeof(nop);
3517 cfg_addr = tbd_addr + sizeof(tbd_t); /* beginning of the buffer */
3518 ias_addr = cfg_addr + sizeof(cfg);
3519 mcs_addr = ias_addr + sizeof(ias);
3520
3521 /*
3522 * Transmit command
3523 */
3524 tx.tx_h.ac_status = 0xFFFF; /* Fake completion value */
3525 obram_write(ioaddr, toff(ac_tx_t, tx_addr, tx_h.ac_status),
3526 (unsigned char *) &tx.tx_h.ac_status,
3527 sizeof(tx.tx_h.ac_status));
3528
3529 /*
3530 * NOP command
3531 */
3532 nop.nop_h.ac_status = 0;
3533 obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status),
3534 (unsigned char *) &nop.nop_h.ac_status,
3535 sizeof(nop.nop_h.ac_status));
3536 nop.nop_h.ac_link = nop_addr;
3537 obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link),
3538 (unsigned char *) &nop.nop_h.ac_link,
3539 sizeof(nop.nop_h.ac_link));
3540
3541 /* Create a configure action. */
3542 memset(&cfg, 0x00, sizeof(cfg));
3543
3544 /*
3545 * For Linux we invert AC_CFG_ALOC() so as to conform
3546 * to the way that net packets reach us from above.
3547 * (See also ac_tx_t.)
3548 *
3549 * Updated from Wavelan Manual WCIN085B
3550 */
3551 cfg.cfg_byte_cnt =
3552 AC_CFG_BYTE_CNT(sizeof(ac_cfg_t) - sizeof(ach_t));
3553 cfg.cfg_fifolim = AC_CFG_FIFOLIM(4);
3554 cfg.cfg_byte8 = AC_CFG_SAV_BF(1) | AC_CFG_SRDY(0);
3555 cfg.cfg_byte9 = AC_CFG_ELPBCK(0) |
3556 AC_CFG_ILPBCK(0) |
3557 AC_CFG_PRELEN(AC_CFG_PLEN_2) |
3558 AC_CFG_ALOC(1) | AC_CFG_ADDRLEN(WAVELAN_ADDR_SIZE);
3559 cfg.cfg_byte10 = AC_CFG_BOFMET(1) |
3560 AC_CFG_ACR(6) | AC_CFG_LINPRIO(0);
3561 cfg.cfg_ifs = 0x20;
3562 cfg.cfg_slotl = 0x0C;
3563 cfg.cfg_byte13 = AC_CFG_RETRYNUM(15) | AC_CFG_SLTTMHI(0);
3564 cfg.cfg_byte14 = AC_CFG_FLGPAD(0) |
3565 AC_CFG_BTSTF(0) |
3566 AC_CFG_CRC16(0) |
3567 AC_CFG_NCRC(0) |
3568 AC_CFG_TNCRS(1) |
3569 AC_CFG_MANCH(0) |
3570 AC_CFG_BCDIS(0) | AC_CFG_PRM(lp->promiscuous);
3571 cfg.cfg_byte15 = AC_CFG_ICDS(0) |
3572 AC_CFG_CDTF(0) | AC_CFG_ICSS(0) | AC_CFG_CSTF(0);
3573/*
3574 cfg.cfg_min_frm_len = AC_CFG_MNFRM(64);
3575*/
3576 cfg.cfg_min_frm_len = AC_CFG_MNFRM(8);
3577
3578 cfg.cfg_h.ac_command = (AC_CFLD_CMD & acmd_configure);
3579 cfg.cfg_h.ac_link = ias_addr;
3580 obram_write(ioaddr, cfg_addr, (unsigned char *) &cfg, sizeof(cfg));
3581
3582 /* Set up the MAC address */
3583 memset(&ias, 0x00, sizeof(ias));
3584 ias.ias_h.ac_command = (AC_CFLD_CMD & acmd_ia_setup);
3585 ias.ias_h.ac_link = mcs_addr;
3586 memcpy(&ias.ias_addr[0], (unsigned char *) &dev->dev_addr[0],
3587 sizeof(ias.ias_addr));
3588 obram_write(ioaddr, ias_addr, (unsigned char *) &ias, sizeof(ias));
3589
3590 /* Initialize adapter's Ethernet multicast addresses */
3591 memset(&mcs, 0x00, sizeof(mcs));
3592 mcs.mcs_h.ac_command = AC_CFLD_I | (AC_CFLD_CMD & acmd_mc_setup);
3593 mcs.mcs_h.ac_link = nop_addr;
3594 mcs.mcs_cnt = WAVELAN_ADDR_SIZE * lp->mc_count;
3595 obram_write(ioaddr, mcs_addr, (unsigned char *) &mcs, sizeof(mcs));
3596
3597 /* Any address to set? */
3598 if (lp->mc_count) {
3599 for (dmi = dev->mc_list; dmi; dmi = dmi->next)
3600 outsw(PIOP1(ioaddr), (u16 *) dmi->dmi_addr,
3601 WAVELAN_ADDR_SIZE >> 1);
3602
3603#ifdef DEBUG_CONFIG_INFO
3604 printk(KERN_DEBUG
3605 "%s: wv_82586_config(): set %d multicast addresses:\n",
3606 dev->name, lp->mc_count);
3607 for (dmi = dev->mc_list; dmi; dmi = dmi->next)
3608 printk(KERN_DEBUG
3609 " %02x:%02x:%02x:%02x:%02x:%02x\n",
3610 dmi->dmi_addr[0], dmi->dmi_addr[1],
3611 dmi->dmi_addr[2], dmi->dmi_addr[3],
3612 dmi->dmi_addr[4], dmi->dmi_addr[5]);
3613#endif
3614 }
3615
3616 /*
3617 * Overwrite the predecessor NOP link
3618 * so that it points to the configure action.
3619 */
3620 nop_addr = txpred + sizeof(tx);
3621 nop.nop_h.ac_status = 0;
3622 obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status),
3623 (unsigned char *) &nop.nop_h.ac_status,
3624 sizeof(nop.nop_h.ac_status));
3625 nop.nop_h.ac_link = cfg_addr;
3626 obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link),
3627 (unsigned char *) &nop.nop_h.ac_link,
3628 sizeof(nop.nop_h.ac_link));
3629
3630 /* Job done, clear the flag */
3631 lp->reconfig_82586 = 0;
3632
3633 if (lp->tx_first_in_use == I82586NULL)
3634 lp->tx_first_in_use = txblock;
3635
3636 if (lp->tx_n_in_use == (NTXBLOCKS - 1))
3637 netif_stop_queue(dev);
3638
3639#ifdef DEBUG_CONFIG_TRACE
3640 printk(KERN_DEBUG "%s: <-wv_82586_config()\n", dev->name);
3641#endif
3642}
3643
3644/*------------------------------------------------------------------*/
3645/*
3646 * This routine, called by wavelan_close(), gracefully stops the
3647 * WaveLAN controller (i82586).
3648 * (called by wavelan_close())
3649 */
3650static inline void wv_82586_stop(struct net_device * dev)
3651{
3652 net_local *lp = (net_local *) dev->priv;
3653 unsigned long ioaddr = dev->base_addr;
3654 u16 scb_cmd;
3655
3656#ifdef DEBUG_CONFIG_TRACE
3657 printk(KERN_DEBUG "%s: ->wv_82586_stop()\n", dev->name);
3658#endif
3659
3660 /* Suspend both command unit and receive unit. */
3661 scb_cmd =
3662 (SCB_CMD_CUC & SCB_CMD_CUC_SUS) | (SCB_CMD_RUC &
3663 SCB_CMD_RUC_SUS);
3664 obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
3665 (unsigned char *) &scb_cmd, sizeof(scb_cmd));
3666 set_chan_attn(ioaddr, lp->hacr);
3667
3668 /* No more interrupts */
3669 wv_ints_off(dev);
3670
3671#ifdef DEBUG_CONFIG_TRACE
3672 printk(KERN_DEBUG "%s: <-wv_82586_stop()\n", dev->name);
3673#endif
3674}
3675
3676/*------------------------------------------------------------------*/
3677/*
3678 * Totally reset the WaveLAN and restart it.
3679 * Performs the following actions:
3680 * 1. A power reset (reset DMA)
3681 * 2. Initialize the radio modem (using wv_mmc_init)
3682 * 3. Reset & Configure LAN controller (using wv_82586_start)
3683 * 4. Start the LAN controller's command unit
3684 * 5. Start the LAN controller's receive unit
3685 * (called by wavelan_interrupt(), wavelan_watchdog() & wavelan_open())
3686 */
3687static int wv_hw_reset(struct net_device * dev)
3688{
3689 net_local *lp = (net_local *) dev->priv;
3690 unsigned long ioaddr = dev->base_addr;
3691
3692#ifdef DEBUG_CONFIG_TRACE
3693 printk(KERN_DEBUG "%s: ->wv_hw_reset(dev=0x%x)\n", dev->name,
3694 (unsigned int) dev);
3695#endif
3696
3697 /* Increase the number of resets done. */
3698 lp->nresets++;
3699
3700 wv_hacr_reset(ioaddr);
3701 lp->hacr = HACR_DEFAULT;
3702
3703 if ((wv_mmc_init(dev) < 0) || (wv_82586_start(dev) < 0))
3704 return -1;
3705
3706 /* Enable the card to send interrupts. */
3707 wv_ints_on(dev);
3708
3709 /* Start card functions */
3710 if (wv_cu_start(dev) < 0)
3711 return -1;
3712
3713 /* Setup the controller and parameters */
3714 wv_82586_config(dev);
3715
3716 /* Finish configuration with the receive unit */
3717 if (wv_ru_start(dev) < 0)
3718 return -1;
3719
3720#ifdef DEBUG_CONFIG_TRACE
3721 printk(KERN_DEBUG "%s: <-wv_hw_reset()\n", dev->name);
3722#endif
3723 return 0;
3724}
3725
3726/*------------------------------------------------------------------*/
3727/*
3728 * Check if there is a WaveLAN at the specific base address.
3729 * As a side effect, this reads the MAC address.
3730 * (called in wavelan_probe() and init_module())
3731 */
3732static int wv_check_ioaddr(unsigned long ioaddr, u8 * mac)
3733{
3734 int i; /* Loop counter */
3735
3736 /* Check if the base address if available. */
3737 if (!request_region(ioaddr, sizeof(ha_t), "wavelan probe"))
3738 return -EBUSY; /* ioaddr already used */
3739
3740 /* Reset host interface */
3741 wv_hacr_reset(ioaddr);
3742
3743 /* Read the MAC address from the parameter storage area. */
3744 psa_read(ioaddr, HACR_DEFAULT, psaoff(0, psa_univ_mac_addr),
3745 mac, 6);
3746
3747 release_region(ioaddr, sizeof(ha_t));
3748
3749 /*
3750 * Check the first three octets of the address for the manufacturer's code.
3751 * Note: if this can't find your WaveLAN card, you've got a
3752 * non-NCR/AT&T/Lucent ISA card. See wavelan.p.h for detail on
3753 * how to configure your card.
3754 */
3755 for (i = 0; i < (sizeof(MAC_ADDRESSES) / sizeof(char) / 3); i++)
3756 if ((mac[0] == MAC_ADDRESSES[i][0]) &&
3757 (mac[1] == MAC_ADDRESSES[i][1]) &&
3758 (mac[2] == MAC_ADDRESSES[i][2]))
3759 return 0;
3760
3761#ifdef DEBUG_CONFIG_INFO
3762 printk(KERN_WARNING
3763 "WaveLAN (0x%3X): your MAC address might be %02X:%02X:%02X.\n",
3764 ioaddr, mac[0], mac[1], mac[2]);
3765#endif
3766 return -ENODEV;
3767}
3768
3769/************************ INTERRUPT HANDLING ************************/
3770
3771/*
3772 * This function is the interrupt handler for the WaveLAN card. This
3773 * routine will be called whenever:
3774 */
3775static irqreturn_t wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs)
3776{
3777 struct net_device *dev;
3778 unsigned long ioaddr;
3779 net_local *lp;
3780 u16 hasr;
3781 u16 status;
3782 u16 ack_cmd;
3783
3784 dev = dev_id;
3785
3786#ifdef DEBUG_INTERRUPT_TRACE
3787 printk(KERN_DEBUG "%s: ->wavelan_interrupt()\n", dev->name);
3788#endif
3789
3790 lp = (net_local *) dev->priv;
3791 ioaddr = dev->base_addr;
3792
3793#ifdef DEBUG_INTERRUPT_INFO
3794 /* Check state of our spinlock */
3795 if(spin_is_locked(&lp->spinlock))
3796 printk(KERN_DEBUG
3797 "%s: wavelan_interrupt(): spinlock is already locked !!!\n",
3798 dev->name);
3799#endif
3800
3801 /* Prevent reentrancy. We need to do that because we may have
3802 * multiple interrupt handler running concurrently.
3803 * It is safe because interrupts are disabled before acquiring
3804 * the spinlock. */
3805 spin_lock(&lp->spinlock);
3806
3807 /* We always had spurious interrupts at startup, but lately I
3808 * saw them comming *between* the request_irq() and the
3809 * spin_lock_irqsave() in wavelan_open(), so the spinlock
3810 * protection is no enough.
3811 * So, we also check lp->hacr that will tell us is we enabled
3812 * irqs or not (see wv_ints_on()).
3813 * We can't use netif_running(dev) because we depend on the
3814 * proper processing of the irq generated during the config. */
3815
3816 /* Which interrupt it is ? */
3817 hasr = hasr_read(ioaddr);
3818
3819#ifdef DEBUG_INTERRUPT_INFO
3820 printk(KERN_INFO
3821 "%s: wavelan_interrupt(): hasr 0x%04x; hacr 0x%04x.\n",
3822 dev->name, hasr, lp->hacr);
3823#endif
3824
3825 /* Check modem interrupt */
3826 if ((hasr & HASR_MMC_INTR) && (lp->hacr & HACR_MMC_INT_ENABLE)) {
3827 u8 dce_status;
3828
3829 /*
3830 * Interrupt from the modem management controller.
3831 * This will clear it -- ignored for now.
3832 */
3833 mmc_read(ioaddr, mmroff(0, mmr_dce_status), &dce_status,
3834 sizeof(dce_status));
3835
3836#ifdef DEBUG_INTERRUPT_ERROR
3837 printk(KERN_INFO
3838 "%s: wavelan_interrupt(): unexpected mmc interrupt: status 0x%04x.\n",
3839 dev->name, dce_status);
3840#endif
3841 }
3842
3843 /* Check if not controller interrupt */
3844 if (((hasr & HASR_82586_INTR) == 0) ||
3845 ((lp->hacr & HACR_82586_INT_ENABLE) == 0)) {
3846#ifdef DEBUG_INTERRUPT_ERROR
3847 printk(KERN_INFO
3848 "%s: wavelan_interrupt(): interrupt not coming from i82586 - hasr 0x%04x.\n",
3849 dev->name, hasr);
3850#endif
3851 spin_unlock (&lp->spinlock);
3852 return IRQ_NONE;
3853 }
3854
3855 /* Read interrupt data. */
3856 obram_read(ioaddr, scboff(OFFSET_SCB, scb_status),
3857 (unsigned char *) &status, sizeof(status));
3858
3859 /*
3860 * Acknowledge the interrupt(s).
3861 */
3862 ack_cmd = status & SCB_ST_INT;
3863 obram_write(ioaddr, scboff(OFFSET_SCB, scb_command),
3864 (unsigned char *) &ack_cmd, sizeof(ack_cmd));
3865 set_chan_attn(ioaddr, lp->hacr);
3866
3867#ifdef DEBUG_INTERRUPT_INFO
3868 printk(KERN_DEBUG "%s: wavelan_interrupt(): status 0x%04x.\n",
3869 dev->name, status);
3870#endif
3871
3872 /* Command completed. */
3873 if ((status & SCB_ST_CX) == SCB_ST_CX) {
3874#ifdef DEBUG_INTERRUPT_INFO
3875 printk(KERN_DEBUG
3876 "%s: wavelan_interrupt(): command completed.\n",
3877 dev->name);
3878#endif
3879 wv_complete(dev, ioaddr, lp);
3880 }
3881
3882 /* Frame received. */
3883 if ((status & SCB_ST_FR) == SCB_ST_FR) {
3884#ifdef DEBUG_INTERRUPT_INFO
3885 printk(KERN_DEBUG
3886 "%s: wavelan_interrupt(): received packet.\n",
3887 dev->name);
3888#endif
3889 wv_receive(dev);
3890 }
3891
3892 /* Check the state of the command unit. */
3893 if (((status & SCB_ST_CNA) == SCB_ST_CNA) ||
3894 (((status & SCB_ST_CUS) != SCB_ST_CUS_ACTV) &&
3895 (netif_running(dev)))) {
3896#ifdef DEBUG_INTERRUPT_ERROR
3897 printk(KERN_INFO
3898 "%s: wavelan_interrupt(): CU inactive -- restarting\n",
3899 dev->name);
3900#endif
3901 wv_hw_reset(dev);
3902 }
3903
3904 /* Check the state of the command unit. */
3905 if (((status & SCB_ST_RNR) == SCB_ST_RNR) ||
3906 (((status & SCB_ST_RUS) != SCB_ST_RUS_RDY) &&
3907 (netif_running(dev)))) {
3908#ifdef DEBUG_INTERRUPT_ERROR
3909 printk(KERN_INFO
3910 "%s: wavelan_interrupt(): RU not ready -- restarting\n",
3911 dev->name);
3912#endif
3913 wv_hw_reset(dev);
3914 }
3915
3916 /* Release spinlock */
3917 spin_unlock (&lp->spinlock);
3918
3919#ifdef DEBUG_INTERRUPT_TRACE
3920 printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name);
3921#endif
3922 return IRQ_HANDLED;
3923}
3924
3925/*------------------------------------------------------------------*/
3926/*
3927 * Watchdog: when we start a transmission, a timer is set for us in the
3928 * kernel. If the transmission completes, this timer is disabled. If
3929 * the timer expires, we are called and we try to unlock the hardware.
3930 */
3931static void wavelan_watchdog(struct net_device * dev)
3932{
3933 net_local * lp = (net_local *)dev->priv;
3934 u_long ioaddr = dev->base_addr;
3935 unsigned long flags;
3936 unsigned int nreaped;
3937
3938#ifdef DEBUG_INTERRUPT_TRACE
3939 printk(KERN_DEBUG "%s: ->wavelan_watchdog()\n", dev->name);
3940#endif
3941
3942#ifdef DEBUG_INTERRUPT_ERROR
3943 printk(KERN_INFO "%s: wavelan_watchdog: watchdog timer expired\n",
3944 dev->name);
3945#endif
3946
3947 /* Check that we came here for something */
3948 if (lp->tx_n_in_use <= 0) {
3949 return;
3950 }
3951
3952 spin_lock_irqsave(&lp->spinlock, flags);
3953
3954 /* Try to see if some buffers are not free (in case we missed
3955 * an interrupt */
3956 nreaped = wv_complete(dev, ioaddr, lp);
3957
3958#ifdef DEBUG_INTERRUPT_INFO
3959 printk(KERN_DEBUG
3960 "%s: wavelan_watchdog(): %d reaped, %d remain.\n",
3961 dev->name, nreaped, lp->tx_n_in_use);
3962#endif
3963
3964#ifdef DEBUG_PSA_SHOW
3965 {
3966 psa_t psa;
3967 psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
3968 wv_psa_show(&psa);
3969 }
3970#endif
3971#ifdef DEBUG_MMC_SHOW
3972 wv_mmc_show(dev);
3973#endif
3974#ifdef DEBUG_I82586_SHOW
3975 wv_cu_show(dev);
3976#endif
3977
3978 /* If no buffer has been freed */
3979 if (nreaped == 0) {
3980#ifdef DEBUG_INTERRUPT_ERROR
3981 printk(KERN_INFO
3982 "%s: wavelan_watchdog(): cleanup failed, trying reset\n",
3983 dev->name);
3984#endif
3985 wv_hw_reset(dev);
3986 }
3987
3988 /* At this point, we should have some free Tx buffer ;-) */
3989 if (lp->tx_n_in_use < NTXBLOCKS - 1)
3990 netif_wake_queue(dev);
3991
3992 spin_unlock_irqrestore(&lp->spinlock, flags);
3993
3994#ifdef DEBUG_INTERRUPT_TRACE
3995 printk(KERN_DEBUG "%s: <-wavelan_watchdog()\n", dev->name);
3996#endif
3997}
3998
3999/********************* CONFIGURATION CALLBACKS *********************/
4000/*
4001 * Here are the functions called by the Linux networking code (NET3)
4002 * for initialization, configuration and deinstallations of the
4003 * WaveLAN ISA hardware.
4004 */
4005
4006/*------------------------------------------------------------------*/
4007/*
4008 * Configure and start up the WaveLAN PCMCIA adaptor.
4009 * Called by NET3 when it "opens" the device.
4010 */
4011static int wavelan_open(struct net_device * dev)
4012{
4013 net_local * lp = (net_local *)dev->priv;
4014 unsigned long flags;
4015
4016#ifdef DEBUG_CALLBACK_TRACE
4017 printk(KERN_DEBUG "%s: ->wavelan_open(dev=0x%x)\n", dev->name,
4018 (unsigned int) dev);
4019#endif
4020
4021 /* Check irq */
4022 if (dev->irq == 0) {
4023#ifdef DEBUG_CONFIG_ERROR
4024 printk(KERN_WARNING "%s: wavelan_open(): no IRQ\n",
4025 dev->name);
4026#endif
4027 return -ENXIO;
4028 }
4029
4030 if (request_irq(dev->irq, &wavelan_interrupt, 0, "WaveLAN", dev) != 0)
4031 {
4032#ifdef DEBUG_CONFIG_ERROR
4033 printk(KERN_WARNING "%s: wavelan_open(): invalid IRQ\n",
4034 dev->name);
4035#endif
4036 return -EAGAIN;
4037 }
4038
4039 spin_lock_irqsave(&lp->spinlock, flags);
4040
4041 if (wv_hw_reset(dev) != -1) {
4042 netif_start_queue(dev);
4043 } else {
4044 free_irq(dev->irq, dev);
4045#ifdef DEBUG_CONFIG_ERROR
4046 printk(KERN_INFO
4047 "%s: wavelan_open(): impossible to start the card\n",
4048 dev->name);
4049#endif
4050 spin_unlock_irqrestore(&lp->spinlock, flags);
4051 return -EAGAIN;
4052 }
4053 spin_unlock_irqrestore(&lp->spinlock, flags);
4054
4055#ifdef DEBUG_CALLBACK_TRACE
4056 printk(KERN_DEBUG "%s: <-wavelan_open()\n", dev->name);
4057#endif
4058 return 0;
4059}
4060
4061/*------------------------------------------------------------------*/
4062/*
4063 * Shut down the WaveLAN ISA card.
4064 * Called by NET3 when it "closes" the device.
4065 */
4066static int wavelan_close(struct net_device * dev)
4067{
4068 net_local *lp = (net_local *) dev->priv;
4069 unsigned long flags;
4070
4071#ifdef DEBUG_CALLBACK_TRACE
4072 printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name,
4073 (unsigned int) dev);
4074#endif
4075
4076 netif_stop_queue(dev);
4077
4078 /*
4079 * Flush the Tx and disable Rx.
4080 */
4081 spin_lock_irqsave(&lp->spinlock, flags);
4082 wv_82586_stop(dev);
4083 spin_unlock_irqrestore(&lp->spinlock, flags);
4084
4085 free_irq(dev->irq, dev);
4086
4087#ifdef DEBUG_CALLBACK_TRACE
4088 printk(KERN_DEBUG "%s: <-wavelan_close()\n", dev->name);
4089#endif
4090 return 0;
4091}
4092
4093/*------------------------------------------------------------------*/
4094/*
4095 * Probe an I/O address, and if the WaveLAN is there configure the
4096 * device structure
4097 * (called by wavelan_probe() and via init_module()).
4098 */
4099static int __init wavelan_config(struct net_device *dev, unsigned short ioaddr)
4100{
4101 u8 irq_mask;
4102 int irq;
4103 net_local *lp;
4104 mac_addr mac;
4105 int err;
4106
4107 if (!request_region(ioaddr, sizeof(ha_t), "wavelan"))
4108 return -EADDRINUSE;
4109
4110 err = wv_check_ioaddr(ioaddr, mac);
4111 if (err)
4112 goto out;
4113
4114 memcpy(dev->dev_addr, mac, 6);
4115
4116 dev->base_addr = ioaddr;
4117
4118#ifdef DEBUG_CALLBACK_TRACE
4119 printk(KERN_DEBUG "%s: ->wavelan_config(dev=0x%x, ioaddr=0x%lx)\n",
4120 dev->name, (unsigned int) dev, ioaddr);
4121#endif
4122
4123 /* Check IRQ argument on command line. */
4124 if (dev->irq != 0) {
4125 irq_mask = wv_irq_to_psa(dev->irq);
4126
4127 if (irq_mask == 0) {
4128#ifdef DEBUG_CONFIG_ERROR
4129 printk(KERN_WARNING
4130 "%s: wavelan_config(): invalid IRQ %d ignored.\n",
4131 dev->name, dev->irq);
4132#endif
4133 dev->irq = 0;
4134 } else {
4135#ifdef DEBUG_CONFIG_INFO
4136 printk(KERN_DEBUG
4137 "%s: wavelan_config(): changing IRQ to %d\n",
4138 dev->name, dev->irq);
4139#endif
4140 psa_write(ioaddr, HACR_DEFAULT,
4141 psaoff(0, psa_int_req_no), &irq_mask, 1);
4142 /* update the Wavelan checksum */
4143 update_psa_checksum(dev, ioaddr, HACR_DEFAULT);
4144 wv_hacr_reset(ioaddr);
4145 }
4146 }
4147
4148 psa_read(ioaddr, HACR_DEFAULT, psaoff(0, psa_int_req_no),
4149 &irq_mask, 1);
4150 if ((irq = wv_psa_to_irq(irq_mask)) == -1) {
4151#ifdef DEBUG_CONFIG_ERROR
4152 printk(KERN_INFO
4153 "%s: wavelan_config(): could not wavelan_map_irq(%d).\n",
4154 dev->name, irq_mask);
4155#endif
4156 err = -EAGAIN;
4157 goto out;
4158 }
4159
4160 dev->irq = irq;
4161
4162 dev->mem_start = 0x0000;
4163 dev->mem_end = 0x0000;
4164 dev->if_port = 0;
4165
4166 /* Initialize device structures */
4167 memset(dev->priv, 0, sizeof(net_local));
4168 lp = (net_local *) dev->priv;
4169
4170 /* Back link to the device structure. */
4171 lp->dev = dev;
4172 /* Add the device at the beginning of the linked list. */
4173 lp->next = wavelan_list;
4174 wavelan_list = lp;
4175
4176 lp->hacr = HACR_DEFAULT;
4177
4178 /* Multicast stuff */
4179 lp->promiscuous = 0;
4180 lp->mc_count = 0;
4181
4182 /* Init spinlock */
4183 spin_lock_init(&lp->spinlock);
4184
4185 SET_MODULE_OWNER(dev);
4186 dev->open = wavelan_open;
4187 dev->stop = wavelan_close;
4188 dev->hard_start_xmit = wavelan_packet_xmit;
4189 dev->get_stats = wavelan_get_stats;
4190 dev->set_multicast_list = &wavelan_set_multicast_list;
4191 dev->tx_timeout = &wavelan_watchdog;
4192 dev->watchdog_timeo = WATCHDOG_JIFFIES;
4193#ifdef SET_MAC_ADDRESS
4194 dev->set_mac_address = &wavelan_set_mac_address;
4195#endif /* SET_MAC_ADDRESS */
4196
4197#ifdef WIRELESS_EXT /* if wireless extension exists in the kernel */
4198 dev->wireless_handlers = &wavelan_handler_def;
4199 lp->wireless_data.spy_data = &lp->spy_data;
4200 dev->wireless_data = &lp->wireless_data;
4201#endif
4202
4203 dev->mtu = WAVELAN_MTU;
4204
4205 /* Display nice information. */
4206 wv_init_info(dev);
4207
4208#ifdef DEBUG_CALLBACK_TRACE
4209 printk(KERN_DEBUG "%s: <-wavelan_config()\n", dev->name);
4210#endif
4211 return 0;
4212out:
4213 release_region(ioaddr, sizeof(ha_t));
4214 return err;
4215}
4216
4217/*------------------------------------------------------------------*/
4218/*
4219 * Check for a network adaptor of this type. Return '0' iff one
4220 * exists. There seem to be different interpretations of
4221 * the initial value of dev->base_addr.
4222 * We follow the example in drivers/net/ne.c.
4223 * (called in "Space.c")
4224 */
4225struct net_device * __init wavelan_probe(int unit)
4226{
4227 struct net_device *dev;
4228 short base_addr;
4229 int def_irq;
4230 int i;
4231 int r = 0;
4232
4233#ifdef STRUCT_CHECK
4234 if (wv_struct_check() != (char *) NULL) {
4235 printk(KERN_WARNING
4236 "%s: wavelan_probe(): structure/compiler botch: \"%s\"\n",
4237 dev->name, wv_struct_check());
4238 return -ENODEV;
4239 }
4240#endif /* STRUCT_CHECK */
4241
4242 dev = alloc_etherdev(sizeof(net_local));
4243 if (!dev)
4244 return ERR_PTR(-ENOMEM);
4245
4246 sprintf(dev->name, "eth%d", unit);
4247 netdev_boot_setup_check(dev);
4248 base_addr = dev->base_addr;
4249 def_irq = dev->irq;
4250
4251#ifdef DEBUG_CALLBACK_TRACE
4252 printk(KERN_DEBUG
4253 "%s: ->wavelan_probe(dev=%p (base_addr=0x%x))\n",
4254 dev->name, dev, (unsigned int) dev->base_addr);
4255#endif
4256
4257 /* Don't probe at all. */
4258 if (base_addr < 0) {
4259#ifdef DEBUG_CONFIG_ERROR
4260 printk(KERN_WARNING
4261 "%s: wavelan_probe(): invalid base address\n",
4262 dev->name);
4263#endif
4264 r = -ENXIO;
4265 } else if (base_addr > 0x100) { /* Check a single specified location. */
4266 r = wavelan_config(dev, base_addr);
4267#ifdef DEBUG_CONFIG_INFO
4268 if (r != 0)
4269 printk(KERN_DEBUG
4270 "%s: wavelan_probe(): no device at specified base address (0x%X) or address already in use\n",
4271 dev->name, base_addr);
4272#endif
4273
4274#ifdef DEBUG_CALLBACK_TRACE
4275 printk(KERN_DEBUG "%s: <-wavelan_probe()\n", dev->name);
4276#endif
4277 } else { /* Scan all possible addresses of the WaveLAN hardware. */
4278 for (i = 0; i < NELS(iobase); i++) {
4279 dev->irq = def_irq;
4280 if (wavelan_config(dev, iobase[i]) == 0) {
4281#ifdef DEBUG_CALLBACK_TRACE
4282 printk(KERN_DEBUG
4283 "%s: <-wavelan_probe()\n",
4284 dev->name);
4285#endif
4286 break;
4287 }
4288 }
4289 if (i == NELS(iobase))
4290 r = -ENODEV;
4291 }
4292 if (r)
4293 goto out;
4294 r = register_netdev(dev);
4295 if (r)
4296 goto out1;
4297 return dev;
4298out1:
4299 release_region(dev->base_addr, sizeof(ha_t));
4300 wavelan_list = wavelan_list->next;
4301out:
4302 free_netdev(dev);
4303 return ERR_PTR(r);
4304}
4305
4306/****************************** MODULE ******************************/
4307/*
4308 * Module entry point: insertion and removal
4309 */
4310
4311#ifdef MODULE
4312/*------------------------------------------------------------------*/
4313/*
4314 * Insertion of the module
4315 * I'm now quite proud of the multi-device support.
4316 */
4317int init_module(void)
4318{
4319 int ret = -EIO; /* Return error if no cards found */
4320 int i;
4321
4322#ifdef DEBUG_MODULE_TRACE
4323 printk(KERN_DEBUG "-> init_module()\n");
4324#endif
4325
4326 /* If probing is asked */
4327 if (io[0] == 0) {
4328#ifdef DEBUG_CONFIG_ERROR
4329 printk(KERN_WARNING
4330 "WaveLAN init_module(): doing device probing (bad !)\n");
4331 printk(KERN_WARNING
4332 "Specify base addresses while loading module to correct the problem\n");
4333#endif
4334
4335 /* Copy the basic set of address to be probed. */
4336 for (i = 0; i < NELS(iobase); i++)
4337 io[i] = iobase[i];
4338 }
4339
4340
4341 /* Loop on all possible base addresses. */
4342 i = -1;
4343 while ((io[++i] != 0) && (i < NELS(io))) {
4344 struct net_device *dev = alloc_etherdev(sizeof(net_local));
4345 if (!dev)
4346 break;
4347 if (name[i])
4348 strcpy(dev->name, name[i]); /* Copy name */
4349 dev->base_addr = io[i];
4350 dev->irq = irq[i];
4351
4352 /* Check if there is something at this base address. */
4353 if (wavelan_config(dev, io[i]) == 0) {
4354 if (register_netdev(dev) != 0) {
4355 release_region(dev->base_addr, sizeof(ha_t));
4356 wavelan_list = wavelan_list->next;
4357 } else {
4358 ret = 0;
4359 continue;
4360 }
4361 }
4362 free_netdev(dev);
4363 }
4364
4365#ifdef DEBUG_CONFIG_ERROR
4366 if (!wavelan_list)
4367 printk(KERN_WARNING
4368 "WaveLAN init_module(): no device found\n");
4369#endif
4370
4371#ifdef DEBUG_MODULE_TRACE
4372 printk(KERN_DEBUG "<- init_module()\n");
4373#endif
4374 return ret;
4375}
4376
4377/*------------------------------------------------------------------*/
4378/*
4379 * Removal of the module
4380 */
4381void cleanup_module(void)
4382{
4383#ifdef DEBUG_MODULE_TRACE
4384 printk(KERN_DEBUG "-> cleanup_module()\n");
4385#endif
4386
4387 /* Loop on all devices and release them. */
4388 while (wavelan_list) {
4389 struct net_device *dev = wavelan_list->dev;
4390
4391#ifdef DEBUG_CONFIG_INFO
4392 printk(KERN_DEBUG
4393 "%s: cleanup_module(): removing device at 0x%x\n",
4394 dev->name, (unsigned int) dev);
4395#endif
4396 unregister_netdev(dev);
4397
4398 release_region(dev->base_addr, sizeof(ha_t));
4399 wavelan_list = wavelan_list->next;
4400
4401 free_netdev(dev);
4402 }
4403
4404#ifdef DEBUG_MODULE_TRACE
4405 printk(KERN_DEBUG "<- cleanup_module()\n");
4406#endif
4407}
4408#endif /* MODULE */
4409MODULE_LICENSE("GPL");
4410
4411/*
4412 * This software may only be used and distributed
4413 * according to the terms of the GNU General Public License.
4414 *
4415 * This software was developed as a component of the
4416 * Linux operating system.
4417 * It is based on other device drivers and information
4418 * either written or supplied by:
4419 * Ajay Bakre (bakre@paul.rutgers.edu),
4420 * Donald Becker (becker@scyld.com),
4421 * Loeke Brederveld (Loeke.Brederveld@Utrecht.NCR.com),
4422 * Anders Klemets (klemets@it.kth.se),
4423 * Vladimir V. Kolpakov (w@stier.koenig.ru),
4424 * Marc Meertens (Marc.Meertens@Utrecht.NCR.com),
4425 * Pauline Middelink (middelin@polyware.iaf.nl),
4426 * Robert Morris (rtm@das.harvard.edu),
4427 * Jean Tourrilhes (jt@hplb.hpl.hp.com),
4428 * Girish Welling (welling@paul.rutgers.edu),
4429 *
4430 * Thanks go also to:
4431 * James Ashton (jaa101@syseng.anu.edu.au),
4432 * Alan Cox (alan@redhat.com),
4433 * Allan Creighton (allanc@cs.usyd.edu.au),
4434 * Matthew Geier (matthew@cs.usyd.edu.au),
4435 * Remo di Giovanni (remo@cs.usyd.edu.au),
4436 * Eckhard Grah (grah@wrcs1.urz.uni-wuppertal.de),
4437 * Vipul Gupta (vgupta@cs.binghamton.edu),
4438 * Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM),
4439 * Tim Nicholson (tim@cs.usyd.edu.au),
4440 * Ian Parkin (ian@cs.usyd.edu.au),
4441 * John Rosenberg (johnr@cs.usyd.edu.au),
4442 * George Rossi (george@phm.gov.au),
4443 * Arthur Scott (arthur@cs.usyd.edu.au),
4444 * Peter Storey,
4445 * for their assistance and advice.
4446 *
4447 * Please send bug reports, updates, comments to:
4448 *
4449 * Bruce Janson Email: bruce@cs.usyd.edu.au
4450 * Basser Department of Computer Science Phone: +61-2-9351-3423
4451 * University of Sydney, N.S.W., 2006, AUSTRALIA Fax: +61-2-9351-3838
4452 */
diff --git a/drivers/net/wireless/wavelan.h b/drivers/net/wireless/wavelan.h
new file mode 100644
index 000000000000..27172cde5a39
--- /dev/null
+++ b/drivers/net/wireless/wavelan.h
@@ -0,0 +1,370 @@
1/*
2 * WaveLAN ISA driver
3 *
4 * Jean II - HPLB '96
5 *
6 * Reorganisation and extension of the driver.
7 * Original copyright follows. See wavelan.p.h for details.
8 *
9 * This file contains the declarations for the WaveLAN hardware. Note that
10 * the WaveLAN ISA includes a i82586 controller (see definitions in
11 * file i82586.h).
12 *
13 * The main difference between the ISA hardware and the PCMCIA one is
14 * the Ethernet controller (i82586 instead of i82593).
15 * The i82586 allows multiple transmit buffers. The PSA needs to be accessed
16 * through the host interface.
17 */
18
19#ifndef _WAVELAN_H
20#define _WAVELAN_H
21
22/************************** MAGIC NUMBERS ***************************/
23
24/* Detection of the WaveLAN card is done by reading the MAC
25 * address from the card and checking it. If you have a non-AT&T
26 * product (OEM, like DEC RoamAbout, Digital Ocean, or Epson),
27 * you might need to modify this part to accommodate your hardware.
28 */
29static const char MAC_ADDRESSES[][3] =
30{
31 { 0x08, 0x00, 0x0E }, /* AT&T WaveLAN (standard) & DEC RoamAbout */
32 { 0x08, 0x00, 0x6A }, /* AT&T WaveLAN (alternate) */
33 { 0x00, 0x00, 0xE1 }, /* Hitachi Wavelan */
34 { 0x00, 0x60, 0x1D } /* Lucent Wavelan (another one) */
35 /* Add your card here and send me the patch! */
36};
37
38#define WAVELAN_ADDR_SIZE 6 /* Size of a MAC address */
39
40#define WAVELAN_MTU 1500 /* Maximum size of WaveLAN packet */
41
42#define MAXDATAZ (WAVELAN_ADDR_SIZE + WAVELAN_ADDR_SIZE + 2 + WAVELAN_MTU)
43
44/*
45 * Constants used to convert channels to frequencies
46 */
47
48/* Frequency available in the 2.0 modem, in units of 250 kHz
49 * (as read in the offset register of the dac area).
50 * Used to map channel numbers used by `wfreqsel' to frequencies
51 */
52static const short channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8,
53 0xD0, 0xF0, 0xF8, 0x150 };
54
55/* Frequencies of the 1.0 modem (fixed frequencies).
56 * Use to map the PSA `subband' to a frequency
57 * Note : all frequencies apart from the first one need to be multiplied by 10
58 */
59static const int fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 };
60
61
62
63/*************************** PC INTERFACE ****************************/
64
65/*
66 * Host Adaptor structure.
67 * (base is board port address).
68 */
69typedef union hacs_u hacs_u;
70union hacs_u
71{
72 unsigned short hu_command; /* Command register */
73#define HACR_RESET 0x0001 /* Reset board */
74#define HACR_CA 0x0002 /* Set Channel Attention for 82586 */
75#define HACR_16BITS 0x0004 /* 16-bit operation (0 => 8bits) */
76#define HACR_OUT0 0x0008 /* General purpose output pin 0 */
77 /* not used - must be 1 */
78#define HACR_OUT1 0x0010 /* General purpose output pin 1 */
79 /* not used - must be 1 */
80#define HACR_82586_INT_ENABLE 0x0020 /* Enable 82586 interrupts */
81#define HACR_MMC_INT_ENABLE 0x0040 /* Enable MMC interrupts */
82#define HACR_INTR_CLR_ENABLE 0x0080 /* Enable interrupt status read/clear */
83 unsigned short hu_status; /* Status Register */
84#define HASR_82586_INTR 0x0001 /* Interrupt request from 82586 */
85#define HASR_MMC_INTR 0x0002 /* Interrupt request from MMC */
86#define HASR_MMC_BUSY 0x0004 /* MMC busy indication */
87#define HASR_PSA_BUSY 0x0008 /* LAN parameter storage area busy */
88};
89
90typedef struct ha_t ha_t;
91struct ha_t
92{
93 hacs_u ha_cs; /* Command and status registers */
94#define ha_command ha_cs.hu_command
95#define ha_status ha_cs.hu_status
96 unsigned short ha_mmcr; /* Modem Management Ctrl Register */
97 unsigned short ha_pior0; /* Program I/O Address Register Port 0 */
98 unsigned short ha_piop0; /* Program I/O Port 0 */
99 unsigned short ha_pior1; /* Program I/O Address Register Port 1 */
100 unsigned short ha_piop1; /* Program I/O Port 1 */
101 unsigned short ha_pior2; /* Program I/O Address Register Port 2 */
102 unsigned short ha_piop2; /* Program I/O Port 2 */
103};
104
105#define HA_SIZE 16
106
107#define hoff(p,f) (unsigned short)((void *)(&((ha_t *)((void *)0 + (p)))->f) - (void *)0)
108#define HACR(p) hoff(p, ha_command)
109#define HASR(p) hoff(p, ha_status)
110#define MMCR(p) hoff(p, ha_mmcr)
111#define PIOR0(p) hoff(p, ha_pior0)
112#define PIOP0(p) hoff(p, ha_piop0)
113#define PIOR1(p) hoff(p, ha_pior1)
114#define PIOP1(p) hoff(p, ha_piop1)
115#define PIOR2(p) hoff(p, ha_pior2)
116#define PIOP2(p) hoff(p, ha_piop2)
117
118/*
119 * Program I/O Mode Register values.
120 */
121#define STATIC_PIO 0 /* Mode 1: static mode */
122 /* RAM access ??? */
123#define AUTOINCR_PIO 1 /* Mode 2: auto increment mode */
124 /* RAM access ??? */
125#define AUTODECR_PIO 2 /* Mode 3: auto decrement mode */
126 /* RAM access ??? */
127#define PARAM_ACCESS_PIO 3 /* Mode 4: LAN parameter access mode */
128 /* Parameter access. */
129#define PIO_MASK 3 /* register mask */
130#define PIOM(cmd,piono) ((u_short)cmd << 10 << (piono * 2))
131
132#define HACR_DEFAULT (HACR_OUT0 | HACR_OUT1 | HACR_16BITS | PIOM(STATIC_PIO, 0) | PIOM(AUTOINCR_PIO, 1) | PIOM(PARAM_ACCESS_PIO, 2))
133#define HACR_INTRON (HACR_82586_INT_ENABLE | HACR_MMC_INT_ENABLE | HACR_INTR_CLR_ENABLE)
134
135/************************** MEMORY LAYOUT **************************/
136
137/*
138 * Onboard 64 k RAM layout.
139 * (Offsets from 0x0000.)
140 */
141#define OFFSET_RU 0x0000 /* 75% memory */
142#define OFFSET_CU 0xC000 /* 25% memory */
143#define OFFSET_SCB (OFFSET_ISCP - sizeof(scb_t))
144#define OFFSET_ISCP (OFFSET_SCP - sizeof(iscp_t))
145#define OFFSET_SCP I82586_SCP_ADDR
146
147#define RXBLOCKZ (sizeof(fd_t) + sizeof(rbd_t) + MAXDATAZ)
148#define TXBLOCKZ (sizeof(ac_tx_t) + sizeof(ac_nop_t) + sizeof(tbd_t) + MAXDATAZ)
149
150#define NRXBLOCKS ((OFFSET_CU - OFFSET_RU) / RXBLOCKZ)
151#define NTXBLOCKS ((OFFSET_SCB - OFFSET_CU) / TXBLOCKZ)
152
153/********************** PARAMETER STORAGE AREA **********************/
154
155/*
156 * Parameter Storage Area (PSA).
157 */
158typedef struct psa_t psa_t;
159struct psa_t
160{
161 unsigned char psa_io_base_addr_1; /* [0x00] Base address 1 ??? */
162 unsigned char psa_io_base_addr_2; /* [0x01] Base address 2 */
163 unsigned char psa_io_base_addr_3; /* [0x02] Base address 3 */
164 unsigned char psa_io_base_addr_4; /* [0x03] Base address 4 */
165 unsigned char psa_rem_boot_addr_1; /* [0x04] Remote Boot Address 1 */
166 unsigned char psa_rem_boot_addr_2; /* [0x05] Remote Boot Address 2 */
167 unsigned char psa_rem_boot_addr_3; /* [0x06] Remote Boot Address 3 */
168 unsigned char psa_holi_params; /* [0x07] HOst Lan Interface (HOLI) Parameters */
169 unsigned char psa_int_req_no; /* [0x08] Interrupt Request Line */
170 unsigned char psa_unused0[7]; /* [0x09-0x0F] unused */
171
172 unsigned char psa_univ_mac_addr[WAVELAN_ADDR_SIZE]; /* [0x10-0x15] Universal (factory) MAC Address */
173 unsigned char psa_local_mac_addr[WAVELAN_ADDR_SIZE]; /* [0x16-1B] Local MAC Address */
174 unsigned char psa_univ_local_sel; /* [0x1C] Universal Local Selection */
175#define PSA_UNIVERSAL 0 /* Universal (factory) */
176#define PSA_LOCAL 1 /* Local */
177 unsigned char psa_comp_number; /* [0x1D] Compatibility Number: */
178#define PSA_COMP_PC_AT_915 0 /* PC-AT 915 MHz */
179#define PSA_COMP_PC_MC_915 1 /* PC-MC 915 MHz */
180#define PSA_COMP_PC_AT_2400 2 /* PC-AT 2.4 GHz */
181#define PSA_COMP_PC_MC_2400 3 /* PC-MC 2.4 GHz */
182#define PSA_COMP_PCMCIA_915 4 /* PCMCIA 915 MHz or 2.0 */
183 unsigned char psa_thr_pre_set; /* [0x1E] Modem Threshold Preset */
184 unsigned char psa_feature_select; /* [0x1F] Call code required (1=on) */
185#define PSA_FEATURE_CALL_CODE 0x01 /* Call code required (Japan) */
186 unsigned char psa_subband; /* [0x20] Subband */
187#define PSA_SUBBAND_915 0 /* 915 MHz or 2.0 */
188#define PSA_SUBBAND_2425 1 /* 2425 MHz */
189#define PSA_SUBBAND_2460 2 /* 2460 MHz */
190#define PSA_SUBBAND_2484 3 /* 2484 MHz */
191#define PSA_SUBBAND_2430_5 4 /* 2430.5 MHz */
192 unsigned char psa_quality_thr; /* [0x21] Modem Quality Threshold */
193 unsigned char psa_mod_delay; /* [0x22] Modem Delay (?) (reserved) */
194 unsigned char psa_nwid[2]; /* [0x23-0x24] Network ID */
195 unsigned char psa_nwid_select; /* [0x25] Network ID Select On/Off */
196 unsigned char psa_encryption_select; /* [0x26] Encryption On/Off */
197 unsigned char psa_encryption_key[8]; /* [0x27-0x2E] Encryption Key */
198 unsigned char psa_databus_width; /* [0x2F] AT bus width select 8/16 */
199 unsigned char psa_call_code[8]; /* [0x30-0x37] (Japan) Call Code */
200 unsigned char psa_nwid_prefix[2]; /* [0x38-0x39] Roaming domain */
201 unsigned char psa_reserved[2]; /* [0x3A-0x3B] Reserved - fixed 00 */
202 unsigned char psa_conf_status; /* [0x3C] Conf Status, bit 0=1:config*/
203 unsigned char psa_crc[2]; /* [0x3D] CRC-16 over PSA */
204 unsigned char psa_crc_status; /* [0x3F] CRC Valid Flag */
205};
206
207#define PSA_SIZE 64
208
209/* Calculate offset of a field in the above structure.
210 * Warning: only even addresses are used. */
211#define psaoff(p,f) ((unsigned short) ((void *)(&((psa_t *) ((void *) NULL + (p)))->f) - (void *) NULL))
212
213/******************** MODEM MANAGEMENT INTERFACE ********************/
214
215/*
216 * Modem Management Controller (MMC) write structure.
217 */
218typedef struct mmw_t mmw_t;
219struct mmw_t
220{
221 unsigned char mmw_encr_key[8]; /* encryption key */
222 unsigned char mmw_encr_enable; /* Enable or disable encryption. */
223#define MMW_ENCR_ENABLE_MODE 0x02 /* mode of security option */
224#define MMW_ENCR_ENABLE_EN 0x01 /* Enable security option. */
225 unsigned char mmw_unused0[1]; /* unused */
226 unsigned char mmw_des_io_invert; /* encryption option */
227#define MMW_DES_IO_INVERT_RES 0x0F /* reserved */
228#define MMW_DES_IO_INVERT_CTRL 0xF0 /* control (?) (set to 0) */
229 unsigned char mmw_unused1[5]; /* unused */
230 unsigned char mmw_loopt_sel; /* looptest selection */
231#define MMW_LOOPT_SEL_DIS_NWID 0x40 /* Disable NWID filtering. */
232#define MMW_LOOPT_SEL_INT 0x20 /* Activate Attention Request. */
233#define MMW_LOOPT_SEL_LS 0x10 /* looptest, no collision avoidance */
234#define MMW_LOOPT_SEL_LT3A 0x08 /* looptest 3a */
235#define MMW_LOOPT_SEL_LT3B 0x04 /* looptest 3b */
236#define MMW_LOOPT_SEL_LT3C 0x02 /* looptest 3c */
237#define MMW_LOOPT_SEL_LT3D 0x01 /* looptest 3d */
238 unsigned char mmw_jabber_enable; /* jabber timer enable */
239 /* Abort transmissions > 200 ms */
240 unsigned char mmw_freeze; /* freeze or unfreeze signal level */
241 /* 0 : signal level & qual updated for every new message, 1 : frozen */
242 unsigned char mmw_anten_sel; /* antenna selection */
243#define MMW_ANTEN_SEL_SEL 0x01 /* direct antenna selection */
244#define MMW_ANTEN_SEL_ALG_EN 0x02 /* antenna selection algo. enable */
245 unsigned char mmw_ifs; /* inter frame spacing */
246 /* min time between transmission in bit periods (.5 us) - bit 0 ignored */
247 unsigned char mmw_mod_delay; /* modem delay (synchro) */
248 unsigned char mmw_jam_time; /* jamming time (after collision) */
249 unsigned char mmw_unused2[1]; /* unused */
250 unsigned char mmw_thr_pre_set; /* level threshold preset */
251 /* Discard all packet with signal < this value (4) */
252 unsigned char mmw_decay_prm; /* decay parameters */
253 unsigned char mmw_decay_updat_prm; /* decay update parameters */
254 unsigned char mmw_quality_thr; /* quality (z-quotient) threshold */
255 /* Discard all packet with quality < this value (3) */
256 unsigned char mmw_netw_id_l; /* NWID low order byte */
257 unsigned char mmw_netw_id_h; /* NWID high order byte */
258 /* Network ID or Domain : create virtual net on the air */
259
260 /* 2.0 Hardware extension - frequency selection support */
261 unsigned char mmw_mode_select; /* for analog tests (set to 0) */
262 unsigned char mmw_unused3[1]; /* unused */
263 unsigned char mmw_fee_ctrl; /* frequency EEPROM control */
264#define MMW_FEE_CTRL_PRE 0x10 /* Enable protected instructions. */
265#define MMW_FEE_CTRL_DWLD 0x08 /* Download EEPROM to mmc. */
266#define MMW_FEE_CTRL_CMD 0x07 /* EEPROM commands: */
267#define MMW_FEE_CTRL_READ 0x06 /* Read */
268#define MMW_FEE_CTRL_WREN 0x04 /* Write enable */
269#define MMW_FEE_CTRL_WRITE 0x05 /* Write data to address. */
270#define MMW_FEE_CTRL_WRALL 0x04 /* Write data to all addresses. */
271#define MMW_FEE_CTRL_WDS 0x04 /* Write disable */
272#define MMW_FEE_CTRL_PRREAD 0x16 /* Read addr from protect register */
273#define MMW_FEE_CTRL_PREN 0x14 /* Protect register enable */
274#define MMW_FEE_CTRL_PRCLEAR 0x17 /* Unprotect all registers. */
275#define MMW_FEE_CTRL_PRWRITE 0x15 /* Write address in protect register */
276#define MMW_FEE_CTRL_PRDS 0x14 /* Protect register disable */
277 /* Never issue the PRDS command: it's irreversible! */
278
279 unsigned char mmw_fee_addr; /* EEPROM address */
280#define MMW_FEE_ADDR_CHANNEL 0xF0 /* Select the channel. */
281#define MMW_FEE_ADDR_OFFSET 0x0F /* Offset in channel data */
282#define MMW_FEE_ADDR_EN 0xC0 /* FEE_CTRL enable operations */
283#define MMW_FEE_ADDR_DS 0x00 /* FEE_CTRL disable operations */
284#define MMW_FEE_ADDR_ALL 0x40 /* FEE_CTRL all operations */
285#define MMW_FEE_ADDR_CLEAR 0xFF /* FEE_CTRL clear operations */
286
287 unsigned char mmw_fee_data_l; /* Write data to EEPROM. */
288 unsigned char mmw_fee_data_h; /* high octet */
289 unsigned char mmw_ext_ant; /* Setting for external antenna */
290#define MMW_EXT_ANT_EXTANT 0x01 /* Select external antenna */
291#define MMW_EXT_ANT_POL 0x02 /* Polarity of the antenna */
292#define MMW_EXT_ANT_INTERNAL 0x00 /* Internal antenna */
293#define MMW_EXT_ANT_EXTERNAL 0x03 /* External antenna */
294#define MMW_EXT_ANT_IQ_TEST 0x1C /* IQ test pattern (set to 0) */
295};
296
297#define MMW_SIZE 37
298
299#define mmwoff(p,f) (unsigned short)((void *)(&((mmw_t *)((void *)0 + (p)))->f) - (void *)0)
300
301/*
302 * Modem Management Controller (MMC) read structure.
303 */
304typedef struct mmr_t mmr_t;
305struct mmr_t
306{
307 unsigned char mmr_unused0[8]; /* unused */
308 unsigned char mmr_des_status; /* encryption status */
309 unsigned char mmr_des_avail; /* encryption available (0x55 read) */
310#define MMR_DES_AVAIL_DES 0x55 /* DES available */
311#define MMR_DES_AVAIL_AES 0x33 /* AES (AT&T) available */
312 unsigned char mmr_des_io_invert; /* des I/O invert register */
313 unsigned char mmr_unused1[5]; /* unused */
314 unsigned char mmr_dce_status; /* DCE status */
315#define MMR_DCE_STATUS_RX_BUSY 0x01 /* receiver busy */
316#define MMR_DCE_STATUS_LOOPT_IND 0x02 /* loop test indicated */
317#define MMR_DCE_STATUS_TX_BUSY 0x04 /* transmitter on */
318#define MMR_DCE_STATUS_JBR_EXPIRED 0x08 /* jabber timer expired */
319#define MMR_DCE_STATUS 0x0F /* mask to get the bits */
320 unsigned char mmr_dsp_id; /* DSP ID (AA = Daedalus rev A) */
321 unsigned char mmr_unused2[2]; /* unused */
322 unsigned char mmr_correct_nwid_l; /* # of correct NWIDs rxd (low) */
323 unsigned char mmr_correct_nwid_h; /* # of correct NWIDs rxd (high) */
324 /* Warning: read high-order octet first! */
325 unsigned char mmr_wrong_nwid_l; /* # of wrong NWIDs rxd (low) */
326 unsigned char mmr_wrong_nwid_h; /* # of wrong NWIDs rxd (high) */
327 unsigned char mmr_thr_pre_set; /* level threshold preset */
328#define MMR_THR_PRE_SET 0x3F /* level threshold preset */
329#define MMR_THR_PRE_SET_CUR 0x80 /* Current signal above it */
330 unsigned char mmr_signal_lvl; /* signal level */
331#define MMR_SIGNAL_LVL 0x3F /* signal level */
332#define MMR_SIGNAL_LVL_VALID 0x80 /* Updated since last read */
333 unsigned char mmr_silence_lvl; /* silence level (noise) */
334#define MMR_SILENCE_LVL 0x3F /* silence level */
335#define MMR_SILENCE_LVL_VALID 0x80 /* Updated since last read */
336 unsigned char mmr_sgnl_qual; /* signal quality */
337#define MMR_SGNL_QUAL 0x0F /* signal quality */
338#define MMR_SGNL_QUAL_ANT 0x80 /* current antenna used */
339 unsigned char mmr_netw_id_l; /* NWID low order byte (?) */
340 unsigned char mmr_unused3[3]; /* unused */
341
342 /* 2.0 Hardware extension - frequency selection support */
343 unsigned char mmr_fee_status; /* Status of frequency EEPROM */
344#define MMR_FEE_STATUS_ID 0xF0 /* Modem revision ID */
345#define MMR_FEE_STATUS_DWLD 0x08 /* Download in progress */
346#define MMR_FEE_STATUS_BUSY 0x04 /* EEPROM busy */
347 unsigned char mmr_unused4[1]; /* unused */
348 unsigned char mmr_fee_data_l; /* Read data from EEPROM (low) */
349 unsigned char mmr_fee_data_h; /* Read data from EEPROM (high) */
350};
351
352#define MMR_SIZE 36
353
354#define mmroff(p,f) (unsigned short)((void *)(&((mmr_t *)((void *)0 + (p)))->f) - (void *)0)
355
356/* Make the two above structures one */
357typedef union mm_t
358{
359 struct mmw_t w; /* Write to the mmc */
360 struct mmr_t r; /* Read from the mmc */
361} mm_t;
362
363#endif /* _WAVELAN_H */
364
365/*
366 * This software may only be used and distributed
367 * according to the terms of the GNU General Public License.
368 *
369 * For more details, see wavelan.c.
370 */
diff --git a/drivers/net/wireless/wavelan.p.h b/drivers/net/wireless/wavelan.p.h
new file mode 100644
index 000000000000..509ff22a6caa
--- /dev/null
+++ b/drivers/net/wireless/wavelan.p.h
@@ -0,0 +1,716 @@
1/*
2 * WaveLAN ISA driver
3 *
4 * Jean II - HPLB '96
5 *
6 * Reorganisation and extension of the driver.
7 *
8 * This file contains all definitions and declarations necessary for the
9 * WaveLAN ISA driver. This file is a private header, so it should
10 * be included only in wavelan.c!
11 */
12
13#ifndef WAVELAN_P_H
14#define WAVELAN_P_H
15
16/************************** DOCUMENTATION ***************************/
17/*
18 * This driver provides a Linux interface to the WaveLAN ISA hardware.
19 * The WaveLAN is a product of Lucent (http://www.wavelan.com/).
20 * This division was formerly part of NCR and then AT&T.
21 * WaveLANs are also distributed by DEC (RoamAbout DS) and Digital Ocean.
22 *
23 * To learn how to use this driver, read the NET3 HOWTO.
24 * If you want to exploit the many other functionalities, read the comments
25 * in the code.
26 *
27 * This driver is the result of the effort of many people (see below).
28 */
29
30/* ------------------------ SPECIFIC NOTES ------------------------ */
31/*
32 * Web page
33 * --------
34 * I try to maintain a web page with the Wireless LAN Howto at :
35 * http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html
36 *
37 * SMP
38 * ---
39 * We now are SMP compliant (I eventually fixed the remaining bugs).
40 * The driver has been tested on a dual P6-150 and survived my usual
41 * set of torture tests.
42 * Anyway, I spent enough time chasing interrupt re-entrancy during
43 * errors or reconfigure, and I designed the locked/unlocked sections
44 * of the driver with great care, and with the recent addition of
45 * the spinlock (thanks to the new API), we should be quite close to
46 * the truth.
47 * The SMP/IRQ locking is quite coarse and conservative (i.e. not fast),
48 * but better safe than sorry (especially at 2 Mb/s ;-).
49 *
50 * I have also looked into disabling only our interrupt on the card
51 * (via HACR) instead of all interrupts in the processor (via cli),
52 * so that other driver are not impacted, and it look like it's
53 * possible, but it's very tricky to do right (full of races). As
54 * the gain would be mostly for SMP systems, it can wait...
55 *
56 * Debugging and options
57 * ---------------------
58 * You will find below a set of '#define" allowing a very fine control
59 * on the driver behaviour and the debug messages printed.
60 * The main options are :
61 * o SET_PSA_CRC, to have your card correctly recognised by
62 * an access point and the Point-to-Point diagnostic tool.
63 * o USE_PSA_CONFIG, to read configuration from the PSA (EEprom)
64 * (otherwise we always start afresh with some defaults)
65 *
66 * wavelan.o is too darned big
67 * ---------------------------
68 * That's true! There is a very simple way to reduce the driver
69 * object by 33%! Comment out the following line:
70 * #include <linux/wireless.h>
71 * Other compile options can also reduce the size of it...
72 *
73 * MAC address and hardware detection:
74 * -----------------------------------
75 * The detection code for the WaveLAN checks that the first three
76 * octets of the MAC address fit the company code. This type of
77 * detection works well for AT&T cards (because the AT&T code is
78 * hardcoded in wavelan.h), but of course will fail for other
79 * manufacturers.
80 *
81 * If you are sure that your card is derived from the WaveLAN,
82 * here is the way to configure it:
83 * 1) Get your MAC address
84 * a) With your card utilities (wfreqsel, instconf, etc.)
85 * b) With the driver:
86 * o compile the kernel with DEBUG_CONFIG_INFO enabled
87 * o Boot and look the card messages
88 * 2) Set your MAC code (3 octets) in MAC_ADDRESSES[][3] (wavelan.h)
89 * 3) Compile and verify
90 * 4) Send me the MAC code. I will include it in the next version.
91 *
92 */
93
94/* --------------------- WIRELESS EXTENSIONS --------------------- */
95/*
96 * This driver is the first to support "wireless extensions".
97 * This set of extensions provides a standard way to control the wireless
98 * characteristics of the hardware. Applications such as mobile IP may
99 * take advantage of it.
100 *
101 * You will need to enable the CONFIG_NET_RADIO define in the kernel
102 * configuration to enable the wireless extensions (this is the one
103 * giving access to the radio network device choice).
104 *
105 * It might also be a good idea as well to fetch the wireless tools to
106 * configure the device and play a bit.
107 */
108
109/* ---------------------------- FILES ---------------------------- */
110/*
111 * wavelan.c: actual code for the driver: C functions
112 *
113 * wavelan.p.h: private header: local types and variables for driver
114 *
115 * wavelan.h: description of the hardware interface and structs
116 *
117 * i82586.h: description of the Ethernet controller
118 */
119
120/* --------------------------- HISTORY --------------------------- */
121/*
122 * This is based on information in the drivers' headers. It may not be
123 * accurate, and I guarantee only my best effort.
124 *
125 * The history of the WaveLAN drivers is as complicated as the history of
126 * the WaveLAN itself (NCR -> AT&T -> Lucent).
127 *
128 * It all started with Anders Klemets <klemets@paul.rutgers.edu>
129 * writing a WaveLAN ISA driver for the Mach microkernel. Girish
130 * Welling <welling@paul.rutgers.edu> had also worked on it.
131 * Keith Moore modified this for the PCMCIA hardware.
132 *
133 * Robert Morris <rtm@das.harvard.edu> ported these two drivers to BSDI
134 * and added specific PCMCIA support (there is currently no equivalent
135 * of the PCMCIA package under BSD).
136 *
137 * Jim Binkley <jrb@cs.pdx.edu> ported both BSDI drivers to FreeBSD.
138 *
139 * Bruce Janson <bruce@cs.usyd.edu.au> ported the BSDI ISA driver to Linux.
140 *
141 * Anthony D. Joseph <adj@lcs.mit.edu> started to modify Bruce's driver
142 * (with help of the BSDI PCMCIA driver) for PCMCIA.
143 * Yunzhou Li <yunzhou@strat.iol.unh.edu> finished this work.
144 * Joe Finney <joe@comp.lancs.ac.uk> patched the driver to start
145 * 2.00 cards correctly (2.4 GHz with frequency selection).
146 * David Hinds <dahinds@users.sourceforge.net> integrated the whole in his
147 * PCMCIA package (and bug corrections).
148 *
149 * I (Jean Tourrilhes - jt@hplb.hpl.hp.com) then started to make some
150 * patches to the PCMCIA driver. Later, I added code in the ISA driver
151 * for Wireless Extensions and full support of frequency selection
152 * cards. Then, I did the same to the PCMCIA driver, and did some
153 * reorganisation. Finally, I came back to the ISA driver to
154 * upgrade it at the same level as the PCMCIA one and reorganise
155 * the code.
156 * Loeke Brederveld <lbrederv@wavelan.com> from Lucent has given me
157 * much needed information on the WaveLAN hardware.
158 */
159
160/* The original copyrights and literature mention others' names and
161 * credits. I don't know what their part in this development was.
162 */
163
164/* By the way, for the copyright and legal stuff:
165 * almost everybody wrote code under the GNU or BSD license (or similar),
166 * and want their original copyright to remain somewhere in the
167 * code (for myself, I go with the GPL).
168 * Nobody wants to take responsibility for anything, except the fame.
169 */
170
171/* --------------------------- CREDITS --------------------------- */
172/*
173 * This software was developed as a component of the
174 * Linux operating system.
175 * It is based on other device drivers and information
176 * either written or supplied by:
177 * Ajay Bakre <bakre@paul.rutgers.edu>,
178 * Donald Becker <becker@cesdis.gsfc.nasa.gov>,
179 * Loeke Brederveld <Loeke.Brederveld@Utrecht.NCR.com>,
180 * Brent Elphick <belphick@uwaterloo.ca>,
181 * Anders Klemets <klemets@it.kth.se>,
182 * Vladimir V. Kolpakov <w@stier.koenig.ru>,
183 * Marc Meertens <Marc.Meertens@Utrecht.NCR.com>,
184 * Pauline Middelink <middelin@polyware.iaf.nl>,
185 * Robert Morris <rtm@das.harvard.edu>,
186 * Jean Tourrilhes <jt@hpl.hp.com>,
187 * Girish Welling <welling@paul.rutgers.edu>,
188 * Clark Woodworth <clark@hiway1.exit109.com>
189 * Yongguang Zhang <ygz@isl.hrl.hac.com>
190 *
191 * Thanks go also to:
192 * James Ashton <jaa101@syseng.anu.edu.au>,
193 * Alan Cox <alan@redhat.com>,
194 * Allan Creighton <allanc@cs.usyd.edu.au>,
195 * Matthew Geier <matthew@cs.usyd.edu.au>,
196 * Remo di Giovanni <remo@cs.usyd.edu.au>,
197 * Eckhard Grah <grah@wrcs1.urz.uni-wuppertal.de>,
198 * Vipul Gupta <vgupta@cs.binghamton.edu>,
199 * Mark Hagan <mhagan@wtcpost.daytonoh.NCR.COM>,
200 * Tim Nicholson <tim@cs.usyd.edu.au>,
201 * Ian Parkin <ian@cs.usyd.edu.au>,
202 * John Rosenberg <johnr@cs.usyd.edu.au>,
203 * George Rossi <george@phm.gov.au>,
204 * Arthur Scott <arthur@cs.usyd.edu.au>,
205 * Stanislav Sinyagin <stas@isf.ru>
206 * and Peter Storey for their assistance and advice.
207 *
208 * Additional Credits:
209 *
210 * My development has been done initially under Debian 1.1 (Linux 2.0.x)
211 * and now under Debian 2.2, initially with an HP Vectra XP/60, and now
212 * an HP Vectra XP/90.
213 *
214 */
215
216/* ------------------------- IMPROVEMENTS ------------------------- */
217/*
218 * I proudly present:
219 *
220 * Changes made in first pre-release:
221 * ----------------------------------
222 * - reorganisation of the code, function name change
223 * - creation of private header (wavelan.p.h)
224 * - reorganised debug messages
225 * - more comments, history, etc.
226 * - mmc_init: configure the PSA if not done
227 * - mmc_init: correct default value of level threshold for PCMCIA
228 * - mmc_init: 2.00 detection better code for 2.00 initialization
229 * - better info at startup
230 * - IRQ setting (note: this setting is permanent)
231 * - watchdog: change strategy (and solve module removal problems)
232 * - add wireless extensions (ioctl and get_wireless_stats)
233 * get/set nwid/frequency on fly, info for /proc/net/wireless
234 * - more wireless extensions: SETSPY and GETSPY
235 * - make wireless extensions optional
236 * - private ioctl to set/get quality and level threshold, histogram
237 * - remove /proc/net/wavelan
238 * - suppress useless stuff from lp (net_local)
239 * - kernel 2.1 support (copy_to/from_user instead of memcpy_to/fromfs)
240 * - add message level (debug stuff in /var/adm/debug and errors not
241 * displayed at console and still in /var/adm/messages)
242 * - multi device support
243 * - start fixing the probe (init code)
244 * - more inlines
245 * - man page
246 * - many other minor details and cleanups
247 *
248 * Changes made in second pre-release:
249 * -----------------------------------
250 * - clean up init code (probe and module init)
251 * - better multiple device support (module)
252 * - name assignment (module)
253 *
254 * Changes made in third pre-release:
255 * ----------------------------------
256 * - be more conservative on timers
257 * - preliminary support for multicast (I still lack some details)
258 *
259 * Changes made in fourth pre-release:
260 * -----------------------------------
261 * - multicast (revisited and finished)
262 * - avoid reset in set_multicast_list (a really big hack)
263 * if somebody could apply this code for other i82586 based drivers
264 * - share onboard memory 75% RU and 25% CU (instead of 50/50)
265 *
266 * Changes made for release in 2.1.15:
267 * -----------------------------------
268 * - change the detection code for multi manufacturer code support
269 *
270 * Changes made for release in 2.1.17:
271 * -----------------------------------
272 * - update to wireless extensions changes
273 * - silly bug in card initial configuration (psa_conf_status)
274 *
275 * Changes made for release in 2.1.27 & 2.0.30:
276 * --------------------------------------------
277 * - small bug in debug code (probably not the last one...)
278 * - remove extern keyword for wavelan_probe()
279 * - level threshold is now a standard wireless extension (version 4 !)
280 * - modules parameters types (new module interface)
281 *
282 * Changes made for release in 2.1.36:
283 * -----------------------------------
284 * - byte count stats (courtesy of David Hinds)
285 * - remove dev_tint stuff (courtesy of David Hinds)
286 * - encryption setting from Brent Elphick (thanks a lot!)
287 * - 'ioaddr' to 'u_long' for the Alpha (thanks to Stanislav Sinyagin)
288 *
289 * Other changes (not by me) :
290 * -------------------------
291 * - Spelling and gramar "rectification".
292 *
293 * Changes made for release in 2.0.37 & 2.2.2 :
294 * ------------------------------------------
295 * - Correct status in /proc/net/wireless
296 * - Set PSA CRC to make PtP diagnostic tool happy (Bob Gray)
297 * - Module init code don't fail if we found at least one card in
298 * the address list (Karlis Peisenieks)
299 * - Missing parenthesis (Christopher Peterson)
300 * - Correct i82586 configuration parameters
301 * - Encryption initialisation bug (Robert McCormack)
302 * - New mac addresses detected in the probe
303 * - Increase watchdog for busy environments
304 *
305 * Changes made for release in 2.0.38 & 2.2.7 :
306 * ------------------------------------------
307 * - Correct the reception logic to better report errors and avoid
308 * sending bogus packet up the stack
309 * - Delay RU config to avoid corrupting first received packet
310 * - Change config completion code (to actually check something)
311 * - Avoid reading out of bound in skbuf to transmit
312 * - Rectify a lot of (useless) debugging code
313 * - Change the way to `#ifdef SET_PSA_CRC'
314 *
315 * Changes made for release in 2.2.11 & 2.3.13 :
316 * -------------------------------------------
317 * - Change e-mail and web page addresses
318 * - Watchdog timer is now correctly expressed in HZ, not in jiffies
319 * - Add channel number to the list of frequencies in range
320 * - Add the (short) list of bit-rates in range
321 * - Developp a new sensitivity... (sens.value & sens.fixed)
322 *
323 * Changes made for release in 2.2.14 & 2.3.23 :
324 * -------------------------------------------
325 * - Fix check for root permission (break instead of exit)
326 * - New nwid & encoding setting (Wireless Extension 9)
327 *
328 * Changes made for release in 2.3.49 :
329 * ----------------------------------
330 * - Indentation reformating (Alan)
331 * - Update to new network API (softnet - 2.3.43) :
332 * o replace dev->tbusy (Alan)
333 * o replace dev->tstart (Alan)
334 * o remove dev->interrupt (Alan)
335 * o add SMP locking via spinlock in splxx (me)
336 * o add spinlock in interrupt handler (me)
337 * o use kernel watchdog instead of ours (me)
338 * o increase watchdog timeout (kernel is more sensitive) (me)
339 * o verify that all the changes make sense and work (me)
340 * - Fixup a potential gotcha when reconfiguring and thighten a bit
341 * the interactions with Tx queue.
342 *
343 * Changes made for release in 2.4.0 :
344 * ---------------------------------
345 * - Fix spinlock stupid bugs that I left in. The driver is now SMP
346 * compliant and doesn't lockup at startup.
347 *
348 * Changes made for release in 2.5.2 :
349 * ---------------------------------
350 * - Use new driver API for Wireless Extensions :
351 * o got rid of wavelan_ioctl()
352 * o use a bunch of iw_handler instead
353 *
354 * Changes made for release in 2.5.35 :
355 * ----------------------------------
356 * - Set dev->trans_start to avoid filling the logs
357 * - Handle better spurious/bogus interrupt
358 * - Avoid deadlocks in mmc_out()/mmc_in()
359 *
360 * Wishes & dreams:
361 * ----------------
362 * - roaming (see Pcmcia driver)
363 */
364
365/***************************** INCLUDES *****************************/
366
367#include <linux/module.h>
368
369#include <linux/kernel.h>
370#include <linux/sched.h>
371#include <linux/types.h>
372#include <linux/fcntl.h>
373#include <linux/interrupt.h>
374#include <linux/stat.h>
375#include <linux/ptrace.h>
376#include <linux/ioport.h>
377#include <linux/in.h>
378#include <linux/string.h>
379#include <linux/delay.h>
380#include <linux/bitops.h>
381#include <asm/system.h>
382#include <asm/io.h>
383#include <asm/dma.h>
384#include <asm/uaccess.h>
385#include <linux/errno.h>
386#include <linux/netdevice.h>
387#include <linux/etherdevice.h>
388#include <linux/skbuff.h>
389#include <linux/slab.h>
390#include <linux/timer.h>
391#include <linux/init.h>
392
393#include <linux/wireless.h> /* Wireless extensions */
394#include <net/iw_handler.h> /* Wireless handlers */
395
396/* WaveLAN declarations */
397#include "i82586.h"
398#include "wavelan.h"
399
400/************************** DRIVER OPTIONS **************************/
401/*
402 * `#define' or `#undef' the following constant to change the behaviour
403 * of the driver...
404 */
405#undef SET_PSA_CRC /* Calculate and set the CRC on PSA (slower) */
406#define USE_PSA_CONFIG /* Use info from the PSA. */
407#undef STRUCT_CHECK /* Verify padding of structures. */
408#undef EEPROM_IS_PROTECTED /* doesn't seem to be necessary */
409#define MULTICAST_AVOID /* Avoid extra multicast (I'm sceptical). */
410#undef SET_MAC_ADDRESS /* Experimental */
411
412#ifdef WIRELESS_EXT /* If wireless extensions exist in the kernel */
413/* Warning: this stuff will slow down the driver. */
414#define WIRELESS_SPY /* Enable spying addresses. */
415#undef HISTOGRAM /* Enable histogram of signal level. */
416#endif
417
418/****************************** DEBUG ******************************/
419
420#undef DEBUG_MODULE_TRACE /* module insertion/removal */
421#undef DEBUG_CALLBACK_TRACE /* calls made by Linux */
422#undef DEBUG_INTERRUPT_TRACE /* calls to handler */
423#undef DEBUG_INTERRUPT_INFO /* type of interrupt and so on */
424#define DEBUG_INTERRUPT_ERROR /* problems */
425#undef DEBUG_CONFIG_TRACE /* Trace the config functions. */
426#undef DEBUG_CONFIG_INFO /* what's going on */
427#define DEBUG_CONFIG_ERROR /* errors on configuration */
428#undef DEBUG_TX_TRACE /* transmission calls */
429#undef DEBUG_TX_INFO /* header of the transmitted packet */
430#undef DEBUG_TX_FAIL /* Normal failure conditions */
431#define DEBUG_TX_ERROR /* Unexpected conditions */
432#undef DEBUG_RX_TRACE /* transmission calls */
433#undef DEBUG_RX_INFO /* header of the received packet */
434#undef DEBUG_RX_FAIL /* Normal failure conditions */
435#define DEBUG_RX_ERROR /* Unexpected conditions */
436
437#undef DEBUG_PACKET_DUMP /* Dump packet on the screen if defined to 32. */
438#undef DEBUG_IOCTL_TRACE /* misc. call by Linux */
439#undef DEBUG_IOCTL_INFO /* various debugging info */
440#define DEBUG_IOCTL_ERROR /* what's going wrong */
441#define DEBUG_BASIC_SHOW /* Show basic startup info. */
442#undef DEBUG_VERSION_SHOW /* Print version info. */
443#undef DEBUG_PSA_SHOW /* Dump PSA to screen. */
444#undef DEBUG_MMC_SHOW /* Dump mmc to screen. */
445#undef DEBUG_SHOW_UNUSED /* Show unused fields too. */
446#undef DEBUG_I82586_SHOW /* Show i82586 status. */
447#undef DEBUG_DEVICE_SHOW /* Show device parameters. */
448
449/************************ CONSTANTS & MACROS ************************/
450
451#ifdef DEBUG_VERSION_SHOW
452static const char *version = "wavelan.c : v24 (SMP + wireless extensions) 11/12/01\n";
453#endif
454
455/* Watchdog temporisation */
456#define WATCHDOG_JIFFIES (512*HZ/100)
457
458/* Macro to get the number of elements in an array */
459#define NELS(a) (sizeof(a) / sizeof(a[0]))
460
461/* ------------------------ PRIVATE IOCTL ------------------------ */
462
463#define SIOCSIPQTHR SIOCIWFIRSTPRIV /* Set quality threshold */
464#define SIOCGIPQTHR SIOCIWFIRSTPRIV + 1 /* Get quality threshold */
465
466#define SIOCSIPHISTO SIOCIWFIRSTPRIV + 2 /* Set histogram ranges */
467#define SIOCGIPHISTO SIOCIWFIRSTPRIV + 3 /* Get histogram values */
468
469/****************************** TYPES ******************************/
470
471/* Shortcuts */
472typedef struct net_device_stats en_stats;
473typedef struct iw_statistics iw_stats;
474typedef struct iw_quality iw_qual;
475typedef struct iw_freq iw_freq;
476typedef struct net_local net_local;
477typedef struct timer_list timer_list;
478
479/* Basic types */
480typedef u_char mac_addr[WAVELAN_ADDR_SIZE]; /* Hardware address */
481
482/*
483 * Static specific data for the interface.
484 *
485 * For each network interface, Linux keeps data in two structures: "device"
486 * keeps the generic data (same format for everybody) and "net_local" keeps
487 * additional specific data.
488 * Note that some of this specific data is in fact generic (en_stats, for
489 * example).
490 */
491struct net_local
492{
493 net_local * next; /* linked list of the devices */
494 struct net_device * dev; /* reverse link */
495 spinlock_t spinlock; /* Serialize access to the hardware (SMP) */
496 en_stats stats; /* Ethernet interface statistics */
497 int nresets; /* number of hardware resets */
498 u_char reconfig_82586; /* We need to reconfigure the controller. */
499 u_char promiscuous; /* promiscuous mode */
500 int mc_count; /* number of multicast addresses */
501 u_short hacr; /* current host interface state */
502
503 int tx_n_in_use;
504 u_short rx_head;
505 u_short rx_last;
506 u_short tx_first_free;
507 u_short tx_first_in_use;
508
509#ifdef WIRELESS_EXT
510 iw_stats wstats; /* Wireless-specific statistics */
511
512 struct iw_spy_data spy_data;
513 struct iw_public_data wireless_data;
514#endif
515
516#ifdef HISTOGRAM
517 int his_number; /* number of intervals */
518 u_char his_range[16]; /* boundaries of interval ]n-1; n] */
519 u_long his_sum[16]; /* sum in interval */
520#endif /* HISTOGRAM */
521};
522
523/**************************** PROTOTYPES ****************************/
524
525/* ----------------------- MISC. SUBROUTINES ------------------------ */
526static u_char
527 wv_irq_to_psa(int);
528static int
529 wv_psa_to_irq(u_char);
530/* ------------------- HOST ADAPTER SUBROUTINES ------------------- */
531static inline u_short /* data */
532 hasr_read(u_long); /* Read the host interface: base address */
533static inline void
534 hacr_write(u_long, /* Write to host interface: base address */
535 u_short), /* data */
536 hacr_write_slow(u_long,
537 u_short),
538 set_chan_attn(u_long, /* ioaddr */
539 u_short), /* hacr */
540 wv_hacr_reset(u_long), /* ioaddr */
541 wv_16_off(u_long, /* ioaddr */
542 u_short), /* hacr */
543 wv_16_on(u_long, /* ioaddr */
544 u_short), /* hacr */
545 wv_ints_off(struct net_device *),
546 wv_ints_on(struct net_device *);
547/* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */
548static void
549 psa_read(u_long, /* Read the Parameter Storage Area. */
550 u_short, /* hacr */
551 int, /* offset in PSA */
552 u_char *, /* buffer to fill */
553 int), /* size to read */
554 psa_write(u_long, /* Write to the PSA. */
555 u_short, /* hacr */
556 int, /* offset in PSA */
557 u_char *, /* buffer in memory */
558 int); /* length of buffer */
559static inline void
560 mmc_out(u_long, /* Write 1 byte to the Modem Manag Control. */
561 u_short,
562 u_char),
563 mmc_write(u_long, /* Write n bytes to the MMC. */
564 u_char,
565 u_char *,
566 int);
567static inline u_char /* Read 1 byte from the MMC. */
568 mmc_in(u_long,
569 u_short);
570static inline void
571 mmc_read(u_long, /* Read n bytes from the MMC. */
572 u_char,
573 u_char *,
574 int),
575 fee_wait(u_long, /* Wait for frequency EEPROM: base address */
576 int, /* base delay to wait for */
577 int); /* time to wait */
578static void
579 fee_read(u_long, /* Read the frequency EEPROM: base address */
580 u_short, /* destination offset */
581 u_short *, /* data buffer */
582 int); /* number of registers */
583/* ---------------------- I82586 SUBROUTINES ----------------------- */
584static /*inline*/ void
585 obram_read(u_long, /* ioaddr */
586 u_short, /* o */
587 u_char *, /* b */
588 int); /* n */
589static inline void
590 obram_write(u_long, /* ioaddr */
591 u_short, /* o */
592 u_char *, /* b */
593 int); /* n */
594static void
595 wv_ack(struct net_device *);
596static inline int
597 wv_synchronous_cmd(struct net_device *,
598 const char *),
599 wv_config_complete(struct net_device *,
600 u_long,
601 net_local *);
602static int
603 wv_complete(struct net_device *,
604 u_long,
605 net_local *);
606static inline void
607 wv_82586_reconfig(struct net_device *);
608/* ------------------- DEBUG & INFO SUBROUTINES ------------------- */
609#ifdef DEBUG_I82586_SHOW
610static void
611 wv_scb_show(unsigned short);
612#endif
613static inline void
614 wv_init_info(struct net_device *); /* display startup info */
615/* ------------------- IOCTL, STATS & RECONFIG ------------------- */
616static en_stats *
617 wavelan_get_stats(struct net_device *); /* Give stats /proc/net/dev */
618static iw_stats *
619 wavelan_get_wireless_stats(struct net_device *);
620static void
621 wavelan_set_multicast_list(struct net_device *);
622/* ----------------------- PACKET RECEPTION ----------------------- */
623static inline void
624 wv_packet_read(struct net_device *, /* Read a packet from a frame. */
625 u_short,
626 int),
627 wv_receive(struct net_device *); /* Read all packets waiting. */
628/* --------------------- PACKET TRANSMISSION --------------------- */
629static inline int
630 wv_packet_write(struct net_device *, /* Write a packet to the Tx buffer. */
631 void *,
632 short);
633static int
634 wavelan_packet_xmit(struct sk_buff *, /* Send a packet. */
635 struct net_device *);
636/* -------------------- HARDWARE CONFIGURATION -------------------- */
637static inline int
638 wv_mmc_init(struct net_device *), /* Initialize the modem. */
639 wv_ru_start(struct net_device *), /* Start the i82586 receiver unit. */
640 wv_cu_start(struct net_device *), /* Start the i82586 command unit. */
641 wv_82586_start(struct net_device *); /* Start the i82586. */
642static void
643 wv_82586_config(struct net_device *); /* Configure the i82586. */
644static inline void
645 wv_82586_stop(struct net_device *);
646static int
647 wv_hw_reset(struct net_device *), /* Reset the WaveLAN hardware. */
648 wv_check_ioaddr(u_long, /* ioaddr */
649 u_char *); /* mac address (read) */
650/* ---------------------- INTERRUPT HANDLING ---------------------- */
651static irqreturn_t
652 wavelan_interrupt(int, /* interrupt handler */
653 void *,
654 struct pt_regs *);
655static void
656 wavelan_watchdog(struct net_device *); /* transmission watchdog */
657/* ------------------- CONFIGURATION CALLBACKS ------------------- */
658static int
659 wavelan_open(struct net_device *), /* Open the device. */
660 wavelan_close(struct net_device *), /* Close the device. */
661 wavelan_config(struct net_device *, unsigned short);/* Configure one device. */
662extern struct net_device *wavelan_probe(int unit); /* See Space.c. */
663
664/**************************** VARIABLES ****************************/
665
666/*
667 * This is the root of the linked list of WaveLAN drivers
668 * It is use to verify that we don't reuse the same base address
669 * for two different drivers and to clean up when removing the module.
670 */
671static net_local * wavelan_list = (net_local *) NULL;
672
673/*
674 * This table is used to translate the PSA value to IRQ number
675 * and vice versa.
676 */
677static u_char irqvals[] =
678{
679 0, 0, 0, 0x01,
680 0x02, 0x04, 0, 0x08,
681 0, 0, 0x10, 0x20,
682 0x40, 0, 0, 0x80,
683};
684
685/*
686 * Table of the available I/O addresses (base addresses) for WaveLAN
687 */
688static unsigned short iobase[] =
689{
690#if 0
691 /* Leave out 0x3C0 for now -- seems to clash with some video
692 * controllers.
693 * Leave out the others too -- we will always use 0x390 and leave
694 * 0x300 for the Ethernet device.
695 * Jean II: 0x3E0 is fine as well.
696 */
697 0x300, 0x390, 0x3E0, 0x3C0
698#endif /* 0 */
699 0x390, 0x3E0
700};
701
702#ifdef MODULE
703/* Parameters set by insmod */
704static int io[4];
705static int irq[4];
706static char *name[4];
707module_param_array(io, int, NULL, 0);
708module_param_array(irq, int, NULL, 0);
709module_param_array(name, charp, NULL, 0);
710
711MODULE_PARM_DESC(io, "WaveLAN I/O base address(es),required");
712MODULE_PARM_DESC(irq, "WaveLAN IRQ number(s)");
713MODULE_PARM_DESC(name, "WaveLAN interface neme(s)");
714#endif /* MODULE */
715
716#endif /* WAVELAN_P_H */
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
new file mode 100644
index 000000000000..ec8329788e49
--- /dev/null
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -0,0 +1,4914 @@
1/*
2 * Wavelan Pcmcia driver
3 *
4 * Jean II - HPLB '96
5 *
6 * Reorganisation and extension of the driver.
7 * Original copyright follow. See wavelan_cs.p.h for details.
8 *
9 * This code is derived from Anthony D. Joseph's code and all the changes here
10 * are also under the original copyright below.
11 *
12 * This code supports version 2.00 of WaveLAN/PCMCIA cards (2.4GHz), and
13 * can work on Linux 2.0.36 with support of David Hinds' PCMCIA Card Services
14 *
15 * Joe Finney (joe@comp.lancs.ac.uk) at Lancaster University in UK added
16 * critical code in the routine to initialize the Modem Management Controller.
17 *
18 * Thanks to Alan Cox and Bruce Janson for their advice.
19 *
20 * -- Yunzhou Li (scip4166@nus.sg)
21 *
22#ifdef WAVELAN_ROAMING
23 * Roaming support added 07/22/98 by Justin Seger (jseger@media.mit.edu)
24 * based on patch by Joe Finney from Lancaster University.
25#endif
26 *
27 * Lucent (formerly AT&T GIS, formerly NCR) WaveLAN PCMCIA card: An
28 * Ethernet-like radio transceiver controlled by an Intel 82593 coprocessor.
29 *
30 * A non-shared memory PCMCIA ethernet driver for linux
31 *
32 * ISA version modified to support PCMCIA by Anthony Joseph (adj@lcs.mit.edu)
33 *
34 *
35 * Joseph O'Sullivan & John Langford (josullvn@cs.cmu.edu & jcl@cs.cmu.edu)
36 *
37 * Apr 2 '98 made changes to bring the i82593 control/int handling in line
38 * with offical specs...
39 *
40 ****************************************************************************
41 * Copyright 1995
42 * Anthony D. Joseph
43 * Massachusetts Institute of Technology
44 *
45 * Permission to use, copy, modify, and distribute this program
46 * for any purpose and without fee is hereby granted, provided
47 * that this copyright and permission notice appear on all copies
48 * and supporting documentation, the name of M.I.T. not be used
49 * in advertising or publicity pertaining to distribution of the
50 * program without specific prior permission, and notice be given
51 * in supporting documentation that copying and distribution is
52 * by permission of M.I.T. M.I.T. makes no representations about
53 * the suitability of this software for any purpose. It is pro-
54 * vided "as is" without express or implied warranty.
55 ****************************************************************************
56 *
57 */
58
59/* Do *NOT* add other headers here, you are guaranteed to be wrong - Jean II */
60#include "wavelan_cs.p.h" /* Private header */
61
62/************************* MISC SUBROUTINES **************************/
63/*
64 * Subroutines which won't fit in one of the following category
65 * (wavelan modem or i82593)
66 */
67
68#ifdef STRUCT_CHECK
69/*------------------------------------------------------------------*/
70/*
71 * Sanity routine to verify the sizes of the various WaveLAN interface
72 * structures.
73 */
74static char *
75wv_structuct_check(void)
76{
77#define SC(t,s,n) if (sizeof(t) != s) return(n);
78
79 SC(psa_t, PSA_SIZE, "psa_t");
80 SC(mmw_t, MMW_SIZE, "mmw_t");
81 SC(mmr_t, MMR_SIZE, "mmr_t");
82
83#undef SC
84
85 return((char *) NULL);
86} /* wv_structuct_check */
87#endif /* STRUCT_CHECK */
88
89/******************* MODEM MANAGEMENT SUBROUTINES *******************/
90/*
91 * Useful subroutines to manage the modem of the wavelan
92 */
93
94/*------------------------------------------------------------------*/
95/*
96 * Read from card's Host Adaptor Status Register.
97 */
98static inline u_char
99hasr_read(u_long base)
100{
101 return(inb(HASR(base)));
102} /* hasr_read */
103
104/*------------------------------------------------------------------*/
105/*
106 * Write to card's Host Adapter Command Register.
107 */
108static inline void
109hacr_write(u_long base,
110 u_char hacr)
111{
112 outb(hacr, HACR(base));
113} /* hacr_write */
114
115/*------------------------------------------------------------------*/
116/*
117 * Write to card's Host Adapter Command Register. Include a delay for
118 * those times when it is needed.
119 */
120static inline void
121hacr_write_slow(u_long base,
122 u_char hacr)
123{
124 hacr_write(base, hacr);
125 /* delay might only be needed sometimes */
126 mdelay(1);
127} /* hacr_write_slow */
128
129/*------------------------------------------------------------------*/
130/*
131 * Read the Parameter Storage Area from the WaveLAN card's memory
132 */
133static void
134psa_read(struct net_device * dev,
135 int o, /* offset in PSA */
136 u_char * b, /* buffer to fill */
137 int n) /* size to read */
138{
139 net_local *lp = netdev_priv(dev);
140 u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1);
141
142 while(n-- > 0)
143 {
144 *b++ = readb(ptr);
145 /* Due to a lack of address decode pins, the WaveLAN PCMCIA card
146 * only supports reading even memory addresses. That means the
147 * increment here MUST be two.
148 * Because of that, we can't use memcpy_fromio()...
149 */
150 ptr += 2;
151 }
152} /* psa_read */
153
154/*------------------------------------------------------------------*/
155/*
156 * Write the Paramter Storage Area to the WaveLAN card's memory
157 */
158static void
159psa_write(struct net_device * dev,
160 int o, /* Offset in psa */
161 u_char * b, /* Buffer in memory */
162 int n) /* Length of buffer */
163{
164 net_local *lp = netdev_priv(dev);
165 u_char __iomem *ptr = lp->mem + PSA_ADDR + (o << 1);
166 int count = 0;
167 kio_addr_t base = dev->base_addr;
168 /* As there seem to have no flag PSA_BUSY as in the ISA model, we are
169 * oblige to verify this address to know when the PSA is ready... */
170 volatile u_char __iomem *verify = lp->mem + PSA_ADDR +
171 (psaoff(0, psa_comp_number) << 1);
172
173 /* Authorize writting to PSA */
174 hacr_write(base, HACR_PWR_STAT | HACR_ROM_WEN);
175
176 while(n-- > 0)
177 {
178 /* write to PSA */
179 writeb(*b++, ptr);
180 ptr += 2;
181
182 /* I don't have the spec, so I don't know what the correct
183 * sequence to write is. This hack seem to work for me... */
184 count = 0;
185 while((readb(verify) != PSA_COMP_PCMCIA_915) && (count++ < 100))
186 mdelay(1);
187 }
188
189 /* Put the host interface back in standard state */
190 hacr_write(base, HACR_DEFAULT);
191} /* psa_write */
192
193#ifdef SET_PSA_CRC
194/*------------------------------------------------------------------*/
195/*
196 * Calculate the PSA CRC
197 * Thanks to Valster, Nico <NVALSTER@wcnd.nl.lucent.com> for the code
198 * NOTE: By specifying a length including the CRC position the
199 * returned value should be zero. (i.e. a correct checksum in the PSA)
200 *
201 * The Windows drivers don't use the CRC, but the AP and the PtP tool
202 * depend on it.
203 */
204static u_short
205psa_crc(unsigned char * psa, /* The PSA */
206 int size) /* Number of short for CRC */
207{
208 int byte_cnt; /* Loop on the PSA */
209 u_short crc_bytes = 0; /* Data in the PSA */
210 int bit_cnt; /* Loop on the bits of the short */
211
212 for(byte_cnt = 0; byte_cnt < size; byte_cnt++ )
213 {
214 crc_bytes ^= psa[byte_cnt]; /* Its an xor */
215
216 for(bit_cnt = 1; bit_cnt < 9; bit_cnt++ )
217 {
218 if(crc_bytes & 0x0001)
219 crc_bytes = (crc_bytes >> 1) ^ 0xA001;
220 else
221 crc_bytes >>= 1 ;
222 }
223 }
224
225 return crc_bytes;
226} /* psa_crc */
227#endif /* SET_PSA_CRC */
228
229/*------------------------------------------------------------------*/
230/*
231 * update the checksum field in the Wavelan's PSA
232 */
233static void
234update_psa_checksum(struct net_device * dev)
235{
236#ifdef SET_PSA_CRC
237 psa_t psa;
238 u_short crc;
239
240 /* read the parameter storage area */
241 psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
242
243 /* update the checksum */
244 crc = psa_crc((unsigned char *) &psa,
245 sizeof(psa) - sizeof(psa.psa_crc[0]) - sizeof(psa.psa_crc[1])
246 - sizeof(psa.psa_crc_status));
247
248 psa.psa_crc[0] = crc & 0xFF;
249 psa.psa_crc[1] = (crc & 0xFF00) >> 8;
250
251 /* Write it ! */
252 psa_write(dev, (char *)&psa.psa_crc - (char *)&psa,
253 (unsigned char *)&psa.psa_crc, 2);
254
255#ifdef DEBUG_IOCTL_INFO
256 printk (KERN_DEBUG "%s: update_psa_checksum(): crc = 0x%02x%02x\n",
257 dev->name, psa.psa_crc[0], psa.psa_crc[1]);
258
259 /* Check again (luxury !) */
260 crc = psa_crc((unsigned char *) &psa,
261 sizeof(psa) - sizeof(psa.psa_crc_status));
262
263 if(crc != 0)
264 printk(KERN_WARNING "%s: update_psa_checksum(): CRC does not agree with PSA data (even after recalculating)\n", dev->name);
265#endif /* DEBUG_IOCTL_INFO */
266#endif /* SET_PSA_CRC */
267} /* update_psa_checksum */
268
269/*------------------------------------------------------------------*/
270/*
271 * Write 1 byte to the MMC.
272 */
273static inline void
274mmc_out(u_long base,
275 u_short o,
276 u_char d)
277{
278 int count = 0;
279
280 /* Wait for MMC to go idle */
281 while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY))
282 udelay(10);
283
284 outb((u_char)((o << 1) | MMR_MMI_WR), MMR(base));
285 outb(d, MMD(base));
286}
287
288/*------------------------------------------------------------------*/
289/*
290 * Routine to write bytes to the Modem Management Controller.
291 * We start by the end because it is the way it should be !
292 */
293static inline void
294mmc_write(u_long base,
295 u_char o,
296 u_char * b,
297 int n)
298{
299 o += n;
300 b += n;
301
302 while(n-- > 0 )
303 mmc_out(base, --o, *(--b));
304} /* mmc_write */
305
306/*------------------------------------------------------------------*/
307/*
308 * Read 1 byte from the MMC.
309 * Optimised version for 1 byte, avoid using memory...
310 */
311static inline u_char
312mmc_in(u_long base,
313 u_short o)
314{
315 int count = 0;
316
317 while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY))
318 udelay(10);
319 outb(o << 1, MMR(base)); /* Set the read address */
320
321 outb(0, MMD(base)); /* Required dummy write */
322
323 while((count++ < 100) && (inb(HASR(base)) & HASR_MMI_BUSY))
324 udelay(10);
325 return (u_char) (inb(MMD(base))); /* Now do the actual read */
326}
327
328/*------------------------------------------------------------------*/
329/*
330 * Routine to read bytes from the Modem Management Controller.
331 * The implementation is complicated by a lack of address lines,
332 * which prevents decoding of the low-order bit.
333 * (code has just been moved in the above function)
334 * We start by the end because it is the way it should be !
335 */
336static inline void
337mmc_read(u_long base,
338 u_char o,
339 u_char * b,
340 int n)
341{
342 o += n;
343 b += n;
344
345 while(n-- > 0)
346 *(--b) = mmc_in(base, --o);
347} /* mmc_read */
348
349/*------------------------------------------------------------------*/
350/*
351 * Get the type of encryption available...
352 */
353static inline int
354mmc_encr(u_long base) /* i/o port of the card */
355{
356 int temp;
357
358 temp = mmc_in(base, mmroff(0, mmr_des_avail));
359 if((temp != MMR_DES_AVAIL_DES) && (temp != MMR_DES_AVAIL_AES))
360 return 0;
361 else
362 return temp;
363}
364
365/*------------------------------------------------------------------*/
366/*
367 * Wait for the frequency EEprom to complete a command...
368 * I hope this one will be optimally inlined...
369 */
370static inline void
371fee_wait(u_long base, /* i/o port of the card */
372 int delay, /* Base delay to wait for */
373 int number) /* Number of time to wait */
374{
375 int count = 0; /* Wait only a limited time */
376
377 while((count++ < number) &&
378 (mmc_in(base, mmroff(0, mmr_fee_status)) & MMR_FEE_STATUS_BUSY))
379 udelay(delay);
380}
381
382/*------------------------------------------------------------------*/
383/*
384 * Read bytes from the Frequency EEprom (frequency select cards).
385 */
386static void
387fee_read(u_long base, /* i/o port of the card */
388 u_short o, /* destination offset */
389 u_short * b, /* data buffer */
390 int n) /* number of registers */
391{
392 b += n; /* Position at the end of the area */
393
394 /* Write the address */
395 mmc_out(base, mmwoff(0, mmw_fee_addr), o + n - 1);
396
397 /* Loop on all buffer */
398 while(n-- > 0)
399 {
400 /* Write the read command */
401 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_READ);
402
403 /* Wait until EEprom is ready (should be quick !) */
404 fee_wait(base, 10, 100);
405
406 /* Read the value */
407 *--b = ((mmc_in(base, mmroff(0, mmr_fee_data_h)) << 8) |
408 mmc_in(base, mmroff(0, mmr_fee_data_l)));
409 }
410}
411
412#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
413
414/*------------------------------------------------------------------*/
415/*
416 * Write bytes from the Frequency EEprom (frequency select cards).
417 * This is a bit complicated, because the frequency eeprom has to
418 * be unprotected and the write enabled.
419 * Jean II
420 */
421static void
422fee_write(u_long base, /* i/o port of the card */
423 u_short o, /* destination offset */
424 u_short * b, /* data buffer */
425 int n) /* number of registers */
426{
427 b += n; /* Position at the end of the area */
428
429#ifdef EEPROM_IS_PROTECTED /* disabled */
430#ifdef DOESNT_SEEM_TO_WORK /* disabled */
431 /* Ask to read the protected register */
432 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRREAD);
433
434 fee_wait(base, 10, 100);
435
436 /* Read the protected register */
437 printk("Protected 2 : %02X-%02X\n",
438 mmc_in(base, mmroff(0, mmr_fee_data_h)),
439 mmc_in(base, mmroff(0, mmr_fee_data_l)));
440#endif /* DOESNT_SEEM_TO_WORK */
441
442 /* Enable protected register */
443 mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
444 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PREN);
445
446 fee_wait(base, 10, 100);
447
448 /* Unprotect area */
449 mmc_out(base, mmwoff(0, mmw_fee_addr), o + n);
450 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
451#ifdef DOESNT_SEEM_TO_WORK /* disabled */
452 /* Or use : */
453 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRCLEAR);
454#endif /* DOESNT_SEEM_TO_WORK */
455
456 fee_wait(base, 10, 100);
457#endif /* EEPROM_IS_PROTECTED */
458
459 /* Write enable */
460 mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_EN);
461 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WREN);
462
463 fee_wait(base, 10, 100);
464
465 /* Write the EEprom address */
466 mmc_out(base, mmwoff(0, mmw_fee_addr), o + n - 1);
467
468 /* Loop on all buffer */
469 while(n-- > 0)
470 {
471 /* Write the value */
472 mmc_out(base, mmwoff(0, mmw_fee_data_h), (*--b) >> 8);
473 mmc_out(base, mmwoff(0, mmw_fee_data_l), *b & 0xFF);
474
475 /* Write the write command */
476 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WRITE);
477
478 /* Wavelan doc says : wait at least 10 ms for EEBUSY = 0 */
479 mdelay(10);
480 fee_wait(base, 10, 100);
481 }
482
483 /* Write disable */
484 mmc_out(base, mmwoff(0, mmw_fee_addr), MMW_FEE_ADDR_DS);
485 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_WDS);
486
487 fee_wait(base, 10, 100);
488
489#ifdef EEPROM_IS_PROTECTED /* disabled */
490 /* Reprotect EEprom */
491 mmc_out(base, mmwoff(0, mmw_fee_addr), 0x00);
492 mmc_out(base, mmwoff(0, mmw_fee_ctrl), MMW_FEE_CTRL_PRWRITE);
493
494 fee_wait(base, 10, 100);
495#endif /* EEPROM_IS_PROTECTED */
496}
497#endif /* WIRELESS_EXT */
498
499/******************* WaveLAN Roaming routines... ********************/
500
501#ifdef WAVELAN_ROAMING /* Conditional compile, see wavelan_cs.h */
502
503unsigned char WAVELAN_BEACON_ADDRESS[]= {0x09,0x00,0x0e,0x20,0x03,0x00};
504
505void wv_roam_init(struct net_device *dev)
506{
507 net_local *lp= netdev_priv(dev);
508
509 /* Do not remove this unless you have a good reason */
510 printk(KERN_NOTICE "%s: Warning, you have enabled roaming on"
511 " device %s !\n", dev->name, dev->name);
512 printk(KERN_NOTICE "Roaming is currently an experimental unsupported feature"
513 " of the Wavelan driver.\n");
514 printk(KERN_NOTICE "It may work, but may also make the driver behave in"
515 " erratic ways or crash.\n");
516
517 lp->wavepoint_table.head=NULL; /* Initialise WavePoint table */
518 lp->wavepoint_table.num_wavepoints=0;
519 lp->wavepoint_table.locked=0;
520 lp->curr_point=NULL; /* No default WavePoint */
521 lp->cell_search=0;
522
523 lp->cell_timer.data=(long)lp; /* Start cell expiry timer */
524 lp->cell_timer.function=wl_cell_expiry;
525 lp->cell_timer.expires=jiffies+CELL_TIMEOUT;
526 add_timer(&lp->cell_timer);
527
528 wv_nwid_filter(NWID_PROMISC,lp) ; /* Enter NWID promiscuous mode */
529 /* to build up a good WavePoint */
530 /* table... */
531 printk(KERN_DEBUG "WaveLAN: Roaming enabled on device %s\n",dev->name);
532}
533
534void wv_roam_cleanup(struct net_device *dev)
535{
536 wavepoint_history *ptr,*old_ptr;
537 net_local *lp= netdev_priv(dev);
538
539 printk(KERN_DEBUG "WaveLAN: Roaming Disabled on device %s\n",dev->name);
540
541 /* Fixme : maybe we should check that the timer exist before deleting it */
542 del_timer(&lp->cell_timer); /* Remove cell expiry timer */
543 ptr=lp->wavepoint_table.head; /* Clear device's WavePoint table */
544 while(ptr!=NULL)
545 {
546 old_ptr=ptr;
547 ptr=ptr->next;
548 wl_del_wavepoint(old_ptr,lp);
549 }
550}
551
552/* Enable/Disable NWID promiscuous mode on a given device */
553void wv_nwid_filter(unsigned char mode, net_local *lp)
554{
555 mm_t m;
556 unsigned long flags;
557
558#ifdef WAVELAN_ROAMING_DEBUG
559 printk(KERN_DEBUG "WaveLAN: NWID promisc %s, device %s\n",(mode==NWID_PROMISC) ? "on" : "off", lp->dev->name);
560#endif
561
562 /* Disable interrupts & save flags */
563 spin_lock_irqsave(&lp->spinlock, flags);
564
565 m.w.mmw_loopt_sel = (mode==NWID_PROMISC) ? MMW_LOOPT_SEL_DIS_NWID : 0x00;
566 mmc_write(lp->dev->base_addr, (char *)&m.w.mmw_loopt_sel - (char *)&m, (unsigned char *)&m.w.mmw_loopt_sel, 1);
567
568 if(mode==NWID_PROMISC)
569 lp->cell_search=1;
570 else
571 lp->cell_search=0;
572
573 /* ReEnable interrupts & restore flags */
574 spin_unlock_irqrestore(&lp->spinlock, flags);
575}
576
577/* Find a record in the WavePoint table matching a given NWID */
578wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp)
579{
580 wavepoint_history *ptr=lp->wavepoint_table.head;
581
582 while(ptr!=NULL){
583 if(ptr->nwid==nwid)
584 return ptr;
585 ptr=ptr->next;
586 }
587 return NULL;
588}
589
590/* Create a new wavepoint table entry */
591wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local* lp)
592{
593 wavepoint_history *new_wavepoint;
594
595#ifdef WAVELAN_ROAMING_DEBUG
596 printk(KERN_DEBUG "WaveLAN: New Wavepoint, NWID:%.4X\n",nwid);
597#endif
598
599 if(lp->wavepoint_table.num_wavepoints==MAX_WAVEPOINTS)
600 return NULL;
601
602 new_wavepoint=(wavepoint_history *) kmalloc(sizeof(wavepoint_history),GFP_ATOMIC);
603 if(new_wavepoint==NULL)
604 return NULL;
605
606 new_wavepoint->nwid=nwid; /* New WavePoints NWID */
607 new_wavepoint->average_fast=0; /* Running Averages..*/
608 new_wavepoint->average_slow=0;
609 new_wavepoint->qualptr=0; /* Start of ringbuffer */
610 new_wavepoint->last_seq=seq-1; /* Last sequence no.seen */
611 memset(new_wavepoint->sigqual,0,WAVEPOINT_HISTORY);/* Empty ringbuffer */
612
613 new_wavepoint->next=lp->wavepoint_table.head;/* Add to wavepoint table */
614 new_wavepoint->prev=NULL;
615
616 if(lp->wavepoint_table.head!=NULL)
617 lp->wavepoint_table.head->prev=new_wavepoint;
618
619 lp->wavepoint_table.head=new_wavepoint;
620
621 lp->wavepoint_table.num_wavepoints++; /* no. of visible wavepoints */
622
623 return new_wavepoint;
624}
625
626/* Remove a wavepoint entry from WavePoint table */
627void wl_del_wavepoint(wavepoint_history *wavepoint, struct net_local *lp)
628{
629 if(wavepoint==NULL)
630 return;
631
632 if(lp->curr_point==wavepoint)
633 lp->curr_point=NULL;
634
635 if(wavepoint->prev!=NULL)
636 wavepoint->prev->next=wavepoint->next;
637
638 if(wavepoint->next!=NULL)
639 wavepoint->next->prev=wavepoint->prev;
640
641 if(lp->wavepoint_table.head==wavepoint)
642 lp->wavepoint_table.head=wavepoint->next;
643
644 lp->wavepoint_table.num_wavepoints--;
645 kfree(wavepoint);
646}
647
648/* Timer callback function - checks WavePoint table for stale entries */
649void wl_cell_expiry(unsigned long data)
650{
651 net_local *lp=(net_local *)data;
652 wavepoint_history *wavepoint=lp->wavepoint_table.head,*old_point;
653
654#if WAVELAN_ROAMING_DEBUG > 1
655 printk(KERN_DEBUG "WaveLAN: Wavepoint timeout, dev %s\n",lp->dev->name);
656#endif
657
658 if(lp->wavepoint_table.locked)
659 {
660#if WAVELAN_ROAMING_DEBUG > 1
661 printk(KERN_DEBUG "WaveLAN: Wavepoint table locked...\n");
662#endif
663
664 lp->cell_timer.expires=jiffies+1; /* If table in use, come back later */
665 add_timer(&lp->cell_timer);
666 return;
667 }
668
669 while(wavepoint!=NULL)
670 {
671 if(time_after(jiffies, wavepoint->last_seen + CELL_TIMEOUT))
672 {
673#ifdef WAVELAN_ROAMING_DEBUG
674 printk(KERN_DEBUG "WaveLAN: Bye bye %.4X\n",wavepoint->nwid);
675#endif
676
677 old_point=wavepoint;
678 wavepoint=wavepoint->next;
679 wl_del_wavepoint(old_point,lp);
680 }
681 else
682 wavepoint=wavepoint->next;
683 }
684 lp->cell_timer.expires=jiffies+CELL_TIMEOUT;
685 add_timer(&lp->cell_timer);
686}
687
688/* Update SNR history of a wavepoint */
689void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq)
690{
691 int i=0,num_missed=0,ptr=0;
692 int average_fast=0,average_slow=0;
693
694 num_missed=(seq-wavepoint->last_seq)%WAVEPOINT_HISTORY;/* Have we missed
695 any beacons? */
696 if(num_missed)
697 for(i=0;i<num_missed;i++)
698 {
699 wavepoint->sigqual[wavepoint->qualptr++]=0; /* If so, enter them as 0's */
700 wavepoint->qualptr %=WAVEPOINT_HISTORY; /* in the ringbuffer. */
701 }
702 wavepoint->last_seen=jiffies; /* Add beacon to history */
703 wavepoint->last_seq=seq;
704 wavepoint->sigqual[wavepoint->qualptr++]=sigqual;
705 wavepoint->qualptr %=WAVEPOINT_HISTORY;
706 ptr=(wavepoint->qualptr-WAVEPOINT_FAST_HISTORY+WAVEPOINT_HISTORY)%WAVEPOINT_HISTORY;
707
708 for(i=0;i<WAVEPOINT_FAST_HISTORY;i++) /* Update running averages */
709 {
710 average_fast+=wavepoint->sigqual[ptr++];
711 ptr %=WAVEPOINT_HISTORY;
712 }
713
714 average_slow=average_fast;
715 for(i=WAVEPOINT_FAST_HISTORY;i<WAVEPOINT_HISTORY;i++)
716 {
717 average_slow+=wavepoint->sigqual[ptr++];
718 ptr %=WAVEPOINT_HISTORY;
719 }
720
721 wavepoint->average_fast=average_fast/WAVEPOINT_FAST_HISTORY;
722 wavepoint->average_slow=average_slow/WAVEPOINT_HISTORY;
723}
724
725/* Perform a handover to a new WavePoint */
726void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp)
727{
728 kio_addr_t base = lp->dev->base_addr;
729 mm_t m;
730 unsigned long flags;
731
732 if(wavepoint==lp->curr_point) /* Sanity check... */
733 {
734 wv_nwid_filter(!NWID_PROMISC,lp);
735 return;
736 }
737
738#ifdef WAVELAN_ROAMING_DEBUG
739 printk(KERN_DEBUG "WaveLAN: Doing handover to %.4X, dev %s\n",wavepoint->nwid,lp->dev->name);
740#endif
741
742 /* Disable interrupts & save flags */
743 spin_lock_irqsave(&lp->spinlock, flags);
744
745 m.w.mmw_netw_id_l = wavepoint->nwid & 0xFF;
746 m.w.mmw_netw_id_h = (wavepoint->nwid & 0xFF00) >> 8;
747
748 mmc_write(base, (char *)&m.w.mmw_netw_id_l - (char *)&m, (unsigned char *)&m.w.mmw_netw_id_l, 2);
749
750 /* ReEnable interrupts & restore flags */
751 spin_unlock_irqrestore(&lp->spinlock, flags);
752
753 wv_nwid_filter(!NWID_PROMISC,lp);
754 lp->curr_point=wavepoint;
755}
756
757/* Called when a WavePoint beacon is received */
758static inline void wl_roam_gather(struct net_device * dev,
759 u_char * hdr, /* Beacon header */
760 u_char * stats) /* SNR, Signal quality
761 of packet */
762{
763 wavepoint_beacon *beacon= (wavepoint_beacon *)hdr; /* Rcvd. Beacon */
764 unsigned short nwid=ntohs(beacon->nwid);
765 unsigned short sigqual=stats[2] & MMR_SGNL_QUAL; /* SNR of beacon */
766 wavepoint_history *wavepoint=NULL; /* WavePoint table entry */
767 net_local *lp = netdev_priv(dev); /* Device info */
768
769#ifdef I_NEED_THIS_FEATURE
770 /* Some people don't need this, some other may need it */
771 nwid=nwid^ntohs(beacon->domain_id);
772#endif
773
774#if WAVELAN_ROAMING_DEBUG > 1
775 printk(KERN_DEBUG "WaveLAN: beacon, dev %s:\n",dev->name);
776 printk(KERN_DEBUG "Domain: %.4X NWID: %.4X SigQual=%d\n",ntohs(beacon->domain_id),nwid,sigqual);
777#endif
778
779 lp->wavepoint_table.locked=1; /* <Mutex> */
780
781 wavepoint=wl_roam_check(nwid,lp); /* Find WavePoint table entry */
782 if(wavepoint==NULL) /* If no entry, Create a new one... */
783 {
784 wavepoint=wl_new_wavepoint(nwid,beacon->seq,lp);
785 if(wavepoint==NULL)
786 goto out;
787 }
788 if(lp->curr_point==NULL) /* If this is the only WavePoint, */
789 wv_roam_handover(wavepoint, lp); /* Jump on it! */
790
791 wl_update_history(wavepoint, sigqual, beacon->seq); /* Update SNR history
792 stats. */
793
794 if(lp->curr_point->average_slow < SEARCH_THRESH_LOW) /* If our current */
795 if(!lp->cell_search) /* WavePoint is getting faint, */
796 wv_nwid_filter(NWID_PROMISC,lp); /* start looking for a new one */
797
798 if(wavepoint->average_slow >
799 lp->curr_point->average_slow + WAVELAN_ROAMING_DELTA)
800 wv_roam_handover(wavepoint, lp); /* Handover to a better WavePoint */
801
802 if(lp->curr_point->average_slow > SEARCH_THRESH_HIGH) /* If our SNR is */
803 if(lp->cell_search) /* getting better, drop out of cell search mode */
804 wv_nwid_filter(!NWID_PROMISC,lp);
805
806out:
807 lp->wavepoint_table.locked=0; /* </MUTEX> :-) */
808}
809
810/* Test this MAC frame a WavePoint beacon */
811static inline int WAVELAN_BEACON(unsigned char *data)
812{
813 wavepoint_beacon *beacon= (wavepoint_beacon *)data;
814 static wavepoint_beacon beacon_template={0xaa,0xaa,0x03,0x08,0x00,0x0e,0x20,0x03,0x00};
815
816 if(memcmp(beacon,&beacon_template,9)==0)
817 return 1;
818 else
819 return 0;
820}
821#endif /* WAVELAN_ROAMING */
822
823/************************ I82593 SUBROUTINES *************************/
824/*
825 * Useful subroutines to manage the Ethernet controller
826 */
827
828/*------------------------------------------------------------------*/
829/*
830 * Routine to synchronously send a command to the i82593 chip.
831 * Should be called with interrupts disabled.
832 * (called by wv_packet_write(), wv_ru_stop(), wv_ru_start(),
833 * wv_82593_config() & wv_diag())
834 */
835static int
836wv_82593_cmd(struct net_device * dev,
837 char * str,
838 int cmd,
839 int result)
840{
841 kio_addr_t base = dev->base_addr;
842 int status;
843 int wait_completed;
844 long spin;
845
846 /* Spin until the chip finishes executing its current command (if any) */
847 spin = 1000;
848 do
849 {
850 /* Time calibration of the loop */
851 udelay(10);
852
853 /* Read the interrupt register */
854 outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
855 status = inb(LCSR(base));
856 }
857 while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0));
858
859 /* If the interrupt hasn't be posted */
860 if(spin <= 0)
861 {
862#ifdef DEBUG_INTERRUPT_ERROR
863 printk(KERN_INFO "wv_82593_cmd: %s timeout (previous command), status 0x%02x\n",
864 str, status);
865#endif
866 return(FALSE);
867 }
868
869 /* Issue the command to the controller */
870 outb(cmd, LCCR(base));
871
872 /* If we don't have to check the result of the command
873 * Note : this mean that the irq handler will deal with that */
874 if(result == SR0_NO_RESULT)
875 return(TRUE);
876
877 /* We are waiting for command completion */
878 wait_completed = TRUE;
879
880 /* Busy wait while the LAN controller executes the command. */
881 spin = 1000;
882 do
883 {
884 /* Time calibration of the loop */
885 udelay(10);
886
887 /* Read the interrupt register */
888 outb(CR0_STATUS_0 | OP0_NOP, LCCR(base));
889 status = inb(LCSR(base));
890
891 /* Check if there was an interrupt posted */
892 if((status & SR0_INTERRUPT))
893 {
894 /* Acknowledge the interrupt */
895 outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
896
897 /* Check if interrupt is a command completion */
898 if(((status & SR0_BOTH_RX_TX) != SR0_BOTH_RX_TX) &&
899 ((status & SR0_BOTH_RX_TX) != 0x0) &&
900 !(status & SR0_RECEPTION))
901 {
902 /* Signal command completion */
903 wait_completed = FALSE;
904 }
905 else
906 {
907 /* Note : Rx interrupts will be handled later, because we can
908 * handle multiple Rx packets at once */
909#ifdef DEBUG_INTERRUPT_INFO
910 printk(KERN_INFO "wv_82593_cmd: not our interrupt\n");
911#endif
912 }
913 }
914 }
915 while(wait_completed && (spin-- > 0));
916
917 /* If the interrupt hasn't be posted */
918 if(wait_completed)
919 {
920#ifdef DEBUG_INTERRUPT_ERROR
921 printk(KERN_INFO "wv_82593_cmd: %s timeout, status 0x%02x\n",
922 str, status);
923#endif
924 return(FALSE);
925 }
926
927 /* Check the return code returned by the card (see above) against
928 * the expected return code provided by the caller */
929 if((status & SR0_EVENT_MASK) != result)
930 {
931#ifdef DEBUG_INTERRUPT_ERROR
932 printk(KERN_INFO "wv_82593_cmd: %s failed, status = 0x%x\n",
933 str, status);
934#endif
935 return(FALSE);
936 }
937
938 return(TRUE);
939} /* wv_82593_cmd */
940
941/*------------------------------------------------------------------*/
942/*
943 * This routine does a 593 op-code number 7, and obtains the diagnose
944 * status for the WaveLAN.
945 */
946static inline int
947wv_diag(struct net_device * dev)
948{
949 int ret = FALSE;
950
951 if(wv_82593_cmd(dev, "wv_diag(): diagnose",
952 OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED))
953 ret = TRUE;
954
955#ifdef DEBUG_CONFIG_ERRORS
956 printk(KERN_INFO "wavelan_cs: i82593 Self Test failed!\n");
957#endif
958 return(ret);
959} /* wv_diag */
960
961/*------------------------------------------------------------------*/
962/*
963 * Routine to read len bytes from the i82593's ring buffer, starting at
964 * chip address addr. The results read from the chip are stored in buf.
965 * The return value is the address to use for next the call.
966 */
967static int
968read_ringbuf(struct net_device * dev,
969 int addr,
970 char * buf,
971 int len)
972{
973 kio_addr_t base = dev->base_addr;
974 int ring_ptr = addr;
975 int chunk_len;
976 char * buf_ptr = buf;
977
978 /* Get all the buffer */
979 while(len > 0)
980 {
981 /* Position the Program I/O Register at the ring buffer pointer */
982 outb(ring_ptr & 0xff, PIORL(base));
983 outb(((ring_ptr >> 8) & PIORH_MASK), PIORH(base));
984
985 /* First, determine how much we can read without wrapping around the
986 ring buffer */
987 if((addr + len) < (RX_BASE + RX_SIZE))
988 chunk_len = len;
989 else
990 chunk_len = RX_BASE + RX_SIZE - addr;
991 insb(PIOP(base), buf_ptr, chunk_len);
992 buf_ptr += chunk_len;
993 len -= chunk_len;
994 ring_ptr = (ring_ptr - RX_BASE + chunk_len) % RX_SIZE + RX_BASE;
995 }
996 return(ring_ptr);
997} /* read_ringbuf */
998
999/*------------------------------------------------------------------*/
1000/*
1001 * Reconfigure the i82593, or at least ask for it...
1002 * Because wv_82593_config use the transmission buffer, we must do it
1003 * when we are sure that there is no transmission, so we do it now
1004 * or in wavelan_packet_xmit() (I can't find any better place,
1005 * wavelan_interrupt is not an option...), so you may experience
1006 * some delay sometime...
1007 */
1008static inline void
1009wv_82593_reconfig(struct net_device * dev)
1010{
1011 net_local * lp = netdev_priv(dev);
1012 dev_link_t * link = lp->link;
1013 unsigned long flags;
1014
1015 /* Arm the flag, will be cleard in wv_82593_config() */
1016 lp->reconfig_82593 = TRUE;
1017
1018 /* Check if we can do it now ! */
1019 if((link->open) && (netif_running(dev)) && !(netif_queue_stopped(dev)))
1020 {
1021 spin_lock_irqsave(&lp->spinlock, flags); /* Disable interrupts */
1022 wv_82593_config(dev);
1023 spin_unlock_irqrestore(&lp->spinlock, flags); /* Re-enable interrupts */
1024 }
1025 else
1026 {
1027#ifdef DEBUG_IOCTL_INFO
1028 printk(KERN_DEBUG
1029 "%s: wv_82593_reconfig(): delayed (state = %lX, link = %d)\n",
1030 dev->name, dev->state, link->open);
1031#endif
1032 }
1033}
1034
1035/********************* DEBUG & INFO SUBROUTINES *********************/
1036/*
1037 * This routines are used in the code to show debug informations.
1038 * Most of the time, it dump the content of hardware structures...
1039 */
1040
1041#ifdef DEBUG_PSA_SHOW
1042/*------------------------------------------------------------------*/
1043/*
1044 * Print the formatted contents of the Parameter Storage Area.
1045 */
1046static void
1047wv_psa_show(psa_t * p)
1048{
1049 printk(KERN_DEBUG "##### wavelan psa contents: #####\n");
1050 printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n",
1051 p->psa_io_base_addr_1,
1052 p->psa_io_base_addr_2,
1053 p->psa_io_base_addr_3,
1054 p->psa_io_base_addr_4);
1055 printk(KERN_DEBUG "psa_rem_boot_addr_1: 0x%02X %02X %02X\n",
1056 p->psa_rem_boot_addr_1,
1057 p->psa_rem_boot_addr_2,
1058 p->psa_rem_boot_addr_3);
1059 printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params);
1060 printk("psa_int_req_no: %d\n", p->psa_int_req_no);
1061#ifdef DEBUG_SHOW_UNUSED
1062 printk(KERN_DEBUG "psa_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
1063 p->psa_unused0[0],
1064 p->psa_unused0[1],
1065 p->psa_unused0[2],
1066 p->psa_unused0[3],
1067 p->psa_unused0[4],
1068 p->psa_unused0[5],
1069 p->psa_unused0[6]);
1070#endif /* DEBUG_SHOW_UNUSED */
1071 printk(KERN_DEBUG "psa_univ_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x\n",
1072 p->psa_univ_mac_addr[0],
1073 p->psa_univ_mac_addr[1],
1074 p->psa_univ_mac_addr[2],
1075 p->psa_univ_mac_addr[3],
1076 p->psa_univ_mac_addr[4],
1077 p->psa_univ_mac_addr[5]);
1078 printk(KERN_DEBUG "psa_local_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x\n",
1079 p->psa_local_mac_addr[0],
1080 p->psa_local_mac_addr[1],
1081 p->psa_local_mac_addr[2],
1082 p->psa_local_mac_addr[3],
1083 p->psa_local_mac_addr[4],
1084 p->psa_local_mac_addr[5]);
1085 printk(KERN_DEBUG "psa_univ_local_sel: %d, ", p->psa_univ_local_sel);
1086 printk("psa_comp_number: %d, ", p->psa_comp_number);
1087 printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set);
1088 printk(KERN_DEBUG "psa_feature_select/decay_prm: 0x%02x, ",
1089 p->psa_feature_select);
1090 printk("psa_subband/decay_update_prm: %d\n", p->psa_subband);
1091 printk(KERN_DEBUG "psa_quality_thr: 0x%02x, ", p->psa_quality_thr);
1092 printk("psa_mod_delay: 0x%02x\n", p->psa_mod_delay);
1093 printk(KERN_DEBUG "psa_nwid: 0x%02x%02x, ", p->psa_nwid[0], p->psa_nwid[1]);
1094 printk("psa_nwid_select: %d\n", p->psa_nwid_select);
1095 printk(KERN_DEBUG "psa_encryption_select: %d, ", p->psa_encryption_select);
1096 printk("psa_encryption_key[]: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
1097 p->psa_encryption_key[0],
1098 p->psa_encryption_key[1],
1099 p->psa_encryption_key[2],
1100 p->psa_encryption_key[3],
1101 p->psa_encryption_key[4],
1102 p->psa_encryption_key[5],
1103 p->psa_encryption_key[6],
1104 p->psa_encryption_key[7]);
1105 printk(KERN_DEBUG "psa_databus_width: %d\n", p->psa_databus_width);
1106 printk(KERN_DEBUG "psa_call_code/auto_squelch: 0x%02x, ",
1107 p->psa_call_code[0]);
1108 printk("psa_call_code[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
1109 p->psa_call_code[0],
1110 p->psa_call_code[1],
1111 p->psa_call_code[2],
1112 p->psa_call_code[3],
1113 p->psa_call_code[4],
1114 p->psa_call_code[5],
1115 p->psa_call_code[6],
1116 p->psa_call_code[7]);
1117#ifdef DEBUG_SHOW_UNUSED
1118 printk(KERN_DEBUG "psa_reserved[]: %02X:%02X:%02X:%02X\n",
1119 p->psa_reserved[0],
1120 p->psa_reserved[1],
1121 p->psa_reserved[2],
1122 p->psa_reserved[3]);
1123#endif /* DEBUG_SHOW_UNUSED */
1124 printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status);
1125 printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]);
1126 printk("psa_crc_status: 0x%02x\n", p->psa_crc_status);
1127} /* wv_psa_show */
1128#endif /* DEBUG_PSA_SHOW */
1129
1130#ifdef DEBUG_MMC_SHOW
1131/*------------------------------------------------------------------*/
1132/*
1133 * Print the formatted status of the Modem Management Controller.
1134 * This function need to be completed...
1135 */
1136static void
1137wv_mmc_show(struct net_device * dev)
1138{
1139 kio_addr_t base = dev->base_addr;
1140 net_local * lp = netdev_priv(dev);
1141 mmr_t m;
1142
1143 /* Basic check */
1144 if(hasr_read(base) & HASR_NO_CLK)
1145 {
1146 printk(KERN_WARNING "%s: wv_mmc_show: modem not connected\n",
1147 dev->name);
1148 return;
1149 }
1150
1151 spin_lock_irqsave(&lp->spinlock, flags);
1152
1153 /* Read the mmc */
1154 mmc_out(base, mmwoff(0, mmw_freeze), 1);
1155 mmc_read(base, 0, (u_char *)&m, sizeof(m));
1156 mmc_out(base, mmwoff(0, mmw_freeze), 0);
1157
1158#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
1159 /* Don't forget to update statistics */
1160 lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
1161#endif /* WIRELESS_EXT */
1162
1163 spin_unlock_irqrestore(&lp->spinlock, flags);
1164
1165 printk(KERN_DEBUG "##### wavelan modem status registers: #####\n");
1166#ifdef DEBUG_SHOW_UNUSED
1167 printk(KERN_DEBUG "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
1168 m.mmr_unused0[0],
1169 m.mmr_unused0[1],
1170 m.mmr_unused0[2],
1171 m.mmr_unused0[3],
1172 m.mmr_unused0[4],
1173 m.mmr_unused0[5],
1174 m.mmr_unused0[6],
1175 m.mmr_unused0[7]);
1176#endif /* DEBUG_SHOW_UNUSED */
1177 printk(KERN_DEBUG "Encryption algorythm: %02X - Status: %02X\n",
1178 m.mmr_des_avail, m.mmr_des_status);
1179#ifdef DEBUG_SHOW_UNUSED
1180 printk(KERN_DEBUG "mmc_unused1[]: %02X:%02X:%02X:%02X:%02X\n",
1181 m.mmr_unused1[0],
1182 m.mmr_unused1[1],
1183 m.mmr_unused1[2],
1184 m.mmr_unused1[3],
1185 m.mmr_unused1[4]);
1186#endif /* DEBUG_SHOW_UNUSED */
1187 printk(KERN_DEBUG "dce_status: 0x%x [%s%s%s%s]\n",
1188 m.mmr_dce_status,
1189 (m.mmr_dce_status & MMR_DCE_STATUS_RX_BUSY) ? "energy detected,":"",
1190 (m.mmr_dce_status & MMR_DCE_STATUS_LOOPT_IND) ?
1191 "loop test indicated," : "",
1192 (m.mmr_dce_status & MMR_DCE_STATUS_TX_BUSY) ? "transmitter on," : "",
1193 (m.mmr_dce_status & MMR_DCE_STATUS_JBR_EXPIRED) ?
1194 "jabber timer expired," : "");
1195 printk(KERN_DEBUG "Dsp ID: %02X\n",
1196 m.mmr_dsp_id);
1197#ifdef DEBUG_SHOW_UNUSED
1198 printk(KERN_DEBUG "mmc_unused2[]: %02X:%02X\n",
1199 m.mmr_unused2[0],
1200 m.mmr_unused2[1]);
1201#endif /* DEBUG_SHOW_UNUSED */
1202 printk(KERN_DEBUG "# correct_nwid: %d, # wrong_nwid: %d\n",
1203 (m.mmr_correct_nwid_h << 8) | m.mmr_correct_nwid_l,
1204 (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l);
1205 printk(KERN_DEBUG "thr_pre_set: 0x%x [current signal %s]\n",
1206 m.mmr_thr_pre_set & MMR_THR_PRE_SET,
1207 (m.mmr_thr_pre_set & MMR_THR_PRE_SET_CUR) ? "above" : "below");
1208 printk(KERN_DEBUG "signal_lvl: %d [%s], ",
1209 m.mmr_signal_lvl & MMR_SIGNAL_LVL,
1210 (m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) ? "new msg" : "no new msg");
1211 printk("silence_lvl: %d [%s], ", m.mmr_silence_lvl & MMR_SILENCE_LVL,
1212 (m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) ? "update done" : "no new update");
1213 printk("sgnl_qual: 0x%x [%s]\n", m.mmr_sgnl_qual & MMR_SGNL_QUAL,
1214 (m.mmr_sgnl_qual & MMR_SGNL_QUAL_ANT) ? "Antenna 1" : "Antenna 0");
1215#ifdef DEBUG_SHOW_UNUSED
1216 printk(KERN_DEBUG "netw_id_l: %x\n", m.mmr_netw_id_l);
1217#endif /* DEBUG_SHOW_UNUSED */
1218} /* wv_mmc_show */
1219#endif /* DEBUG_MMC_SHOW */
1220
1221#ifdef DEBUG_I82593_SHOW
1222/*------------------------------------------------------------------*/
1223/*
1224 * Print the formatted status of the i82593's receive unit.
1225 */
1226static void
1227wv_ru_show(struct net_device * dev)
1228{
1229 net_local *lp = netdev_priv(dev);
1230
1231 printk(KERN_DEBUG "##### wavelan i82593 receiver status: #####\n");
1232 printk(KERN_DEBUG "ru: rfp %d stop %d", lp->rfp, lp->stop);
1233 /*
1234 * Not implemented yet...
1235 */
1236 printk("\n");
1237} /* wv_ru_show */
1238#endif /* DEBUG_I82593_SHOW */
1239
1240#ifdef DEBUG_DEVICE_SHOW
1241/*------------------------------------------------------------------*/
1242/*
1243 * Print the formatted status of the WaveLAN PCMCIA device driver.
1244 */
1245static void
1246wv_dev_show(struct net_device * dev)
1247{
1248 printk(KERN_DEBUG "dev:");
1249 printk(" state=%lX,", dev->state);
1250 printk(" trans_start=%ld,", dev->trans_start);
1251 printk(" flags=0x%x,", dev->flags);
1252 printk("\n");
1253} /* wv_dev_show */
1254
1255/*------------------------------------------------------------------*/
1256/*
1257 * Print the formatted status of the WaveLAN PCMCIA device driver's
1258 * private information.
1259 */
1260static void
1261wv_local_show(struct net_device * dev)
1262{
1263 net_local *lp = netdev_priv(dev);
1264
1265 printk(KERN_DEBUG "local:");
1266 /*
1267 * Not implemented yet...
1268 */
1269 printk("\n");
1270} /* wv_local_show */
1271#endif /* DEBUG_DEVICE_SHOW */
1272
1273#if defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO)
1274/*------------------------------------------------------------------*/
1275/*
1276 * Dump packet header (and content if necessary) on the screen
1277 */
1278static inline void
1279wv_packet_info(u_char * p, /* Packet to dump */
1280 int length, /* Length of the packet */
1281 char * msg1, /* Name of the device */
1282 char * msg2) /* Name of the function */
1283{
1284 int i;
1285 int maxi;
1286
1287 printk(KERN_DEBUG "%s: %s(): dest %02X:%02X:%02X:%02X:%02X:%02X, length %d\n",
1288 msg1, msg2, p[0], p[1], p[2], p[3], p[4], p[5], length);
1289 printk(KERN_DEBUG "%s: %s(): src %02X:%02X:%02X:%02X:%02X:%02X, type 0x%02X%02X\n",
1290 msg1, msg2, p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13]);
1291
1292#ifdef DEBUG_PACKET_DUMP
1293
1294 printk(KERN_DEBUG "data=\"");
1295
1296 if((maxi = length) > DEBUG_PACKET_DUMP)
1297 maxi = DEBUG_PACKET_DUMP;
1298 for(i = 14; i < maxi; i++)
1299 if(p[i] >= ' ' && p[i] <= '~')
1300 printk(" %c", p[i]);
1301 else
1302 printk("%02X", p[i]);
1303 if(maxi < length)
1304 printk("..");
1305 printk("\"\n");
1306 printk(KERN_DEBUG "\n");
1307#endif /* DEBUG_PACKET_DUMP */
1308}
1309#endif /* defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO) */
1310
1311/*------------------------------------------------------------------*/
1312/*
1313 * This is the information which is displayed by the driver at startup
1314 * There is a lot of flag to configure it at your will...
1315 */
1316static inline void
1317wv_init_info(struct net_device * dev)
1318{
1319 kio_addr_t base = dev->base_addr;
1320 psa_t psa;
1321 int i;
1322
1323 /* Read the parameter storage area */
1324 psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
1325
1326#ifdef DEBUG_PSA_SHOW
1327 wv_psa_show(&psa);
1328#endif
1329#ifdef DEBUG_MMC_SHOW
1330 wv_mmc_show(dev);
1331#endif
1332#ifdef DEBUG_I82593_SHOW
1333 wv_ru_show(dev);
1334#endif
1335
1336#ifdef DEBUG_BASIC_SHOW
1337 /* Now, let's go for the basic stuff */
1338 printk(KERN_NOTICE "%s: WaveLAN: port %#lx, irq %d, hw_addr",
1339 dev->name, base, dev->irq);
1340 for(i = 0; i < WAVELAN_ADDR_SIZE; i++)
1341 printk("%s%02X", (i == 0) ? " " : ":", dev->dev_addr[i]);
1342
1343 /* Print current network id */
1344 if(psa.psa_nwid_select)
1345 printk(", nwid 0x%02X-%02X", psa.psa_nwid[0], psa.psa_nwid[1]);
1346 else
1347 printk(", nwid off");
1348
1349 /* If 2.00 card */
1350 if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
1351 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
1352 {
1353 unsigned short freq;
1354
1355 /* Ask the EEprom to read the frequency from the first area */
1356 fee_read(base, 0x00 /* 1st area - frequency... */,
1357 &freq, 1);
1358
1359 /* Print frequency */
1360 printk(", 2.00, %ld", (freq >> 6) + 2400L);
1361
1362 /* Hack !!! */
1363 if(freq & 0x20)
1364 printk(".5");
1365 }
1366 else
1367 {
1368 printk(", PCMCIA, ");
1369 switch (psa.psa_subband)
1370 {
1371 case PSA_SUBBAND_915:
1372 printk("915");
1373 break;
1374 case PSA_SUBBAND_2425:
1375 printk("2425");
1376 break;
1377 case PSA_SUBBAND_2460:
1378 printk("2460");
1379 break;
1380 case PSA_SUBBAND_2484:
1381 printk("2484");
1382 break;
1383 case PSA_SUBBAND_2430_5:
1384 printk("2430.5");
1385 break;
1386 default:
1387 printk("unknown");
1388 }
1389 }
1390
1391 printk(" MHz\n");
1392#endif /* DEBUG_BASIC_SHOW */
1393
1394#ifdef DEBUG_VERSION_SHOW
1395 /* Print version information */
1396 printk(KERN_NOTICE "%s", version);
1397#endif
1398} /* wv_init_info */
1399
1400/********************* IOCTL, STATS & RECONFIG *********************/
1401/*
1402 * We found here routines that are called by Linux on differents
1403 * occasions after the configuration and not for transmitting data
1404 * These may be called when the user use ifconfig, /proc/net/dev
1405 * or wireless extensions
1406 */
1407
1408/*------------------------------------------------------------------*/
1409/*
1410 * Get the current ethernet statistics. This may be called with the
1411 * card open or closed.
1412 * Used when the user read /proc/net/dev
1413 */
1414static en_stats *
1415wavelan_get_stats(struct net_device * dev)
1416{
1417#ifdef DEBUG_IOCTL_TRACE
1418 printk(KERN_DEBUG "%s: <>wavelan_get_stats()\n", dev->name);
1419#endif
1420
1421 return(&((net_local *)netdev_priv(dev))->stats);
1422}
1423
1424/*------------------------------------------------------------------*/
1425/*
1426 * Set or clear the multicast filter for this adaptor.
1427 * num_addrs == -1 Promiscuous mode, receive all packets
1428 * num_addrs == 0 Normal mode, clear multicast list
1429 * num_addrs > 0 Multicast mode, receive normal and MC packets,
1430 * and do best-effort filtering.
1431 */
1432
1433static void
1434wavelan_set_multicast_list(struct net_device * dev)
1435{
1436 net_local * lp = netdev_priv(dev);
1437
1438#ifdef DEBUG_IOCTL_TRACE
1439 printk(KERN_DEBUG "%s: ->wavelan_set_multicast_list()\n", dev->name);
1440#endif
1441
1442#ifdef DEBUG_IOCTL_INFO
1443 printk(KERN_DEBUG "%s: wavelan_set_multicast_list(): setting Rx mode %02X to %d addresses.\n",
1444 dev->name, dev->flags, dev->mc_count);
1445#endif
1446
1447 if(dev->flags & IFF_PROMISC)
1448 {
1449 /*
1450 * Enable promiscuous mode: receive all packets.
1451 */
1452 if(!lp->promiscuous)
1453 {
1454 lp->promiscuous = 1;
1455 lp->allmulticast = 0;
1456 lp->mc_count = 0;
1457
1458 wv_82593_reconfig(dev);
1459
1460 /* Tell the kernel that we are doing a really bad job... */
1461 dev->flags |= IFF_PROMISC;
1462 }
1463 }
1464 else
1465 /* If all multicast addresses
1466 * or too much multicast addresses for the hardware filter */
1467 if((dev->flags & IFF_ALLMULTI) ||
1468 (dev->mc_count > I82593_MAX_MULTICAST_ADDRESSES))
1469 {
1470 /*
1471 * Disable promiscuous mode, but active the all multicast mode
1472 */
1473 if(!lp->allmulticast)
1474 {
1475 lp->promiscuous = 0;
1476 lp->allmulticast = 1;
1477 lp->mc_count = 0;
1478
1479 wv_82593_reconfig(dev);
1480
1481 /* Tell the kernel that we are doing a really bad job... */
1482 dev->flags |= IFF_ALLMULTI;
1483 }
1484 }
1485 else
1486 /* If there is some multicast addresses to send */
1487 if(dev->mc_list != (struct dev_mc_list *) NULL)
1488 {
1489 /*
1490 * Disable promiscuous mode, but receive all packets
1491 * in multicast list
1492 */
1493#ifdef MULTICAST_AVOID
1494 if(lp->promiscuous || lp->allmulticast ||
1495 (dev->mc_count != lp->mc_count))
1496#endif
1497 {
1498 lp->promiscuous = 0;
1499 lp->allmulticast = 0;
1500 lp->mc_count = dev->mc_count;
1501
1502 wv_82593_reconfig(dev);
1503 }
1504 }
1505 else
1506 {
1507 /*
1508 * Switch to normal mode: disable promiscuous mode and
1509 * clear the multicast list.
1510 */
1511 if(lp->promiscuous || lp->mc_count == 0)
1512 {
1513 lp->promiscuous = 0;
1514 lp->allmulticast = 0;
1515 lp->mc_count = 0;
1516
1517 wv_82593_reconfig(dev);
1518 }
1519 }
1520#ifdef DEBUG_IOCTL_TRACE
1521 printk(KERN_DEBUG "%s: <-wavelan_set_multicast_list()\n", dev->name);
1522#endif
1523}
1524
1525/*------------------------------------------------------------------*/
1526/*
1527 * This function doesn't exist...
1528 * (Note : it was a nice way to test the reconfigure stuff...)
1529 */
1530#ifdef SET_MAC_ADDRESS
1531static int
1532wavelan_set_mac_address(struct net_device * dev,
1533 void * addr)
1534{
1535 struct sockaddr * mac = addr;
1536
1537 /* Copy the address */
1538 memcpy(dev->dev_addr, mac->sa_data, WAVELAN_ADDR_SIZE);
1539
1540 /* Reconfig the beast */
1541 wv_82593_reconfig(dev);
1542
1543 return 0;
1544}
1545#endif /* SET_MAC_ADDRESS */
1546
1547#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
1548
1549/*------------------------------------------------------------------*/
1550/*
1551 * Frequency setting (for hardware able of it)
1552 * It's a bit complicated and you don't really want to look into it...
1553 */
1554static inline int
1555wv_set_frequency(u_long base, /* i/o port of the card */
1556 iw_freq * frequency)
1557{
1558 const int BAND_NUM = 10; /* Number of bands */
1559 long freq = 0L; /* offset to 2.4 GHz in .5 MHz */
1560#ifdef DEBUG_IOCTL_INFO
1561 int i;
1562#endif
1563
1564 /* Setting by frequency */
1565 /* Theoritically, you may set any frequency between
1566 * the two limits with a 0.5 MHz precision. In practice,
1567 * I don't want you to have trouble with local
1568 * regulations... */
1569 if((frequency->e == 1) &&
1570 (frequency->m >= (int) 2.412e8) && (frequency->m <= (int) 2.487e8))
1571 {
1572 freq = ((frequency->m / 10000) - 24000L) / 5;
1573 }
1574
1575 /* Setting by channel (same as wfreqsel) */
1576 /* Warning : each channel is 22MHz wide, so some of the channels
1577 * will interfere... */
1578 if((frequency->e == 0) &&
1579 (frequency->m >= 0) && (frequency->m < BAND_NUM))
1580 {
1581 /* Get frequency offset. */
1582 freq = channel_bands[frequency->m] >> 1;
1583 }
1584
1585 /* Verify if the frequency is allowed */
1586 if(freq != 0L)
1587 {
1588 u_short table[10]; /* Authorized frequency table */
1589
1590 /* Read the frequency table */
1591 fee_read(base, 0x71 /* frequency table */,
1592 table, 10);
1593
1594#ifdef DEBUG_IOCTL_INFO
1595 printk(KERN_DEBUG "Frequency table :");
1596 for(i = 0; i < 10; i++)
1597 {
1598 printk(" %04X",
1599 table[i]);
1600 }
1601 printk("\n");
1602#endif
1603
1604 /* Look in the table if the frequency is allowed */
1605 if(!(table[9 - ((freq - 24) / 16)] &
1606 (1 << ((freq - 24) % 16))))
1607 return -EINVAL; /* not allowed */
1608 }
1609 else
1610 return -EINVAL;
1611
1612 /* If we get a usable frequency */
1613 if(freq != 0L)
1614 {
1615 unsigned short area[16];
1616 unsigned short dac[2];
1617 unsigned short area_verify[16];
1618 unsigned short dac_verify[2];
1619 /* Corresponding gain (in the power adjust value table)
1620 * see AT&T Wavelan Data Manual, REF 407-024689/E, page 3-8
1621 * & WCIN062D.DOC, page 6.2.9 */
1622 unsigned short power_limit[] = { 40, 80, 120, 160, 0 };
1623 int power_band = 0; /* Selected band */
1624 unsigned short power_adjust; /* Correct value */
1625
1626 /* Search for the gain */
1627 power_band = 0;
1628 while((freq > power_limit[power_band]) &&
1629 (power_limit[++power_band] != 0))
1630 ;
1631
1632 /* Read the first area */
1633 fee_read(base, 0x00,
1634 area, 16);
1635
1636 /* Read the DAC */
1637 fee_read(base, 0x60,
1638 dac, 2);
1639
1640 /* Read the new power adjust value */
1641 fee_read(base, 0x6B - (power_band >> 1),
1642 &power_adjust, 1);
1643 if(power_band & 0x1)
1644 power_adjust >>= 8;
1645 else
1646 power_adjust &= 0xFF;
1647
1648#ifdef DEBUG_IOCTL_INFO
1649 printk(KERN_DEBUG "Wavelan EEprom Area 1 :");
1650 for(i = 0; i < 16; i++)
1651 {
1652 printk(" %04X",
1653 area[i]);
1654 }
1655 printk("\n");
1656
1657 printk(KERN_DEBUG "Wavelan EEprom DAC : %04X %04X\n",
1658 dac[0], dac[1]);
1659#endif
1660
1661 /* Frequency offset (for info only...) */
1662 area[0] = ((freq << 5) & 0xFFE0) | (area[0] & 0x1F);
1663
1664 /* Receiver Principle main divider coefficient */
1665 area[3] = (freq >> 1) + 2400L - 352L;
1666 area[2] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
1667
1668 /* Transmitter Main divider coefficient */
1669 area[13] = (freq >> 1) + 2400L;
1670 area[12] = ((freq & 0x1) << 4) | (area[2] & 0xFFEF);
1671
1672 /* Others part of the area are flags, bit streams or unused... */
1673
1674 /* Set the value in the DAC */
1675 dac[1] = ((power_adjust >> 1) & 0x7F) | (dac[1] & 0xFF80);
1676 dac[0] = ((power_adjust & 0x1) << 4) | (dac[0] & 0xFFEF);
1677
1678 /* Write the first area */
1679 fee_write(base, 0x00,
1680 area, 16);
1681
1682 /* Write the DAC */
1683 fee_write(base, 0x60,
1684 dac, 2);
1685
1686 /* We now should verify here that the EEprom writting was ok */
1687
1688 /* ReRead the first area */
1689 fee_read(base, 0x00,
1690 area_verify, 16);
1691
1692 /* ReRead the DAC */
1693 fee_read(base, 0x60,
1694 dac_verify, 2);
1695
1696 /* Compare */
1697 if(memcmp(area, area_verify, 16 * 2) ||
1698 memcmp(dac, dac_verify, 2 * 2))
1699 {
1700#ifdef DEBUG_IOCTL_ERROR
1701 printk(KERN_INFO "Wavelan: wv_set_frequency : unable to write new frequency to EEprom (?)\n");
1702#endif
1703 return -EOPNOTSUPP;
1704 }
1705
1706 /* We must download the frequency parameters to the
1707 * synthetisers (from the EEprom - area 1)
1708 * Note : as the EEprom is auto decremented, we set the end
1709 * if the area... */
1710 mmc_out(base, mmwoff(0, mmw_fee_addr), 0x0F);
1711 mmc_out(base, mmwoff(0, mmw_fee_ctrl),
1712 MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
1713
1714 /* Wait until the download is finished */
1715 fee_wait(base, 100, 100);
1716
1717 /* We must now download the power adjust value (gain) to
1718 * the synthetisers (from the EEprom - area 7 - DAC) */
1719 mmc_out(base, mmwoff(0, mmw_fee_addr), 0x61);
1720 mmc_out(base, mmwoff(0, mmw_fee_ctrl),
1721 MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD);
1722
1723 /* Wait until the download is finished */
1724 fee_wait(base, 100, 100);
1725
1726#ifdef DEBUG_IOCTL_INFO
1727 /* Verification of what we have done... */
1728
1729 printk(KERN_DEBUG "Wavelan EEprom Area 1 :");
1730 for(i = 0; i < 16; i++)
1731 {
1732 printk(" %04X",
1733 area_verify[i]);
1734 }
1735 printk("\n");
1736
1737 printk(KERN_DEBUG "Wavelan EEprom DAC : %04X %04X\n",
1738 dac_verify[0], dac_verify[1]);
1739#endif
1740
1741 return 0;
1742 }
1743 else
1744 return -EINVAL; /* Bah, never get there... */
1745}
1746
1747/*------------------------------------------------------------------*/
1748/*
1749 * Give the list of available frequencies
1750 */
1751static inline int
1752wv_frequency_list(u_long base, /* i/o port of the card */
1753 iw_freq * list, /* List of frequency to fill */
1754 int max) /* Maximum number of frequencies */
1755{
1756 u_short table[10]; /* Authorized frequency table */
1757 long freq = 0L; /* offset to 2.4 GHz in .5 MHz + 12 MHz */
1758 int i; /* index in the table */
1759 const int BAND_NUM = 10; /* Number of bands */
1760 int c = 0; /* Channel number */
1761
1762 /* Read the frequency table */
1763 fee_read(base, 0x71 /* frequency table */,
1764 table, 10);
1765
1766 /* Look all frequencies */
1767 i = 0;
1768 for(freq = 0; freq < 150; freq++)
1769 /* Look in the table if the frequency is allowed */
1770 if(table[9 - (freq / 16)] & (1 << (freq % 16)))
1771 {
1772 /* Compute approximate channel number */
1773 while((((channel_bands[c] >> 1) - 24) < freq) &&
1774 (c < BAND_NUM))
1775 c++;
1776 list[i].i = c; /* Set the list index */
1777
1778 /* put in the list */
1779 list[i].m = (((freq + 24) * 5) + 24000L) * 10000;
1780 list[i++].e = 1;
1781
1782 /* Check number */
1783 if(i >= max)
1784 return(i);
1785 }
1786
1787 return(i);
1788}
1789
1790#ifdef IW_WIRELESS_SPY
1791/*------------------------------------------------------------------*/
1792/*
1793 * Gather wireless spy statistics : for each packet, compare the source
1794 * address with out list, and if match, get the stats...
1795 * Sorry, but this function really need wireless extensions...
1796 */
1797static inline void
1798wl_spy_gather(struct net_device * dev,
1799 u_char * mac, /* MAC address */
1800 u_char * stats) /* Statistics to gather */
1801{
1802 struct iw_quality wstats;
1803
1804 wstats.qual = stats[2] & MMR_SGNL_QUAL;
1805 wstats.level = stats[0] & MMR_SIGNAL_LVL;
1806 wstats.noise = stats[1] & MMR_SILENCE_LVL;
1807 wstats.updated = 0x7;
1808
1809 /* Update spy records */
1810 wireless_spy_update(dev, mac, &wstats);
1811}
1812#endif /* IW_WIRELESS_SPY */
1813
1814#ifdef HISTOGRAM
1815/*------------------------------------------------------------------*/
1816/*
1817 * This function calculate an histogram on the signal level.
1818 * As the noise is quite constant, it's like doing it on the SNR.
1819 * We have defined a set of interval (lp->his_range), and each time
1820 * the level goes in that interval, we increment the count (lp->his_sum).
1821 * With this histogram you may detect if one wavelan is really weak,
1822 * or you may also calculate the mean and standard deviation of the level...
1823 */
1824static inline void
1825wl_his_gather(struct net_device * dev,
1826 u_char * stats) /* Statistics to gather */
1827{
1828 net_local * lp = netdev_priv(dev);
1829 u_char level = stats[0] & MMR_SIGNAL_LVL;
1830 int i;
1831
1832 /* Find the correct interval */
1833 i = 0;
1834 while((i < (lp->his_number - 1)) && (level >= lp->his_range[i++]))
1835 ;
1836
1837 /* Increment interval counter */
1838 (lp->his_sum[i])++;
1839}
1840#endif /* HISTOGRAM */
1841
1842static void wl_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
1843{
1844 strncpy(info->driver, "wavelan_cs", sizeof(info->driver)-1);
1845}
1846
1847static struct ethtool_ops ops = {
1848 .get_drvinfo = wl_get_drvinfo
1849};
1850
1851/*------------------------------------------------------------------*/
1852/*
1853 * Wireless Handler : get protocol name
1854 */
1855static int wavelan_get_name(struct net_device *dev,
1856 struct iw_request_info *info,
1857 union iwreq_data *wrqu,
1858 char *extra)
1859{
1860 strcpy(wrqu->name, "WaveLAN");
1861 return 0;
1862}
1863
1864/*------------------------------------------------------------------*/
1865/*
1866 * Wireless Handler : set NWID
1867 */
1868static int wavelan_set_nwid(struct net_device *dev,
1869 struct iw_request_info *info,
1870 union iwreq_data *wrqu,
1871 char *extra)
1872{
1873 kio_addr_t base = dev->base_addr;
1874 net_local *lp = netdev_priv(dev);
1875 psa_t psa;
1876 mm_t m;
1877 unsigned long flags;
1878 int ret = 0;
1879
1880 /* Disable interrupts and save flags. */
1881 spin_lock_irqsave(&lp->spinlock, flags);
1882
1883 /* Set NWID in WaveLAN. */
1884 if (!wrqu->nwid.disabled) {
1885 /* Set NWID in psa */
1886 psa.psa_nwid[0] = (wrqu->nwid.value & 0xFF00) >> 8;
1887 psa.psa_nwid[1] = wrqu->nwid.value & 0xFF;
1888 psa.psa_nwid_select = 0x01;
1889 psa_write(dev,
1890 (char *) psa.psa_nwid - (char *) &psa,
1891 (unsigned char *) psa.psa_nwid, 3);
1892
1893 /* Set NWID in mmc. */
1894 m.w.mmw_netw_id_l = psa.psa_nwid[1];
1895 m.w.mmw_netw_id_h = psa.psa_nwid[0];
1896 mmc_write(base,
1897 (char *) &m.w.mmw_netw_id_l -
1898 (char *) &m,
1899 (unsigned char *) &m.w.mmw_netw_id_l, 2);
1900 mmc_out(base, mmwoff(0, mmw_loopt_sel), 0x00);
1901 } else {
1902 /* Disable NWID in the psa. */
1903 psa.psa_nwid_select = 0x00;
1904 psa_write(dev,
1905 (char *) &psa.psa_nwid_select -
1906 (char *) &psa,
1907 (unsigned char *) &psa.psa_nwid_select,
1908 1);
1909
1910 /* Disable NWID in the mmc (no filtering). */
1911 mmc_out(base, mmwoff(0, mmw_loopt_sel),
1912 MMW_LOOPT_SEL_DIS_NWID);
1913 }
1914 /* update the Wavelan checksum */
1915 update_psa_checksum(dev);
1916
1917 /* Enable interrupts and restore flags. */
1918 spin_unlock_irqrestore(&lp->spinlock, flags);
1919
1920 return ret;
1921}
1922
1923/*------------------------------------------------------------------*/
1924/*
1925 * Wireless Handler : get NWID
1926 */
1927static int wavelan_get_nwid(struct net_device *dev,
1928 struct iw_request_info *info,
1929 union iwreq_data *wrqu,
1930 char *extra)
1931{
1932 net_local *lp = netdev_priv(dev);
1933 psa_t psa;
1934 unsigned long flags;
1935 int ret = 0;
1936
1937 /* Disable interrupts and save flags. */
1938 spin_lock_irqsave(&lp->spinlock, flags);
1939
1940 /* Read the NWID. */
1941 psa_read(dev,
1942 (char *) psa.psa_nwid - (char *) &psa,
1943 (unsigned char *) psa.psa_nwid, 3);
1944 wrqu->nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
1945 wrqu->nwid.disabled = !(psa.psa_nwid_select);
1946 wrqu->nwid.fixed = 1; /* Superfluous */
1947
1948 /* Enable interrupts and restore flags. */
1949 spin_unlock_irqrestore(&lp->spinlock, flags);
1950
1951 return ret;
1952}
1953
1954/*------------------------------------------------------------------*/
1955/*
1956 * Wireless Handler : set frequency
1957 */
1958static int wavelan_set_freq(struct net_device *dev,
1959 struct iw_request_info *info,
1960 union iwreq_data *wrqu,
1961 char *extra)
1962{
1963 kio_addr_t base = dev->base_addr;
1964 net_local *lp = netdev_priv(dev);
1965 unsigned long flags;
1966 int ret;
1967
1968 /* Disable interrupts and save flags. */
1969 spin_lock_irqsave(&lp->spinlock, flags);
1970
1971 /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
1972 if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
1973 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
1974 ret = wv_set_frequency(base, &(wrqu->freq));
1975 else
1976 ret = -EOPNOTSUPP;
1977
1978 /* Enable interrupts and restore flags. */
1979 spin_unlock_irqrestore(&lp->spinlock, flags);
1980
1981 return ret;
1982}
1983
1984/*------------------------------------------------------------------*/
1985/*
1986 * Wireless Handler : get frequency
1987 */
1988static int wavelan_get_freq(struct net_device *dev,
1989 struct iw_request_info *info,
1990 union iwreq_data *wrqu,
1991 char *extra)
1992{
1993 kio_addr_t base = dev->base_addr;
1994 net_local *lp = netdev_priv(dev);
1995 psa_t psa;
1996 unsigned long flags;
1997 int ret = 0;
1998
1999 /* Disable interrupts and save flags. */
2000 spin_lock_irqsave(&lp->spinlock, flags);
2001
2002 /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable).
2003 * Does it work for everybody, especially old cards? */
2004 if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
2005 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
2006 unsigned short freq;
2007
2008 /* Ask the EEPROM to read the frequency from the first area. */
2009 fee_read(base, 0x00, &freq, 1);
2010 wrqu->freq.m = ((freq >> 5) * 5 + 24000L) * 10000;
2011 wrqu->freq.e = 1;
2012 } else {
2013 psa_read(dev,
2014 (char *) &psa.psa_subband - (char *) &psa,
2015 (unsigned char *) &psa.psa_subband, 1);
2016
2017 if (psa.psa_subband <= 4) {
2018 wrqu->freq.m = fixed_bands[psa.psa_subband];
2019 wrqu->freq.e = (psa.psa_subband != 0);
2020 } else
2021 ret = -EOPNOTSUPP;
2022 }
2023
2024 /* Enable interrupts and restore flags. */
2025 spin_unlock_irqrestore(&lp->spinlock, flags);
2026
2027 return ret;
2028}
2029
2030/*------------------------------------------------------------------*/
2031/*
2032 * Wireless Handler : set level threshold
2033 */
2034static int wavelan_set_sens(struct net_device *dev,
2035 struct iw_request_info *info,
2036 union iwreq_data *wrqu,
2037 char *extra)
2038{
2039 kio_addr_t base = dev->base_addr;
2040 net_local *lp = netdev_priv(dev);
2041 psa_t psa;
2042 unsigned long flags;
2043 int ret = 0;
2044
2045 /* Disable interrupts and save flags. */
2046 spin_lock_irqsave(&lp->spinlock, flags);
2047
2048 /* Set the level threshold. */
2049 /* We should complain loudly if wrqu->sens.fixed = 0, because we
2050 * can't set auto mode... */
2051 psa.psa_thr_pre_set = wrqu->sens.value & 0x3F;
2052 psa_write(dev,
2053 (char *) &psa.psa_thr_pre_set - (char *) &psa,
2054 (unsigned char *) &psa.psa_thr_pre_set, 1);
2055 /* update the Wavelan checksum */
2056 update_psa_checksum(dev);
2057 mmc_out(base, mmwoff(0, mmw_thr_pre_set),
2058 psa.psa_thr_pre_set);
2059
2060 /* Enable interrupts and restore flags. */
2061 spin_unlock_irqrestore(&lp->spinlock, flags);
2062
2063 return ret;
2064}
2065
2066/*------------------------------------------------------------------*/
2067/*
2068 * Wireless Handler : get level threshold
2069 */
2070static int wavelan_get_sens(struct net_device *dev,
2071 struct iw_request_info *info,
2072 union iwreq_data *wrqu,
2073 char *extra)
2074{
2075 net_local *lp = netdev_priv(dev);
2076 psa_t psa;
2077 unsigned long flags;
2078 int ret = 0;
2079
2080 /* Disable interrupts and save flags. */
2081 spin_lock_irqsave(&lp->spinlock, flags);
2082
2083 /* Read the level threshold. */
2084 psa_read(dev,
2085 (char *) &psa.psa_thr_pre_set - (char *) &psa,
2086 (unsigned char *) &psa.psa_thr_pre_set, 1);
2087 wrqu->sens.value = psa.psa_thr_pre_set & 0x3F;
2088 wrqu->sens.fixed = 1;
2089
2090 /* Enable interrupts and restore flags. */
2091 spin_unlock_irqrestore(&lp->spinlock, flags);
2092
2093 return ret;
2094}
2095
2096/*------------------------------------------------------------------*/
2097/*
2098 * Wireless Handler : set encryption key
2099 */
2100static int wavelan_set_encode(struct net_device *dev,
2101 struct iw_request_info *info,
2102 union iwreq_data *wrqu,
2103 char *extra)
2104{
2105 kio_addr_t base = dev->base_addr;
2106 net_local *lp = netdev_priv(dev);
2107 unsigned long flags;
2108 psa_t psa;
2109 int ret = 0;
2110
2111 /* Disable interrupts and save flags. */
2112 spin_lock_irqsave(&lp->spinlock, flags);
2113
2114 /* Check if capable of encryption */
2115 if (!mmc_encr(base)) {
2116 ret = -EOPNOTSUPP;
2117 }
2118
2119 /* Check the size of the key */
2120 if((wrqu->encoding.length != 8) && (wrqu->encoding.length != 0)) {
2121 ret = -EINVAL;
2122 }
2123
2124 if(!ret) {
2125 /* Basic checking... */
2126 if (wrqu->encoding.length == 8) {
2127 /* Copy the key in the driver */
2128 memcpy(psa.psa_encryption_key, extra,
2129 wrqu->encoding.length);
2130 psa.psa_encryption_select = 1;
2131
2132 psa_write(dev,
2133 (char *) &psa.psa_encryption_select -
2134 (char *) &psa,
2135 (unsigned char *) &psa.
2136 psa_encryption_select, 8 + 1);
2137
2138 mmc_out(base, mmwoff(0, mmw_encr_enable),
2139 MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);
2140 mmc_write(base, mmwoff(0, mmw_encr_key),
2141 (unsigned char *) &psa.
2142 psa_encryption_key, 8);
2143 }
2144
2145 /* disable encryption */
2146 if (wrqu->encoding.flags & IW_ENCODE_DISABLED) {
2147 psa.psa_encryption_select = 0;
2148 psa_write(dev,
2149 (char *) &psa.psa_encryption_select -
2150 (char *) &psa,
2151 (unsigned char *) &psa.
2152 psa_encryption_select, 1);
2153
2154 mmc_out(base, mmwoff(0, mmw_encr_enable), 0);
2155 }
2156 /* update the Wavelan checksum */
2157 update_psa_checksum(dev);
2158 }
2159
2160 /* Enable interrupts and restore flags. */
2161 spin_unlock_irqrestore(&lp->spinlock, flags);
2162
2163 return ret;
2164}
2165
2166/*------------------------------------------------------------------*/
2167/*
2168 * Wireless Handler : get encryption key
2169 */
2170static int wavelan_get_encode(struct net_device *dev,
2171 struct iw_request_info *info,
2172 union iwreq_data *wrqu,
2173 char *extra)
2174{
2175 kio_addr_t base = dev->base_addr;
2176 net_local *lp = netdev_priv(dev);
2177 psa_t psa;
2178 unsigned long flags;
2179 int ret = 0;
2180
2181 /* Disable interrupts and save flags. */
2182 spin_lock_irqsave(&lp->spinlock, flags);
2183
2184 /* Check if encryption is available */
2185 if (!mmc_encr(base)) {
2186 ret = -EOPNOTSUPP;
2187 } else {
2188 /* Read the encryption key */
2189 psa_read(dev,
2190 (char *) &psa.psa_encryption_select -
2191 (char *) &psa,
2192 (unsigned char *) &psa.
2193 psa_encryption_select, 1 + 8);
2194
2195 /* encryption is enabled ? */
2196 if (psa.psa_encryption_select)
2197 wrqu->encoding.flags = IW_ENCODE_ENABLED;
2198 else
2199 wrqu->encoding.flags = IW_ENCODE_DISABLED;
2200 wrqu->encoding.flags |= mmc_encr(base);
2201
2202 /* Copy the key to the user buffer */
2203 wrqu->encoding.length = 8;
2204 memcpy(extra, psa.psa_encryption_key, wrqu->encoding.length);
2205 }
2206
2207 /* Enable interrupts and restore flags. */
2208 spin_unlock_irqrestore(&lp->spinlock, flags);
2209
2210 return ret;
2211}
2212
2213#ifdef WAVELAN_ROAMING_EXT
2214/*------------------------------------------------------------------*/
2215/*
2216 * Wireless Handler : set ESSID (domain)
2217 */
2218static int wavelan_set_essid(struct net_device *dev,
2219 struct iw_request_info *info,
2220 union iwreq_data *wrqu,
2221 char *extra)
2222{
2223 net_local *lp = netdev_priv(dev);
2224 unsigned long flags;
2225 int ret = 0;
2226
2227 /* Disable interrupts and save flags. */
2228 spin_lock_irqsave(&lp->spinlock, flags);
2229
2230 /* Check if disable */
2231 if(wrqu->data.flags == 0)
2232 lp->filter_domains = 0;
2233 else {
2234 char essid[IW_ESSID_MAX_SIZE + 1];
2235 char * endp;
2236
2237 /* Terminate the string */
2238 memcpy(essid, extra, wrqu->data.length);
2239 essid[IW_ESSID_MAX_SIZE] = '\0';
2240
2241#ifdef DEBUG_IOCTL_INFO
2242 printk(KERN_DEBUG "SetEssid : ``%s''\n", essid);
2243#endif /* DEBUG_IOCTL_INFO */
2244
2245 /* Convert to a number (note : Wavelan specific) */
2246 lp->domain_id = simple_strtoul(essid, &endp, 16);
2247 /* Has it worked ? */
2248 if(endp > essid)
2249 lp->filter_domains = 1;
2250 else {
2251 lp->filter_domains = 0;
2252 ret = -EINVAL;
2253 }
2254 }
2255
2256 /* Enable interrupts and restore flags. */
2257 spin_unlock_irqrestore(&lp->spinlock, flags);
2258
2259 return ret;
2260}
2261
2262/*------------------------------------------------------------------*/
2263/*
2264 * Wireless Handler : get ESSID (domain)
2265 */
2266static int wavelan_get_essid(struct net_device *dev,
2267 struct iw_request_info *info,
2268 union iwreq_data *wrqu,
2269 char *extra)
2270{
2271 net_local *lp = netdev_priv(dev);
2272
2273 /* Is the domain ID active ? */
2274 wrqu->data.flags = lp->filter_domains;
2275
2276 /* Copy Domain ID into a string (Wavelan specific) */
2277 /* Sound crazy, be we can't have a snprintf in the kernel !!! */
2278 sprintf(extra, "%lX", lp->domain_id);
2279 extra[IW_ESSID_MAX_SIZE] = '\0';
2280
2281 /* Set the length */
2282 wrqu->data.length = strlen(extra) + 1;
2283
2284 return 0;
2285}
2286
2287/*------------------------------------------------------------------*/
2288/*
2289 * Wireless Handler : set AP address
2290 */
2291static int wavelan_set_wap(struct net_device *dev,
2292 struct iw_request_info *info,
2293 union iwreq_data *wrqu,
2294 char *extra)
2295{
2296#ifdef DEBUG_IOCTL_INFO
2297 printk(KERN_DEBUG "Set AP to : %02X:%02X:%02X:%02X:%02X:%02X\n",
2298 wrqu->ap_addr.sa_data[0],
2299 wrqu->ap_addr.sa_data[1],
2300 wrqu->ap_addr.sa_data[2],
2301 wrqu->ap_addr.sa_data[3],
2302 wrqu->ap_addr.sa_data[4],
2303 wrqu->ap_addr.sa_data[5]);
2304#endif /* DEBUG_IOCTL_INFO */
2305
2306 return -EOPNOTSUPP;
2307}
2308
2309/*------------------------------------------------------------------*/
2310/*
2311 * Wireless Handler : get AP address
2312 */
2313static int wavelan_get_wap(struct net_device *dev,
2314 struct iw_request_info *info,
2315 union iwreq_data *wrqu,
2316 char *extra)
2317{
2318 /* Should get the real McCoy instead of own Ethernet address */
2319 memcpy(wrqu->ap_addr.sa_data, dev->dev_addr, WAVELAN_ADDR_SIZE);
2320 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
2321
2322 return -EOPNOTSUPP;
2323}
2324#endif /* WAVELAN_ROAMING_EXT */
2325
2326#ifdef WAVELAN_ROAMING
2327/*------------------------------------------------------------------*/
2328/*
2329 * Wireless Handler : set mode
2330 */
2331static int wavelan_set_mode(struct net_device *dev,
2332 struct iw_request_info *info,
2333 union iwreq_data *wrqu,
2334 char *extra)
2335{
2336 net_local *lp = netdev_priv(dev);
2337 unsigned long flags;
2338 int ret = 0;
2339
2340 /* Disable interrupts and save flags. */
2341 spin_lock_irqsave(&lp->spinlock, flags);
2342
2343 /* Check mode */
2344 switch(wrqu->mode) {
2345 case IW_MODE_ADHOC:
2346 if(do_roaming) {
2347 wv_roam_cleanup(dev);
2348 do_roaming = 0;
2349 }
2350 break;
2351 case IW_MODE_INFRA:
2352 if(!do_roaming) {
2353 wv_roam_init(dev);
2354 do_roaming = 1;
2355 }
2356 break;
2357 default:
2358 ret = -EINVAL;
2359 }
2360
2361 /* Enable interrupts and restore flags. */
2362 spin_unlock_irqrestore(&lp->spinlock, flags);
2363
2364 return ret;
2365}
2366
2367/*------------------------------------------------------------------*/
2368/*
2369 * Wireless Handler : get mode
2370 */
2371static int wavelan_get_mode(struct net_device *dev,
2372 struct iw_request_info *info,
2373 union iwreq_data *wrqu,
2374 char *extra)
2375{
2376 if(do_roaming)
2377 wrqu->mode = IW_MODE_INFRA;
2378 else
2379 wrqu->mode = IW_MODE_ADHOC;
2380
2381 return 0;
2382}
2383#endif /* WAVELAN_ROAMING */
2384
2385/*------------------------------------------------------------------*/
2386/*
2387 * Wireless Handler : get range info
2388 */
2389static int wavelan_get_range(struct net_device *dev,
2390 struct iw_request_info *info,
2391 union iwreq_data *wrqu,
2392 char *extra)
2393{
2394 kio_addr_t base = dev->base_addr;
2395 net_local *lp = netdev_priv(dev);
2396 struct iw_range *range = (struct iw_range *) extra;
2397 unsigned long flags;
2398 int ret = 0;
2399
2400 /* Set the length (very important for backward compatibility) */
2401 wrqu->data.length = sizeof(struct iw_range);
2402
2403 /* Set all the info we don't care or don't know about to zero */
2404 memset(range, 0, sizeof(struct iw_range));
2405
2406 /* Set the Wireless Extension versions */
2407 range->we_version_compiled = WIRELESS_EXT;
2408 range->we_version_source = 9;
2409
2410 /* Set information in the range struct. */
2411 range->throughput = 1.4 * 1000 * 1000; /* don't argue on this ! */
2412 range->min_nwid = 0x0000;
2413 range->max_nwid = 0xFFFF;
2414
2415 range->sensitivity = 0x3F;
2416 range->max_qual.qual = MMR_SGNL_QUAL;
2417 range->max_qual.level = MMR_SIGNAL_LVL;
2418 range->max_qual.noise = MMR_SILENCE_LVL;
2419 range->avg_qual.qual = MMR_SGNL_QUAL; /* Always max */
2420 /* Need to get better values for those two */
2421 range->avg_qual.level = 30;
2422 range->avg_qual.noise = 8;
2423
2424 range->num_bitrates = 1;
2425 range->bitrate[0] = 2000000; /* 2 Mb/s */
2426
2427 /* Event capability (kernel + driver) */
2428 range->event_capa[0] = (IW_EVENT_CAPA_MASK(0x8B02) |
2429 IW_EVENT_CAPA_MASK(0x8B04) |
2430 IW_EVENT_CAPA_MASK(0x8B06));
2431 range->event_capa[1] = IW_EVENT_CAPA_K_1;
2432
2433 /* Disable interrupts and save flags. */
2434 spin_lock_irqsave(&lp->spinlock, flags);
2435
2436 /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable). */
2437 if (!(mmc_in(base, mmroff(0, mmr_fee_status)) &
2438 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY))) {
2439 range->num_channels = 10;
2440 range->num_frequency = wv_frequency_list(base, range->freq,
2441 IW_MAX_FREQUENCIES);
2442 } else
2443 range->num_channels = range->num_frequency = 0;
2444
2445 /* Encryption supported ? */
2446 if (mmc_encr(base)) {
2447 range->encoding_size[0] = 8; /* DES = 64 bits key */
2448 range->num_encoding_sizes = 1;
2449 range->max_encoding_tokens = 1; /* Only one key possible */
2450 } else {
2451 range->num_encoding_sizes = 0;
2452 range->max_encoding_tokens = 0;
2453 }
2454
2455 /* Enable interrupts and restore flags. */
2456 spin_unlock_irqrestore(&lp->spinlock, flags);
2457
2458 return ret;
2459}
2460
2461/*------------------------------------------------------------------*/
2462/*
2463 * Wireless Private Handler : set quality threshold
2464 */
2465static int wavelan_set_qthr(struct net_device *dev,
2466 struct iw_request_info *info,
2467 union iwreq_data *wrqu,
2468 char *extra)
2469{
2470 kio_addr_t base = dev->base_addr;
2471 net_local *lp = netdev_priv(dev);
2472 psa_t psa;
2473 unsigned long flags;
2474
2475 /* Disable interrupts and save flags. */
2476 spin_lock_irqsave(&lp->spinlock, flags);
2477
2478 psa.psa_quality_thr = *(extra) & 0x0F;
2479 psa_write(dev,
2480 (char *) &psa.psa_quality_thr - (char *) &psa,
2481 (unsigned char *) &psa.psa_quality_thr, 1);
2482 /* update the Wavelan checksum */
2483 update_psa_checksum(dev);
2484 mmc_out(base, mmwoff(0, mmw_quality_thr),
2485 psa.psa_quality_thr);
2486
2487 /* Enable interrupts and restore flags. */
2488 spin_unlock_irqrestore(&lp->spinlock, flags);
2489
2490 return 0;
2491}
2492
2493/*------------------------------------------------------------------*/
2494/*
2495 * Wireless Private Handler : get quality threshold
2496 */
2497static int wavelan_get_qthr(struct net_device *dev,
2498 struct iw_request_info *info,
2499 union iwreq_data *wrqu,
2500 char *extra)
2501{
2502 net_local *lp = netdev_priv(dev);
2503 psa_t psa;
2504 unsigned long flags;
2505
2506 /* Disable interrupts and save flags. */
2507 spin_lock_irqsave(&lp->spinlock, flags);
2508
2509 psa_read(dev,
2510 (char *) &psa.psa_quality_thr - (char *) &psa,
2511 (unsigned char *) &psa.psa_quality_thr, 1);
2512 *(extra) = psa.psa_quality_thr & 0x0F;
2513
2514 /* Enable interrupts and restore flags. */
2515 spin_unlock_irqrestore(&lp->spinlock, flags);
2516
2517 return 0;
2518}
2519
2520#ifdef WAVELAN_ROAMING
2521/*------------------------------------------------------------------*/
2522/*
2523 * Wireless Private Handler : set roaming
2524 */
2525static int wavelan_set_roam(struct net_device *dev,
2526 struct iw_request_info *info,
2527 union iwreq_data *wrqu,
2528 char *extra)
2529{
2530 net_local *lp = netdev_priv(dev);
2531 unsigned long flags;
2532
2533 /* Disable interrupts and save flags. */
2534 spin_lock_irqsave(&lp->spinlock, flags);
2535
2536 /* Note : should check if user == root */
2537 if(do_roaming && (*extra)==0)
2538 wv_roam_cleanup(dev);
2539 else if(do_roaming==0 && (*extra)!=0)
2540 wv_roam_init(dev);
2541
2542 do_roaming = (*extra);
2543
2544 /* Enable interrupts and restore flags. */
2545 spin_unlock_irqrestore(&lp->spinlock, flags);
2546
2547 return 0;
2548}
2549
2550/*------------------------------------------------------------------*/
2551/*
2552 * Wireless Private Handler : get quality threshold
2553 */
2554static int wavelan_get_roam(struct net_device *dev,
2555 struct iw_request_info *info,
2556 union iwreq_data *wrqu,
2557 char *extra)
2558{
2559 *(extra) = do_roaming;
2560
2561 return 0;
2562}
2563#endif /* WAVELAN_ROAMING */
2564
2565#ifdef HISTOGRAM
2566/*------------------------------------------------------------------*/
2567/*
2568 * Wireless Private Handler : set histogram
2569 */
2570static int wavelan_set_histo(struct net_device *dev,
2571 struct iw_request_info *info,
2572 union iwreq_data *wrqu,
2573 char *extra)
2574{
2575 net_local *lp = netdev_priv(dev);
2576
2577 /* Check the number of intervals. */
2578 if (wrqu->data.length > 16) {
2579 return(-E2BIG);
2580 }
2581
2582 /* Disable histo while we copy the addresses.
2583 * As we don't disable interrupts, we need to do this */
2584 lp->his_number = 0;
2585
2586 /* Are there ranges to copy? */
2587 if (wrqu->data.length > 0) {
2588 /* Copy interval ranges to the driver */
2589 memcpy(lp->his_range, extra, wrqu->data.length);
2590
2591 {
2592 int i;
2593 printk(KERN_DEBUG "Histo :");
2594 for(i = 0; i < wrqu->data.length; i++)
2595 printk(" %d", lp->his_range[i]);
2596 printk("\n");
2597 }
2598
2599 /* Reset result structure. */
2600 memset(lp->his_sum, 0x00, sizeof(long) * 16);
2601 }
2602
2603 /* Now we can set the number of ranges */
2604 lp->his_number = wrqu->data.length;
2605
2606 return(0);
2607}
2608
2609/*------------------------------------------------------------------*/
2610/*
2611 * Wireless Private Handler : get histogram
2612 */
2613static int wavelan_get_histo(struct net_device *dev,
2614 struct iw_request_info *info,
2615 union iwreq_data *wrqu,
2616 char *extra)
2617{
2618 net_local *lp = netdev_priv(dev);
2619
2620 /* Set the number of intervals. */
2621 wrqu->data.length = lp->his_number;
2622
2623 /* Give back the distribution statistics */
2624 if(lp->his_number > 0)
2625 memcpy(extra, lp->his_sum, sizeof(long) * lp->his_number);
2626
2627 return(0);
2628}
2629#endif /* HISTOGRAM */
2630
2631/*------------------------------------------------------------------*/
2632/*
2633 * Structures to export the Wireless Handlers
2634 */
2635
2636static const struct iw_priv_args wavelan_private_args[] = {
2637/*{ cmd, set_args, get_args, name } */
2638 { SIOCSIPQTHR, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setqualthr" },
2639 { SIOCGIPQTHR, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getqualthr" },
2640 { SIOCSIPROAM, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setroam" },
2641 { SIOCGIPROAM, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getroam" },
2642 { SIOCSIPHISTO, IW_PRIV_TYPE_BYTE | 16, 0, "sethisto" },
2643 { SIOCGIPHISTO, 0, IW_PRIV_TYPE_INT | 16, "gethisto" },
2644};
2645
2646static const iw_handler wavelan_handler[] =
2647{
2648 NULL, /* SIOCSIWNAME */
2649 wavelan_get_name, /* SIOCGIWNAME */
2650 wavelan_set_nwid, /* SIOCSIWNWID */
2651 wavelan_get_nwid, /* SIOCGIWNWID */
2652 wavelan_set_freq, /* SIOCSIWFREQ */
2653 wavelan_get_freq, /* SIOCGIWFREQ */
2654#ifdef WAVELAN_ROAMING
2655 wavelan_set_mode, /* SIOCSIWMODE */
2656 wavelan_get_mode, /* SIOCGIWMODE */
2657#else /* WAVELAN_ROAMING */
2658 NULL, /* SIOCSIWMODE */
2659 NULL, /* SIOCGIWMODE */
2660#endif /* WAVELAN_ROAMING */
2661 wavelan_set_sens, /* SIOCSIWSENS */
2662 wavelan_get_sens, /* SIOCGIWSENS */
2663 NULL, /* SIOCSIWRANGE */
2664 wavelan_get_range, /* SIOCGIWRANGE */
2665 NULL, /* SIOCSIWPRIV */
2666 NULL, /* SIOCGIWPRIV */
2667 NULL, /* SIOCSIWSTATS */
2668 NULL, /* SIOCGIWSTATS */
2669 iw_handler_set_spy, /* SIOCSIWSPY */
2670 iw_handler_get_spy, /* SIOCGIWSPY */
2671 iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
2672 iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
2673#ifdef WAVELAN_ROAMING_EXT
2674 wavelan_set_wap, /* SIOCSIWAP */
2675 wavelan_get_wap, /* SIOCGIWAP */
2676 NULL, /* -- hole -- */
2677 NULL, /* SIOCGIWAPLIST */
2678 NULL, /* -- hole -- */
2679 NULL, /* -- hole -- */
2680 wavelan_set_essid, /* SIOCSIWESSID */
2681 wavelan_get_essid, /* SIOCGIWESSID */
2682#else /* WAVELAN_ROAMING_EXT */
2683 NULL, /* SIOCSIWAP */
2684 NULL, /* SIOCGIWAP */
2685 NULL, /* -- hole -- */
2686 NULL, /* SIOCGIWAPLIST */
2687 NULL, /* -- hole -- */
2688 NULL, /* -- hole -- */
2689 NULL, /* SIOCSIWESSID */
2690 NULL, /* SIOCGIWESSID */
2691#endif /* WAVELAN_ROAMING_EXT */
2692 NULL, /* SIOCSIWNICKN */
2693 NULL, /* SIOCGIWNICKN */
2694 NULL, /* -- hole -- */
2695 NULL, /* -- hole -- */
2696 NULL, /* SIOCSIWRATE */
2697 NULL, /* SIOCGIWRATE */
2698 NULL, /* SIOCSIWRTS */
2699 NULL, /* SIOCGIWRTS */
2700 NULL, /* SIOCSIWFRAG */
2701 NULL, /* SIOCGIWFRAG */
2702 NULL, /* SIOCSIWTXPOW */
2703 NULL, /* SIOCGIWTXPOW */
2704 NULL, /* SIOCSIWRETRY */
2705 NULL, /* SIOCGIWRETRY */
2706 wavelan_set_encode, /* SIOCSIWENCODE */
2707 wavelan_get_encode, /* SIOCGIWENCODE */
2708};
2709
2710static const iw_handler wavelan_private_handler[] =
2711{
2712 wavelan_set_qthr, /* SIOCIWFIRSTPRIV */
2713 wavelan_get_qthr, /* SIOCIWFIRSTPRIV + 1 */
2714#ifdef WAVELAN_ROAMING
2715 wavelan_set_roam, /* SIOCIWFIRSTPRIV + 2 */
2716 wavelan_get_roam, /* SIOCIWFIRSTPRIV + 3 */
2717#else /* WAVELAN_ROAMING */
2718 NULL, /* SIOCIWFIRSTPRIV + 2 */
2719 NULL, /* SIOCIWFIRSTPRIV + 3 */
2720#endif /* WAVELAN_ROAMING */
2721#ifdef HISTOGRAM
2722 wavelan_set_histo, /* SIOCIWFIRSTPRIV + 4 */
2723 wavelan_get_histo, /* SIOCIWFIRSTPRIV + 5 */
2724#endif /* HISTOGRAM */
2725};
2726
2727static const struct iw_handler_def wavelan_handler_def =
2728{
2729 .num_standard = sizeof(wavelan_handler)/sizeof(iw_handler),
2730 .num_private = sizeof(wavelan_private_handler)/sizeof(iw_handler),
2731 .num_private_args = sizeof(wavelan_private_args)/sizeof(struct iw_priv_args),
2732 .standard = wavelan_handler,
2733 .private = wavelan_private_handler,
2734 .private_args = wavelan_private_args,
2735 .get_wireless_stats = wavelan_get_wireless_stats,
2736};
2737
2738/*------------------------------------------------------------------*/
2739/*
2740 * Get wireless statistics
2741 * Called by /proc/net/wireless...
2742 */
2743static iw_stats *
2744wavelan_get_wireless_stats(struct net_device * dev)
2745{
2746 kio_addr_t base = dev->base_addr;
2747 net_local * lp = netdev_priv(dev);
2748 mmr_t m;
2749 iw_stats * wstats;
2750 unsigned long flags;
2751
2752#ifdef DEBUG_IOCTL_TRACE
2753 printk(KERN_DEBUG "%s: ->wavelan_get_wireless_stats()\n", dev->name);
2754#endif
2755
2756 /* Disable interrupts & save flags */
2757 spin_lock_irqsave(&lp->spinlock, flags);
2758
2759 wstats = &lp->wstats;
2760
2761 /* Get data from the mmc */
2762 mmc_out(base, mmwoff(0, mmw_freeze), 1);
2763
2764 mmc_read(base, mmroff(0, mmr_dce_status), &m.mmr_dce_status, 1);
2765 mmc_read(base, mmroff(0, mmr_wrong_nwid_l), &m.mmr_wrong_nwid_l, 2);
2766 mmc_read(base, mmroff(0, mmr_thr_pre_set), &m.mmr_thr_pre_set, 4);
2767
2768 mmc_out(base, mmwoff(0, mmw_freeze), 0);
2769
2770 /* Copy data to wireless stuff */
2771 wstats->status = m.mmr_dce_status & MMR_DCE_STATUS;
2772 wstats->qual.qual = m.mmr_sgnl_qual & MMR_SGNL_QUAL;
2773 wstats->qual.level = m.mmr_signal_lvl & MMR_SIGNAL_LVL;
2774 wstats->qual.noise = m.mmr_silence_lvl & MMR_SILENCE_LVL;
2775 wstats->qual.updated = (((m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 7) |
2776 ((m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) >> 6) |
2777 ((m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) >> 5));
2778 wstats->discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
2779 wstats->discard.code = 0L;
2780 wstats->discard.misc = 0L;
2781
2782 /* ReEnable interrupts & restore flags */
2783 spin_unlock_irqrestore(&lp->spinlock, flags);
2784
2785#ifdef DEBUG_IOCTL_TRACE
2786 printk(KERN_DEBUG "%s: <-wavelan_get_wireless_stats()\n", dev->name);
2787#endif
2788 return &lp->wstats;
2789}
2790#endif /* WIRELESS_EXT */
2791
2792/************************* PACKET RECEPTION *************************/
2793/*
2794 * This part deal with receiving the packets.
2795 * The interrupt handler get an interrupt when a packet has been
2796 * successfully received and called this part...
2797 */
2798
2799/*------------------------------------------------------------------*/
2800/*
2801 * Calculate the starting address of the frame pointed to by the receive
2802 * frame pointer and verify that the frame seem correct
2803 * (called by wv_packet_rcv())
2804 */
2805static inline int
2806wv_start_of_frame(struct net_device * dev,
2807 int rfp, /* end of frame */
2808 int wrap) /* start of buffer */
2809{
2810 kio_addr_t base = dev->base_addr;
2811 int rp;
2812 int len;
2813
2814 rp = (rfp - 5 + RX_SIZE) % RX_SIZE;
2815 outb(rp & 0xff, PIORL(base));
2816 outb(((rp >> 8) & PIORH_MASK), PIORH(base));
2817 len = inb(PIOP(base));
2818 len |= inb(PIOP(base)) << 8;
2819
2820 /* Sanity checks on size */
2821 /* Frame too big */
2822 if(len > MAXDATAZ + 100)
2823 {
2824#ifdef DEBUG_RX_ERROR
2825 printk(KERN_INFO "%s: wv_start_of_frame: Received frame too large, rfp %d len 0x%x\n",
2826 dev->name, rfp, len);
2827#endif
2828 return(-1);
2829 }
2830
2831 /* Frame too short */
2832 if(len < 7)
2833 {
2834#ifdef DEBUG_RX_ERROR
2835 printk(KERN_INFO "%s: wv_start_of_frame: Received null frame, rfp %d len 0x%x\n",
2836 dev->name, rfp, len);
2837#endif
2838 return(-1);
2839 }
2840
2841 /* Wrap around buffer */
2842 if(len > ((wrap - (rfp - len) + RX_SIZE) % RX_SIZE)) /* magic formula ! */
2843 {
2844#ifdef DEBUG_RX_ERROR
2845 printk(KERN_INFO "%s: wv_start_of_frame: wrap around buffer, wrap %d rfp %d len 0x%x\n",
2846 dev->name, wrap, rfp, len);
2847#endif
2848 return(-1);
2849 }
2850
2851 return((rp - len + RX_SIZE) % RX_SIZE);
2852} /* wv_start_of_frame */
2853
2854/*------------------------------------------------------------------*/
2855/*
2856 * This routine does the actual copy of data (including the ethernet
2857 * header structure) from the WaveLAN card to an sk_buff chain that
2858 * will be passed up to the network interface layer. NOTE: We
2859 * currently don't handle trailer protocols (neither does the rest of
2860 * the network interface), so if that is needed, it will (at least in
2861 * part) be added here. The contents of the receive ring buffer are
2862 * copied to a message chain that is then passed to the kernel.
2863 *
2864 * Note: if any errors occur, the packet is "dropped on the floor"
2865 * (called by wv_packet_rcv())
2866 */
2867static inline void
2868wv_packet_read(struct net_device * dev,
2869 int fd_p,
2870 int sksize)
2871{
2872 net_local * lp = netdev_priv(dev);
2873 struct sk_buff * skb;
2874
2875#ifdef DEBUG_RX_TRACE
2876 printk(KERN_DEBUG "%s: ->wv_packet_read(0x%X, %d)\n",
2877 dev->name, fd_p, sksize);
2878#endif
2879
2880 /* Allocate some buffer for the new packet */
2881 if((skb = dev_alloc_skb(sksize+2)) == (struct sk_buff *) NULL)
2882 {
2883#ifdef DEBUG_RX_ERROR
2884 printk(KERN_INFO "%s: wv_packet_read(): could not alloc_skb(%d, GFP_ATOMIC)\n",
2885 dev->name, sksize);
2886#endif
2887 lp->stats.rx_dropped++;
2888 /*
2889 * Not only do we want to return here, but we also need to drop the
2890 * packet on the floor to clear the interrupt.
2891 */
2892 return;
2893 }
2894
2895 skb->dev = dev;
2896
2897 skb_reserve(skb, 2);
2898 fd_p = read_ringbuf(dev, fd_p, (char *) skb_put(skb, sksize), sksize);
2899 skb->protocol = eth_type_trans(skb, dev);
2900
2901#ifdef DEBUG_RX_INFO
2902 wv_packet_info(skb->mac.raw, sksize, dev->name, "wv_packet_read");
2903#endif /* DEBUG_RX_INFO */
2904
2905 /* Statistics gathering & stuff associated.
2906 * It seem a bit messy with all the define, but it's really simple... */
2907 if(
2908#ifdef IW_WIRELESS_SPY
2909 (lp->spy_data.spy_number > 0) ||
2910#endif /* IW_WIRELESS_SPY */
2911#ifdef HISTOGRAM
2912 (lp->his_number > 0) ||
2913#endif /* HISTOGRAM */
2914#ifdef WAVELAN_ROAMING
2915 (do_roaming) ||
2916#endif /* WAVELAN_ROAMING */
2917 0)
2918 {
2919 u_char stats[3]; /* Signal level, Noise level, Signal quality */
2920
2921 /* read signal level, silence level and signal quality bytes */
2922 fd_p = read_ringbuf(dev, (fd_p + 4) % RX_SIZE + RX_BASE,
2923 stats, 3);
2924#ifdef DEBUG_RX_INFO
2925 printk(KERN_DEBUG "%s: wv_packet_read(): Signal level %d/63, Silence level %d/63, signal quality %d/16\n",
2926 dev->name, stats[0] & 0x3F, stats[1] & 0x3F, stats[2] & 0x0F);
2927#endif
2928
2929#ifdef WAVELAN_ROAMING
2930 if(do_roaming)
2931 if(WAVELAN_BEACON(skb->data))
2932 wl_roam_gather(dev, skb->data, stats);
2933#endif /* WAVELAN_ROAMING */
2934
2935#ifdef WIRELESS_SPY
2936 wl_spy_gather(dev, skb->mac.raw + WAVELAN_ADDR_SIZE, stats);
2937#endif /* WIRELESS_SPY */
2938#ifdef HISTOGRAM
2939 wl_his_gather(dev, stats);
2940#endif /* HISTOGRAM */
2941 }
2942
2943 /*
2944 * Hand the packet to the Network Module
2945 */
2946 netif_rx(skb);
2947
2948 /* Keep stats up to date */
2949 dev->last_rx = jiffies;
2950 lp->stats.rx_packets++;
2951 lp->stats.rx_bytes += sksize;
2952
2953#ifdef DEBUG_RX_TRACE
2954 printk(KERN_DEBUG "%s: <-wv_packet_read()\n", dev->name);
2955#endif
2956 return;
2957}
2958
2959/*------------------------------------------------------------------*/
2960/*
2961 * This routine is called by the interrupt handler to initiate a
2962 * packet transfer from the card to the network interface layer above
2963 * this driver. This routine checks if a buffer has been successfully
2964 * received by the WaveLAN card. If so, the routine wv_packet_read is
2965 * called to do the actual transfer of the card's data including the
2966 * ethernet header into a packet consisting of an sk_buff chain.
2967 * (called by wavelan_interrupt())
2968 * Note : the spinlock is already grabbed for us and irq are disabled.
2969 */
2970static inline void
2971wv_packet_rcv(struct net_device * dev)
2972{
2973 kio_addr_t base = dev->base_addr;
2974 net_local * lp = netdev_priv(dev);
2975 int newrfp;
2976 int rp;
2977 int len;
2978 int f_start;
2979 int status;
2980 int i593_rfp;
2981 int stat_ptr;
2982 u_char c[4];
2983
2984#ifdef DEBUG_RX_TRACE
2985 printk(KERN_DEBUG "%s: ->wv_packet_rcv()\n", dev->name);
2986#endif
2987
2988 /* Get the new receive frame pointer from the i82593 chip */
2989 outb(CR0_STATUS_2 | OP0_NOP, LCCR(base));
2990 i593_rfp = inb(LCSR(base));
2991 i593_rfp |= inb(LCSR(base)) << 8;
2992 i593_rfp %= RX_SIZE;
2993
2994 /* Get the new receive frame pointer from the WaveLAN card.
2995 * It is 3 bytes more than the increment of the i82593 receive
2996 * frame pointer, for each packet. This is because it includes the
2997 * 3 roaming bytes added by the mmc.
2998 */
2999 newrfp = inb(RPLL(base));
3000 newrfp |= inb(RPLH(base)) << 8;
3001 newrfp %= RX_SIZE;
3002
3003#ifdef DEBUG_RX_INFO
3004 printk(KERN_DEBUG "%s: wv_packet_rcv(): i593_rfp %d stop %d newrfp %d lp->rfp %d\n",
3005 dev->name, i593_rfp, lp->stop, newrfp, lp->rfp);
3006#endif
3007
3008#ifdef DEBUG_RX_ERROR
3009 /* If no new frame pointer... */
3010 if(lp->overrunning || newrfp == lp->rfp)
3011 printk(KERN_INFO "%s: wv_packet_rcv(): no new frame: i593_rfp %d stop %d newrfp %d lp->rfp %d\n",
3012 dev->name, i593_rfp, lp->stop, newrfp, lp->rfp);
3013#endif
3014
3015 /* Read all frames (packets) received */
3016 while(newrfp != lp->rfp)
3017 {
3018 /* A frame is composed of the packet, followed by a status word,
3019 * the length of the frame (word) and the mmc info (SNR & qual).
3020 * It's because the length is at the end that we can only scan
3021 * frames backward. */
3022
3023 /* Find the first frame by skipping backwards over the frames */
3024 rp = newrfp; /* End of last frame */
3025 while(((f_start = wv_start_of_frame(dev, rp, newrfp)) != lp->rfp) &&
3026 (f_start != -1))
3027 rp = f_start;
3028
3029 /* If we had a problem */
3030 if(f_start == -1)
3031 {
3032#ifdef DEBUG_RX_ERROR
3033 printk(KERN_INFO "wavelan_cs: cannot find start of frame ");
3034 printk(" i593_rfp %d stop %d newrfp %d lp->rfp %d\n",
3035 i593_rfp, lp->stop, newrfp, lp->rfp);
3036#endif
3037 lp->rfp = rp; /* Get to the last usable frame */
3038 continue;
3039 }
3040
3041 /* f_start point to the beggining of the first frame received
3042 * and rp to the beggining of the next one */
3043
3044 /* Read status & length of the frame */
3045 stat_ptr = (rp - 7 + RX_SIZE) % RX_SIZE;
3046 stat_ptr = read_ringbuf(dev, stat_ptr, c, 4);
3047 status = c[0] | (c[1] << 8);
3048 len = c[2] | (c[3] << 8);
3049
3050 /* Check status */
3051 if((status & RX_RCV_OK) != RX_RCV_OK)
3052 {
3053 lp->stats.rx_errors++;
3054 if(status & RX_NO_SFD)
3055 lp->stats.rx_frame_errors++;
3056 if(status & RX_CRC_ERR)
3057 lp->stats.rx_crc_errors++;
3058 if(status & RX_OVRRUN)
3059 lp->stats.rx_over_errors++;
3060
3061#ifdef DEBUG_RX_FAIL
3062 printk(KERN_DEBUG "%s: wv_packet_rcv(): packet not received ok, status = 0x%x\n",
3063 dev->name, status);
3064#endif
3065 }
3066 else
3067 /* Read the packet and transmit to Linux */
3068 wv_packet_read(dev, f_start, len - 2);
3069
3070 /* One frame has been processed, skip it */
3071 lp->rfp = rp;
3072 }
3073
3074 /*
3075 * Update the frame stop register, but set it to less than
3076 * the full 8K to allow space for 3 bytes of signal strength
3077 * per packet.
3078 */
3079 lp->stop = (i593_rfp + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE;
3080 outb(OP0_SWIT_TO_PORT_1 | CR0_CHNL, LCCR(base));
3081 outb(CR1_STOP_REG_UPDATE | (lp->stop >> RX_SIZE_SHIFT), LCCR(base));
3082 outb(OP1_SWIT_TO_PORT_0, LCCR(base));
3083
3084#ifdef DEBUG_RX_TRACE
3085 printk(KERN_DEBUG "%s: <-wv_packet_rcv()\n", dev->name);
3086#endif
3087}
3088
3089/*********************** PACKET TRANSMISSION ***********************/
3090/*
3091 * This part deal with sending packet through the wavelan
3092 * We copy the packet to the send buffer and then issue the send
3093 * command to the i82593. The result of this operation will be
3094 * checked in wavelan_interrupt()
3095 */
3096
3097/*------------------------------------------------------------------*/
3098/*
3099 * This routine fills in the appropriate registers and memory
3100 * locations on the WaveLAN card and starts the card off on
3101 * the transmit.
3102 * (called in wavelan_packet_xmit())
3103 */
3104static inline void
3105wv_packet_write(struct net_device * dev,
3106 void * buf,
3107 short length)
3108{
3109 net_local * lp = netdev_priv(dev);
3110 kio_addr_t base = dev->base_addr;
3111 unsigned long flags;
3112 int clen = length;
3113 register u_short xmtdata_base = TX_BASE;
3114
3115#ifdef DEBUG_TX_TRACE
3116 printk(KERN_DEBUG "%s: ->wv_packet_write(%d)\n", dev->name, length);
3117#endif
3118
3119 spin_lock_irqsave(&lp->spinlock, flags);
3120
3121 /* Write the length of data buffer followed by the buffer */
3122 outb(xmtdata_base & 0xff, PIORL(base));
3123 outb(((xmtdata_base >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
3124 outb(clen & 0xff, PIOP(base)); /* lsb */
3125 outb(clen >> 8, PIOP(base)); /* msb */
3126
3127 /* Send the data */
3128 outsb(PIOP(base), buf, clen);
3129
3130 /* Indicate end of transmit chain */
3131 outb(OP0_NOP, PIOP(base));
3132 /* josullvn@cs.cmu.edu: need to send a second NOP for alignment... */
3133 outb(OP0_NOP, PIOP(base));
3134
3135 /* Reset the transmit DMA pointer */
3136 hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
3137 hacr_write(base, HACR_DEFAULT);
3138 /* Send the transmit command */
3139 wv_82593_cmd(dev, "wv_packet_write(): transmit",
3140 OP0_TRANSMIT, SR0_NO_RESULT);
3141
3142 /* Make sure the watchdog will keep quiet for a while */
3143 dev->trans_start = jiffies;
3144
3145 /* Keep stats up to date */
3146 lp->stats.tx_bytes += length;
3147
3148 spin_unlock_irqrestore(&lp->spinlock, flags);
3149
3150#ifdef DEBUG_TX_INFO
3151 wv_packet_info((u_char *) buf, length, dev->name, "wv_packet_write");
3152#endif /* DEBUG_TX_INFO */
3153
3154#ifdef DEBUG_TX_TRACE
3155 printk(KERN_DEBUG "%s: <-wv_packet_write()\n", dev->name);
3156#endif
3157}
3158
3159/*------------------------------------------------------------------*/
3160/*
3161 * This routine is called when we want to send a packet (NET3 callback)
3162 * In this routine, we check if the harware is ready to accept
3163 * the packet. We also prevent reentrance. Then, we call the function
3164 * to send the packet...
3165 */
3166static int
3167wavelan_packet_xmit(struct sk_buff * skb,
3168 struct net_device * dev)
3169{
3170 net_local * lp = netdev_priv(dev);
3171 unsigned long flags;
3172
3173#ifdef DEBUG_TX_TRACE
3174 printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name,
3175 (unsigned) skb);
3176#endif
3177
3178 /*
3179 * Block a timer-based transmit from overlapping a previous transmit.
3180 * In other words, prevent reentering this routine.
3181 */
3182 netif_stop_queue(dev);
3183
3184 /* If somebody has asked to reconfigure the controller,
3185 * we can do it now */
3186 if(lp->reconfig_82593)
3187 {
3188 spin_lock_irqsave(&lp->spinlock, flags); /* Disable interrupts */
3189 wv_82593_config(dev);
3190 spin_unlock_irqrestore(&lp->spinlock, flags); /* Re-enable interrupts */
3191 /* Note : the configure procedure was totally synchronous,
3192 * so the Tx buffer is now free */
3193 }
3194
3195#ifdef DEBUG_TX_ERROR
3196 if (skb->next)
3197 printk(KERN_INFO "skb has next\n");
3198#endif
3199
3200 /* Check if we need some padding */
3201 /* Note : on wireless the propagation time is in the order of 1us,
3202 * and we don't have the Ethernet specific requirement of beeing
3203 * able to detect collisions, therefore in theory we don't really
3204 * need to pad. Jean II */
3205 if (skb->len < ETH_ZLEN) {
3206 skb = skb_padto(skb, ETH_ZLEN);
3207 if (skb == NULL)
3208 return 0;
3209 }
3210
3211 wv_packet_write(dev, skb->data, skb->len);
3212
3213 dev_kfree_skb(skb);
3214
3215#ifdef DEBUG_TX_TRACE
3216 printk(KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name);
3217#endif
3218 return(0);
3219}
3220
3221/********************** HARDWARE CONFIGURATION **********************/
3222/*
3223 * This part do the real job of starting and configuring the hardware.
3224 */
3225
3226/*------------------------------------------------------------------*/
3227/*
3228 * Routine to initialize the Modem Management Controller.
3229 * (called by wv_hw_config())
3230 */
3231static inline int
3232wv_mmc_init(struct net_device * dev)
3233{
3234 kio_addr_t base = dev->base_addr;
3235 psa_t psa;
3236 mmw_t m;
3237 int configured;
3238 int i; /* Loop counter */
3239
3240#ifdef DEBUG_CONFIG_TRACE
3241 printk(KERN_DEBUG "%s: ->wv_mmc_init()\n", dev->name);
3242#endif
3243
3244 /* Read the parameter storage area */
3245 psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
3246
3247 /*
3248 * Check the first three octets of the MAC addr for the manufacturer's code.
3249 * Note: If you get the error message below, you've got a
3250 * non-NCR/AT&T/Lucent PCMCIA cards, see wavelan_cs.h for detail on
3251 * how to configure your card...
3252 */
3253 for(i = 0; i < (sizeof(MAC_ADDRESSES) / sizeof(char) / 3); i++)
3254 if((psa.psa_univ_mac_addr[0] == MAC_ADDRESSES[i][0]) &&
3255 (psa.psa_univ_mac_addr[1] == MAC_ADDRESSES[i][1]) &&
3256 (psa.psa_univ_mac_addr[2] == MAC_ADDRESSES[i][2]))
3257 break;
3258
3259 /* If we have not found it... */
3260 if(i == (sizeof(MAC_ADDRESSES) / sizeof(char) / 3))
3261 {
3262#ifdef DEBUG_CONFIG_ERRORS
3263 printk(KERN_WARNING "%s: wv_mmc_init(): Invalid MAC address: %02X:%02X:%02X:...\n",
3264 dev->name, psa.psa_univ_mac_addr[0],
3265 psa.psa_univ_mac_addr[1], psa.psa_univ_mac_addr[2]);
3266#endif
3267 return FALSE;
3268 }
3269
3270 /* Get the MAC address */
3271 memcpy(&dev->dev_addr[0], &psa.psa_univ_mac_addr[0], WAVELAN_ADDR_SIZE);
3272
3273#ifdef USE_PSA_CONFIG
3274 configured = psa.psa_conf_status & 1;
3275#else
3276 configured = 0;
3277#endif
3278
3279 /* Is the PSA is not configured */
3280 if(!configured)
3281 {
3282 /* User will be able to configure NWID after (with iwconfig) */
3283 psa.psa_nwid[0] = 0;
3284 psa.psa_nwid[1] = 0;
3285
3286 /* As NWID is not set : no NWID checking */
3287 psa.psa_nwid_select = 0;
3288
3289 /* Disable encryption */
3290 psa.psa_encryption_select = 0;
3291
3292 /* Set to standard values
3293 * 0x04 for AT,
3294 * 0x01 for MCA,
3295 * 0x04 for PCMCIA and 2.00 card (AT&T 407-024689/E document)
3296 */
3297 if (psa.psa_comp_number & 1)
3298 psa.psa_thr_pre_set = 0x01;
3299 else
3300 psa.psa_thr_pre_set = 0x04;
3301 psa.psa_quality_thr = 0x03;
3302
3303 /* It is configured */
3304 psa.psa_conf_status |= 1;
3305
3306#ifdef USE_PSA_CONFIG
3307 /* Write the psa */
3308 psa_write(dev, (char *)psa.psa_nwid - (char *)&psa,
3309 (unsigned char *)psa.psa_nwid, 4);
3310 psa_write(dev, (char *)&psa.psa_thr_pre_set - (char *)&psa,
3311 (unsigned char *)&psa.psa_thr_pre_set, 1);
3312 psa_write(dev, (char *)&psa.psa_quality_thr - (char *)&psa,
3313 (unsigned char *)&psa.psa_quality_thr, 1);
3314 psa_write(dev, (char *)&psa.psa_conf_status - (char *)&psa,
3315 (unsigned char *)&psa.psa_conf_status, 1);
3316 /* update the Wavelan checksum */
3317 update_psa_checksum(dev);
3318#endif /* USE_PSA_CONFIG */
3319 }
3320
3321 /* Zero the mmc structure */
3322 memset(&m, 0x00, sizeof(m));
3323
3324 /* Copy PSA info to the mmc */
3325 m.mmw_netw_id_l = psa.psa_nwid[1];
3326 m.mmw_netw_id_h = psa.psa_nwid[0];
3327
3328 if(psa.psa_nwid_select & 1)
3329 m.mmw_loopt_sel = 0x00;
3330 else
3331 m.mmw_loopt_sel = MMW_LOOPT_SEL_DIS_NWID;
3332
3333 memcpy(&m.mmw_encr_key, &psa.psa_encryption_key,
3334 sizeof(m.mmw_encr_key));
3335
3336 if(psa.psa_encryption_select)
3337 m.mmw_encr_enable = MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE;
3338 else
3339 m.mmw_encr_enable = 0;
3340
3341 m.mmw_thr_pre_set = psa.psa_thr_pre_set & 0x3F;
3342 m.mmw_quality_thr = psa.psa_quality_thr & 0x0F;
3343
3344 /*
3345 * Set default modem control parameters.
3346 * See NCR document 407-0024326 Rev. A.
3347 */
3348 m.mmw_jabber_enable = 0x01;
3349 m.mmw_anten_sel = MMW_ANTEN_SEL_ALG_EN;
3350 m.mmw_ifs = 0x20;
3351 m.mmw_mod_delay = 0x04;
3352 m.mmw_jam_time = 0x38;
3353
3354 m.mmw_des_io_invert = 0;
3355 m.mmw_freeze = 0;
3356 m.mmw_decay_prm = 0;
3357 m.mmw_decay_updat_prm = 0;
3358
3359 /* Write all info to mmc */
3360 mmc_write(base, 0, (u_char *)&m, sizeof(m));
3361
3362 /* The following code start the modem of the 2.00 frequency
3363 * selectable cards at power on. It's not strictly needed for the
3364 * following boots...
3365 * The original patch was by Joe Finney for the PCMCIA driver, but
3366 * I've cleaned it a bit and add documentation.
3367 * Thanks to Loeke Brederveld from Lucent for the info.
3368 */
3369
3370 /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable)
3371 * (does it work for everybody ? - especially old cards...) */
3372 /* Note : WFREQSEL verify that it is able to read from EEprom
3373 * a sensible frequency (address 0x00) + that MMR_FEE_STATUS_ID
3374 * is 0xA (Xilinx version) or 0xB (Ariadne version).
3375 * My test is more crude but do work... */
3376 if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
3377 (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
3378 {
3379 /* We must download the frequency parameters to the
3380 * synthetisers (from the EEprom - area 1)
3381 * Note : as the EEprom is auto decremented, we set the end
3382 * if the area... */
3383 m.mmw_fee_addr = 0x0F;
3384 m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
3385 mmc_write(base, (char *)&m.mmw_fee_ctrl - (char *)&m,
3386 (unsigned char *)&m.mmw_fee_ctrl, 2);
3387
3388 /* Wait until the download is finished */
3389 fee_wait(base, 100, 100);
3390
3391#ifdef DEBUG_CONFIG_INFO
3392 /* The frequency was in the last word downloaded... */
3393 mmc_read(base, (char *)&m.mmw_fee_data_l - (char *)&m,
3394 (unsigned char *)&m.mmw_fee_data_l, 2);
3395
3396 /* Print some info for the user */
3397 printk(KERN_DEBUG "%s: Wavelan 2.00 recognised (frequency select) : Current frequency = %ld\n",
3398 dev->name,
3399 ((m.mmw_fee_data_h << 4) |
3400 (m.mmw_fee_data_l >> 4)) * 5 / 2 + 24000L);
3401#endif
3402
3403 /* We must now download the power adjust value (gain) to
3404 * the synthetisers (from the EEprom - area 7 - DAC) */
3405 m.mmw_fee_addr = 0x61;
3406 m.mmw_fee_ctrl = MMW_FEE_CTRL_READ | MMW_FEE_CTRL_DWLD;
3407 mmc_write(base, (char *)&m.mmw_fee_ctrl - (char *)&m,
3408 (unsigned char *)&m.mmw_fee_ctrl, 2);
3409
3410 /* Wait until the download is finished */
3411 } /* if 2.00 card */
3412
3413#ifdef DEBUG_CONFIG_TRACE
3414 printk(KERN_DEBUG "%s: <-wv_mmc_init()\n", dev->name);
3415#endif
3416 return TRUE;
3417}
3418
3419/*------------------------------------------------------------------*/
3420/*
3421 * Routine to gracefully turn off reception, and wait for any commands
3422 * to complete.
3423 * (called in wv_ru_start() and wavelan_close() and wavelan_event())
3424 */
3425static int
3426wv_ru_stop(struct net_device * dev)
3427{
3428 kio_addr_t base = dev->base_addr;
3429 net_local * lp = netdev_priv(dev);
3430 unsigned long flags;
3431 int status;
3432 int spin;
3433
3434#ifdef DEBUG_CONFIG_TRACE
3435 printk(KERN_DEBUG "%s: ->wv_ru_stop()\n", dev->name);
3436#endif
3437
3438 spin_lock_irqsave(&lp->spinlock, flags);
3439
3440 /* First, send the LAN controller a stop receive command */
3441 wv_82593_cmd(dev, "wv_graceful_shutdown(): stop-rcv",
3442 OP0_STOP_RCV, SR0_NO_RESULT);
3443
3444 /* Then, spin until the receive unit goes idle */
3445 spin = 300;
3446 do
3447 {
3448 udelay(10);
3449 outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
3450 status = inb(LCSR(base));
3451 }
3452 while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_IDLE) && (spin-- > 0));
3453
3454 /* Now, spin until the chip finishes executing its current command */
3455 do
3456 {
3457 udelay(10);
3458 outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
3459 status = inb(LCSR(base));
3460 }
3461 while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0));
3462
3463 spin_unlock_irqrestore(&lp->spinlock, flags);
3464
3465 /* If there was a problem */
3466 if(spin <= 0)
3467 {
3468#ifdef DEBUG_CONFIG_ERRORS
3469 printk(KERN_INFO "%s: wv_ru_stop(): The chip doesn't want to stop...\n",
3470 dev->name);
3471#endif
3472 return FALSE;
3473 }
3474
3475#ifdef DEBUG_CONFIG_TRACE
3476 printk(KERN_DEBUG "%s: <-wv_ru_stop()\n", dev->name);
3477#endif
3478 return TRUE;
3479} /* wv_ru_stop */
3480
3481/*------------------------------------------------------------------*/
3482/*
3483 * This routine starts the receive unit running. First, it checks if
3484 * the card is actually ready. Then the card is instructed to receive
3485 * packets again.
3486 * (called in wv_hw_reset() & wavelan_open())
3487 */
3488static int
3489wv_ru_start(struct net_device * dev)
3490{
3491 kio_addr_t base = dev->base_addr;
3492 net_local * lp = netdev_priv(dev);
3493 unsigned long flags;
3494
3495#ifdef DEBUG_CONFIG_TRACE
3496 printk(KERN_DEBUG "%s: ->wv_ru_start()\n", dev->name);
3497#endif
3498
3499 /*
3500 * We need to start from a quiescent state. To do so, we could check
3501 * if the card is already running, but instead we just try to shut
3502 * it down. First, we disable reception (in case it was already enabled).
3503 */
3504 if(!wv_ru_stop(dev))
3505 return FALSE;
3506
3507 spin_lock_irqsave(&lp->spinlock, flags);
3508
3509 /* Now we know that no command is being executed. */
3510
3511 /* Set the receive frame pointer and stop pointer */
3512 lp->rfp = 0;
3513 outb(OP0_SWIT_TO_PORT_1 | CR0_CHNL, LCCR(base));
3514
3515 /* Reset ring management. This sets the receive frame pointer to 1 */
3516 outb(OP1_RESET_RING_MNGMT, LCCR(base));
3517
3518#if 0
3519 /* XXX the i82593 manual page 6-4 seems to indicate that the stop register
3520 should be set as below */
3521 /* outb(CR1_STOP_REG_UPDATE|((RX_SIZE - 0x40)>> RX_SIZE_SHIFT),LCCR(base));*/
3522#elif 0
3523 /* but I set it 0 instead */
3524 lp->stop = 0;
3525#else
3526 /* but I set it to 3 bytes per packet less than 8K */
3527 lp->stop = (0 + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE;
3528#endif
3529 outb(CR1_STOP_REG_UPDATE | (lp->stop >> RX_SIZE_SHIFT), LCCR(base));
3530 outb(OP1_INT_ENABLE, LCCR(base));
3531 outb(OP1_SWIT_TO_PORT_0, LCCR(base));
3532
3533 /* Reset receive DMA pointer */
3534 hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
3535 hacr_write_slow(base, HACR_DEFAULT);
3536
3537 /* Receive DMA on channel 1 */
3538 wv_82593_cmd(dev, "wv_ru_start(): rcv-enable",
3539 CR0_CHNL | OP0_RCV_ENABLE, SR0_NO_RESULT);
3540
3541#ifdef DEBUG_I82593_SHOW
3542 {
3543 int status;
3544 int opri;
3545 int spin = 10000;
3546
3547 /* spin until the chip starts receiving */
3548 do
3549 {
3550 outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
3551 status = inb(LCSR(base));
3552 if(spin-- <= 0)
3553 break;
3554 }
3555 while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_ACTIVE) &&
3556 ((status & SR3_RCV_STATE_MASK) != SR3_RCV_READY));
3557 printk(KERN_DEBUG "rcv status is 0x%x [i:%d]\n",
3558 (status & SR3_RCV_STATE_MASK), i);
3559 }
3560#endif
3561
3562 spin_unlock_irqrestore(&lp->spinlock, flags);
3563
3564#ifdef DEBUG_CONFIG_TRACE
3565 printk(KERN_DEBUG "%s: <-wv_ru_start()\n", dev->name);
3566#endif
3567 return TRUE;
3568}
3569
3570/*------------------------------------------------------------------*/
3571/*
3572 * This routine does a standard config of the WaveLAN controller (i82593).
3573 * In the ISA driver, this is integrated in wavelan_hardware_reset()
3574 * (called by wv_hw_config(), wv_82593_reconfig() & wavelan_packet_xmit())
3575 */
3576static int
3577wv_82593_config(struct net_device * dev)
3578{
3579 kio_addr_t base = dev->base_addr;
3580 net_local * lp = netdev_priv(dev);
3581 struct i82593_conf_block cfblk;
3582 int ret = TRUE;
3583
3584#ifdef DEBUG_CONFIG_TRACE
3585 printk(KERN_DEBUG "%s: ->wv_82593_config()\n", dev->name);
3586#endif
3587
3588 /* Create & fill i82593 config block
3589 *
3590 * Now conform to Wavelan document WCIN085B
3591 */
3592 memset(&cfblk, 0x00, sizeof(struct i82593_conf_block));
3593 cfblk.d6mod = FALSE; /* Run in i82593 advanced mode */
3594 cfblk.fifo_limit = 5; /* = 56 B rx and 40 B tx fifo thresholds */
3595 cfblk.forgnesi = FALSE; /* 0=82C501, 1=AMD7992B compatibility */
3596 cfblk.fifo_32 = 1;
3597 cfblk.throttle_enb = FALSE;
3598 cfblk.contin = TRUE; /* enable continuous mode */
3599 cfblk.cntrxint = FALSE; /* enable continuous mode receive interrupts */
3600 cfblk.addr_len = WAVELAN_ADDR_SIZE;
3601 cfblk.acloc = TRUE; /* Disable source addr insertion by i82593 */
3602 cfblk.preamb_len = 0; /* 2 bytes preamble (SFD) */
3603 cfblk.loopback = FALSE;
3604 cfblk.lin_prio = 0; /* conform to 802.3 backoff algoritm */
3605 cfblk.exp_prio = 5; /* conform to 802.3 backoff algoritm */
3606 cfblk.bof_met = 1; /* conform to 802.3 backoff algoritm */
3607 cfblk.ifrm_spc = 0x20; /* 32 bit times interframe spacing */
3608 cfblk.slottim_low = 0x20; /* 32 bit times slot time */
3609 cfblk.slottim_hi = 0x0;
3610 cfblk.max_retr = 15;
3611 cfblk.prmisc = ((lp->promiscuous) ? TRUE: FALSE); /* Promiscuous mode */
3612 cfblk.bc_dis = FALSE; /* Enable broadcast reception */
3613 cfblk.crs_1 = TRUE; /* Transmit without carrier sense */
3614 cfblk.nocrc_ins = FALSE; /* i82593 generates CRC */
3615 cfblk.crc_1632 = FALSE; /* 32-bit Autodin-II CRC */
3616 cfblk.crs_cdt = FALSE; /* CD not to be interpreted as CS */
3617 cfblk.cs_filter = 0; /* CS is recognized immediately */
3618 cfblk.crs_src = FALSE; /* External carrier sense */
3619 cfblk.cd_filter = 0; /* CD is recognized immediately */
3620 cfblk.min_fr_len = ETH_ZLEN >> 2; /* Minimum frame length 64 bytes */
3621 cfblk.lng_typ = FALSE; /* Length field > 1500 = type field */
3622 cfblk.lng_fld = TRUE; /* Disable 802.3 length field check */
3623 cfblk.rxcrc_xf = TRUE; /* Don't transfer CRC to memory */
3624 cfblk.artx = TRUE; /* Disable automatic retransmission */
3625 cfblk.sarec = TRUE; /* Disable source addr trig of CD */
3626 cfblk.tx_jabber = TRUE; /* Disable jabber jam sequence */
3627 cfblk.hash_1 = FALSE; /* Use bits 0-5 in mc address hash */
3628 cfblk.lbpkpol = TRUE; /* Loopback pin active high */
3629 cfblk.fdx = FALSE; /* Disable full duplex operation */
3630 cfblk.dummy_6 = 0x3f; /* all ones */
3631 cfblk.mult_ia = FALSE; /* No multiple individual addresses */
3632 cfblk.dis_bof = FALSE; /* Disable the backoff algorithm ?! */
3633 cfblk.dummy_1 = TRUE; /* set to 1 */
3634 cfblk.tx_ifs_retrig = 3; /* Hmm... Disabled */
3635#ifdef MULTICAST_ALL
3636 cfblk.mc_all = (lp->allmulticast ? TRUE: FALSE); /* Allow all multicasts */
3637#else
3638 cfblk.mc_all = FALSE; /* No multicast all mode */
3639#endif
3640 cfblk.rcv_mon = 0; /* Monitor mode disabled */
3641 cfblk.frag_acpt = TRUE; /* Do not accept fragments */
3642 cfblk.tstrttrs = FALSE; /* No start transmission threshold */
3643 cfblk.fretx = TRUE; /* FIFO automatic retransmission */
3644 cfblk.syncrqs = FALSE; /* Synchronous DRQ deassertion... */
3645 cfblk.sttlen = TRUE; /* 6 byte status registers */
3646 cfblk.rx_eop = TRUE; /* Signal EOP on packet reception */
3647 cfblk.tx_eop = TRUE; /* Signal EOP on packet transmission */
3648 cfblk.rbuf_size = RX_SIZE>>11; /* Set receive buffer size */
3649 cfblk.rcvstop = TRUE; /* Enable Receive Stop Register */
3650
3651#ifdef DEBUG_I82593_SHOW
3652 {
3653 u_char *c = (u_char *) &cfblk;
3654 int i;
3655 printk(KERN_DEBUG "wavelan_cs: config block:");
3656 for(i = 0; i < sizeof(struct i82593_conf_block); i++,c++)
3657 {
3658 if((i % 16) == 0) printk("\n" KERN_DEBUG);
3659 printk("%02x ", *c);
3660 }
3661 printk("\n");
3662 }
3663#endif
3664
3665 /* Copy the config block to the i82593 */
3666 outb(TX_BASE & 0xff, PIORL(base));
3667 outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
3668 outb(sizeof(struct i82593_conf_block) & 0xff, PIOP(base)); /* lsb */
3669 outb(sizeof(struct i82593_conf_block) >> 8, PIOP(base)); /* msb */
3670 outsb(PIOP(base), (char *) &cfblk, sizeof(struct i82593_conf_block));
3671
3672 /* reset transmit DMA pointer */
3673 hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
3674 hacr_write(base, HACR_DEFAULT);
3675 if(!wv_82593_cmd(dev, "wv_82593_config(): configure",
3676 OP0_CONFIGURE, SR0_CONFIGURE_DONE))
3677 ret = FALSE;
3678
3679 /* Initialize adapter's ethernet MAC address */
3680 outb(TX_BASE & 0xff, PIORL(base));
3681 outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
3682 outb(WAVELAN_ADDR_SIZE, PIOP(base)); /* byte count lsb */
3683 outb(0, PIOP(base)); /* byte count msb */
3684 outsb(PIOP(base), &dev->dev_addr[0], WAVELAN_ADDR_SIZE);
3685
3686 /* reset transmit DMA pointer */
3687 hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
3688 hacr_write(base, HACR_DEFAULT);
3689 if(!wv_82593_cmd(dev, "wv_82593_config(): ia-setup",
3690 OP0_IA_SETUP, SR0_IA_SETUP_DONE))
3691 ret = FALSE;
3692
3693#ifdef WAVELAN_ROAMING
3694 /* If roaming is enabled, join the "Beacon Request" multicast group... */
3695 /* But only if it's not in there already! */
3696 if(do_roaming)
3697 dev_mc_add(dev,WAVELAN_BEACON_ADDRESS, WAVELAN_ADDR_SIZE, 1);
3698#endif /* WAVELAN_ROAMING */
3699
3700 /* If any multicast address to set */
3701 if(lp->mc_count)
3702 {
3703 struct dev_mc_list * dmi;
3704 int addrs_len = WAVELAN_ADDR_SIZE * lp->mc_count;
3705
3706#ifdef DEBUG_CONFIG_INFO
3707 printk(KERN_DEBUG "%s: wv_hw_config(): set %d multicast addresses:\n",
3708 dev->name, lp->mc_count);
3709 for(dmi=dev->mc_list; dmi; dmi=dmi->next)
3710 printk(KERN_DEBUG " %02x:%02x:%02x:%02x:%02x:%02x\n",
3711 dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2],
3712 dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5] );
3713#endif
3714
3715 /* Initialize adapter's ethernet multicast addresses */
3716 outb(TX_BASE & 0xff, PIORL(base));
3717 outb(((TX_BASE >> 8) & PIORH_MASK) | PIORH_SEL_TX, PIORH(base));
3718 outb(addrs_len & 0xff, PIOP(base)); /* byte count lsb */
3719 outb((addrs_len >> 8), PIOP(base)); /* byte count msb */
3720 for(dmi=dev->mc_list; dmi; dmi=dmi->next)
3721 outsb(PIOP(base), dmi->dmi_addr, dmi->dmi_addrlen);
3722
3723 /* reset transmit DMA pointer */
3724 hacr_write_slow(base, HACR_PWR_STAT | HACR_TX_DMA_RESET);
3725 hacr_write(base, HACR_DEFAULT);
3726 if(!wv_82593_cmd(dev, "wv_82593_config(): mc-setup",
3727 OP0_MC_SETUP, SR0_MC_SETUP_DONE))
3728 ret = FALSE;
3729 lp->mc_count = dev->mc_count; /* remember to avoid repeated reset */
3730 }
3731
3732 /* Job done, clear the flag */
3733 lp->reconfig_82593 = FALSE;
3734
3735#ifdef DEBUG_CONFIG_TRACE
3736 printk(KERN_DEBUG "%s: <-wv_82593_config()\n", dev->name);
3737#endif
3738 return(ret);
3739}
3740
3741/*------------------------------------------------------------------*/
3742/*
3743 * Read the Access Configuration Register, perform a software reset,
3744 * and then re-enable the card's software.
3745 *
3746 * If I understand correctly : reset the pcmcia interface of the
3747 * wavelan.
3748 * (called by wv_config())
3749 */
3750static inline int
3751wv_pcmcia_reset(struct net_device * dev)
3752{
3753 int i;
3754 conf_reg_t reg = { 0, CS_READ, CISREG_COR, 0 };
3755 dev_link_t * link = ((net_local *)netdev_priv(dev))->link;
3756
3757#ifdef DEBUG_CONFIG_TRACE
3758 printk(KERN_DEBUG "%s: ->wv_pcmcia_reset()\n", dev->name);
3759#endif
3760
3761 i = pcmcia_access_configuration_register(link->handle, &reg);
3762 if(i != CS_SUCCESS)
3763 {
3764 cs_error(link->handle, AccessConfigurationRegister, i);
3765 return FALSE;
3766 }
3767
3768#ifdef DEBUG_CONFIG_INFO
3769 printk(KERN_DEBUG "%s: wavelan_pcmcia_reset(): Config reg is 0x%x\n",
3770 dev->name, (u_int) reg.Value);
3771#endif
3772
3773 reg.Action = CS_WRITE;
3774 reg.Value = reg.Value | COR_SW_RESET;
3775 i = pcmcia_access_configuration_register(link->handle, &reg);
3776 if(i != CS_SUCCESS)
3777 {
3778 cs_error(link->handle, AccessConfigurationRegister, i);
3779 return FALSE;
3780 }
3781
3782 reg.Action = CS_WRITE;
3783 reg.Value = COR_LEVEL_IRQ | COR_CONFIG;
3784 i = pcmcia_access_configuration_register(link->handle, &reg);
3785 if(i != CS_SUCCESS)
3786 {
3787 cs_error(link->handle, AccessConfigurationRegister, i);
3788 return FALSE;
3789 }
3790
3791#ifdef DEBUG_CONFIG_TRACE
3792 printk(KERN_DEBUG "%s: <-wv_pcmcia_reset()\n", dev->name);
3793#endif
3794 return TRUE;
3795}
3796
3797/*------------------------------------------------------------------*/
3798/*
3799 * wavelan_hw_config() is called after a CARD_INSERTION event is
3800 * received, to configure the wavelan hardware.
3801 * Note that the reception will be enabled in wavelan->open(), so the
3802 * device is configured but idle...
3803 * Performs the following actions:
3804 * 1. A pcmcia software reset (using wv_pcmcia_reset())
3805 * 2. A power reset (reset DMA)
3806 * 3. Reset the LAN controller
3807 * 4. Initialize the radio modem (using wv_mmc_init)
3808 * 5. Configure LAN controller (using wv_82593_config)
3809 * 6. Perform a diagnostic on the LAN controller
3810 * (called by wavelan_event() & wv_hw_reset())
3811 */
3812static int
3813wv_hw_config(struct net_device * dev)
3814{
3815 net_local * lp = netdev_priv(dev);
3816 kio_addr_t base = dev->base_addr;
3817 unsigned long flags;
3818 int ret = FALSE;
3819
3820#ifdef DEBUG_CONFIG_TRACE
3821 printk(KERN_DEBUG "%s: ->wv_hw_config()\n", dev->name);
3822#endif
3823
3824#ifdef STRUCT_CHECK
3825 if(wv_structuct_check() != (char *) NULL)
3826 {
3827 printk(KERN_WARNING "%s: wv_hw_config: structure/compiler botch: \"%s\"\n",
3828 dev->name, wv_structuct_check());
3829 return FALSE;
3830 }
3831#endif /* STRUCT_CHECK == 1 */
3832
3833 /* Reset the pcmcia interface */
3834 if(wv_pcmcia_reset(dev) == FALSE)
3835 return FALSE;
3836
3837 /* Disable interrupts */
3838 spin_lock_irqsave(&lp->spinlock, flags);
3839
3840 /* Disguised goto ;-) */
3841 do
3842 {
3843 /* Power UP the module + reset the modem + reset host adapter
3844 * (in fact, reset DMA channels) */
3845 hacr_write_slow(base, HACR_RESET);
3846 hacr_write(base, HACR_DEFAULT);
3847
3848 /* Check if the module has been powered up... */
3849 if(hasr_read(base) & HASR_NO_CLK)
3850 {
3851#ifdef DEBUG_CONFIG_ERRORS
3852 printk(KERN_WARNING "%s: wv_hw_config(): modem not connected or not a wavelan card\n",
3853 dev->name);
3854#endif
3855 break;
3856 }
3857
3858 /* initialize the modem */
3859 if(wv_mmc_init(dev) == FALSE)
3860 {
3861#ifdef DEBUG_CONFIG_ERRORS
3862 printk(KERN_WARNING "%s: wv_hw_config(): Can't configure the modem\n",
3863 dev->name);
3864#endif
3865 break;
3866 }
3867
3868 /* reset the LAN controller (i82593) */
3869 outb(OP0_RESET, LCCR(base));
3870 mdelay(1); /* A bit crude ! */
3871
3872 /* Initialize the LAN controller */
3873 if(wv_82593_config(dev) == FALSE)
3874 {
3875#ifdef DEBUG_CONFIG_ERRORS
3876 printk(KERN_INFO "%s: wv_hw_config(): i82593 init failed\n",
3877 dev->name);
3878#endif
3879 break;
3880 }
3881
3882 /* Diagnostic */
3883 if(wv_diag(dev) == FALSE)
3884 {
3885#ifdef DEBUG_CONFIG_ERRORS
3886 printk(KERN_INFO "%s: wv_hw_config(): i82593 diagnostic failed\n",
3887 dev->name);
3888#endif
3889 break;
3890 }
3891
3892 /*
3893 * insert code for loopback test here
3894 */
3895
3896 /* The device is now configured */
3897 lp->configured = 1;
3898 ret = TRUE;
3899 }
3900 while(0);
3901
3902 /* Re-enable interrupts */
3903 spin_unlock_irqrestore(&lp->spinlock, flags);
3904
3905#ifdef DEBUG_CONFIG_TRACE
3906 printk(KERN_DEBUG "%s: <-wv_hw_config()\n", dev->name);
3907#endif
3908 return(ret);
3909}
3910
3911/*------------------------------------------------------------------*/
3912/*
3913 * Totally reset the wavelan and restart it.
3914 * Performs the following actions:
3915 * 1. Call wv_hw_config()
3916 * 2. Start the LAN controller's receive unit
3917 * (called by wavelan_event(), wavelan_watchdog() and wavelan_open())
3918 */
3919static inline void
3920wv_hw_reset(struct net_device * dev)
3921{
3922 net_local * lp = netdev_priv(dev);
3923
3924#ifdef DEBUG_CONFIG_TRACE
3925 printk(KERN_DEBUG "%s: ->wv_hw_reset()\n", dev->name);
3926#endif
3927
3928 lp->nresets++;
3929 lp->configured = 0;
3930
3931 /* Call wv_hw_config() for most of the reset & init stuff */
3932 if(wv_hw_config(dev) == FALSE)
3933 return;
3934
3935 /* start receive unit */
3936 wv_ru_start(dev);
3937
3938#ifdef DEBUG_CONFIG_TRACE
3939 printk(KERN_DEBUG "%s: <-wv_hw_reset()\n", dev->name);
3940#endif
3941}
3942
3943/*------------------------------------------------------------------*/
3944/*
3945 * wv_pcmcia_config() is called after a CARD_INSERTION event is
3946 * received, to configure the PCMCIA socket, and to make the ethernet
3947 * device available to the system.
3948 * (called by wavelan_event())
3949 */
3950static inline int
3951wv_pcmcia_config(dev_link_t * link)
3952{
3953 client_handle_t handle = link->handle;
3954 tuple_t tuple;
3955 cisparse_t parse;
3956 struct net_device * dev = (struct net_device *) link->priv;
3957 int i;
3958 u_char buf[64];
3959 win_req_t req;
3960 memreq_t mem;
3961 net_local * lp = netdev_priv(dev);
3962
3963
3964#ifdef DEBUG_CONFIG_TRACE
3965 printk(KERN_DEBUG "->wv_pcmcia_config(0x%p)\n", link);
3966#endif
3967
3968 /*
3969 * This reads the card's CONFIG tuple to find its configuration
3970 * registers.
3971 */
3972 do
3973 {
3974 tuple.Attributes = 0;
3975 tuple.DesiredTuple = CISTPL_CONFIG;
3976 i = pcmcia_get_first_tuple(handle, &tuple);
3977 if(i != CS_SUCCESS)
3978 break;
3979 tuple.TupleData = (cisdata_t *)buf;
3980 tuple.TupleDataMax = 64;
3981 tuple.TupleOffset = 0;
3982 i = pcmcia_get_tuple_data(handle, &tuple);
3983 if(i != CS_SUCCESS)
3984 break;
3985 i = pcmcia_parse_tuple(handle, &tuple, &parse);
3986 if(i != CS_SUCCESS)
3987 break;
3988 link->conf.ConfigBase = parse.config.base;
3989 link->conf.Present = parse.config.rmask[0];
3990 }
3991 while(0);
3992 if(i != CS_SUCCESS)
3993 {
3994 cs_error(link->handle, ParseTuple, i);
3995 link->state &= ~DEV_CONFIG_PENDING;
3996 return FALSE;
3997 }
3998
3999 /* Configure card */
4000 link->state |= DEV_CONFIG;
4001 do
4002 {
4003 i = pcmcia_request_io(link->handle, &link->io);
4004 if(i != CS_SUCCESS)
4005 {
4006 cs_error(link->handle, RequestIO, i);
4007 break;
4008 }
4009
4010 /*
4011 * Now allocate an interrupt line. Note that this does not
4012 * actually assign a handler to the interrupt.
4013 */
4014 i = pcmcia_request_irq(link->handle, &link->irq);
4015 if(i != CS_SUCCESS)
4016 {
4017 cs_error(link->handle, RequestIRQ, i);
4018 break;
4019 }
4020
4021 /*
4022 * This actually configures the PCMCIA socket -- setting up
4023 * the I/O windows and the interrupt mapping.
4024 */
4025 link->conf.ConfigIndex = 1;
4026 i = pcmcia_request_configuration(link->handle, &link->conf);
4027 if(i != CS_SUCCESS)
4028 {
4029 cs_error(link->handle, RequestConfiguration, i);
4030 break;
4031 }
4032
4033 /*
4034 * Allocate a small memory window. Note that the dev_link_t
4035 * structure provides space for one window handle -- if your
4036 * device needs several windows, you'll need to keep track of
4037 * the handles in your private data structure, link->priv.
4038 */
4039 req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
4040 req.Base = req.Size = 0;
4041 req.AccessSpeed = mem_speed;
4042 i = pcmcia_request_window(&link->handle, &req, &link->win);
4043 if(i != CS_SUCCESS)
4044 {
4045 cs_error(link->handle, RequestWindow, i);
4046 break;
4047 }
4048
4049 lp->mem = ioremap(req.Base, req.Size);
4050 dev->mem_start = (u_long)lp->mem;
4051 dev->mem_end = dev->mem_start + req.Size;
4052
4053 mem.CardOffset = 0; mem.Page = 0;
4054 i = pcmcia_map_mem_page(link->win, &mem);
4055 if(i != CS_SUCCESS)
4056 {
4057 cs_error(link->handle, MapMemPage, i);
4058 break;
4059 }
4060
4061 /* Feed device with this info... */
4062 dev->irq = link->irq.AssignedIRQ;
4063 dev->base_addr = link->io.BasePort1;
4064 netif_start_queue(dev);
4065
4066#ifdef DEBUG_CONFIG_INFO
4067 printk(KERN_DEBUG "wv_pcmcia_config: MEMSTART %p IRQ %d IOPORT 0x%x\n",
4068 lp->mem, dev->irq, (u_int) dev->base_addr);
4069#endif
4070
4071 SET_NETDEV_DEV(dev, &handle_to_dev(handle));
4072 i = register_netdev(dev);
4073 if(i != 0)
4074 {
4075#ifdef DEBUG_CONFIG_ERRORS
4076 printk(KERN_INFO "wv_pcmcia_config(): register_netdev() failed\n");
4077#endif
4078 break;
4079 }
4080 }
4081 while(0); /* Humm... Disguised goto !!! */
4082
4083 link->state &= ~DEV_CONFIG_PENDING;
4084 /* If any step failed, release any partially configured state */
4085 if(i != 0)
4086 {
4087 wv_pcmcia_release(link);
4088 return FALSE;
4089 }
4090
4091 strcpy(((net_local *) netdev_priv(dev))->node.dev_name, dev->name);
4092 link->dev = &((net_local *) netdev_priv(dev))->node;
4093
4094#ifdef DEBUG_CONFIG_TRACE
4095 printk(KERN_DEBUG "<-wv_pcmcia_config()\n");
4096#endif
4097 return TRUE;
4098}
4099
4100/*------------------------------------------------------------------*/
4101/*
4102 * After a card is removed, wv_pcmcia_release() will unregister the net
4103 * device, and release the PCMCIA configuration. If the device is
4104 * still open, this will be postponed until it is closed.
4105 */
4106static void
4107wv_pcmcia_release(dev_link_t *link)
4108{
4109 struct net_device * dev = (struct net_device *) link->priv;
4110 net_local * lp = netdev_priv(dev);
4111
4112#ifdef DEBUG_CONFIG_TRACE
4113 printk(KERN_DEBUG "%s: -> wv_pcmcia_release(0x%p)\n", dev->name, link);
4114#endif
4115
4116 /* Don't bother checking to see if these succeed or not */
4117 iounmap(lp->mem);
4118 pcmcia_release_window(link->win);
4119 pcmcia_release_configuration(link->handle);
4120 pcmcia_release_io(link->handle, &link->io);
4121 pcmcia_release_irq(link->handle, &link->irq);
4122
4123 link->state &= ~DEV_CONFIG;
4124
4125#ifdef DEBUG_CONFIG_TRACE
4126 printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name);
4127#endif
4128}
4129
4130/************************ INTERRUPT HANDLING ************************/
4131
4132/*
4133 * This function is the interrupt handler for the WaveLAN card. This
4134 * routine will be called whenever:
4135 * 1. A packet is received.
4136 * 2. A packet has successfully been transferred and the unit is
4137 * ready to transmit another packet.
4138 * 3. A command has completed execution.
4139 */
4140static irqreturn_t
4141wavelan_interrupt(int irq,
4142 void * dev_id,
4143 struct pt_regs * regs)
4144{
4145 struct net_device * dev;
4146 net_local * lp;
4147 kio_addr_t base;
4148 int status0;
4149 u_int tx_status;
4150
4151 if ((dev = dev_id) == NULL)
4152 {
4153#ifdef DEBUG_INTERRUPT_ERROR
4154 printk(KERN_WARNING "wavelan_interrupt(): irq %d for unknown device.\n",
4155 irq);
4156#endif
4157 return IRQ_NONE;
4158 }
4159
4160#ifdef DEBUG_INTERRUPT_TRACE
4161 printk(KERN_DEBUG "%s: ->wavelan_interrupt()\n", dev->name);
4162#endif
4163
4164 lp = netdev_priv(dev);
4165 base = dev->base_addr;
4166
4167#ifdef DEBUG_INTERRUPT_INFO
4168 /* Check state of our spinlock (it should be cleared) */
4169 if(spin_is_locked(&lp->spinlock))
4170 printk(KERN_DEBUG
4171 "%s: wavelan_interrupt(): spinlock is already locked !!!\n",
4172 dev->name);
4173#endif
4174
4175 /* Prevent reentrancy. We need to do that because we may have
4176 * multiple interrupt handler running concurently.
4177 * It is safe because interrupts are disabled before aquiring
4178 * the spinlock. */
4179 spin_lock(&lp->spinlock);
4180
4181 /* Treat all pending interrupts */
4182 while(1)
4183 {
4184 /* ---------------- INTERRUPT CHECKING ---------------- */
4185 /*
4186 * Look for the interrupt and verify the validity
4187 */
4188 outb(CR0_STATUS_0 | OP0_NOP, LCCR(base));
4189 status0 = inb(LCSR(base));
4190
4191#ifdef DEBUG_INTERRUPT_INFO
4192 printk(KERN_DEBUG "status0 0x%x [%s => 0x%x]", status0,
4193 (status0&SR0_INTERRUPT)?"int":"no int",status0&~SR0_INTERRUPT);
4194 if(status0&SR0_INTERRUPT)
4195 {
4196 printk(" [%s => %d]\n", (status0 & SR0_CHNL) ? "chnl" :
4197 ((status0 & SR0_EXECUTION) ? "cmd" :
4198 ((status0 & SR0_RECEPTION) ? "recv" : "unknown")),
4199 (status0 & SR0_EVENT_MASK));
4200 }
4201 else
4202 printk("\n");
4203#endif
4204
4205 /* Return if no actual interrupt from i82593 (normal exit) */
4206 if(!(status0 & SR0_INTERRUPT))
4207 break;
4208
4209 /* If interrupt is both Rx and Tx or none...
4210 * This code in fact is there to catch the spurious interrupt
4211 * when you remove the wavelan pcmcia card from the socket */
4212 if(((status0 & SR0_BOTH_RX_TX) == SR0_BOTH_RX_TX) ||
4213 ((status0 & SR0_BOTH_RX_TX) == 0x0))
4214 {
4215#ifdef DEBUG_INTERRUPT_INFO
4216 printk(KERN_INFO "%s: wv_interrupt(): bogus interrupt (or from dead card) : %X\n",
4217 dev->name, status0);
4218#endif
4219 /* Acknowledge the interrupt */
4220 outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
4221 break;
4222 }
4223
4224 /* ----------------- RECEIVING PACKET ----------------- */
4225 /*
4226 * When the wavelan signal the reception of a new packet,
4227 * we call wv_packet_rcv() to copy if from the buffer and
4228 * send it to NET3
4229 */
4230 if(status0 & SR0_RECEPTION)
4231 {
4232#ifdef DEBUG_INTERRUPT_INFO
4233 printk(KERN_DEBUG "%s: wv_interrupt(): receive\n", dev->name);
4234#endif
4235
4236 if((status0 & SR0_EVENT_MASK) == SR0_STOP_REG_HIT)
4237 {
4238#ifdef DEBUG_INTERRUPT_ERROR
4239 printk(KERN_INFO "%s: wv_interrupt(): receive buffer overflow\n",
4240 dev->name);
4241#endif
4242 lp->stats.rx_over_errors++;
4243 lp->overrunning = 1;
4244 }
4245
4246 /* Get the packet */
4247 wv_packet_rcv(dev);
4248 lp->overrunning = 0;
4249
4250 /* Acknowledge the interrupt */
4251 outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
4252 continue;
4253 }
4254
4255 /* ---------------- COMMAND COMPLETION ---------------- */
4256 /*
4257 * Interrupts issued when the i82593 has completed a command.
4258 * Most likely : transmission done
4259 */
4260
4261 /* If a transmission has been done */
4262 if((status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_DONE ||
4263 (status0 & SR0_EVENT_MASK) == SR0_RETRANSMIT_DONE ||
4264 (status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_NO_CRC_DONE)
4265 {
4266#ifdef DEBUG_TX_ERROR
4267 if((status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_NO_CRC_DONE)
4268 printk(KERN_INFO "%s: wv_interrupt(): packet transmitted without CRC.\n",
4269 dev->name);
4270#endif
4271
4272 /* Get transmission status */
4273 tx_status = inb(LCSR(base));
4274 tx_status |= (inb(LCSR(base)) << 8);
4275#ifdef DEBUG_INTERRUPT_INFO
4276 printk(KERN_DEBUG "%s: wv_interrupt(): transmission done\n",
4277 dev->name);
4278 {
4279 u_int rcv_bytes;
4280 u_char status3;
4281 rcv_bytes = inb(LCSR(base));
4282 rcv_bytes |= (inb(LCSR(base)) << 8);
4283 status3 = inb(LCSR(base));
4284 printk(KERN_DEBUG "tx_status 0x%02x rcv_bytes 0x%02x status3 0x%x\n",
4285 tx_status, rcv_bytes, (u_int) status3);
4286 }
4287#endif
4288 /* Check for possible errors */
4289 if((tx_status & TX_OK) != TX_OK)
4290 {
4291 lp->stats.tx_errors++;
4292
4293 if(tx_status & TX_FRTL)
4294 {
4295#ifdef DEBUG_TX_ERROR
4296 printk(KERN_INFO "%s: wv_interrupt(): frame too long\n",
4297 dev->name);
4298#endif
4299 }
4300 if(tx_status & TX_UND_RUN)
4301 {
4302#ifdef DEBUG_TX_FAIL
4303 printk(KERN_DEBUG "%s: wv_interrupt(): DMA underrun\n",
4304 dev->name);
4305#endif
4306 lp->stats.tx_aborted_errors++;
4307 }
4308 if(tx_status & TX_LOST_CTS)
4309 {
4310#ifdef DEBUG_TX_FAIL
4311 printk(KERN_DEBUG "%s: wv_interrupt(): no CTS\n", dev->name);
4312#endif
4313 lp->stats.tx_carrier_errors++;
4314 }
4315 if(tx_status & TX_LOST_CRS)
4316 {
4317#ifdef DEBUG_TX_FAIL
4318 printk(KERN_DEBUG "%s: wv_interrupt(): no carrier\n",
4319 dev->name);
4320#endif
4321 lp->stats.tx_carrier_errors++;
4322 }
4323 if(tx_status & TX_HRT_BEAT)
4324 {
4325#ifdef DEBUG_TX_FAIL
4326 printk(KERN_DEBUG "%s: wv_interrupt(): heart beat\n", dev->name);
4327#endif
4328 lp->stats.tx_heartbeat_errors++;
4329 }
4330 if(tx_status & TX_DEFER)
4331 {
4332#ifdef DEBUG_TX_FAIL
4333 printk(KERN_DEBUG "%s: wv_interrupt(): channel jammed\n",
4334 dev->name);
4335#endif
4336 }
4337 /* Ignore late collisions since they're more likely to happen
4338 * here (the WaveLAN design prevents the LAN controller from
4339 * receiving while it is transmitting). We take action only when
4340 * the maximum retransmit attempts is exceeded.
4341 */
4342 if(tx_status & TX_COLL)
4343 {
4344 if(tx_status & TX_MAX_COL)
4345 {
4346#ifdef DEBUG_TX_FAIL
4347 printk(KERN_DEBUG "%s: wv_interrupt(): channel congestion\n",
4348 dev->name);
4349#endif
4350 if(!(tx_status & TX_NCOL_MASK))
4351 {
4352 lp->stats.collisions += 0x10;
4353 }
4354 }
4355 }
4356 } /* if(!(tx_status & TX_OK)) */
4357
4358 lp->stats.collisions += (tx_status & TX_NCOL_MASK);
4359 lp->stats.tx_packets++;
4360
4361 netif_wake_queue(dev);
4362 outb(CR0_INT_ACK | OP0_NOP, LCCR(base)); /* Acknowledge the interrupt */
4363 }
4364 else /* if interrupt = transmit done or retransmit done */
4365 {
4366#ifdef DEBUG_INTERRUPT_ERROR
4367 printk(KERN_INFO "wavelan_cs: unknown interrupt, status0 = %02x\n",
4368 status0);
4369#endif
4370 outb(CR0_INT_ACK | OP0_NOP, LCCR(base)); /* Acknowledge the interrupt */
4371 }
4372 } /* while(1) */
4373
4374 spin_unlock(&lp->spinlock);
4375
4376#ifdef DEBUG_INTERRUPT_TRACE
4377 printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name);
4378#endif
4379
4380 /* We always return IRQ_HANDLED, because we will receive empty
4381 * interrupts under normal operations. Anyway, it doesn't matter
4382 * as we are dealing with an ISA interrupt that can't be shared.
4383 *
4384 * Explanation : under heavy receive, the following happens :
4385 * ->wavelan_interrupt()
4386 * (status0 & SR0_INTERRUPT) != 0
4387 * ->wv_packet_rcv()
4388 * (status0 & SR0_INTERRUPT) != 0
4389 * ->wv_packet_rcv()
4390 * (status0 & SR0_INTERRUPT) == 0 // i.e. no more event
4391 * <-wavelan_interrupt()
4392 * ->wavelan_interrupt()
4393 * (status0 & SR0_INTERRUPT) == 0 // i.e. empty interrupt
4394 * <-wavelan_interrupt()
4395 * Jean II */
4396 return IRQ_HANDLED;
4397} /* wv_interrupt */
4398
4399/*------------------------------------------------------------------*/
4400/*
4401 * Watchdog: when we start a transmission, a timer is set for us in the
4402 * kernel. If the transmission completes, this timer is disabled. If
4403 * the timer expires, we are called and we try to unlock the hardware.
4404 *
4405 * Note : This watchdog is move clever than the one in the ISA driver,
4406 * because it try to abort the current command before reseting
4407 * everything...
4408 * On the other hand, it's a bit simpler, because we don't have to
4409 * deal with the multiple Tx buffers...
4410 */
4411static void
4412wavelan_watchdog(struct net_device * dev)
4413{
4414 net_local * lp = netdev_priv(dev);
4415 kio_addr_t base = dev->base_addr;
4416 unsigned long flags;
4417 int aborted = FALSE;
4418
4419#ifdef DEBUG_INTERRUPT_TRACE
4420 printk(KERN_DEBUG "%s: ->wavelan_watchdog()\n", dev->name);
4421#endif
4422
4423#ifdef DEBUG_INTERRUPT_ERROR
4424 printk(KERN_INFO "%s: wavelan_watchdog: watchdog timer expired\n",
4425 dev->name);
4426#endif
4427
4428 spin_lock_irqsave(&lp->spinlock, flags);
4429
4430 /* Ask to abort the current command */
4431 outb(OP0_ABORT, LCCR(base));
4432
4433 /* Wait for the end of the command (a bit hackish) */
4434 if(wv_82593_cmd(dev, "wavelan_watchdog(): abort",
4435 OP0_NOP | CR0_STATUS_3, SR0_EXECUTION_ABORTED))
4436 aborted = TRUE;
4437
4438 /* Release spinlock here so that wv_hw_reset() can grab it */
4439 spin_unlock_irqrestore(&lp->spinlock, flags);
4440
4441 /* Check if we were successful in aborting it */
4442 if(!aborted)
4443 {
4444 /* It seem that it wasn't enough */
4445#ifdef DEBUG_INTERRUPT_ERROR
4446 printk(KERN_INFO "%s: wavelan_watchdog: abort failed, trying reset\n",
4447 dev->name);
4448#endif
4449 wv_hw_reset(dev);
4450 }
4451
4452#ifdef DEBUG_PSA_SHOW
4453 {
4454 psa_t psa;
4455 psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));
4456 wv_psa_show(&psa);
4457 }
4458#endif
4459#ifdef DEBUG_MMC_SHOW
4460 wv_mmc_show(dev);
4461#endif
4462#ifdef DEBUG_I82593_SHOW
4463 wv_ru_show(dev);
4464#endif
4465
4466 /* We are no more waiting for something... */
4467 netif_wake_queue(dev);
4468
4469#ifdef DEBUG_INTERRUPT_TRACE
4470 printk(KERN_DEBUG "%s: <-wavelan_watchdog()\n", dev->name);
4471#endif
4472}
4473
4474/********************* CONFIGURATION CALLBACKS *********************/
4475/*
4476 * Here are the functions called by the pcmcia package (cardmgr) and
4477 * linux networking (NET3) for initialization, configuration and
4478 * deinstallations of the Wavelan Pcmcia Hardware.
4479 */
4480
4481/*------------------------------------------------------------------*/
4482/*
4483 * Configure and start up the WaveLAN PCMCIA adaptor.
4484 * Called by NET3 when it "open" the device.
4485 */
4486static int
4487wavelan_open(struct net_device * dev)
4488{
4489 net_local * lp = netdev_priv(dev);
4490 dev_link_t * link = lp->link;
4491 kio_addr_t base = dev->base_addr;
4492
4493#ifdef DEBUG_CALLBACK_TRACE
4494 printk(KERN_DEBUG "%s: ->wavelan_open(dev=0x%x)\n", dev->name,
4495 (unsigned int) dev);
4496#endif
4497
4498 /* Check if the modem is powered up (wavelan_close() power it down */
4499 if(hasr_read(base) & HASR_NO_CLK)
4500 {
4501 /* Power up (power up time is 250us) */
4502 hacr_write(base, HACR_DEFAULT);
4503
4504 /* Check if the module has been powered up... */
4505 if(hasr_read(base) & HASR_NO_CLK)
4506 {
4507#ifdef DEBUG_CONFIG_ERRORS
4508 printk(KERN_WARNING "%s: wavelan_open(): modem not connected\n",
4509 dev->name);
4510#endif
4511 return FALSE;
4512 }
4513 }
4514
4515 /* Start reception and declare the driver ready */
4516 if(!lp->configured)
4517 return FALSE;
4518 if(!wv_ru_start(dev))
4519 wv_hw_reset(dev); /* If problem : reset */
4520 netif_start_queue(dev);
4521
4522 /* Mark the device as used */
4523 link->open++;
4524
4525#ifdef WAVELAN_ROAMING
4526 if(do_roaming)
4527 wv_roam_init(dev);
4528#endif /* WAVELAN_ROAMING */
4529
4530#ifdef DEBUG_CALLBACK_TRACE
4531 printk(KERN_DEBUG "%s: <-wavelan_open()\n", dev->name);
4532#endif
4533 return 0;
4534}
4535
4536/*------------------------------------------------------------------*/
4537/*
4538 * Shutdown the WaveLAN PCMCIA adaptor.
4539 * Called by NET3 when it "close" the device.
4540 */
4541static int
4542wavelan_close(struct net_device * dev)
4543{
4544 dev_link_t * link = ((net_local *)netdev_priv(dev))->link;
4545 kio_addr_t base = dev->base_addr;
4546
4547#ifdef DEBUG_CALLBACK_TRACE
4548 printk(KERN_DEBUG "%s: ->wavelan_close(dev=0x%x)\n", dev->name,
4549 (unsigned int) dev);
4550#endif
4551
4552 /* If the device isn't open, then nothing to do */
4553 if(!link->open)
4554 {
4555#ifdef DEBUG_CONFIG_INFO
4556 printk(KERN_DEBUG "%s: wavelan_close(): device not open\n", dev->name);
4557#endif
4558 return 0;
4559 }
4560
4561#ifdef WAVELAN_ROAMING
4562 /* Cleanup of roaming stuff... */
4563 if(do_roaming)
4564 wv_roam_cleanup(dev);
4565#endif /* WAVELAN_ROAMING */
4566
4567 link->open--;
4568
4569 /* If the card is still present */
4570 if(netif_running(dev))
4571 {
4572 netif_stop_queue(dev);
4573
4574 /* Stop receiving new messages and wait end of transmission */
4575 wv_ru_stop(dev);
4576
4577 /* Power down the module */
4578 hacr_write(base, HACR_DEFAULT & (~HACR_PWR_STAT));
4579 }
4580
4581#ifdef DEBUG_CALLBACK_TRACE
4582 printk(KERN_DEBUG "%s: <-wavelan_close()\n", dev->name);
4583#endif
4584 return 0;
4585}
4586
4587/*------------------------------------------------------------------*/
4588/*
4589 * wavelan_attach() creates an "instance" of the driver, allocating
4590 * local data structures for one device (one interface). The device
4591 * is registered with Card Services.
4592 *
4593 * The dev_link structure is initialized, but we don't actually
4594 * configure the card at this point -- we wait until we receive a
4595 * card insertion event.
4596 */
4597static dev_link_t *
4598wavelan_attach(void)
4599{
4600 client_reg_t client_reg; /* Register with cardmgr */
4601 dev_link_t * link; /* Info for cardmgr */
4602 struct net_device * dev; /* Interface generic data */
4603 net_local * lp; /* Interface specific data */
4604 int ret;
4605
4606#ifdef DEBUG_CALLBACK_TRACE
4607 printk(KERN_DEBUG "-> wavelan_attach()\n");
4608#endif
4609
4610 /* Initialize the dev_link_t structure */
4611 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
4612 if (!link) return NULL;
4613 memset(link, 0, sizeof(struct dev_link_t));
4614
4615 /* The io structure describes IO port mapping */
4616 link->io.NumPorts1 = 8;
4617 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
4618 link->io.IOAddrLines = 3;
4619
4620 /* Interrupt setup */
4621 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
4622 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
4623 link->irq.Handler = wavelan_interrupt;
4624
4625 /* General socket configuration */
4626 link->conf.Attributes = CONF_ENABLE_IRQ;
4627 link->conf.Vcc = 50;
4628 link->conf.IntType = INT_MEMORY_AND_IO;
4629
4630 /* Chain drivers */
4631 link->next = dev_list;
4632 dev_list = link;
4633
4634 /* Allocate the generic data structure */
4635 dev = alloc_etherdev(sizeof(net_local));
4636 if (!dev) {
4637 kfree(link);
4638 return NULL;
4639 }
4640 link->priv = link->irq.Instance = dev;
4641
4642 lp = netdev_priv(dev);
4643
4644 /* Init specific data */
4645 lp->configured = 0;
4646 lp->reconfig_82593 = FALSE;
4647 lp->nresets = 0;
4648 /* Multicast stuff */
4649 lp->promiscuous = 0;
4650 lp->allmulticast = 0;
4651 lp->mc_count = 0;
4652
4653 /* Init spinlock */
4654 spin_lock_init(&lp->spinlock);
4655
4656 /* back links */
4657 lp->link = link;
4658 lp->dev = dev;
4659
4660 /* wavelan NET3 callbacks */
4661 SET_MODULE_OWNER(dev);
4662 dev->open = &wavelan_open;
4663 dev->stop = &wavelan_close;
4664 dev->hard_start_xmit = &wavelan_packet_xmit;
4665 dev->get_stats = &wavelan_get_stats;
4666 dev->set_multicast_list = &wavelan_set_multicast_list;
4667#ifdef SET_MAC_ADDRESS
4668 dev->set_mac_address = &wavelan_set_mac_address;
4669#endif /* SET_MAC_ADDRESS */
4670
4671 /* Set the watchdog timer */
4672 dev->tx_timeout = &wavelan_watchdog;
4673 dev->watchdog_timeo = WATCHDOG_JIFFIES;
4674 SET_ETHTOOL_OPS(dev, &ops);
4675
4676#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
4677 dev->wireless_handlers = &wavelan_handler_def;
4678 lp->wireless_data.spy_data = &lp->spy_data;
4679 dev->wireless_data = &lp->wireless_data;
4680#endif
4681
4682 /* Other specific data */
4683 dev->mtu = WAVELAN_MTU;
4684
4685 /* Register with Card Services */
4686 client_reg.dev_info = &dev_info;
4687 client_reg.EventMask =
4688 CS_EVENT_REGISTRATION_COMPLETE |
4689 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
4690 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
4691 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
4692 client_reg.event_handler = &wavelan_event;
4693 client_reg.Version = 0x0210;
4694 client_reg.event_callback_args.client_data = link;
4695
4696#ifdef DEBUG_CONFIG_INFO
4697 printk(KERN_DEBUG "wavelan_attach(): almost done, calling pcmcia_register_client\n");
4698#endif
4699
4700 ret = pcmcia_register_client(&link->handle, &client_reg);
4701 if(ret != 0)
4702 {
4703 cs_error(link->handle, RegisterClient, ret);
4704 wavelan_detach(link);
4705 return NULL;
4706 }
4707
4708#ifdef DEBUG_CALLBACK_TRACE
4709 printk(KERN_DEBUG "<- wavelan_attach()\n");
4710#endif
4711
4712 return link;
4713}
4714
4715/*------------------------------------------------------------------*/
4716/*
4717 * This deletes a driver "instance". The device is de-registered with
4718 * Card Services. If it has been released, all local data structures
4719 * are freed. Otherwise, the structures will be freed when the device
4720 * is released.
4721 */
4722static void
4723wavelan_detach(dev_link_t * link)
4724{
4725#ifdef DEBUG_CALLBACK_TRACE
4726 printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link);
4727#endif
4728
4729 /*
4730 * If the device is currently configured and active, we won't
4731 * actually delete it yet. Instead, it is marked so that when the
4732 * release() function is called, that will trigger a proper
4733 * detach().
4734 */
4735 if(link->state & DEV_CONFIG)
4736 {
4737 /* Some others haven't done their job : give them another chance */
4738 wv_pcmcia_release(link);
4739 }
4740
4741 /* Break the link with Card Services */
4742 if(link->handle)
4743 pcmcia_deregister_client(link->handle);
4744
4745 /* Remove the interface data from the linked list */
4746 if(dev_list == link)
4747 dev_list = link->next;
4748 else
4749 {
4750 dev_link_t * prev = dev_list;
4751
4752 while((prev != (dev_link_t *) NULL) && (prev->next != link))
4753 prev = prev->next;
4754
4755 if(prev == (dev_link_t *) NULL)
4756 {
4757#ifdef DEBUG_CONFIG_ERRORS
4758 printk(KERN_WARNING "wavelan_detach : Attempting to remove a nonexistent device.\n");
4759#endif
4760 return;
4761 }
4762
4763 prev->next = link->next;
4764 }
4765
4766 /* Free pieces */
4767 if(link->priv)
4768 {
4769 struct net_device * dev = (struct net_device *) link->priv;
4770
4771 /* Remove ourselves from the kernel list of ethernet devices */
4772 /* Warning : can't be called from interrupt, timer or wavelan_close() */
4773 if (link->dev)
4774 unregister_netdev(dev);
4775 link->dev = NULL;
4776 ((net_local *)netdev_priv(dev))->link = NULL;
4777 ((net_local *)netdev_priv(dev))->dev = NULL;
4778 free_netdev(dev);
4779 }
4780 kfree(link);
4781
4782#ifdef DEBUG_CALLBACK_TRACE
4783 printk(KERN_DEBUG "<- wavelan_detach()\n");
4784#endif
4785}
4786
4787/*------------------------------------------------------------------*/
4788/*
4789 * The card status event handler. Mostly, this schedules other stuff
4790 * to run after an event is received. A CARD_REMOVAL event also sets
4791 * some flags to discourage the net drivers from trying to talk to the
4792 * card any more.
4793 */
4794static int
4795wavelan_event(event_t event, /* The event received */
4796 int priority,
4797 event_callback_args_t * args)
4798{
4799 dev_link_t * link = (dev_link_t *) args->client_data;
4800 struct net_device * dev = (struct net_device *) link->priv;
4801
4802#ifdef DEBUG_CALLBACK_TRACE
4803 printk(KERN_DEBUG "->wavelan_event(): %s\n",
4804 ((event == CS_EVENT_REGISTRATION_COMPLETE)?"registration complete" :
4805 ((event == CS_EVENT_CARD_REMOVAL) ? "card removal" :
4806 ((event == CS_EVENT_CARD_INSERTION) ? "card insertion" :
4807 ((event == CS_EVENT_PM_SUSPEND) ? "pm suspend" :
4808 ((event == CS_EVENT_RESET_PHYSICAL) ? "physical reset" :
4809 ((event == CS_EVENT_PM_RESUME) ? "pm resume" :
4810 ((event == CS_EVENT_CARD_RESET) ? "card reset" :
4811 "unknown"))))))));
4812#endif
4813
4814 switch(event)
4815 {
4816 case CS_EVENT_REGISTRATION_COMPLETE:
4817#ifdef DEBUG_CONFIG_INFO
4818 printk(KERN_DEBUG "wavelan_cs: registration complete\n");
4819#endif
4820 break;
4821
4822 case CS_EVENT_CARD_REMOVAL:
4823 /* Oups ! The card is no more there */
4824 link->state &= ~DEV_PRESENT;
4825 if(link->state & DEV_CONFIG)
4826 {
4827 /* Accept no more transmissions */
4828 netif_device_detach(dev);
4829
4830 /* Release the card */
4831 wv_pcmcia_release(link);
4832 }
4833 break;
4834
4835 case CS_EVENT_CARD_INSERTION:
4836 /* Reset and configure the card */
4837 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
4838 if(wv_pcmcia_config(link) &&
4839 wv_hw_config(dev))
4840 wv_init_info(dev);
4841 else
4842 dev->irq = 0;
4843 break;
4844
4845 case CS_EVENT_PM_SUSPEND:
4846 /* NB: wavelan_close will be called, but too late, so we are
4847 * obliged to close nicely the wavelan here. David, could you
4848 * close the device before suspending them ? And, by the way,
4849 * could you, on resume, add a "route add -net ..." after the
4850 * ifconfig up ? Thanks... */
4851
4852 /* Stop receiving new messages and wait end of transmission */
4853 wv_ru_stop(dev);
4854
4855 /* Power down the module */
4856 hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT));
4857
4858 /* The card is now suspended */
4859 link->state |= DEV_SUSPEND;
4860 /* Fall through... */
4861 case CS_EVENT_RESET_PHYSICAL:
4862 if(link->state & DEV_CONFIG)
4863 {
4864 if(link->open)
4865 netif_device_detach(dev);
4866 pcmcia_release_configuration(link->handle);
4867 }
4868 break;
4869
4870 case CS_EVENT_PM_RESUME:
4871 link->state &= ~DEV_SUSPEND;
4872 /* Fall through... */
4873 case CS_EVENT_CARD_RESET:
4874 if(link->state & DEV_CONFIG)
4875 {
4876 pcmcia_request_configuration(link->handle, &link->conf);
4877 if(link->open) /* If RESET -> True, If RESUME -> False ? */
4878 {
4879 wv_hw_reset(dev);
4880 netif_device_attach(dev);
4881 }
4882 }
4883 break;
4884 }
4885
4886#ifdef DEBUG_CALLBACK_TRACE
4887 printk(KERN_DEBUG "<-wavelan_event()\n");
4888#endif
4889 return 0;
4890}
4891
4892static struct pcmcia_driver wavelan_driver = {
4893 .owner = THIS_MODULE,
4894 .drv = {
4895 .name = "wavelan_cs",
4896 },
4897 .attach = wavelan_attach,
4898 .detach = wavelan_detach,
4899};
4900
4901static int __init
4902init_wavelan_cs(void)
4903{
4904 return pcmcia_register_driver(&wavelan_driver);
4905}
4906
4907static void __exit
4908exit_wavelan_cs(void)
4909{
4910 pcmcia_unregister_driver(&wavelan_driver);
4911}
4912
4913module_init(init_wavelan_cs);
4914module_exit(exit_wavelan_cs);
diff --git a/drivers/net/wireless/wavelan_cs.h b/drivers/net/wireless/wavelan_cs.h
new file mode 100644
index 000000000000..29cff6daf860
--- /dev/null
+++ b/drivers/net/wireless/wavelan_cs.h
@@ -0,0 +1,386 @@
1/*
2 * Wavelan Pcmcia driver
3 *
4 * Jean II - HPLB '96
5 *
6 * Reorganization and extension of the driver.
7 * Original copyright follow. See wavelan_cs.h for details.
8 *
9 * This file contain the declarations of the Wavelan hardware. Note that
10 * the Pcmcia Wavelan include a i82593 controller (see definitions in
11 * file i82593.h).
12 *
13 * The main difference between the pcmcia hardware and the ISA one is
14 * the Ethernet Controller (i82593 instead of i82586). The i82593 allow
15 * only one send buffer. The PSA (Parameter Storage Area : EEprom for
16 * permanent storage of various info) is memory mapped, but not the
17 * MMI (Modem Management Interface).
18 */
19
20/*
21 * Definitions for the AT&T GIS (formerly NCR) WaveLAN PCMCIA card:
22 * An Ethernet-like radio transceiver controlled by an Intel 82593
23 * coprocessor.
24 *
25 *
26 ****************************************************************************
27 * Copyright 1995
28 * Anthony D. Joseph
29 * Massachusetts Institute of Technology
30 *
31 * Permission to use, copy, modify, and distribute this program
32 * for any purpose and without fee is hereby granted, provided
33 * that this copyright and permission notice appear on all copies
34 * and supporting documentation, the name of M.I.T. not be used
35 * in advertising or publicity pertaining to distribution of the
36 * program without specific prior permission, and notice be given
37 * in supporting documentation that copying and distribution is
38 * by permission of M.I.T. M.I.T. makes no representations about
39 * the suitability of this software for any purpose. It is pro-
40 * vided "as is" without express or implied warranty.
41 ****************************************************************************
42 *
43 *
44 * Credits:
45 * Special thanks to Jan Hoogendoorn of AT&T GIS Utrecht for
46 * providing extremely useful information about WaveLAN PCMCIA hardware
47 *
48 * This driver is based upon several other drivers, in particular:
49 * David Hinds' Linux driver for the PCMCIA 3c589 ethernet adapter
50 * Bruce Janson's Linux driver for the AT-bus WaveLAN adapter
51 * Anders Klemets' PCMCIA WaveLAN adapter driver
52 * Robert Morris' BSDI driver for the PCMCIA WaveLAN adapter
53 */
54
55#ifndef _WAVELAN_CS_H
56#define _WAVELAN_CS_H
57
58/************************** MAGIC NUMBERS ***************************/
59
60/* The detection of the wavelan card is made by reading the MAC address
61 * from the card and checking it. If you have a non AT&T product (OEM,
62 * like DEC RoamAbout, or Digital Ocean, Epson, ...), you must modify this
63 * part to accommodate your hardware...
64 */
65const unsigned char MAC_ADDRESSES[][3] =
66{
67 { 0x08, 0x00, 0x0E }, /* AT&T Wavelan (standard) & DEC RoamAbout */
68 { 0x08, 0x00, 0x6A }, /* AT&T Wavelan (alternate) */
69 { 0x00, 0x00, 0xE1 }, /* Hitachi Wavelan */
70 { 0x00, 0x60, 0x1D } /* Lucent Wavelan (another one) */
71 /* Add your card here and send me the patch ! */
72};
73
74/*
75 * Constants used to convert channels to frequencies
76 */
77
78/* Frequency available in the 2.0 modem, in units of 250 kHz
79 * (as read in the offset register of the dac area).
80 * Used to map channel numbers used by `wfreqsel' to frequencies
81 */
82const short channel_bands[] = { 0x30, 0x58, 0x64, 0x7A, 0x80, 0xA8,
83 0xD0, 0xF0, 0xF8, 0x150 };
84
85/* Frequencies of the 1.0 modem (fixed frequencies).
86 * Use to map the PSA `subband' to a frequency
87 * Note : all frequencies apart from the first one need to be multiplied by 10
88 */
89const int fixed_bands[] = { 915e6, 2.425e8, 2.46e8, 2.484e8, 2.4305e8 };
90
91
92/*************************** PC INTERFACE ****************************/
93
94/* WaveLAN host interface definitions */
95
96#define LCCR(base) (base) /* LAN Controller Command Register */
97#define LCSR(base) (base) /* LAN Controller Status Register */
98#define HACR(base) (base+0x1) /* Host Adapter Command Register */
99#define HASR(base) (base+0x1) /* Host Adapter Status Register */
100#define PIORL(base) (base+0x2) /* Program I/O Register Low */
101#define RPLL(base) (base+0x2) /* Receive Pointer Latched Low */
102#define PIORH(base) (base+0x3) /* Program I/O Register High */
103#define RPLH(base) (base+0x3) /* Receive Pointer Latched High */
104#define PIOP(base) (base+0x4) /* Program I/O Port */
105#define MMR(base) (base+0x6) /* MMI Address Register */
106#define MMD(base) (base+0x7) /* MMI Data Register */
107
108/* Host Adaptor Command Register bit definitions */
109
110#define HACR_LOF (1 << 3) /* Lock Out Flag, toggle every 250ms */
111#define HACR_PWR_STAT (1 << 4) /* Power State, 1=active, 0=sleep */
112#define HACR_TX_DMA_RESET (1 << 5) /* Reset transmit DMA ptr on high */
113#define HACR_RX_DMA_RESET (1 << 6) /* Reset receive DMA ptr on high */
114#define HACR_ROM_WEN (1 << 7) /* EEPROM write enabled when true */
115
116#define HACR_RESET (HACR_TX_DMA_RESET | HACR_RX_DMA_RESET)
117#define HACR_DEFAULT (HACR_PWR_STAT)
118
119/* Host Adapter Status Register bit definitions */
120
121#define HASR_MMI_BUSY (1 << 2) /* MMI is busy when true */
122#define HASR_LOF (1 << 3) /* Lock out flag status */
123#define HASR_NO_CLK (1 << 4) /* active when modem not connected */
124
125/* Miscellaneous bit definitions */
126
127#define PIORH_SEL_TX (1 << 5) /* PIOR points to 0=rx/1=tx buffer */
128#define MMR_MMI_WR (1 << 0) /* Next MMI cycle is 0=read, 1=write */
129#define PIORH_MASK 0x1f /* only low 5 bits are significant */
130#define RPLH_MASK 0x1f /* only low 5 bits are significant */
131#define MMI_ADDR_MASK 0x7e /* Bits 1-6 of MMR are significant */
132
133/* Attribute Memory map */
134
135#define CIS_ADDR 0x0000 /* Card Information Status Register */
136#define PSA_ADDR 0x0e00 /* Parameter Storage Area address */
137#define EEPROM_ADDR 0x1000 /* EEPROM address (unused ?) */
138#define COR_ADDR 0x4000 /* Configuration Option Register */
139
140/* Configuration Option Register bit definitions */
141
142#define COR_CONFIG (1 << 0) /* Config Index, 0 when unconfigured */
143#define COR_SW_RESET (1 << 7) /* Software Reset on true */
144#define COR_LEVEL_IRQ (1 << 6) /* Level IRQ */
145
146/* Local Memory map */
147
148#define RX_BASE 0x0000 /* Receive memory, 8 kB */
149#define TX_BASE 0x2000 /* Transmit memory, 2 kB */
150#define UNUSED_BASE 0x2800 /* Unused, 22 kB */
151#define RX_SIZE (TX_BASE-RX_BASE) /* Size of receive area */
152#define RX_SIZE_SHIFT 6 /* Bits to shift in stop register */
153
154#define TRUE 1
155#define FALSE 0
156
157#define MOD_ENAL 1
158#define MOD_PROM 2
159
160/* Size of a MAC address */
161#define WAVELAN_ADDR_SIZE 6
162
163/* Maximum size of Wavelan packet */
164#define WAVELAN_MTU 1500
165
166#define MAXDATAZ (6 + 6 + 2 + WAVELAN_MTU)
167
168/********************** PARAMETER STORAGE AREA **********************/
169
170/*
171 * Parameter Storage Area (PSA).
172 */
173typedef struct psa_t psa_t;
174struct psa_t
175{
176 /* For the PCMCIA Adapter, locations 0x00-0x0F are unused and fixed at 00 */
177 unsigned char psa_io_base_addr_1; /* [0x00] Base address 1 ??? */
178 unsigned char psa_io_base_addr_2; /* [0x01] Base address 2 */
179 unsigned char psa_io_base_addr_3; /* [0x02] Base address 3 */
180 unsigned char psa_io_base_addr_4; /* [0x03] Base address 4 */
181 unsigned char psa_rem_boot_addr_1; /* [0x04] Remote Boot Address 1 */
182 unsigned char psa_rem_boot_addr_2; /* [0x05] Remote Boot Address 2 */
183 unsigned char psa_rem_boot_addr_3; /* [0x06] Remote Boot Address 3 */
184 unsigned char psa_holi_params; /* [0x07] HOst Lan Interface (HOLI) Parameters */
185 unsigned char psa_int_req_no; /* [0x08] Interrupt Request Line */
186 unsigned char psa_unused0[7]; /* [0x09-0x0F] unused */
187
188 unsigned char psa_univ_mac_addr[WAVELAN_ADDR_SIZE]; /* [0x10-0x15] Universal (factory) MAC Address */
189 unsigned char psa_local_mac_addr[WAVELAN_ADDR_SIZE]; /* [0x16-1B] Local MAC Address */
190 unsigned char psa_univ_local_sel; /* [0x1C] Universal Local Selection */
191#define PSA_UNIVERSAL 0 /* Universal (factory) */
192#define PSA_LOCAL 1 /* Local */
193 unsigned char psa_comp_number; /* [0x1D] Compatability Number: */
194#define PSA_COMP_PC_AT_915 0 /* PC-AT 915 MHz */
195#define PSA_COMP_PC_MC_915 1 /* PC-MC 915 MHz */
196#define PSA_COMP_PC_AT_2400 2 /* PC-AT 2.4 GHz */
197#define PSA_COMP_PC_MC_2400 3 /* PC-MC 2.4 GHz */
198#define PSA_COMP_PCMCIA_915 4 /* PCMCIA 915 MHz or 2.0 */
199 unsigned char psa_thr_pre_set; /* [0x1E] Modem Threshold Preset */
200 unsigned char psa_feature_select; /* [0x1F] Call code required (1=on) */
201#define PSA_FEATURE_CALL_CODE 0x01 /* Call code required (Japan) */
202 unsigned char psa_subband; /* [0x20] Subband */
203#define PSA_SUBBAND_915 0 /* 915 MHz or 2.0 */
204#define PSA_SUBBAND_2425 1 /* 2425 MHz */
205#define PSA_SUBBAND_2460 2 /* 2460 MHz */
206#define PSA_SUBBAND_2484 3 /* 2484 MHz */
207#define PSA_SUBBAND_2430_5 4 /* 2430.5 MHz */
208 unsigned char psa_quality_thr; /* [0x21] Modem Quality Threshold */
209 unsigned char psa_mod_delay; /* [0x22] Modem Delay ??? (reserved) */
210 unsigned char psa_nwid[2]; /* [0x23-0x24] Network ID */
211 unsigned char psa_nwid_select; /* [0x25] Network ID Select On Off */
212 unsigned char psa_encryption_select; /* [0x26] Encryption On Off */
213 unsigned char psa_encryption_key[8]; /* [0x27-0x2E] Encryption Key */
214 unsigned char psa_databus_width; /* [0x2F] AT bus width select 8/16 */
215 unsigned char psa_call_code[8]; /* [0x30-0x37] (Japan) Call Code */
216 unsigned char psa_nwid_prefix[2]; /* [0x38-0x39] Roaming domain */
217 unsigned char psa_reserved[2]; /* [0x3A-0x3B] Reserved - fixed 00 */
218 unsigned char psa_conf_status; /* [0x3C] Conf Status, bit 0=1:config*/
219 unsigned char psa_crc[2]; /* [0x3D] CRC-16 over PSA */
220 unsigned char psa_crc_status; /* [0x3F] CRC Valid Flag */
221};
222
223/* Size for structure checking (if padding is correct) */
224#define PSA_SIZE 64
225
226/* Calculate offset of a field in the above structure
227 * Warning : only even addresses are used */
228#define psaoff(p,f) ((unsigned short) ((void *)(&((psa_t *) ((void *) NULL + (p)))->f) - (void *) NULL))
229
230/******************** MODEM MANAGEMENT INTERFACE ********************/
231
232/*
233 * Modem Management Controller (MMC) write structure.
234 */
235typedef struct mmw_t mmw_t;
236struct mmw_t
237{
238 unsigned char mmw_encr_key[8]; /* encryption key */
239 unsigned char mmw_encr_enable; /* enable/disable encryption */
240#define MMW_ENCR_ENABLE_MODE 0x02 /* Mode of security option */
241#define MMW_ENCR_ENABLE_EN 0x01 /* Enable security option */
242 unsigned char mmw_unused0[1]; /* unused */
243 unsigned char mmw_des_io_invert; /* Encryption option */
244#define MMW_DES_IO_INVERT_RES 0x0F /* Reserved */
245#define MMW_DES_IO_INVERT_CTRL 0xF0 /* Control ??? (set to 0) */
246 unsigned char mmw_unused1[5]; /* unused */
247 unsigned char mmw_loopt_sel; /* looptest selection */
248#define MMW_LOOPT_SEL_DIS_NWID 0x40 /* disable NWID filtering */
249#define MMW_LOOPT_SEL_INT 0x20 /* activate Attention Request */
250#define MMW_LOOPT_SEL_LS 0x10 /* looptest w/o collision avoidance */
251#define MMW_LOOPT_SEL_LT3A 0x08 /* looptest 3a */
252#define MMW_LOOPT_SEL_LT3B 0x04 /* looptest 3b */
253#define MMW_LOOPT_SEL_LT3C 0x02 /* looptest 3c */
254#define MMW_LOOPT_SEL_LT3D 0x01 /* looptest 3d */
255 unsigned char mmw_jabber_enable; /* jabber timer enable */
256 /* Abort transmissions > 200 ms */
257 unsigned char mmw_freeze; /* freeze / unfreeeze signal level */
258 /* 0 : signal level & qual updated for every new message, 1 : frozen */
259 unsigned char mmw_anten_sel; /* antenna selection */
260#define MMW_ANTEN_SEL_SEL 0x01 /* direct antenna selection */
261#define MMW_ANTEN_SEL_ALG_EN 0x02 /* antenna selection algo. enable */
262 unsigned char mmw_ifs; /* inter frame spacing */
263 /* min time between transmission in bit periods (.5 us) - bit 0 ignored */
264 unsigned char mmw_mod_delay; /* modem delay (synchro) */
265 unsigned char mmw_jam_time; /* jamming time (after collision) */
266 unsigned char mmw_unused2[1]; /* unused */
267 unsigned char mmw_thr_pre_set; /* level threshold preset */
268 /* Discard all packet with signal < this value (4) */
269 unsigned char mmw_decay_prm; /* decay parameters */
270 unsigned char mmw_decay_updat_prm; /* decay update parameterz */
271 unsigned char mmw_quality_thr; /* quality (z-quotient) threshold */
272 /* Discard all packet with quality < this value (3) */
273 unsigned char mmw_netw_id_l; /* NWID low order byte */
274 unsigned char mmw_netw_id_h; /* NWID high order byte */
275 /* Network ID or Domain : create virtual net on the air */
276
277 /* 2.0 Hardware extension - frequency selection support */
278 unsigned char mmw_mode_select; /* for analog tests (set to 0) */
279 unsigned char mmw_unused3[1]; /* unused */
280 unsigned char mmw_fee_ctrl; /* frequency eeprom control */
281#define MMW_FEE_CTRL_PRE 0x10 /* Enable protected instructions */
282#define MMW_FEE_CTRL_DWLD 0x08 /* Download eeprom to mmc */
283#define MMW_FEE_CTRL_CMD 0x07 /* EEprom commands : */
284#define MMW_FEE_CTRL_READ 0x06 /* Read */
285#define MMW_FEE_CTRL_WREN 0x04 /* Write enable */
286#define MMW_FEE_CTRL_WRITE 0x05 /* Write data to address */
287#define MMW_FEE_CTRL_WRALL 0x04 /* Write data to all addresses */
288#define MMW_FEE_CTRL_WDS 0x04 /* Write disable */
289#define MMW_FEE_CTRL_PRREAD 0x16 /* Read addr from protect register */
290#define MMW_FEE_CTRL_PREN 0x14 /* Protect register enable */
291#define MMW_FEE_CTRL_PRCLEAR 0x17 /* Unprotect all registers */
292#define MMW_FEE_CTRL_PRWRITE 0x15 /* Write addr in protect register */
293#define MMW_FEE_CTRL_PRDS 0x14 /* Protect register disable */
294 /* Never issue this command (PRDS) : it's irreversible !!! */
295
296 unsigned char mmw_fee_addr; /* EEprom address */
297#define MMW_FEE_ADDR_CHANNEL 0xF0 /* Select the channel */
298#define MMW_FEE_ADDR_OFFSET 0x0F /* Offset in channel data */
299#define MMW_FEE_ADDR_EN 0xC0 /* FEE_CTRL enable operations */
300#define MMW_FEE_ADDR_DS 0x00 /* FEE_CTRL disable operations */
301#define MMW_FEE_ADDR_ALL 0x40 /* FEE_CTRL all operations */
302#define MMW_FEE_ADDR_CLEAR 0xFF /* FEE_CTRL clear operations */
303
304 unsigned char mmw_fee_data_l; /* Write data to EEprom */
305 unsigned char mmw_fee_data_h; /* high octet */
306 unsigned char mmw_ext_ant; /* Setting for external antenna */
307#define MMW_EXT_ANT_EXTANT 0x01 /* Select external antenna */
308#define MMW_EXT_ANT_POL 0x02 /* Polarity of the antenna */
309#define MMW_EXT_ANT_INTERNAL 0x00 /* Internal antenna */
310#define MMW_EXT_ANT_EXTERNAL 0x03 /* External antenna */
311#define MMW_EXT_ANT_IQ_TEST 0x1C /* IQ test pattern (set to 0) */
312};
313
314/* Size for structure checking (if padding is correct) */
315#define MMW_SIZE 37
316
317/* Calculate offset of a field in the above structure */
318#define mmwoff(p,f) (unsigned short)((void *)(&((mmw_t *)((void *)0 + (p)))->f) - (void *)0)
319
320
321/*
322 * Modem Management Controller (MMC) read structure.
323 */
324typedef struct mmr_t mmr_t;
325struct mmr_t
326{
327 unsigned char mmr_unused0[8]; /* unused */
328 unsigned char mmr_des_status; /* encryption status */
329 unsigned char mmr_des_avail; /* encryption available (0x55 read) */
330#define MMR_DES_AVAIL_DES 0x55 /* DES available */
331#define MMR_DES_AVAIL_AES 0x33 /* AES (AT&T) available */
332 unsigned char mmr_des_io_invert; /* des I/O invert register */
333 unsigned char mmr_unused1[5]; /* unused */
334 unsigned char mmr_dce_status; /* DCE status */
335#define MMR_DCE_STATUS_RX_BUSY 0x01 /* receiver busy */
336#define MMR_DCE_STATUS_LOOPT_IND 0x02 /* loop test indicated */
337#define MMR_DCE_STATUS_TX_BUSY 0x04 /* transmitter on */
338#define MMR_DCE_STATUS_JBR_EXPIRED 0x08 /* jabber timer expired */
339#define MMR_DCE_STATUS 0x0F /* mask to get the bits */
340 unsigned char mmr_dsp_id; /* DSP id (AA = Daedalus rev A) */
341 unsigned char mmr_unused2[2]; /* unused */
342 unsigned char mmr_correct_nwid_l; /* # of correct NWID's rxd (low) */
343 unsigned char mmr_correct_nwid_h; /* # of correct NWID's rxd (high) */
344 /* Warning : Read high order octet first !!! */
345 unsigned char mmr_wrong_nwid_l; /* # of wrong NWID's rxd (low) */
346 unsigned char mmr_wrong_nwid_h; /* # of wrong NWID's rxd (high) */
347 unsigned char mmr_thr_pre_set; /* level threshold preset */
348#define MMR_THR_PRE_SET 0x3F /* level threshold preset */
349#define MMR_THR_PRE_SET_CUR 0x80 /* Current signal above it */
350 unsigned char mmr_signal_lvl; /* signal level */
351#define MMR_SIGNAL_LVL 0x3F /* signal level */
352#define MMR_SIGNAL_LVL_VALID 0x80 /* Updated since last read */
353 unsigned char mmr_silence_lvl; /* silence level (noise) */
354#define MMR_SILENCE_LVL 0x3F /* silence level */
355#define MMR_SILENCE_LVL_VALID 0x80 /* Updated since last read */
356 unsigned char mmr_sgnl_qual; /* signal quality */
357#define MMR_SGNL_QUAL 0x0F /* signal quality */
358#define MMR_SGNL_QUAL_ANT 0x80 /* current antenna used */
359 unsigned char mmr_netw_id_l; /* NWID low order byte ??? */
360 unsigned char mmr_unused3[3]; /* unused */
361
362 /* 2.0 Hardware extension - frequency selection support */
363 unsigned char mmr_fee_status; /* Status of frequency eeprom */
364#define MMR_FEE_STATUS_ID 0xF0 /* Modem revision id */
365#define MMR_FEE_STATUS_DWLD 0x08 /* Download in progress */
366#define MMR_FEE_STATUS_BUSY 0x04 /* EEprom busy */
367 unsigned char mmr_unused4[1]; /* unused */
368 unsigned char mmr_fee_data_l; /* Read data from eeprom (low) */
369 unsigned char mmr_fee_data_h; /* Read data from eeprom (high) */
370};
371
372/* Size for structure checking (if padding is correct) */
373#define MMR_SIZE 36
374
375/* Calculate offset of a field in the above structure */
376#define mmroff(p,f) (unsigned short)((void *)(&((mmr_t *)((void *)0 + (p)))->f) - (void *)0)
377
378
379/* Make the two above structures one */
380typedef union mm_t
381{
382 struct mmw_t w; /* Write to the mmc */
383 struct mmr_t r; /* Read from the mmc */
384} mm_t;
385
386#endif /* _WAVELAN_CS_H */
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
new file mode 100644
index 000000000000..ea2ef8dddb92
--- /dev/null
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -0,0 +1,813 @@
1/*
2 * Wavelan Pcmcia driver
3 *
4 * Jean II - HPLB '96
5 *
6 * Reorganisation and extension of the driver.
7 *
8 * This file contain all definition and declarations necessary for the
9 * wavelan pcmcia driver. This file is a private header, so it should
10 * be included only on wavelan_cs.c !!!
11 */
12
13#ifndef WAVELAN_CS_P_H
14#define WAVELAN_CS_P_H
15
16/************************** DOCUMENTATION **************************/
17/*
18 * This driver provide a Linux interface to the Wavelan Pcmcia hardware
19 * The Wavelan is a product of Lucent (http://www.wavelan.com/).
20 * This division was formerly part of NCR and then AT&T.
21 * Wavelan are also distributed by DEC (RoamAbout DS)...
22 *
23 * To know how to use this driver, read the PCMCIA HOWTO.
24 * If you want to exploit the many other fonctionalities, look comments
25 * in the code...
26 *
27 * This driver is the result of the effort of many peoples (see below).
28 */
29
30/* ------------------------ SPECIFIC NOTES ------------------------ */
31/*
32 * Web page
33 * --------
34 * I try to maintain a web page with the Wireless LAN Howto at :
35 * http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html
36 *
37 * SMP
38 * ---
39 * We now are SMP compliant (I eventually fixed the remaining bugs).
40 * The driver has been tested on a dual P6-150 and survived my usual
41 * set of torture tests.
42 * Anyway, I spent enough time chasing interrupt re-entrancy during
43 * errors or reconfigure, and I designed the locked/unlocked sections
44 * of the driver with great care, and with the recent addition of
45 * the spinlock (thanks to the new API), we should be quite close to
46 * the truth.
47 * The SMP/IRQ locking is quite coarse and conservative (i.e. not fast),
48 * but better safe than sorry (especially at 2 Mb/s ;-).
49 *
50 * I have also looked into disabling only our interrupt on the card
51 * (via HACR) instead of all interrupts in the processor (via cli),
52 * so that other driver are not impacted, and it look like it's
53 * possible, but it's very tricky to do right (full of races). As
54 * the gain would be mostly for SMP systems, it can wait...
55 *
56 * Debugging and options
57 * ---------------------
58 * You will find below a set of '#define" allowing a very fine control
59 * on the driver behaviour and the debug messages printed.
60 * The main options are :
61 * o WAVELAN_ROAMING, for the experimental roaming support.
62 * o SET_PSA_CRC, to have your card correctly recognised by
63 * an access point and the Point-to-Point diagnostic tool.
64 * o USE_PSA_CONFIG, to read configuration from the PSA (EEprom)
65 * (otherwise we always start afresh with some defaults)
66 *
67 * wavelan_cs.o is darn too big
68 * -------------------------
69 * That's true ! There is a very simple way to reduce the driver
70 * object by 33% (yes !). Comment out the following line :
71 * #include <linux/wireless.h>
72 * Other compile options can also reduce the size of it...
73 *
74 * MAC address and hardware detection :
75 * ----------------------------------
76 * The detection code of the wavelan chech that the first 3
77 * octets of the MAC address fit the company code. This type of
78 * detection work well for AT&T cards (because the AT&T code is
79 * hardcoded in wavelan_cs.h), but of course will fail for other
80 * manufacturer.
81 *
82 * If you are sure that your card is derived from the wavelan,
83 * here is the way to configure it :
84 * 1) Get your MAC address
85 * a) With your card utilities (wfreqsel, instconf, ...)
86 * b) With the driver :
87 * o compile the kernel with DEBUG_CONFIG_INFO enabled
88 * o Boot and look the card messages
89 * 2) Set your MAC code (3 octets) in MAC_ADDRESSES[][3] (wavelan_cs.h)
90 * 3) Compile & verify
91 * 4) Send me the MAC code - I will include it in the next version...
92 *
93 */
94
95/* --------------------- WIRELESS EXTENSIONS --------------------- */
96/*
97 * This driver is the first one to support "wireless extensions".
98 * This set of extensions provide you some way to control the wireless
99 * caracteristics of the hardware in a standard way and support for
100 * applications for taking advantage of it (like Mobile IP).
101 *
102 * You will need to enable the CONFIG_NET_RADIO define in the kernel
103 * configuration to enable the wireless extensions (this is the one
104 * giving access to the radio network device choice).
105 *
106 * It might also be a good idea as well to fetch the wireless tools to
107 * configure the device and play a bit.
108 */
109
110/* ---------------------------- FILES ---------------------------- */
111/*
112 * wavelan_cs.c : The actual code for the driver - C functions
113 *
114 * wavelan_cs.p.h : Private header : local types / vars for the driver
115 *
116 * wavelan_cs.h : Description of the hardware interface & structs
117 *
118 * i82593.h : Description if the Ethernet controller
119 */
120
121/* --------------------------- HISTORY --------------------------- */
122/*
123 * The history of the Wavelan drivers is as complicated as history of
124 * the Wavelan itself (NCR -> AT&T -> Lucent).
125 *
126 * All started with Anders Klemets <klemets@paul.rutgers.edu>,
127 * writting a Wavelan ISA driver for the MACH microkernel. Girish
128 * Welling <welling@paul.rutgers.edu> had also worked on it.
129 * Keith Moore modify this for the Pcmcia hardware.
130 *
131 * Robert Morris <rtm@das.harvard.edu> port these two drivers to BSDI
132 * and add specific Pcmcia support (there is currently no equivalent
133 * of the PCMCIA package under BSD...).
134 *
135 * Jim Binkley <jrb@cs.pdx.edu> port both BSDI drivers to FreeBSD.
136 *
137 * Bruce Janson <bruce@cs.usyd.edu.au> port the BSDI ISA driver to Linux.
138 *
139 * Anthony D. Joseph <adj@lcs.mit.edu> started modify Bruce driver
140 * (with help of the BSDI PCMCIA driver) for PCMCIA.
141 * Yunzhou Li <yunzhou@strat.iol.unh.edu> finished is work.
142 * Joe Finney <joe@comp.lancs.ac.uk> patched the driver to start
143 * correctly 2.00 cards (2.4 GHz with frequency selection).
144 * David Hinds <dahinds@users.sourceforge.net> integrated the whole in his
145 * Pcmcia package (+ bug corrections).
146 *
147 * I (Jean Tourrilhes - jt@hplb.hpl.hp.com) then started to make some
148 * patchs to the Pcmcia driver. After, I added code in the ISA driver
149 * for Wireless Extensions and full support of frequency selection
150 * cards. Now, I'm doing the same to the Pcmcia driver + some
151 * reorganisation.
152 * Loeke Brederveld <lbrederv@wavelan.com> from Lucent has given me
153 * much needed informations on the Wavelan hardware.
154 */
155
156/* By the way : for the copyright & legal stuff :
157 * Almost everybody wrote code under GNU or BSD license (or alike),
158 * and want that their original copyright remain somewhere in the
159 * code (for myself, I go with the GPL).
160 * Nobody want to take responsibility for anything, except the fame...
161 */
162
163/* --------------------------- CREDITS --------------------------- */
164/*
165 * Credits:
166 * Special thanks to Jan Hoogendoorn of AT&T GIS Utrecht and
167 * Loeke Brederveld of Lucent for providing extremely useful
168 * information about WaveLAN PCMCIA hardware
169 *
170 * This driver is based upon several other drivers, in particular:
171 * David Hinds' Linux driver for the PCMCIA 3c589 ethernet adapter
172 * Bruce Janson's Linux driver for the AT-bus WaveLAN adapter
173 * Anders Klemets' PCMCIA WaveLAN adapter driver
174 * Robert Morris' BSDI driver for the PCMCIA WaveLAN adapter
175 *
176 * Additional Credits:
177 *
178 * This software was originally developed under Linux 1.2.3
179 * (Slackware 2.0 distribution).
180 * And then under Linux 2.0.x (Debian 1.1 -> 2.2 - pcmcia 2.8.18+)
181 * with an HP OmniBook 4000 and then a 5500.
182 *
183 * It is based on other device drivers and information either written
184 * or supplied by:
185 * James Ashton (jaa101@syseng.anu.edu.au),
186 * Ajay Bakre (bakre@paul.rutgers.edu),
187 * Donald Becker (becker@super.org),
188 * Jim Binkley <jrb@cs.pdx.edu>,
189 * Loeke Brederveld <lbrederv@wavelan.com>,
190 * Allan Creighton (allanc@cs.su.oz.au),
191 * Brent Elphick <belphick@uwaterloo.ca>,
192 * Joe Finney <joe@comp.lancs.ac.uk>,
193 * Matthew Geier (matthew@cs.su.oz.au),
194 * Remo di Giovanni (remo@cs.su.oz.au),
195 * Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM),
196 * David Hinds <dahinds@users.sourceforge.net>,
197 * Jan Hoogendoorn (c/o marteijn@lucent.com),
198 * Bruce Janson <bruce@cs.usyd.edu.au>,
199 * Anthony D. Joseph <adj@lcs.mit.edu>,
200 * Anders Klemets (klemets@paul.rutgers.edu),
201 * Yunzhou Li <yunzhou@strat.iol.unh.edu>,
202 * Marc Meertens (mmeertens@lucent.com),
203 * Keith Moore,
204 * Robert Morris (rtm@das.harvard.edu),
205 * Ian Parkin (ian@cs.su.oz.au),
206 * John Rosenberg (johnr@cs.su.oz.au),
207 * George Rossi (george@phm.gov.au),
208 * Arthur Scott (arthur@cs.su.oz.au),
209 * Stanislav Sinyagin <stas@isf.ru>
210 * Peter Storey,
211 * Jean Tourrilhes <jt@hpl.hp.com>,
212 * Girish Welling (welling@paul.rutgers.edu)
213 * Clark Woodworth <clark@hiway1.exit109.com>
214 * Yongguang Zhang <ygz@isl.hrl.hac.com>...
215 */
216
217/* ------------------------- IMPROVEMENTS ------------------------- */
218/*
219 * I proudly present :
220 *
221 * Changes made in 2.8.22 :
222 * ----------------------
223 * - improved wv_set_multicast_list
224 * - catch spurious interrupt
225 * - correct release of the device
226 *
227 * Changes mades in release :
228 * ------------------------
229 * - Reorganisation of the code, function name change
230 * - Creation of private header (wavelan_cs.h)
231 * - Reorganised debug messages
232 * - More comments, history, ...
233 * - Configure earlier (in "insert" instead of "open")
234 * and do things only once
235 * - mmc_init : configure the PSA if not done
236 * - mmc_init : 2.00 detection better code for 2.00 init
237 * - better info at startup
238 * - Correct a HUGE bug (volatile & uncalibrated busy loop)
239 * in wv_82593_cmd => config speedup
240 * - Stop receiving & power down on close (and power up on open)
241 * use "ifconfig down" & "ifconfig up ; route add -net ..."
242 * - Send packets : add watchdog instead of pooling
243 * - Receive : check frame wrap around & try to recover some frames
244 * - wavelan_set_multicast_list : avoid reset
245 * - add wireless extensions (ioctl & get_wireless_stats)
246 * get/set nwid/frequency on fly, info for /proc/net/wireless
247 * - Suppress useless stuff from lp (net_local), but add link
248 * - More inlines
249 * - Lot of others minor details & cleanups
250 *
251 * Changes made in second release :
252 * ------------------------------
253 * - Optimise wv_85893_reconfig stuff, fix potential problems
254 * - Change error values for ioctl
255 * - Non blocking wv_ru_stop() + call wv_reset() in case of problems
256 * - Remove development printk from wavelan_watchdog()
257 * - Remove of the watchdog to wavelan_close instead of wavelan_release
258 * fix potential problems...
259 * - Start debugging suspend stuff (but it's still a bit weird)
260 * - Debug & optimize dump header/packet in Rx & Tx (debug)
261 * - Use "readb" and "writeb" to be kernel 2.1 compliant
262 * - Better handling of bogus interrupts
263 * - Wireless extension : SETSPY and GETSPY
264 * - Remove old stuff (stats - for those needing it, just ask me...)
265 * - Make wireless extensions optional
266 *
267 * Changes made in third release :
268 * -----------------------------
269 * - cleanups & typos
270 * - modif wireless ext (spy -> only one pointer)
271 * - new private ioctl to set/get quality & level threshold
272 * - Init : correct default value of level threshold for pcmcia
273 * - kill watchdog in hw_reset
274 * - more 2.1 support (copy_to/from_user instead of memcpy_to/fromfs)
275 * - Add message level (debug stuff in /var/adm/debug & errors not
276 * displayed at console and still in /var/adm/messages)
277 *
278 * Changes made in fourth release :
279 * ------------------------------
280 * - multicast support (yes !) thanks to Yongguang Zhang.
281 *
282 * Changes made in fifth release (2.9.0) :
283 * -------------------------------------
284 * - Revisited multicast code (it was mostly wrong).
285 * - protect code in wv_82593_reconfig with dev->tbusy (oups !)
286 *
287 * Changes made in sixth release (2.9.1a) :
288 * --------------------------------------
289 * - Change the detection code for multi manufacturer code support
290 * - Correct bug (hang kernel) in init when we were "rejecting" a card
291 *
292 * Changes made in seventh release (2.9.1b) :
293 * ----------------------------------------
294 * - Update to wireless extensions changes
295 * - Silly bug in card initial configuration (psa_conf_status)
296 *
297 * Changes made in eigth release :
298 * -----------------------------
299 * - Small bug in debug code (probably not the last one...)
300 * - 1.2.13 support (thanks to Clark Woodworth)
301 *
302 * Changes made for release in 2.9.2b :
303 * ----------------------------------
304 * - Level threshold is now a standard wireless extension (version 4 !)
305 * - modules parameters types for kernel > 2.1.17
306 * - updated man page
307 * - Others cleanup from David Hinds
308 *
309 * Changes made for release in 2.9.5 :
310 * ---------------------------------
311 * - byte count stats (courtesy of David Hinds)
312 * - Remove dev_tint stuff (courtesy of David Hinds)
313 * - Others cleanup from David Hinds
314 * - Encryption setting from Brent Elphick (thanks a lot !)
315 * - 'base' to 'u_long' for the Alpha (thanks to Stanislav Sinyagin)
316 *
317 * Changes made for release in 2.9.6 :
318 * ---------------------------------
319 * - fix bug : no longuer disable watchdog in case of bogus interrupt
320 * - increase timeout in config code for picky hardware
321 * - mask unused bits in status (Wireless Extensions)
322 *
323 * Changes integrated by Justin Seger <jseger@MIT.EDU> & David Hinds :
324 * -----------------------------------------------------------------
325 * - Roaming "hack" from Joe Finney <joe@comp.lancs.ac.uk>
326 * - PSA CRC code from Bob Gray <rgray@bald.cs.dartmouth.edu>
327 * - Better initialisation of the i82593 controller
328 * from Joseph K. O'Sullivan <josullvn+@cs.cmu.edu>
329 *
330 * Changes made for release in 3.0.10 :
331 * ----------------------------------
332 * - Fix eject "hang" of the driver under 2.2.X :
333 * o create wv_flush_stale_links()
334 * o Rename wavelan_release to wv_pcmcia_release & move up
335 * o move unregister_netdev to wavelan_detach()
336 * o wavelan_release() no longer call wavelan_detach()
337 * o Suppress "release" timer
338 * o Other cleanups & fixes
339 * - New MAC address in the probe
340 * - Reorg PSA_CRC code (endian neutral & cleaner)
341 * - Correct initialisation of the i82593 from Lucent manual
342 * - Put back the watchdog, with larger timeout
343 * - TRANSMIT_NO_CRC is a "normal" error, so recover from it
344 * from Derrick J Brashear <shadow@dementia.org>
345 * - Better handling of TX and RX normal failure conditions
346 * - #ifdef out all the roaming code
347 * - Add ESSID & "AP current address" ioctl stubs
348 * - General cleanup of the code
349 *
350 * Changes made for release in 3.0.13 :
351 * ----------------------------------
352 * - Re-enable compilation of roaming code by default, but with
353 * do_roaming = 0
354 * - Nuke `nwid=nwid^ntohs(beacon->domain_id)' in wl_roam_gather
355 * at the demand of John Carol Langford <jcl@gs176.sp.cs.cmu.edu>
356 * - Introduced WAVELAN_ROAMING_EXT for incomplete ESSID stuff.
357 *
358 * Changes made for release in 3.0.15 :
359 * ----------------------------------
360 * - Change e-mail and web page addresses
361 * - Watchdog timer is now correctly expressed in HZ, not in jiffies
362 * - Add channel number to the list of frequencies in range
363 * - Add the (short) list of bit-rates in range
364 * - Developp a new sensitivity... (sens.value & sens.fixed)
365 *
366 * Changes made for release in 3.1.2 :
367 * ---------------------------------
368 * - Fix check for root permission (break instead of exit)
369 * - New nwid & encoding setting (Wireless Extension 9)
370 *
371 * Changes made for release in 3.1.12 :
372 * ----------------------------------
373 * - reworked wv_82593_cmd to avoid using the IRQ handler and doing
374 * ugly things with interrupts.
375 * - Add IRQ protection in 82593_config/ru_start/ru_stop/watchdog
376 * - Update to new network API (softnet - 2.3.43) :
377 * o replace dev->tbusy (David + me)
378 * o replace dev->tstart (David + me)
379 * o remove dev->interrupt (David)
380 * o add SMP locking via spinlock in splxx (me)
381 * o add spinlock in interrupt handler (me)
382 * o use kernel watchdog instead of ours (me)
383 * o verify that all the changes make sense and work (me)
384 * - Re-sync kernel/pcmcia versions (not much actually)
385 * - A few other cleanups (David & me)...
386 *
387 * Changes made for release in 3.1.22 :
388 * ----------------------------------
389 * - Check that SMP works, remove annoying log message
390 *
391 * Changes made for release in 3.1.24 :
392 * ----------------------------------
393 * - Fix unfrequent card lockup when watchdog was reseting the hardware :
394 * o control first busy loop in wv_82593_cmd()
395 * o Extend spinlock protection in wv_hw_config()
396 *
397 * Changes made for release in 3.1.33 :
398 * ----------------------------------
399 * - Optional use new driver API for Wireless Extensions :
400 * o got rid of wavelan_ioctl()
401 * o use a bunch of iw_handler instead
402 *
403 * Changes made for release in 3.2.1 :
404 * ---------------------------------
405 * - Set dev->trans_start to avoid filling the logs
406 * (and generating useless abort commands)
407 * - Avoid deadlocks in mmc_out()/mmc_in()
408 *
409 * Wishes & dreams:
410 * ----------------
411 * - Cleanup and integrate the roaming code
412 * (std debug, set DomainID, decay avg and co...)
413 */
414
415/***************************** INCLUDES *****************************/
416
417/* Linux headers that we need */
418#include <linux/config.h>
419#include <linux/module.h>
420#include <linux/kernel.h>
421#include <linux/init.h>
422#include <linux/sched.h>
423#include <linux/ptrace.h>
424#include <linux/slab.h>
425#include <linux/string.h>
426#include <linux/timer.h>
427#include <linux/interrupt.h>
428#include <linux/spinlock.h>
429#include <linux/in.h>
430#include <linux/delay.h>
431#include <linux/bitops.h>
432#include <asm/uaccess.h>
433#include <asm/io.h>
434#include <asm/system.h>
435
436#include <linux/netdevice.h>
437#include <linux/etherdevice.h>
438#include <linux/skbuff.h>
439#include <linux/if_arp.h>
440#include <linux/ioport.h>
441#include <linux/fcntl.h>
442#include <linux/ethtool.h>
443
444#ifdef CONFIG_NET_RADIO
445#include <linux/wireless.h> /* Wireless extensions */
446#include <net/iw_handler.h> /* New driver API */
447#endif
448
449/* Pcmcia headers that we need */
450#include <pcmcia/cs_types.h>
451#include <pcmcia/cs.h>
452#include <pcmcia/cistpl.h>
453#include <pcmcia/cisreg.h>
454#include <pcmcia/ds.h>
455#include <pcmcia/version.h>
456
457/* Wavelan declarations */
458#include "i82593.h" /* Definitions for the Intel chip */
459
460#include "wavelan_cs.h" /* Others bits of the hardware */
461
462/************************** DRIVER OPTIONS **************************/
463/*
464 * `#define' or `#undef' the following constant to change the behaviour
465 * of the driver...
466 */
467#define WAVELAN_ROAMING /* Include experimental roaming code */
468#undef WAVELAN_ROAMING_EXT /* Enable roaming wireless extensions */
469#undef SET_PSA_CRC /* Set the CRC in PSA (slower) */
470#define USE_PSA_CONFIG /* Use info from the PSA */
471#undef STRUCT_CHECK /* Verify padding of structures */
472#undef EEPROM_IS_PROTECTED /* Doesn't seem to be necessary */
473#define MULTICAST_AVOID /* Avoid extra multicast (I'm sceptical) */
474#undef SET_MAC_ADDRESS /* Experimental */
475
476#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */
477/* Warning : these stuff will slow down the driver... */
478#define WIRELESS_SPY /* Enable spying addresses */
479#undef HISTOGRAM /* Enable histogram of sig level... */
480#endif
481
482/****************************** DEBUG ******************************/
483
484#undef DEBUG_MODULE_TRACE /* Module insertion/removal */
485#undef DEBUG_CALLBACK_TRACE /* Calls made by Linux */
486#undef DEBUG_INTERRUPT_TRACE /* Calls to handler */
487#undef DEBUG_INTERRUPT_INFO /* type of interrupt & so on */
488#define DEBUG_INTERRUPT_ERROR /* problems */
489#undef DEBUG_CONFIG_TRACE /* Trace the config functions */
490#undef DEBUG_CONFIG_INFO /* What's going on... */
491#define DEBUG_CONFIG_ERRORS /* Errors on configuration */
492#undef DEBUG_TX_TRACE /* Transmission calls */
493#undef DEBUG_TX_INFO /* Header of the transmitted packet */
494#undef DEBUG_TX_FAIL /* Normal failure conditions */
495#define DEBUG_TX_ERROR /* Unexpected conditions */
496#undef DEBUG_RX_TRACE /* Transmission calls */
497#undef DEBUG_RX_INFO /* Header of the transmitted packet */
498#undef DEBUG_RX_FAIL /* Normal failure conditions */
499#define DEBUG_RX_ERROR /* Unexpected conditions */
500#undef DEBUG_PACKET_DUMP /* Dump packet on the screen */
501#undef DEBUG_IOCTL_TRACE /* Misc call by Linux */
502#undef DEBUG_IOCTL_INFO /* Various debug info */
503#define DEBUG_IOCTL_ERROR /* What's going wrong */
504#define DEBUG_BASIC_SHOW /* Show basic startup info */
505#undef DEBUG_VERSION_SHOW /* Print version info */
506#undef DEBUG_PSA_SHOW /* Dump psa to screen */
507#undef DEBUG_MMC_SHOW /* Dump mmc to screen */
508#undef DEBUG_SHOW_UNUSED /* Show also unused fields */
509#undef DEBUG_I82593_SHOW /* Show i82593 status */
510#undef DEBUG_DEVICE_SHOW /* Show device parameters */
511
512/************************ CONSTANTS & MACROS ************************/
513
514#ifdef DEBUG_VERSION_SHOW
515static const char *version = "wavelan_cs.c : v24 (SMP + wireless extensions) 11/1/02\n";
516#endif
517
518/* Watchdog temporisation */
519#define WATCHDOG_JIFFIES (256*HZ/100)
520
521/* Fix a bug in some old wireless extension definitions */
522#ifndef IW_ESSID_MAX_SIZE
523#define IW_ESSID_MAX_SIZE 32
524#endif
525
526/* ------------------------ PRIVATE IOCTL ------------------------ */
527
528#define SIOCSIPQTHR SIOCIWFIRSTPRIV /* Set quality threshold */
529#define SIOCGIPQTHR SIOCIWFIRSTPRIV + 1 /* Get quality threshold */
530#define SIOCSIPROAM SIOCIWFIRSTPRIV + 2 /* Set roaming state */
531#define SIOCGIPROAM SIOCIWFIRSTPRIV + 3 /* Get roaming state */
532
533#define SIOCSIPHISTO SIOCIWFIRSTPRIV + 4 /* Set histogram ranges */
534#define SIOCGIPHISTO SIOCIWFIRSTPRIV + 5 /* Get histogram values */
535
536/*************************** WaveLAN Roaming **************************/
537#ifdef WAVELAN_ROAMING /* Conditional compile, see above in options */
538
539#define WAVELAN_ROAMING_DEBUG 0 /* 1 = Trace of handover decisions */
540 /* 2 = Info on each beacon rcvd... */
541#define MAX_WAVEPOINTS 7 /* Max visible at one time */
542#define WAVEPOINT_HISTORY 5 /* SNR sample history slow search */
543#define WAVEPOINT_FAST_HISTORY 2 /* SNR sample history fast search */
544#define SEARCH_THRESH_LOW 10 /* SNR to enter cell search */
545#define SEARCH_THRESH_HIGH 13 /* SNR to leave cell search */
546#define WAVELAN_ROAMING_DELTA 1 /* Hysteresis value (+/- SNR) */
547#define CELL_TIMEOUT 2*HZ /* in jiffies */
548
549#define FAST_CELL_SEARCH 1 /* Boolean values... */
550#define NWID_PROMISC 1 /* for code clarity. */
551
552typedef struct wavepoint_beacon
553{
554 unsigned char dsap, /* Unused */
555 ssap, /* Unused */
556 ctrl, /* Unused */
557 O,U,I, /* Unused */
558 spec_id1, /* Unused */
559 spec_id2, /* Unused */
560 pdu_type, /* Unused */
561 seq; /* WavePoint beacon sequence number */
562 unsigned short domain_id, /* WavePoint Domain ID */
563 nwid; /* WavePoint NWID */
564} wavepoint_beacon;
565
566typedef struct wavepoint_history
567{
568 unsigned short nwid; /* WavePoint's NWID */
569 int average_slow; /* SNR running average */
570 int average_fast; /* SNR running average */
571 unsigned char sigqual[WAVEPOINT_HISTORY]; /* Ringbuffer of recent SNR's */
572 unsigned char qualptr; /* Index into ringbuffer */
573 unsigned char last_seq; /* Last seq. no seen for WavePoint */
574 struct wavepoint_history *next; /* Next WavePoint in table */
575 struct wavepoint_history *prev; /* Previous WavePoint in table */
576 unsigned long last_seen; /* Time of last beacon recvd, jiffies */
577} wavepoint_history;
578
579struct wavepoint_table
580{
581 wavepoint_history *head; /* Start of ringbuffer */
582 int num_wavepoints; /* No. of WavePoints visible */
583 unsigned char locked; /* Table lock */
584};
585
586#endif /* WAVELAN_ROAMING */
587
588/****************************** TYPES ******************************/
589
590/* Shortcuts */
591typedef struct net_device_stats en_stats;
592typedef struct iw_statistics iw_stats;
593typedef struct iw_quality iw_qual;
594typedef struct iw_freq iw_freq;
595typedef struct net_local net_local;
596typedef struct timer_list timer_list;
597
598/* Basic types */
599typedef u_char mac_addr[WAVELAN_ADDR_SIZE]; /* Hardware address */
600
601/*
602 * Static specific data for the interface.
603 *
604 * For each network interface, Linux keep data in two structure. "device"
605 * keep the generic data (same format for everybody) and "net_local" keep
606 * the additional specific data.
607 * Note that some of this specific data is in fact generic (en_stats, for
608 * example).
609 */
610struct net_local
611{
612 dev_node_t node; /* ???? What is this stuff ???? */
613 struct net_device * dev; /* Reverse link... */
614 spinlock_t spinlock; /* Serialize access to the hardware (SMP) */
615 dev_link_t * link; /* pcmcia structure */
616 en_stats stats; /* Ethernet interface statistics */
617 int nresets; /* Number of hw resets */
618 u_char configured; /* If it is configured */
619 u_char reconfig_82593; /* Need to reconfigure the controller */
620 u_char promiscuous; /* Promiscuous mode */
621 u_char allmulticast; /* All Multicast mode */
622 int mc_count; /* Number of multicast addresses */
623
624 int stop; /* Current i82593 Stop Hit Register */
625 int rfp; /* Last DMA machine receive pointer */
626 int overrunning; /* Receiver overrun flag */
627
628#ifdef WIRELESS_EXT
629 iw_stats wstats; /* Wireless specific stats */
630
631 struct iw_spy_data spy_data;
632 struct iw_public_data wireless_data;
633#endif
634
635#ifdef HISTOGRAM
636 int his_number; /* Number of intervals */
637 u_char his_range[16]; /* Boundaries of interval ]n-1; n] */
638 u_long his_sum[16]; /* Sum in interval */
639#endif /* HISTOGRAM */
640#ifdef WAVELAN_ROAMING
641 u_long domain_id; /* Domain ID we lock on for roaming */
642 int filter_domains; /* Check Domain ID of beacon found */
643 struct wavepoint_table wavepoint_table; /* Table of visible WavePoints*/
644 wavepoint_history * curr_point; /* Current wavepoint */
645 int cell_search; /* Searching for new cell? */
646 struct timer_list cell_timer; /* Garbage collection */
647#endif /* WAVELAN_ROAMING */
648 void __iomem *mem;
649};
650
651/**************************** PROTOTYPES ****************************/
652
653#ifdef WAVELAN_ROAMING
654/* ---------------------- ROAMING SUBROUTINES -----------------------*/
655
656wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp);
657wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local *lp);
658void wl_del_wavepoint(wavepoint_history *wavepoint, net_local *lp);
659void wl_cell_expiry(unsigned long data);
660wavepoint_history *wl_best_sigqual(int fast_search, net_local *lp);
661void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq);
662void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp);
663void wv_nwid_filter(unsigned char mode, net_local *lp);
664void wv_roam_init(struct net_device *dev);
665void wv_roam_cleanup(struct net_device *dev);
666#endif /* WAVELAN_ROAMING */
667
668/* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */
669static inline u_char /* data */
670 hasr_read(u_long); /* Read the host interface : base address */
671static inline void
672 hacr_write(u_long, /* Write to host interface : base address */
673 u_char), /* data */
674 hacr_write_slow(u_long,
675 u_char);
676static void
677 psa_read(struct net_device *, /* Read the Parameter Storage Area */
678 int, /* offset in PSA */
679 u_char *, /* buffer to fill */
680 int), /* size to read */
681 psa_write(struct net_device *, /* Write to the PSA */
682 int, /* Offset in psa */
683 u_char *, /* Buffer in memory */
684 int); /* Length of buffer */
685static inline void
686 mmc_out(u_long, /* Write 1 byte to the Modem Manag Control */
687 u_short,
688 u_char),
689 mmc_write(u_long, /* Write n bytes to the MMC */
690 u_char,
691 u_char *,
692 int);
693static inline u_char /* Read 1 byte from the MMC */
694 mmc_in(u_long,
695 u_short);
696static inline void
697 mmc_read(u_long, /* Read n bytes from the MMC */
698 u_char,
699 u_char *,
700 int),
701 fee_wait(u_long, /* Wait for frequency EEprom : base address */
702 int, /* Base delay to wait for */
703 int); /* Number of time to wait */
704static void
705 fee_read(u_long, /* Read the frequency EEprom : base address */
706 u_short, /* destination offset */
707 u_short *, /* data buffer */
708 int); /* number of registers */
709/* ---------------------- I82593 SUBROUTINES ----------------------- */
710static int
711 wv_82593_cmd(struct net_device *, /* synchronously send a command to i82593 */
712 char *,
713 int,
714 int);
715static inline int
716 wv_diag(struct net_device *); /* Diagnostique the i82593 */
717static int
718 read_ringbuf(struct net_device *, /* Read a receive buffer */
719 int,
720 char *,
721 int);
722static inline void
723 wv_82593_reconfig(struct net_device *); /* Reconfigure the controller */
724/* ------------------- DEBUG & INFO SUBROUTINES ------------------- */
725static inline void
726 wv_init_info(struct net_device *); /* display startup info */
727/* ------------------- IOCTL, STATS & RECONFIG ------------------- */
728static en_stats *
729 wavelan_get_stats(struct net_device *); /* Give stats /proc/net/dev */
730static iw_stats *
731 wavelan_get_wireless_stats(struct net_device *);
732/* ----------------------- PACKET RECEPTION ----------------------- */
733static inline int
734 wv_start_of_frame(struct net_device *, /* Seek beggining of current frame */
735 int, /* end of frame */
736 int); /* start of buffer */
737static inline void
738 wv_packet_read(struct net_device *, /* Read a packet from a frame */
739 int,
740 int),
741 wv_packet_rcv(struct net_device *); /* Read all packets waiting */
742/* --------------------- PACKET TRANSMISSION --------------------- */
743static inline void
744 wv_packet_write(struct net_device *, /* Write a packet to the Tx buffer */
745 void *,
746 short);
747static int
748 wavelan_packet_xmit(struct sk_buff *, /* Send a packet */
749 struct net_device *);
750/* -------------------- HARDWARE CONFIGURATION -------------------- */
751static inline int
752 wv_mmc_init(struct net_device *); /* Initialize the modem */
753static int
754 wv_ru_stop(struct net_device *), /* Stop the i82593 receiver unit */
755 wv_ru_start(struct net_device *); /* Start the i82593 receiver unit */
756static int
757 wv_82593_config(struct net_device *); /* Configure the i82593 */
758static inline int
759 wv_pcmcia_reset(struct net_device *); /* Reset the pcmcia interface */
760static int
761 wv_hw_config(struct net_device *); /* Reset & configure the whole hardware */
762static inline void
763 wv_hw_reset(struct net_device *); /* Same, + start receiver unit */
764static inline int
765 wv_pcmcia_config(dev_link_t *); /* Configure the pcmcia interface */
766static void
767 wv_pcmcia_release(dev_link_t *);/* Remove a device */
768/* ---------------------- INTERRUPT HANDLING ---------------------- */
769static irqreturn_t
770 wavelan_interrupt(int, /* Interrupt handler */
771 void *,
772 struct pt_regs *);
773static void
774 wavelan_watchdog(struct net_device *); /* Transmission watchdog */
775/* ------------------- CONFIGURATION CALLBACKS ------------------- */
776static int
777 wavelan_open(struct net_device *), /* Open the device */
778 wavelan_close(struct net_device *); /* Close the device */
779static dev_link_t *
780 wavelan_attach(void); /* Create a new device */
781static void
782 wavelan_detach(dev_link_t *); /* Destroy a removed device */
783static int
784 wavelan_event(event_t, /* Manage pcmcia events */
785 int,
786 event_callback_args_t *);
787
788/**************************** VARIABLES ****************************/
789
790static dev_info_t dev_info = "wavelan_cs";
791static dev_link_t *dev_list = NULL; /* Linked list of devices */
792
793/*
794 * Parameters that can be set with 'insmod'
795 * The exact syntax is 'insmod wavelan_cs.o <var>=<value>'
796 */
797
798/* Shared memory speed, in ns */
799static int mem_speed = 0;
800
801/* New module interface */
802module_param(mem_speed, int, 0);
803
804#ifdef WAVELAN_ROAMING /* Conditional compile, see above in options */
805/* Enable roaming mode ? No ! Please keep this to 0 */
806static int do_roaming = 0;
807module_param(do_roaming, bool, 0);
808#endif /* WAVELAN_ROAMING */
809
810MODULE_LICENSE("GPL");
811
812#endif /* WAVELAN_CS_P_H */
813
diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
new file mode 100644
index 000000000000..8636d9306785
--- /dev/null
+++ b/drivers/net/wireless/wl3501.h
@@ -0,0 +1,614 @@
1#ifndef __WL3501_H__
2#define __WL3501_H__
3
4#include <linux/spinlock.h>
5#include "ieee802_11.h"
6
7/* define for WLA 2.0 */
8#define WL3501_BLKSZ 256
9/*
10 * ID for input Signals of DRIVER block
11 * bit[7-5] is block ID: 000
12 * bit[4-0] is signal ID
13*/
14enum wl3501_signals {
15 WL3501_SIG_ALARM,
16 WL3501_SIG_MD_CONFIRM,
17 WL3501_SIG_MD_IND,
18 WL3501_SIG_ASSOC_CONFIRM,
19 WL3501_SIG_ASSOC_IND,
20 WL3501_SIG_AUTH_CONFIRM,
21 WL3501_SIG_AUTH_IND,
22 WL3501_SIG_DEAUTH_CONFIRM,
23 WL3501_SIG_DEAUTH_IND,
24 WL3501_SIG_DISASSOC_CONFIRM,
25 WL3501_SIG_DISASSOC_IND,
26 WL3501_SIG_GET_CONFIRM,
27 WL3501_SIG_JOIN_CONFIRM,
28 WL3501_SIG_PWR_MGMT_CONFIRM,
29 WL3501_SIG_REASSOC_CONFIRM,
30 WL3501_SIG_REASSOC_IND,
31 WL3501_SIG_SCAN_CONFIRM,
32 WL3501_SIG_SET_CONFIRM,
33 WL3501_SIG_START_CONFIRM,
34 WL3501_SIG_RESYNC_CONFIRM,
35 WL3501_SIG_SITE_CONFIRM,
36 WL3501_SIG_SAVE_CONFIRM,
37 WL3501_SIG_RFTEST_CONFIRM,
38/*
39 * ID for input Signals of MLME block
40 * bit[7-5] is block ID: 010
41 * bit[4-0] is signal ID
42 */
43 WL3501_SIG_ASSOC_REQ = 0x20,
44 WL3501_SIG_AUTH_REQ,
45 WL3501_SIG_DEAUTH_REQ,
46 WL3501_SIG_DISASSOC_REQ,
47 WL3501_SIG_GET_REQ,
48 WL3501_SIG_JOIN_REQ,
49 WL3501_SIG_PWR_MGMT_REQ,
50 WL3501_SIG_REASSOC_REQ,
51 WL3501_SIG_SCAN_REQ,
52 WL3501_SIG_SET_REQ,
53 WL3501_SIG_START_REQ,
54 WL3501_SIG_MD_REQ,
55 WL3501_SIG_RESYNC_REQ,
56 WL3501_SIG_SITE_REQ,
57 WL3501_SIG_SAVE_REQ,
58 WL3501_SIG_RF_TEST_REQ,
59 WL3501_SIG_MM_CONFIRM = 0x60,
60 WL3501_SIG_MM_IND,
61};
62
63enum wl3501_mib_attribs {
64 WL3501_MIB_ATTR_STATION_ID,
65 WL3501_MIB_ATTR_AUTH_ALGORITHMS,
66 WL3501_MIB_ATTR_AUTH_TYPE,
67 WL3501_MIB_ATTR_MEDIUM_OCCUPANCY_LIMIT,
68 WL3501_MIB_ATTR_CF_POLLABLE,
69 WL3501_MIB_ATTR_CFP_PERIOD,
70 WL3501_MIB_ATTR_CFPMAX_DURATION,
71 WL3501_MIB_ATTR_AUTH_RESP_TMOUT,
72 WL3501_MIB_ATTR_RX_DTIMS,
73 WL3501_MIB_ATTR_PRIV_OPT_IMPLEMENTED,
74 WL3501_MIB_ATTR_PRIV_INVOKED,
75 WL3501_MIB_ATTR_WEP_DEFAULT_KEYS,
76 WL3501_MIB_ATTR_WEP_DEFAULT_KEY_ID,
77 WL3501_MIB_ATTR_WEP_KEY_MAPPINGS,
78 WL3501_MIB_ATTR_WEP_KEY_MAPPINGS_LEN,
79 WL3501_MIB_ATTR_EXCLUDE_UNENCRYPTED,
80 WL3501_MIB_ATTR_WEP_ICV_ERROR_COUNT,
81 WL3501_MIB_ATTR_WEP_UNDECRYPTABLE_COUNT,
82 WL3501_MIB_ATTR_WEP_EXCLUDED_COUNT,
83 WL3501_MIB_ATTR_MAC_ADDR,
84 WL3501_MIB_ATTR_GROUP_ADDRS,
85 WL3501_MIB_ATTR_RTS_THRESHOLD,
86 WL3501_MIB_ATTR_SHORT_RETRY_LIMIT,
87 WL3501_MIB_ATTR_LONG_RETRY_LIMIT,
88 WL3501_MIB_ATTR_FRAG_THRESHOLD,
89 WL3501_MIB_ATTR_MAX_TX_MSDU_LIFETIME,
90 WL3501_MIB_ATTR_MAX_RX_LIFETIME,
91 WL3501_MIB_ATTR_MANUFACTURER_ID,
92 WL3501_MIB_ATTR_PRODUCT_ID,
93 WL3501_MIB_ATTR_TX_FRAG_COUNT,
94 WL3501_MIB_ATTR_MULTICAST_TX_FRAME_COUNT,
95 WL3501_MIB_ATTR_FAILED_COUNT,
96 WL3501_MIB_ATTR_RX_FRAG_COUNT,
97 WL3501_MIB_ATTR_MULTICAST_RX_COUNT,
98 WL3501_MIB_ATTR_FCS_ERROR_COUNT,
99 WL3501_MIB_ATTR_RETRY_COUNT,
100 WL3501_MIB_ATTR_MULTIPLE_RETRY_COUNT,
101 WL3501_MIB_ATTR_RTS_SUCCESS_COUNT,
102 WL3501_MIB_ATTR_RTS_FAILURE_COUNT,
103 WL3501_MIB_ATTR_ACK_FAILURE_COUNT,
104 WL3501_MIB_ATTR_FRAME_DUPLICATE_COUNT,
105 WL3501_MIB_ATTR_PHY_TYPE,
106 WL3501_MIB_ATTR_REG_DOMAINS_SUPPORT,
107 WL3501_MIB_ATTR_CURRENT_REG_DOMAIN,
108 WL3501_MIB_ATTR_SLOT_TIME,
109 WL3501_MIB_ATTR_CCA_TIME,
110 WL3501_MIB_ATTR_RX_TX_TURNAROUND_TIME,
111 WL3501_MIB_ATTR_TX_PLCP_DELAY,
112 WL3501_MIB_ATTR_RX_TX_SWITCH_TIME,
113 WL3501_MIB_ATTR_TX_RAMP_ON_TIME,
114 WL3501_MIB_ATTR_TX_RF_DELAY,
115 WL3501_MIB_ATTR_SIFS_TIME,
116 WL3501_MIB_ATTR_RX_RF_DELAY,
117 WL3501_MIB_ATTR_RX_PLCP_DELAY,
118 WL3501_MIB_ATTR_MAC_PROCESSING_DELAY,
119 WL3501_MIB_ATTR_TX_RAMP_OFF_TIME,
120 WL3501_MIB_ATTR_PREAMBLE_LEN,
121 WL3501_MIB_ATTR_PLCP_HEADER_LEN,
122 WL3501_MIB_ATTR_MPDU_DURATION_FACTOR,
123 WL3501_MIB_ATTR_AIR_PROPAGATION_TIME,
124 WL3501_MIB_ATTR_TEMP_TYPE,
125 WL3501_MIB_ATTR_CW_MIN,
126 WL3501_MIB_ATTR_CW_MAX,
127 WL3501_MIB_ATTR_SUPPORT_DATA_RATES_TX,
128 WL3501_MIB_ATTR_SUPPORT_DATA_RATES_RX,
129 WL3501_MIB_ATTR_MPDU_MAX_LEN,
130 WL3501_MIB_ATTR_SUPPORT_TX_ANTENNAS,
131 WL3501_MIB_ATTR_CURRENT_TX_ANTENNA,
132 WL3501_MIB_ATTR_SUPPORT_RX_ANTENNAS,
133 WL3501_MIB_ATTR_DIVERSITY_SUPPORT,
134 WL3501_MIB_ATTR_DIVERSITY_SELECTION_RS,
135 WL3501_MIB_ATTR_NR_SUPPORTED_PWR_LEVELS,
136 WL3501_MIB_ATTR_TX_PWR_LEVEL1,
137 WL3501_MIB_ATTR_TX_PWR_LEVEL2,
138 WL3501_MIB_ATTR_TX_PWR_LEVEL3,
139 WL3501_MIB_ATTR_TX_PWR_LEVEL4,
140 WL3501_MIB_ATTR_TX_PWR_LEVEL5,
141 WL3501_MIB_ATTR_TX_PWR_LEVEL6,
142 WL3501_MIB_ATTR_TX_PWR_LEVEL7,
143 WL3501_MIB_ATTR_TX_PWR_LEVEL8,
144 WL3501_MIB_ATTR_CURRENT_TX_PWR_LEVEL,
145 WL3501_MIB_ATTR_CURRENT_CHAN,
146 WL3501_MIB_ATTR_CCA_MODE_SUPPORTED,
147 WL3501_MIB_ATTR_CURRENT_CCA_MODE,
148 WL3501_MIB_ATTR_ED_THRESHOLD,
149 WL3501_MIB_ATTR_SINTHESIZER_LOCKED,
150 WL3501_MIB_ATTR_CURRENT_PWR_STATE,
151 WL3501_MIB_ATTR_DOZE_TURNON_TIME,
152 WL3501_MIB_ATTR_RCR33,
153 WL3501_MIB_ATTR_DEFAULT_CHAN,
154 WL3501_MIB_ATTR_SSID,
155 WL3501_MIB_ATTR_PWR_MGMT_ENABLE,
156 WL3501_MIB_ATTR_NET_CAPABILITY,
157 WL3501_MIB_ATTR_ROUTING,
158};
159
160enum wl3501_net_type {
161 WL3501_NET_TYPE_INFRA,
162 WL3501_NET_TYPE_ADHOC,
163 WL3501_NET_TYPE_ANY_BSS,
164};
165
166enum wl3501_scan_type {
167 WL3501_SCAN_TYPE_ACTIVE,
168 WL3501_SCAN_TYPE_PASSIVE,
169};
170
171enum wl3501_tx_result {
172 WL3501_TX_RESULT_SUCCESS,
173 WL3501_TX_RESULT_NO_BSS,
174 WL3501_TX_RESULT_RETRY_LIMIT,
175};
176
177enum wl3501_sys_type {
178 WL3501_SYS_TYPE_OPEN,
179 WL3501_SYS_TYPE_SHARE_KEY,
180};
181
182enum wl3501_status {
183 WL3501_STATUS_SUCCESS,
184 WL3501_STATUS_INVALID,
185 WL3501_STATUS_TIMEOUT,
186 WL3501_STATUS_REFUSED,
187 WL3501_STATUS_MANY_REQ,
188 WL3501_STATUS_ALREADY_BSS,
189};
190
191#define WL3501_MGMT_CAPABILITY_ESS 0x0001 /* see 802.11 p.58 */
192#define WL3501_MGMT_CAPABILITY_IBSS 0x0002 /* - " - */
193#define WL3501_MGMT_CAPABILITY_CF_POLLABLE 0x0004 /* - " - */
194#define WL3501_MGMT_CAPABILITY_CF_POLL_REQUEST 0x0008 /* - " - */
195#define WL3501_MGMT_CAPABILITY_PRIVACY 0x0010 /* - " - */
196
197#define IW_REG_DOMAIN_FCC 0x10 /* Channel 1 to 11 USA */
198#define IW_REG_DOMAIN_DOC 0x20 /* Channel 1 to 11 Canada */
199#define IW_REG_DOMAIN_ETSI 0x30 /* Channel 1 to 13 Europe */
200#define IW_REG_DOMAIN_SPAIN 0x31 /* Channel 10 to 11 Spain */
201#define IW_REG_DOMAIN_FRANCE 0x32 /* Channel 10 to 13 France */
202#define IW_REG_DOMAIN_MKK 0x40 /* Channel 14 Japan */
203#define IW_REG_DOMAIN_MKK1 0x41 /* Channel 1-14 Japan */
204#define IW_REG_DOMAIN_ISRAEL 0x50 /* Channel 3 - 9 Israel */
205
206#define IW_MGMT_RATE_LABEL_MANDATORY 128 /* MSB */
207
208enum iw_mgmt_rate_labels {
209 IW_MGMT_RATE_LABEL_1MBIT = 2,
210 IW_MGMT_RATE_LABEL_2MBIT = 4,
211 IW_MGMT_RATE_LABEL_5_5MBIT = 11,
212 IW_MGMT_RATE_LABEL_11MBIT = 22,
213};
214
215enum iw_mgmt_info_element_ids {
216 IW_MGMT_INFO_ELEMENT_SSID, /* Service Set Identity */
217 IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
218 IW_MGMT_INFO_ELEMENT_FH_PARAMETER_SET,
219 IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
220 IW_MGMT_INFO_ELEMENT_CS_PARAMETER_SET,
221 IW_MGMT_INFO_ELEMENT_CS_TIM, /* Traffic Information Map */
222 IW_MGMT_INFO_ELEMENT_IBSS_PARAMETER_SET,
223 /* 7-15: Reserved, unused */
224 IW_MGMT_INFO_ELEMENT_CHALLENGE_TEXT = 16,
225 /* 17-31 Reserved for challenge text extension */
226 /* 32-255 Reserved, unused */
227};
228
229struct iw_mgmt_info_element {
230 u8 id; /* one of enum iw_mgmt_info_element_ids,
231 but sizeof(enum) > sizeof(u8) :-( */
232 u8 len;
233 u8 data[0];
234} __attribute__ ((packed));
235
236struct iw_mgmt_essid_pset {
237 struct iw_mgmt_info_element el;
238 u8 essid[IW_ESSID_MAX_SIZE];
239} __attribute__ ((packed));
240
241/*
242 * According to 802.11 Wireless Netowors, the definitive guide - O'Reilly
243 * Pg 75
244 */
245#define IW_DATA_RATE_MAX_LABELS 8
246
247struct iw_mgmt_data_rset {
248 struct iw_mgmt_info_element el;
249 u8 data_rate_labels[IW_DATA_RATE_MAX_LABELS];
250} __attribute__ ((packed));
251
252struct iw_mgmt_ds_pset {
253 struct iw_mgmt_info_element el;
254 u8 chan;
255} __attribute__ ((packed));
256
257struct iw_mgmt_cf_pset {
258 struct iw_mgmt_info_element el;
259 u8 cfp_count;
260 u8 cfp_period;
261 u16 cfp_max_duration;
262 u16 cfp_dur_remaining;
263} __attribute__ ((packed));
264
265struct iw_mgmt_ibss_pset {
266 struct iw_mgmt_info_element el;
267 u16 atim_window;
268} __attribute__ ((packed));
269
270struct wl3501_tx_hdr {
271 u16 tx_cnt;
272 u8 sync[16];
273 u16 sfd;
274 u8 signal;
275 u8 service;
276 u16 len;
277 u16 crc16;
278 u16 frame_ctrl;
279 u16 duration_id;
280 u8 addr1[ETH_ALEN];
281 u8 addr2[ETH_ALEN];
282 u8 addr3[ETH_ALEN];
283 u16 seq_ctrl;
284 u8 addr4[ETH_ALEN];
285};
286
287struct wl3501_rx_hdr {
288 u16 rx_next_blk;
289 u16 rc_next_frame_blk;
290 u8 rx_blk_ctrl;
291 u8 rx_next_frame;
292 u8 rx_next_frame1;
293 u8 rssi;
294 char time[8];
295 u8 signal;
296 u8 service;
297 u16 len;
298 u16 crc16;
299 u16 frame_ctrl;
300 u16 duration;
301 u8 addr1[ETH_ALEN];
302 u8 addr2[ETH_ALEN];
303 u8 addr3[ETH_ALEN];
304 u16 seq;
305 u8 addr4[ETH_ALEN];
306};
307
308struct wl3501_start_req {
309 u16 next_blk;
310 u8 sig_id;
311 u8 bss_type;
312 u16 beacon_period;
313 u16 dtim_period;
314 u16 probe_delay;
315 u16 cap_info;
316 struct iw_mgmt_essid_pset ssid;
317 struct iw_mgmt_data_rset bss_basic_rset;
318 struct iw_mgmt_data_rset operational_rset;
319 struct iw_mgmt_cf_pset cf_pset;
320 struct iw_mgmt_ds_pset ds_pset;
321 struct iw_mgmt_ibss_pset ibss_pset;
322};
323
324struct wl3501_assoc_req {
325 u16 next_blk;
326 u8 sig_id;
327 u8 reserved;
328 u16 timeout;
329 u16 cap_info;
330 u16 listen_interval;
331 u8 mac_addr[ETH_ALEN];
332};
333
334struct wl3501_assoc_confirm {
335 u16 next_blk;
336 u8 sig_id;
337 u8 reserved;
338 u16 status;
339};
340
341struct wl3501_assoc_ind {
342 u16 next_blk;
343 u8 sig_id;
344 u8 mac_addr[ETH_ALEN];
345};
346
347struct wl3501_auth_req {
348 u16 next_blk;
349 u8 sig_id;
350 u8 reserved;
351 u16 type;
352 u16 timeout;
353 u8 mac_addr[ETH_ALEN];
354};
355
356struct wl3501_auth_confirm {
357 u16 next_blk;
358 u8 sig_id;
359 u8 reserved;
360 u16 type;
361 u16 status;
362 u8 mac_addr[ETH_ALEN];
363};
364
365struct wl3501_get_req {
366 u16 next_blk;
367 u8 sig_id;
368 u8 reserved;
369 u16 mib_attrib;
370};
371
372struct wl3501_get_confirm {
373 u16 next_blk;
374 u8 sig_id;
375 u8 reserved;
376 u16 mib_status;
377 u16 mib_attrib;
378 u8 mib_value[100];
379};
380
381struct wl3501_join_req {
382 u16 next_blk;
383 u8 sig_id;
384 u8 reserved;
385 struct iw_mgmt_data_rset operational_rset;
386 u16 reserved2;
387 u16 timeout;
388 u16 probe_delay;
389 u8 timestamp[8];
390 u8 local_time[8];
391 u16 beacon_period;
392 u16 dtim_period;
393 u16 cap_info;
394 u8 bss_type;
395 u8 bssid[ETH_ALEN];
396 struct iw_mgmt_essid_pset ssid;
397 struct iw_mgmt_ds_pset ds_pset;
398 struct iw_mgmt_cf_pset cf_pset;
399 struct iw_mgmt_ibss_pset ibss_pset;
400 struct iw_mgmt_data_rset bss_basic_rset;
401};
402
403struct wl3501_join_confirm {
404 u16 next_blk;
405 u8 sig_id;
406 u8 reserved;
407 u16 status;
408};
409
410struct wl3501_pwr_mgmt_req {
411 u16 next_blk;
412 u8 sig_id;
413 u8 pwr_save;
414 u8 wake_up;
415 u8 receive_dtims;
416};
417
418struct wl3501_pwr_mgmt_confirm {
419 u16 next_blk;
420 u8 sig_id;
421 u8 reserved;
422 u16 status;
423};
424
425struct wl3501_scan_req {
426 u16 next_blk;
427 u8 sig_id;
428 u8 bss_type;
429 u16 probe_delay;
430 u16 min_chan_time;
431 u16 max_chan_time;
432 u8 chan_list[14];
433 u8 bssid[ETH_ALEN];
434 struct iw_mgmt_essid_pset ssid;
435 enum wl3501_scan_type scan_type;
436};
437
438struct wl3501_scan_confirm {
439 u16 next_blk;
440 u8 sig_id;
441 u8 reserved;
442 u16 status;
443 char timestamp[8];
444 char localtime[8];
445 u16 beacon_period;
446 u16 dtim_period;
447 u16 cap_info;
448 u8 bss_type;
449 u8 bssid[ETH_ALEN];
450 struct iw_mgmt_essid_pset ssid;
451 struct iw_mgmt_ds_pset ds_pset;
452 struct iw_mgmt_cf_pset cf_pset;
453 struct iw_mgmt_ibss_pset ibss_pset;
454 struct iw_mgmt_data_rset bss_basic_rset;
455 u8 rssi;
456};
457
458struct wl3501_start_confirm {
459 u16 next_blk;
460 u8 sig_id;
461 u8 reserved;
462 u16 status;
463};
464
465struct wl3501_md_req {
466 u16 next_blk;
467 u8 sig_id;
468 u8 routing;
469 u16 data;
470 u16 size;
471 u8 pri;
472 u8 service_class;
473 u8 daddr[ETH_ALEN];
474 u8 saddr[ETH_ALEN];
475};
476
477struct wl3501_md_ind {
478 u16 next_blk;
479 u8 sig_id;
480 u8 routing;
481 u16 data;
482 u16 size;
483 u8 reception;
484 u8 pri;
485 u8 service_class;
486 u8 daddr[ETH_ALEN];
487 u8 saddr[ETH_ALEN];
488};
489
490struct wl3501_md_confirm {
491 u16 next_blk;
492 u8 sig_id;
493 u8 reserved;
494 u16 data;
495 u8 status;
496 u8 pri;
497 u8 service_class;
498};
499
500struct wl3501_resync_req {
501 u16 next_blk;
502 u8 sig_id;
503};
504
505/* Definitions for supporting clone adapters. */
506/* System Interface Registers (SIR space) */
507#define WL3501_NIC_GCR ((u8)0x00) /* SIR0 - General Conf Register */
508#define WL3501_NIC_BSS ((u8)0x01) /* SIR1 - Bank Switching Select Reg */
509#define WL3501_NIC_LMAL ((u8)0x02) /* SIR2 - Local Mem addr Reg [7:0] */
510#define WL3501_NIC_LMAH ((u8)0x03) /* SIR3 - Local Mem addr Reg [14:8] */
511#define WL3501_NIC_IODPA ((u8)0x04) /* SIR4 - I/O Data Port A */
512#define WL3501_NIC_IODPB ((u8)0x05) /* SIR5 - I/O Data Port B */
513#define WL3501_NIC_IODPC ((u8)0x06) /* SIR6 - I/O Data Port C */
514#define WL3501_NIC_IODPD ((u8)0x07) /* SIR7 - I/O Data Port D */
515
516/* Bits in GCR */
517#define WL3501_GCR_SWRESET ((u8)0x80)
518#define WL3501_GCR_CORESET ((u8)0x40)
519#define WL3501_GCR_DISPWDN ((u8)0x20)
520#define WL3501_GCR_ECWAIT ((u8)0x10)
521#define WL3501_GCR_ECINT ((u8)0x08)
522#define WL3501_GCR_INT2EC ((u8)0x04)
523#define WL3501_GCR_ENECINT ((u8)0x02)
524#define WL3501_GCR_DAM ((u8)0x01)
525
526/* Bits in BSS (Bank Switching Select Register) */
527#define WL3501_BSS_FPAGE0 ((u8)0x20) /* Flash memory page0 */
528#define WL3501_BSS_FPAGE1 ((u8)0x28)
529#define WL3501_BSS_FPAGE2 ((u8)0x30)
530#define WL3501_BSS_FPAGE3 ((u8)0x38)
531#define WL3501_BSS_SPAGE0 ((u8)0x00) /* SRAM page0 */
532#define WL3501_BSS_SPAGE1 ((u8)0x08)
533#define WL3501_BSS_SPAGE2 ((u8)0x10)
534#define WL3501_BSS_SPAGE3 ((u8)0x18)
535
536/* Define Driver Interface */
537/* Refer IEEE 802.11 */
538/* Tx packet header, include PLCP and MPDU */
539/* Tx PLCP Header */
540struct wl3501_80211_tx_plcp_hdr {
541 u8 sync[16];
542 u16 sfd;
543 u8 signal;
544 u8 service;
545 u16 len;
546 u16 crc16;
547} __attribute__ ((packed));
548
549struct wl3501_80211_tx_hdr {
550 struct wl3501_80211_tx_plcp_hdr pclp_hdr;
551 struct ieee802_11_hdr mac_hdr;
552} __attribute__ ((packed));
553
554/*
555 Reserve the beginning Tx space for descriptor use.
556
557 TxBlockOffset --> *----*----*----*----* \
558 (TxFreeDesc) | 0 | 1 | 2 | 3 | \
559 | 4 | 5 | 6 | 7 | |
560 | 8 | 9 | 10 | 11 | TX_DESC * 20
561 | 12 | 13 | 14 | 15 | |
562 | 16 | 17 | 18 | 19 | /
563 TxBufferBegin --> *----*----*----*----* /
564 (TxBufferHead) | |
565 (TxBufferTail) | |
566 | Send Buffer |
567 | |
568 | |
569 *-------------------*
570 TxBufferEnd -------------------------/
571
572*/
573
574struct wl3501_card {
575 int base_addr;
576 u8 mac_addr[ETH_ALEN];
577 spinlock_t lock;
578 wait_queue_head_t wait;
579 struct wl3501_get_confirm sig_get_confirm;
580 struct wl3501_pwr_mgmt_confirm sig_pwr_mgmt_confirm;
581 u16 tx_buffer_size;
582 u16 tx_buffer_head;
583 u16 tx_buffer_tail;
584 u16 tx_buffer_cnt;
585 u16 esbq_req_start;
586 u16 esbq_req_end;
587 u16 esbq_req_head;
588 u16 esbq_req_tail;
589 u16 esbq_confirm_start;
590 u16 esbq_confirm_end;
591 u16 esbq_confirm;
592 struct iw_mgmt_essid_pset essid;
593 struct iw_mgmt_essid_pset keep_essid;
594 u8 bssid[ETH_ALEN];
595 int net_type;
596 char nick[32];
597 char card_name[32];
598 char firmware_date[32];
599 u8 chan;
600 u8 cap_info;
601 u16 start_seg;
602 u16 bss_cnt;
603 u16 join_sta_bss;
604 u8 rssi;
605 u8 adhoc_times;
606 u8 reg_domain;
607 u8 version[2];
608 struct wl3501_scan_confirm bss_set[20];
609 struct net_device_stats stats;
610 struct iw_statistics wstats;
611 struct iw_spy_data spy_data;
612 struct dev_node_t node;
613};
614#endif
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
new file mode 100644
index 000000000000..1433e5aaf1b4
--- /dev/null
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -0,0 +1,2270 @@
1/*
2 * WL3501 Wireless LAN PCMCIA Card Driver for Linux
3 * Written originally for Linux 2.0.30 by Fox Chen, mhchen@golf.ccl.itri.org.tw
4 * Ported to 2.2, 2.4 & 2.5 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
5 * Wireless extensions in 2.4 by Gustavo Niemeyer <niemeyer@conectiva.com>
6 *
7 * References used by Fox Chen while writing the original driver for 2.0.30:
8 *
9 * 1. WL24xx packet drivers (tooasm.asm)
10 * 2. Access Point Firmware Interface Specification for IEEE 802.11 SUTRO
11 * 3. IEEE 802.11
12 * 4. Linux network driver (/usr/src/linux/drivers/net)
13 * 5. ISA card driver - wl24.c
14 * 6. Linux PCMCIA skeleton driver - skeleton.c
15 * 7. Linux PCMCIA 3c589 network driver - 3c589_cs.c
16 *
17 * Tested with WL2400 firmware 1.2, Linux 2.0.30, and pcmcia-cs-2.9.12
18 * 1. Performance: about 165 Kbytes/sec in TCP/IP with Ad-Hoc mode.
19 * rsh 192.168.1.3 "dd if=/dev/zero bs=1k count=1000" > /dev/null
20 * (Specification 2M bits/sec. is about 250 Kbytes/sec., but we must deduct
21 * ETHER/IP/UDP/TCP header, and acknowledgement overhead)
22 *
23 * Tested with Planet AP in 2.4.17, 184 Kbytes/s in UDP in Infrastructure mode,
24 * 173 Kbytes/s in TCP.
25 *
26 * Tested with Planet AP in 2.5.73-bk, 216 Kbytes/s in Infrastructure mode
27 * with a SMP machine (dual pentium 100), using pktgen, 432 pps (pkt_size = 60)
28 */
29#undef REALLY_SLOW_IO /* most systems can safely undef this */
30
31#include <linux/config.h>
32#include <linux/delay.h>
33#include <linux/types.h>
34#include <linux/ethtool.h>
35#include <linux/init.h>
36#include <linux/interrupt.h>
37#include <linux/in.h>
38#include <linux/kernel.h>
39#include <linux/module.h>
40#include <linux/fcntl.h>
41#include <linux/if_arp.h>
42#include <linux/ioport.h>
43#include <linux/netdevice.h>
44#include <linux/etherdevice.h>
45#include <linux/skbuff.h>
46#include <linux/slab.h>
47#include <linux/string.h>
48#include <linux/wireless.h>
49
50#include <net/iw_handler.h>
51
52#include <pcmcia/version.h>
53#include <pcmcia/cs_types.h>
54#include <pcmcia/cs.h>
55#include <pcmcia/cistpl.h>
56#include <pcmcia/cisreg.h>
57#include <pcmcia/ds.h>
58
59#include <asm/io.h>
60#include <asm/uaccess.h>
61#include <asm/system.h>
62
63#include "wl3501.h"
64
65#ifndef __i386__
66#define slow_down_io()
67#endif
68
69/* For rough constant delay */
70#define WL3501_NOPLOOP(n) { int x = 0; while (x++ < n) slow_down_io(); }
71
72/*
73 * All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If you do not
74 * define PCMCIA_DEBUG at all, all the debug code will be left out. If you
75 * compile with PCMCIA_DEBUG=0, the debug code will be present but disabled --
76 * but it can then be enabled for specific modules at load time with a
77 * 'pc_debug=#' option to insmod.
78 */
79#define PCMCIA_DEBUG 0
80#ifdef PCMCIA_DEBUG
81static int pc_debug = PCMCIA_DEBUG;
82module_param(pc_debug, int, 0);
83#define dprintk(n, format, args...) \
84 { if (pc_debug > (n)) \
85 printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##args); }
86#else
87#define dprintk(n, format, args...)
88#endif
89
90#define wl3501_outb(a, b) { outb(a, b); slow_down_io(); }
91#define wl3501_outb_p(a, b) { outb_p(a, b); slow_down_io(); }
92#define wl3501_outsb(a, b, c) { outsb(a, b, c); slow_down_io(); }
93
94#define WL3501_RELEASE_TIMEOUT (25 * HZ)
95#define WL3501_MAX_ADHOC_TRIES 16
96
97#define WL3501_RESUME 0
98#define WL3501_SUSPEND 1
99
100/*
101 * The event() function is this driver's Card Services event handler. It will
102 * be called by Card Services when an appropriate card status event is
103 * received. The config() and release() entry points are used to configure or
104 * release a socket, in response to card insertion and ejection events. They
105 * are invoked from the wl24 event handler.
106 */
107static void wl3501_config(dev_link_t *link);
108static void wl3501_release(dev_link_t *link);
109static int wl3501_event(event_t event, int pri, event_callback_args_t *args);
110
111/*
112 * The dev_info variable is the "key" that is used to match up this
113 * device driver with appropriate cards, through the card configuration
114 * database.
115 */
116static dev_info_t wl3501_dev_info = "wl3501_cs";
117
118static int wl3501_chan2freq[] = {
119 [0] = 2412, [1] = 2417, [2] = 2422, [3] = 2427, [4] = 2432,
120 [5] = 2437, [6] = 2442, [7] = 2447, [8] = 2452, [9] = 2457,
121 [10] = 2462, [11] = 2467, [12] = 2472, [13] = 2477,
122};
123
124static const struct {
125 int reg_domain;
126 int min, max, deflt;
127} iw_channel_table[] = {
128 {
129 .reg_domain = IW_REG_DOMAIN_FCC,
130 .min = 1,
131 .max = 11,
132 .deflt = 1,
133 },
134 {
135 .reg_domain = IW_REG_DOMAIN_DOC,
136 .min = 1,
137 .max = 11,
138 .deflt = 1,
139 },
140 {
141 .reg_domain = IW_REG_DOMAIN_ETSI,
142 .min = 1,
143 .max = 13,
144 .deflt = 1,
145 },
146 {
147 .reg_domain = IW_REG_DOMAIN_SPAIN,
148 .min = 10,
149 .max = 11,
150 .deflt = 10,
151 },
152 {
153 .reg_domain = IW_REG_DOMAIN_FRANCE,
154 .min = 10,
155 .max = 13,
156 .deflt = 10,
157 },
158 {
159 .reg_domain = IW_REG_DOMAIN_MKK,
160 .min = 14,
161 .max = 14,
162 .deflt = 14,
163 },
164 {
165 .reg_domain = IW_REG_DOMAIN_MKK1,
166 .min = 1,
167 .max = 14,
168 .deflt = 1,
169 },
170 {
171 .reg_domain = IW_REG_DOMAIN_ISRAEL,
172 .min = 3,
173 .max = 9,
174 .deflt = 9,
175 },
176};
177
178/**
179 * iw_valid_channel - validate channel in regulatory domain
180 * @reg_comain - regulatory domain
181 * @channel - channel to validate
182 *
183 * Returns 0 if invalid in the specified regulatory domain, non-zero if valid.
184 */
185static int iw_valid_channel(int reg_domain, int channel)
186{
187 int i, rc = 0;
188
189 for (i = 0; i < ARRAY_SIZE(iw_channel_table); i++)
190 if (reg_domain == iw_channel_table[i].reg_domain) {
191 rc = channel >= iw_channel_table[i].min &&
192 channel <= iw_channel_table[i].max;
193 break;
194 }
195 return rc;
196}
197
198/**
199 * iw_default_channel - get default channel for a regulatory domain
200 * @reg_comain - regulatory domain
201 *
202 * Returns the default channel for a regulatory domain
203 */
204static int iw_default_channel(int reg_domain)
205{
206 int i, rc = 1;
207
208 for (i = 0; i < ARRAY_SIZE(iw_channel_table); i++)
209 if (reg_domain == iw_channel_table[i].reg_domain) {
210 rc = iw_channel_table[i].deflt;
211 break;
212 }
213 return rc;
214}
215
216static void iw_set_mgmt_info_element(enum iw_mgmt_info_element_ids id,
217 struct iw_mgmt_info_element *el,
218 void *value, int len)
219{
220 el->id = id;
221 el->len = len;
222 memcpy(el->data, value, len);
223}
224
225static void iw_copy_mgmt_info_element(struct iw_mgmt_info_element *to,
226 struct iw_mgmt_info_element *from)
227{
228 iw_set_mgmt_info_element(from->id, to, from->data, from->len);
229}
230
231/*
232 * A linked list of "instances" of the wl24 device. Each actual PCMCIA card
233 * corresponds to one device instance, and is described by one dev_link_t
234 * structure (defined in ds.h).
235 *
236 * You may not want to use a linked list for this -- for example, the memory
237 * card driver uses an array of dev_link_t pointers, where minor device numbers
238 * are used to derive the corresponding array index.
239 */
240static dev_link_t *wl3501_dev_list;
241
242static inline void wl3501_switch_page(struct wl3501_card *this, u8 page)
243{
244 wl3501_outb(page, this->base_addr + WL3501_NIC_BSS);
245}
246
247/*
248 * Get Ethernet MAC addresss.
249 *
250 * WARNING: We switch to FPAGE0 and switc back again.
251 * Making sure there is no other WL function beening called by ISR.
252 */
253static int wl3501_get_flash_mac_addr(struct wl3501_card *this)
254{
255 int base_addr = this->base_addr;
256
257 /* get MAC addr */
258 wl3501_outb(WL3501_BSS_FPAGE3, base_addr + WL3501_NIC_BSS); /* BSS */
259 wl3501_outb(0x00, base_addr + WL3501_NIC_LMAL); /* LMAL */
260 wl3501_outb(0x40, base_addr + WL3501_NIC_LMAH); /* LMAH */
261
262 /* wait for reading EEPROM */
263 WL3501_NOPLOOP(100);
264 this->mac_addr[0] = inb(base_addr + WL3501_NIC_IODPA);
265 WL3501_NOPLOOP(100);
266 this->mac_addr[1] = inb(base_addr + WL3501_NIC_IODPA);
267 WL3501_NOPLOOP(100);
268 this->mac_addr[2] = inb(base_addr + WL3501_NIC_IODPA);
269 WL3501_NOPLOOP(100);
270 this->mac_addr[3] = inb(base_addr + WL3501_NIC_IODPA);
271 WL3501_NOPLOOP(100);
272 this->mac_addr[4] = inb(base_addr + WL3501_NIC_IODPA);
273 WL3501_NOPLOOP(100);
274 this->mac_addr[5] = inb(base_addr + WL3501_NIC_IODPA);
275 WL3501_NOPLOOP(100);
276 this->reg_domain = inb(base_addr + WL3501_NIC_IODPA);
277 WL3501_NOPLOOP(100);
278 wl3501_outb(WL3501_BSS_FPAGE0, base_addr + WL3501_NIC_BSS);
279 wl3501_outb(0x04, base_addr + WL3501_NIC_LMAL);
280 wl3501_outb(0x40, base_addr + WL3501_NIC_LMAH);
281 WL3501_NOPLOOP(100);
282 this->version[0] = inb(base_addr + WL3501_NIC_IODPA);
283 WL3501_NOPLOOP(100);
284 this->version[1] = inb(base_addr + WL3501_NIC_IODPA);
285 /* switch to SRAM Page 0 (for safety) */
286 wl3501_switch_page(this, WL3501_BSS_SPAGE0);
287
288 /* The MAC addr should be 00:60:... */
289 return this->mac_addr[0] == 0x00 && this->mac_addr[1] == 0x60;
290}
291
292/**
293 * wl3501_set_to_wla - Move 'size' bytes from PC to card
294 * @dest: Card addressing space
295 * @src: PC addressing space
296 * @size: Bytes to move
297 *
298 * Move 'size' bytes from PC to card. (Shouldn't be interrupted)
299 */
300void wl3501_set_to_wla(struct wl3501_card *this, u16 dest, void *src, int size)
301{
302 /* switch to SRAM Page 0 */
303 wl3501_switch_page(this, (dest & 0x8000) ? WL3501_BSS_SPAGE1 :
304 WL3501_BSS_SPAGE0);
305 /* set LMAL and LMAH */
306 wl3501_outb(dest & 0xff, this->base_addr + WL3501_NIC_LMAL);
307 wl3501_outb(((dest >> 8) & 0x7f), this->base_addr + WL3501_NIC_LMAH);
308
309 /* rep out to Port A */
310 wl3501_outsb(this->base_addr + WL3501_NIC_IODPA, src, size);
311}
312
313/**
314 * wl3501_get_from_wla - Move 'size' bytes from card to PC
315 * @src: Card addressing space
316 * @dest: PC addressing space
317 * @size: Bytes to move
318 *
319 * Move 'size' bytes from card to PC. (Shouldn't be interrupted)
320 */
321void wl3501_get_from_wla(struct wl3501_card *this, u16 src, void *dest,
322 int size)
323{
324 /* switch to SRAM Page 0 */
325 wl3501_switch_page(this, (src & 0x8000) ? WL3501_BSS_SPAGE1 :
326 WL3501_BSS_SPAGE0);
327 /* set LMAL and LMAH */
328 wl3501_outb(src & 0xff, this->base_addr + WL3501_NIC_LMAL);
329 wl3501_outb((src >> 8) & 0x7f, this->base_addr + WL3501_NIC_LMAH);
330
331 /* rep get from Port A */
332 insb(this->base_addr + WL3501_NIC_IODPA, dest, size);
333}
334
335/*
336 * Get/Allocate a free Tx Data Buffer
337 *
338 * *--------------*-----------------*----------------------------------*
339 * | PLCP | MAC Header | DST SRC Data ... |
340 * | (24 bytes) | (30 bytes) | (6) (6) (Ethernet Row Data) |
341 * *--------------*-----------------*----------------------------------*
342 * \ \- IEEE 802.11 -/ \-------------- len --------------/
343 * \-struct wl3501_80211_tx_hdr--/ \-------- Ethernet Frame -------/
344 *
345 * Return = Postion in Card
346 */
347static u16 wl3501_get_tx_buffer(struct wl3501_card *this, u16 len)
348{
349 u16 next, blk_cnt = 0, zero = 0;
350 u16 full_len = sizeof(struct wl3501_80211_tx_hdr) + len;
351 u16 ret = 0;
352
353 if (full_len > this->tx_buffer_cnt * 254)
354 goto out;
355 ret = this->tx_buffer_head;
356 while (full_len) {
357 if (full_len < 254)
358 full_len = 0;
359 else
360 full_len -= 254;
361 wl3501_get_from_wla(this, this->tx_buffer_head, &next,
362 sizeof(next));
363 if (!full_len)
364 wl3501_set_to_wla(this, this->tx_buffer_head, &zero,
365 sizeof(zero));
366 this->tx_buffer_head = next;
367 blk_cnt++;
368 /* if buffer is not enough */
369 if (!next && full_len) {
370 this->tx_buffer_head = ret;
371 ret = 0;
372 goto out;
373 }
374 }
375 this->tx_buffer_cnt -= blk_cnt;
376out:
377 return ret;
378}
379
380/*
381 * Free an allocated Tx Buffer. ptr must be correct position.
382 */
383static void wl3501_free_tx_buffer(struct wl3501_card *this, u16 ptr)
384{
385 /* check if all space is not free */
386 if (!this->tx_buffer_head)
387 this->tx_buffer_head = ptr;
388 else
389 wl3501_set_to_wla(this, this->tx_buffer_tail,
390 &ptr, sizeof(ptr));
391 while (ptr) {
392 u16 next;
393
394 this->tx_buffer_cnt++;
395 wl3501_get_from_wla(this, ptr, &next, sizeof(next));
396 this->tx_buffer_tail = ptr;
397 ptr = next;
398 }
399}
400
401static int wl3501_esbq_req_test(struct wl3501_card *this)
402{
403 u8 tmp;
404
405 wl3501_get_from_wla(this, this->esbq_req_head + 3, &tmp, sizeof(tmp));
406 return tmp & 0x80;
407}
408
409static void wl3501_esbq_req(struct wl3501_card *this, u16 *ptr)
410{
411 u16 tmp = 0;
412
413 wl3501_set_to_wla(this, this->esbq_req_head, ptr, 2);
414 wl3501_set_to_wla(this, this->esbq_req_head + 2, &tmp, sizeof(tmp));
415 this->esbq_req_head += 4;
416 if (this->esbq_req_head >= this->esbq_req_end)
417 this->esbq_req_head = this->esbq_req_start;
418}
419
420static int wl3501_esbq_exec(struct wl3501_card *this, void *sig, int sig_size)
421{
422 int rc = -EIO;
423
424 if (wl3501_esbq_req_test(this)) {
425 u16 ptr = wl3501_get_tx_buffer(this, sig_size);
426 if (ptr) {
427 wl3501_set_to_wla(this, ptr, sig, sig_size);
428 wl3501_esbq_req(this, &ptr);
429 rc = 0;
430 }
431 }
432 return rc;
433}
434
435static int wl3501_get_mib_value(struct wl3501_card *this, u8 index,
436 void *bf, int size)
437{
438 struct wl3501_get_req sig = {
439 .sig_id = WL3501_SIG_GET_REQ,
440 .mib_attrib = index,
441 };
442 unsigned long flags;
443 int rc = -EIO;
444
445 spin_lock_irqsave(&this->lock, flags);
446 if (wl3501_esbq_req_test(this)) {
447 u16 ptr = wl3501_get_tx_buffer(this, sizeof(sig));
448 if (ptr) {
449 wl3501_set_to_wla(this, ptr, &sig, sizeof(sig));
450 wl3501_esbq_req(this, &ptr);
451 this->sig_get_confirm.mib_status = 255;
452 spin_unlock_irqrestore(&this->lock, flags);
453 rc = wait_event_interruptible(this->wait,
454 this->sig_get_confirm.mib_status != 255);
455 if (!rc)
456 memcpy(bf, this->sig_get_confirm.mib_value,
457 size);
458 goto out;
459 }
460 }
461 spin_unlock_irqrestore(&this->lock, flags);
462out:
463 return rc;
464}
465
466static int wl3501_pwr_mgmt(struct wl3501_card *this, int suspend)
467{
468 struct wl3501_pwr_mgmt_req sig = {
469 .sig_id = WL3501_SIG_PWR_MGMT_REQ,
470 .pwr_save = suspend,
471 .wake_up = !suspend,
472 .receive_dtims = 10,
473 };
474 unsigned long flags;
475 int rc = -EIO;
476
477 spin_lock_irqsave(&this->lock, flags);
478 if (wl3501_esbq_req_test(this)) {
479 u16 ptr = wl3501_get_tx_buffer(this, sizeof(sig));
480 if (ptr) {
481 wl3501_set_to_wla(this, ptr, &sig, sizeof(sig));
482 wl3501_esbq_req(this, &ptr);
483 this->sig_pwr_mgmt_confirm.status = 255;
484 spin_unlock_irqrestore(&this->lock, flags);
485 rc = wait_event_interruptible(this->wait,
486 this->sig_pwr_mgmt_confirm.status != 255);
487 printk(KERN_INFO "%s: %s status=%d\n", __FUNCTION__,
488 suspend ? "suspend" : "resume",
489 this->sig_pwr_mgmt_confirm.status);
490 goto out;
491 }
492 }
493 spin_unlock_irqrestore(&this->lock, flags);
494out:
495 return rc;
496}
497
498/**
499 * wl3501_send_pkt - Send a packet.
500 * @this - card
501 *
502 * Send a packet.
503 *
504 * data = Ethernet raw frame. (e.g. data[0] - data[5] is Dest MAC Addr,
505 * data[6] - data[11] is Src MAC Addr)
506 * Ref: IEEE 802.11
507 */
508static int wl3501_send_pkt(struct wl3501_card *this, u8 *data, u16 len)
509{
510 u16 bf, sig_bf, next, tmplen, pktlen;
511 struct wl3501_md_req sig = {
512 .sig_id = WL3501_SIG_MD_REQ,
513 };
514 u8 *pdata = (char *)data;
515 int rc = -EIO;
516
517 if (wl3501_esbq_req_test(this)) {
518 sig_bf = wl3501_get_tx_buffer(this, sizeof(sig));
519 rc = -ENOMEM;
520 if (!sig_bf) /* No free buffer available */
521 goto out;
522 bf = wl3501_get_tx_buffer(this, len + 26 + 24);
523 if (!bf) {
524 /* No free buffer available */
525 wl3501_free_tx_buffer(this, sig_bf);
526 goto out;
527 }
528 rc = 0;
529 memcpy(&sig.daddr[0], pdata, 12);
530 pktlen = len - 12;
531 pdata += 12;
532 sig.data = bf;
533 if (((*pdata) * 256 + (*(pdata + 1))) > 1500) {
534 u8 addr4[ETH_ALEN] = {
535 [0] = 0xAA, [1] = 0xAA, [2] = 0x03, [4] = 0x00,
536 };
537
538 wl3501_set_to_wla(this, bf + 2 +
539 offsetof(struct wl3501_tx_hdr, addr4),
540 addr4, sizeof(addr4));
541 sig.size = pktlen + 24 + 4 + 6;
542 if (pktlen > (254 - sizeof(struct wl3501_tx_hdr))) {
543 tmplen = 254 - sizeof(struct wl3501_tx_hdr);
544 pktlen -= tmplen;
545 } else {
546 tmplen = pktlen;
547 pktlen = 0;
548 }
549 wl3501_set_to_wla(this,
550 bf + 2 + sizeof(struct wl3501_tx_hdr),
551 pdata, tmplen);
552 pdata += tmplen;
553 wl3501_get_from_wla(this, bf, &next, sizeof(next));
554 bf = next;
555 } else {
556 sig.size = pktlen + 24 + 4 - 2;
557 pdata += 2;
558 pktlen -= 2;
559 if (pktlen > (254 - sizeof(struct wl3501_tx_hdr) + 6)) {
560 tmplen = 254 - sizeof(struct wl3501_tx_hdr) + 6;
561 pktlen -= tmplen;
562 } else {
563 tmplen = pktlen;
564 pktlen = 0;
565 }
566 wl3501_set_to_wla(this, bf + 2 +
567 offsetof(struct wl3501_tx_hdr, addr4),
568 pdata, tmplen);
569 pdata += tmplen;
570 wl3501_get_from_wla(this, bf, &next, sizeof(next));
571 bf = next;
572 }
573 while (pktlen > 0) {
574 if (pktlen > 254) {
575 tmplen = 254;
576 pktlen -= 254;
577 } else {
578 tmplen = pktlen;
579 pktlen = 0;
580 }
581 wl3501_set_to_wla(this, bf + 2, pdata, tmplen);
582 pdata += tmplen;
583 wl3501_get_from_wla(this, bf, &next, sizeof(next));
584 bf = next;
585 }
586 wl3501_set_to_wla(this, sig_bf, &sig, sizeof(sig));
587 wl3501_esbq_req(this, &sig_bf);
588 }
589out:
590 return rc;
591}
592
593static int wl3501_mgmt_resync(struct wl3501_card *this)
594{
595 struct wl3501_resync_req sig = {
596 .sig_id = WL3501_SIG_RESYNC_REQ,
597 };
598
599 return wl3501_esbq_exec(this, &sig, sizeof(sig));
600}
601
602static inline int wl3501_fw_bss_type(struct wl3501_card *this)
603{
604 return this->net_type == IW_MODE_INFRA ? WL3501_NET_TYPE_INFRA :
605 WL3501_NET_TYPE_ADHOC;
606}
607
608static inline int wl3501_fw_cap_info(struct wl3501_card *this)
609{
610 return this->net_type == IW_MODE_INFRA ? WL3501_MGMT_CAPABILITY_ESS :
611 WL3501_MGMT_CAPABILITY_IBSS;
612}
613
614static int wl3501_mgmt_scan(struct wl3501_card *this, u16 chan_time)
615{
616 struct wl3501_scan_req sig = {
617 .sig_id = WL3501_SIG_SCAN_REQ,
618 .scan_type = WL3501_SCAN_TYPE_ACTIVE,
619 .probe_delay = 0x10,
620 .min_chan_time = chan_time,
621 .max_chan_time = chan_time,
622 .bss_type = wl3501_fw_bss_type(this),
623 };
624
625 this->bss_cnt = this->join_sta_bss = 0;
626 return wl3501_esbq_exec(this, &sig, sizeof(sig));
627}
628
629static int wl3501_mgmt_join(struct wl3501_card *this, u16 stas)
630{
631 struct wl3501_join_req sig = {
632 .sig_id = WL3501_SIG_JOIN_REQ,
633 .timeout = 10,
634 .ds_pset = {
635 .el = {
636 .id = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
637 .len = 1,
638 },
639 .chan = this->chan,
640 },
641 };
642
643 memcpy(&sig.beacon_period, &this->bss_set[stas].beacon_period, 72);
644 return wl3501_esbq_exec(this, &sig, sizeof(sig));
645}
646
647static int wl3501_mgmt_start(struct wl3501_card *this)
648{
649 struct wl3501_start_req sig = {
650 .sig_id = WL3501_SIG_START_REQ,
651 .beacon_period = 400,
652 .dtim_period = 1,
653 .ds_pset = {
654 .el = {
655 .id = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
656 .len = 1,
657 },
658 .chan = this->chan,
659 },
660 .bss_basic_rset = {
661 .el = {
662 .id = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
663 .len = 2,
664 },
665 .data_rate_labels = {
666 [0] = IW_MGMT_RATE_LABEL_MANDATORY |
667 IW_MGMT_RATE_LABEL_1MBIT,
668 [1] = IW_MGMT_RATE_LABEL_MANDATORY |
669 IW_MGMT_RATE_LABEL_2MBIT,
670 },
671 },
672 .operational_rset = {
673 .el = {
674 .id = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
675 .len = 2,
676 },
677 .data_rate_labels = {
678 [0] = IW_MGMT_RATE_LABEL_MANDATORY |
679 IW_MGMT_RATE_LABEL_1MBIT,
680 [1] = IW_MGMT_RATE_LABEL_MANDATORY |
681 IW_MGMT_RATE_LABEL_2MBIT,
682 },
683 },
684 .ibss_pset = {
685 .el = {
686 .id = IW_MGMT_INFO_ELEMENT_IBSS_PARAMETER_SET,
687 .len = 2,
688 },
689 .atim_window = 10,
690 },
691 .bss_type = wl3501_fw_bss_type(this),
692 .cap_info = wl3501_fw_cap_info(this),
693 };
694
695 iw_copy_mgmt_info_element(&sig.ssid.el, &this->essid.el);
696 iw_copy_mgmt_info_element(&this->keep_essid.el, &this->essid.el);
697 return wl3501_esbq_exec(this, &sig, sizeof(sig));
698}
699
700static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
701{
702 u16 i = 0;
703 int matchflag = 0;
704 struct wl3501_scan_confirm sig;
705
706 dprintk(3, "entry");
707 wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
708 if (sig.status == WL3501_STATUS_SUCCESS) {
709 dprintk(3, "success");
710 if ((this->net_type == IW_MODE_INFRA &&
711 (sig.cap_info & WL3501_MGMT_CAPABILITY_ESS)) ||
712 (this->net_type == IW_MODE_ADHOC &&
713 (sig.cap_info & WL3501_MGMT_CAPABILITY_IBSS)) ||
714 this->net_type == IW_MODE_AUTO) {
715 if (!this->essid.el.len)
716 matchflag = 1;
717 else if (this->essid.el.len == 3 &&
718 !memcmp(this->essid.essid, "ANY", 3))
719 matchflag = 1;
720 else if (this->essid.el.len != sig.ssid.el.len)
721 matchflag = 0;
722 else if (memcmp(this->essid.essid, sig.ssid.essid,
723 this->essid.el.len))
724 matchflag = 0;
725 else
726 matchflag = 1;
727 if (matchflag) {
728 for (i = 0; i < this->bss_cnt; i++) {
729 if (!memcmp(this->bss_set[i].bssid,
730 sig.bssid, ETH_ALEN)) {
731 matchflag = 0;
732 break;
733 }
734 }
735 }
736 if (matchflag && (i < 20)) {
737 memcpy(&this->bss_set[i].beacon_period,
738 &sig.beacon_period, 73);
739 this->bss_cnt++;
740 this->rssi = sig.rssi;
741 }
742 }
743 } else if (sig.status == WL3501_STATUS_TIMEOUT) {
744 dprintk(3, "timeout");
745 this->join_sta_bss = 0;
746 for (i = this->join_sta_bss; i < this->bss_cnt; i++)
747 if (!wl3501_mgmt_join(this, i))
748 break;
749 this->join_sta_bss = i;
750 if (this->join_sta_bss == this->bss_cnt) {
751 if (this->net_type == IW_MODE_INFRA)
752 wl3501_mgmt_scan(this, 100);
753 else {
754 this->adhoc_times++;
755 if (this->adhoc_times > WL3501_MAX_ADHOC_TRIES)
756 wl3501_mgmt_start(this);
757 else
758 wl3501_mgmt_scan(this, 100);
759 }
760 }
761 }
762}
763
764/**
765 * wl3501_block_interrupt - Mask interrupt from SUTRO
766 * @this - card
767 *
768 * Mask interrupt from SUTRO. (i.e. SUTRO cannot interrupt the HOST)
769 * Return: 1 if interrupt is originally enabled
770 */
771static int wl3501_block_interrupt(struct wl3501_card *this)
772{
773 u8 old = inb(this->base_addr + WL3501_NIC_GCR);
774 u8 new = old & (~(WL3501_GCR_ECINT | WL3501_GCR_INT2EC |
775 WL3501_GCR_ENECINT));
776
777 wl3501_outb(new, this->base_addr + WL3501_NIC_GCR);
778 return old & WL3501_GCR_ENECINT;
779}
780
781/**
782 * wl3501_unblock_interrupt - Enable interrupt from SUTRO
783 * @this - card
784 *
785 * Enable interrupt from SUTRO. (i.e. SUTRO can interrupt the HOST)
786 * Return: 1 if interrupt is originally enabled
787 */
788static int wl3501_unblock_interrupt(struct wl3501_card *this)
789{
790 u8 old = inb(this->base_addr + WL3501_NIC_GCR);
791 u8 new = (old & ~(WL3501_GCR_ECINT | WL3501_GCR_INT2EC)) |
792 WL3501_GCR_ENECINT;
793
794 wl3501_outb(new, this->base_addr + WL3501_NIC_GCR);
795 return old & WL3501_GCR_ENECINT;
796}
797
798/**
799 * wl3501_receive - Receive data from Receive Queue.
800 *
801 * Receive data from Receive Queue.
802 *
803 * @this: card
804 * @bf: address of host
805 * @size: size of buffer.
806 */
807static u16 wl3501_receive(struct wl3501_card *this, u8 *bf, u16 size)
808{
809 u16 next_addr, next_addr1;
810 u8 *data = bf + 12;
811
812 size -= 12;
813 wl3501_get_from_wla(this, this->start_seg + 2,
814 &next_addr, sizeof(next_addr));
815 if (size > WL3501_BLKSZ - sizeof(struct wl3501_rx_hdr)) {
816 wl3501_get_from_wla(this,
817 this->start_seg +
818 sizeof(struct wl3501_rx_hdr), data,
819 WL3501_BLKSZ -
820 sizeof(struct wl3501_rx_hdr));
821 size -= WL3501_BLKSZ - sizeof(struct wl3501_rx_hdr);
822 data += WL3501_BLKSZ - sizeof(struct wl3501_rx_hdr);
823 } else {
824 wl3501_get_from_wla(this,
825 this->start_seg +
826 sizeof(struct wl3501_rx_hdr),
827 data, size);
828 size = 0;
829 }
830 while (size > 0) {
831 if (size > WL3501_BLKSZ - 5) {
832 wl3501_get_from_wla(this, next_addr + 5, data,
833 WL3501_BLKSZ - 5);
834 size -= WL3501_BLKSZ - 5;
835 data += WL3501_BLKSZ - 5;
836 wl3501_get_from_wla(this, next_addr + 2, &next_addr1,
837 sizeof(next_addr1));
838 next_addr = next_addr1;
839 } else {
840 wl3501_get_from_wla(this, next_addr + 5, data, size);
841 size = 0;
842 }
843 }
844 return 0;
845}
846
847static void wl3501_esbq_req_free(struct wl3501_card *this)
848{
849 u8 tmp;
850 u16 addr;
851
852 if (this->esbq_req_head == this->esbq_req_tail)
853 goto out;
854 wl3501_get_from_wla(this, this->esbq_req_tail + 3, &tmp, sizeof(tmp));
855 if (!(tmp & 0x80))
856 goto out;
857 wl3501_get_from_wla(this, this->esbq_req_tail, &addr, sizeof(addr));
858 wl3501_free_tx_buffer(this, addr);
859 this->esbq_req_tail += 4;
860 if (this->esbq_req_tail >= this->esbq_req_end)
861 this->esbq_req_tail = this->esbq_req_start;
862out:
863 return;
864}
865
866static int wl3501_esbq_confirm(struct wl3501_card *this)
867{
868 u8 tmp;
869
870 wl3501_get_from_wla(this, this->esbq_confirm + 3, &tmp, sizeof(tmp));
871 return tmp & 0x80;
872}
873
874static void wl3501_online(struct net_device *dev)
875{
876 struct wl3501_card *this = dev->priv;
877
878 printk(KERN_INFO "%s: Wireless LAN online. BSSID: "
879 "%02X %02X %02X %02X %02X %02X\n", dev->name,
880 this->bssid[0], this->bssid[1], this->bssid[2],
881 this->bssid[3], this->bssid[4], this->bssid[5]);
882 netif_wake_queue(dev);
883}
884
885static void wl3501_esbq_confirm_done(struct wl3501_card *this)
886{
887 u8 tmp = 0;
888
889 wl3501_set_to_wla(this, this->esbq_confirm + 3, &tmp, sizeof(tmp));
890 this->esbq_confirm += 4;
891 if (this->esbq_confirm >= this->esbq_confirm_end)
892 this->esbq_confirm = this->esbq_confirm_start;
893}
894
895static int wl3501_mgmt_auth(struct wl3501_card *this)
896{
897 struct wl3501_auth_req sig = {
898 .sig_id = WL3501_SIG_AUTH_REQ,
899 .type = WL3501_SYS_TYPE_OPEN,
900 .timeout = 1000,
901 };
902
903 dprintk(3, "entry");
904 memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
905 return wl3501_esbq_exec(this, &sig, sizeof(sig));
906}
907
908static int wl3501_mgmt_association(struct wl3501_card *this)
909{
910 struct wl3501_assoc_req sig = {
911 .sig_id = WL3501_SIG_ASSOC_REQ,
912 .timeout = 1000,
913 .listen_interval = 5,
914 .cap_info = this->cap_info,
915 };
916
917 dprintk(3, "entry");
918 memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
919 return wl3501_esbq_exec(this, &sig, sizeof(sig));
920}
921
922static void wl3501_mgmt_join_confirm(struct net_device *dev, u16 addr)
923{
924 struct wl3501_card *this = dev->priv;
925 struct wl3501_join_confirm sig;
926
927 dprintk(3, "entry");
928 wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
929 if (sig.status == WL3501_STATUS_SUCCESS) {
930 if (this->net_type == IW_MODE_INFRA) {
931 if (this->join_sta_bss < this->bss_cnt) {
932 const int i = this->join_sta_bss;
933 memcpy(this->bssid,
934 this->bss_set[i].bssid, ETH_ALEN);
935 this->chan = this->bss_set[i].ds_pset.chan;
936 iw_copy_mgmt_info_element(&this->keep_essid.el,
937 &this->bss_set[i].ssid.el);
938 wl3501_mgmt_auth(this);
939 }
940 } else {
941 const int i = this->join_sta_bss;
942
943 memcpy(&this->bssid, &this->bss_set[i].bssid, ETH_ALEN);
944 this->chan = this->bss_set[i].ds_pset.chan;
945 iw_copy_mgmt_info_element(&this->keep_essid.el,
946 &this->bss_set[i].ssid.el);
947 wl3501_online(dev);
948 }
949 } else {
950 int i;
951 this->join_sta_bss++;
952 for (i = this->join_sta_bss; i < this->bss_cnt; i++)
953 if (!wl3501_mgmt_join(this, i))
954 break;
955 this->join_sta_bss = i;
956 if (this->join_sta_bss == this->bss_cnt) {
957 if (this->net_type == IW_MODE_INFRA)
958 wl3501_mgmt_scan(this, 100);
959 else {
960 this->adhoc_times++;
961 if (this->adhoc_times > WL3501_MAX_ADHOC_TRIES)
962 wl3501_mgmt_start(this);
963 else
964 wl3501_mgmt_scan(this, 100);
965 }
966 }
967 }
968}
969
970static inline void wl3501_alarm_interrupt(struct net_device *dev,
971 struct wl3501_card *this)
972{
973 if (this->net_type == IW_MODE_INFRA) {
974 printk(KERN_INFO "Wireless LAN offline\n");
975 netif_stop_queue(dev);
976 wl3501_mgmt_resync(this);
977 }
978}
979
980static inline void wl3501_md_confirm_interrupt(struct net_device *dev,
981 struct wl3501_card *this,
982 u16 addr)
983{
984 struct wl3501_md_confirm sig;
985
986 dprintk(3, "entry");
987 wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
988 wl3501_free_tx_buffer(this, sig.data);
989 if (netif_queue_stopped(dev))
990 netif_wake_queue(dev);
991}
992
993static inline void wl3501_md_ind_interrupt(struct net_device *dev,
994 struct wl3501_card *this, u16 addr)
995{
996 struct wl3501_md_ind sig;
997 struct sk_buff *skb;
998 u8 rssi, addr4[ETH_ALEN];
999 u16 pkt_len;
1000
1001 wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
1002 this->start_seg = sig.data;
1003 wl3501_get_from_wla(this,
1004 sig.data + offsetof(struct wl3501_rx_hdr, rssi),
1005 &rssi, sizeof(rssi));
1006 this->rssi = rssi <= 63 ? (rssi * 100) / 64 : 255;
1007
1008 wl3501_get_from_wla(this,
1009 sig.data +
1010 offsetof(struct wl3501_rx_hdr, addr4),
1011 &addr4, sizeof(addr4));
1012 if (!(addr4[0] == 0xAA && addr4[1] == 0xAA &&
1013 addr4[2] == 0x03 && addr4[4] == 0x00)) {
1014 printk(KERN_INFO "Insupported packet type!\n");
1015 return;
1016 }
1017 pkt_len = sig.size + 12 - 24 - 4 - 6;
1018
1019 skb = dev_alloc_skb(pkt_len + 5);
1020
1021 if (!skb) {
1022 printk(KERN_WARNING "%s: Can't alloc a sk_buff of size %d.\n",
1023 dev->name, pkt_len);
1024 this->stats.rx_dropped++;
1025 } else {
1026 skb->dev = dev;
1027 skb_reserve(skb, 2); /* IP headers on 16 bytes boundaries */
1028 eth_copy_and_sum(skb, (unsigned char *)&sig.daddr, 12, 0);
1029 wl3501_receive(this, skb->data, pkt_len);
1030 skb_put(skb, pkt_len);
1031 skb->protocol = eth_type_trans(skb, dev);
1032 dev->last_rx = jiffies;
1033 this->stats.rx_packets++;
1034 this->stats.rx_bytes += skb->len;
1035 netif_rx(skb);
1036 }
1037}
1038
1039static inline void wl3501_get_confirm_interrupt(struct wl3501_card *this,
1040 u16 addr, void *sig, int size)
1041{
1042 dprintk(3, "entry");
1043 wl3501_get_from_wla(this, addr, &this->sig_get_confirm,
1044 sizeof(this->sig_get_confirm));
1045 wake_up(&this->wait);
1046}
1047
1048static inline void wl3501_start_confirm_interrupt(struct net_device *dev,
1049 struct wl3501_card *this,
1050 u16 addr)
1051{
1052 struct wl3501_start_confirm sig;
1053
1054 dprintk(3, "entry");
1055 wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
1056 if (sig.status == WL3501_STATUS_SUCCESS)
1057 netif_wake_queue(dev);
1058}
1059
1060static inline void wl3501_assoc_confirm_interrupt(struct net_device *dev,
1061 u16 addr)
1062{
1063 struct wl3501_card *this = dev->priv;
1064 struct wl3501_assoc_confirm sig;
1065
1066 dprintk(3, "entry");
1067 wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
1068
1069 if (sig.status == WL3501_STATUS_SUCCESS)
1070 wl3501_online(dev);
1071}
1072
1073static inline void wl3501_auth_confirm_interrupt(struct wl3501_card *this,
1074 u16 addr)
1075{
1076 struct wl3501_auth_confirm sig;
1077
1078 dprintk(3, "entry");
1079 wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
1080
1081 if (sig.status == WL3501_STATUS_SUCCESS)
1082 wl3501_mgmt_association(this);
1083 else
1084 wl3501_mgmt_resync(this);
1085}
1086
1087static inline void wl3501_rx_interrupt(struct net_device *dev)
1088{
1089 int morepkts;
1090 u16 addr;
1091 u8 sig_id;
1092 struct wl3501_card *this = dev->priv;
1093
1094 dprintk(3, "entry");
1095loop:
1096 morepkts = 0;
1097 if (!wl3501_esbq_confirm(this))
1098 goto free;
1099 wl3501_get_from_wla(this, this->esbq_confirm, &addr, sizeof(addr));
1100 wl3501_get_from_wla(this, addr + 2, &sig_id, sizeof(sig_id));
1101
1102 switch (sig_id) {
1103 case WL3501_SIG_DEAUTH_IND:
1104 case WL3501_SIG_DISASSOC_IND:
1105 case WL3501_SIG_ALARM:
1106 wl3501_alarm_interrupt(dev, this);
1107 break;
1108 case WL3501_SIG_MD_CONFIRM:
1109 wl3501_md_confirm_interrupt(dev, this, addr);
1110 break;
1111 case WL3501_SIG_MD_IND:
1112 wl3501_md_ind_interrupt(dev, this, addr);
1113 break;
1114 case WL3501_SIG_GET_CONFIRM:
1115 wl3501_get_confirm_interrupt(this, addr,
1116 &this->sig_get_confirm,
1117 sizeof(this->sig_get_confirm));
1118 break;
1119 case WL3501_SIG_PWR_MGMT_CONFIRM:
1120 wl3501_get_confirm_interrupt(this, addr,
1121 &this->sig_pwr_mgmt_confirm,
1122 sizeof(this->sig_pwr_mgmt_confirm));
1123 break;
1124 case WL3501_SIG_START_CONFIRM:
1125 wl3501_start_confirm_interrupt(dev, this, addr);
1126 break;
1127 case WL3501_SIG_SCAN_CONFIRM:
1128 wl3501_mgmt_scan_confirm(this, addr);
1129 break;
1130 case WL3501_SIG_JOIN_CONFIRM:
1131 wl3501_mgmt_join_confirm(dev, addr);
1132 break;
1133 case WL3501_SIG_ASSOC_CONFIRM:
1134 wl3501_assoc_confirm_interrupt(dev, addr);
1135 break;
1136 case WL3501_SIG_AUTH_CONFIRM:
1137 wl3501_auth_confirm_interrupt(this, addr);
1138 break;
1139 case WL3501_SIG_RESYNC_CONFIRM:
1140 wl3501_mgmt_resync(this); /* FIXME: should be resync_confirm */
1141 break;
1142 }
1143 wl3501_esbq_confirm_done(this);
1144 morepkts = 1;
1145 /* free request if necessary */
1146free:
1147 wl3501_esbq_req_free(this);
1148 if (morepkts)
1149 goto loop;
1150}
1151
1152static inline void wl3501_ack_interrupt(struct wl3501_card *this)
1153{
1154 wl3501_outb(WL3501_GCR_ECINT, this->base_addr + WL3501_NIC_GCR);
1155}
1156
1157/**
1158 * wl3501_interrupt - Hardware interrupt from card.
1159 * @irq - Interrupt number
1160 * @dev_id - net_device
1161 * @regs - registers
1162 *
1163 * We must acknowledge the interrupt as soon as possible, and block the
1164 * interrupt from the same card immediately to prevent re-entry.
1165 *
1166 * Before accessing the Control_Status_Block, we must lock SUTRO first.
1167 * On the other hand, to prevent SUTRO from malfunctioning, we must
1168 * unlock the SUTRO as soon as possible.
1169 */
1170static irqreturn_t wl3501_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1171{
1172 struct net_device *dev = (struct net_device *)dev_id;
1173 struct wl3501_card *this;
1174 int handled = 1;
1175
1176 if (!dev)
1177 goto unknown;
1178 this = dev->priv;
1179 spin_lock(&this->lock);
1180 wl3501_ack_interrupt(this);
1181 wl3501_block_interrupt(this);
1182 wl3501_rx_interrupt(dev);
1183 wl3501_unblock_interrupt(this);
1184 spin_unlock(&this->lock);
1185out:
1186 return IRQ_RETVAL(handled);
1187unknown:
1188 handled = 0;
1189 printk(KERN_ERR "%s: irq %d for unknown device.\n", __FUNCTION__, irq);
1190 goto out;
1191}
1192
1193static int wl3501_reset_board(struct wl3501_card *this)
1194{
1195 u8 tmp = 0;
1196 int i, rc = 0;
1197
1198 /* Coreset */
1199 wl3501_outb_p(WL3501_GCR_CORESET, this->base_addr + WL3501_NIC_GCR);
1200 wl3501_outb_p(0, this->base_addr + WL3501_NIC_GCR);
1201 wl3501_outb_p(WL3501_GCR_CORESET, this->base_addr + WL3501_NIC_GCR);
1202
1203 /* Reset SRAM 0x480 to zero */
1204 wl3501_set_to_wla(this, 0x480, &tmp, sizeof(tmp));
1205
1206 /* Start up */
1207 wl3501_outb_p(0, this->base_addr + WL3501_NIC_GCR);
1208
1209 WL3501_NOPLOOP(1024 * 50);
1210
1211 wl3501_unblock_interrupt(this); /* acme: was commented */
1212
1213 /* Polling Self_Test_Status */
1214 for (i = 0; i < 10000; i++) {
1215 wl3501_get_from_wla(this, 0x480, &tmp, sizeof(tmp));
1216
1217 if (tmp == 'W') {
1218 /* firmware complete all test successfully */
1219 tmp = 'A';
1220 wl3501_set_to_wla(this, 0x480, &tmp, sizeof(tmp));
1221 goto out;
1222 }
1223 WL3501_NOPLOOP(10);
1224 }
1225 printk(KERN_WARNING "%s: failed to reset the board!\n", __FUNCTION__);
1226 rc = -ENODEV;
1227out:
1228 return rc;
1229}
1230
1231static int wl3501_init_firmware(struct wl3501_card *this)
1232{
1233 u16 ptr, next;
1234 int rc = wl3501_reset_board(this);
1235
1236 if (rc)
1237 goto fail;
1238 this->card_name[0] = '\0';
1239 wl3501_get_from_wla(this, 0x1a00,
1240 this->card_name, sizeof(this->card_name));
1241 this->card_name[sizeof(this->card_name) - 1] = '\0';
1242 this->firmware_date[0] = '\0';
1243 wl3501_get_from_wla(this, 0x1a40,
1244 this->firmware_date, sizeof(this->firmware_date));
1245 this->firmware_date[sizeof(this->firmware_date) - 1] = '\0';
1246 /* Switch to SRAM Page 0 */
1247 wl3501_switch_page(this, WL3501_BSS_SPAGE0);
1248 /* Read parameter from card */
1249 wl3501_get_from_wla(this, 0x482, &this->esbq_req_start, 2);
1250 wl3501_get_from_wla(this, 0x486, &this->esbq_req_end, 2);
1251 wl3501_get_from_wla(this, 0x488, &this->esbq_confirm_start, 2);
1252 wl3501_get_from_wla(this, 0x48c, &this->esbq_confirm_end, 2);
1253 wl3501_get_from_wla(this, 0x48e, &this->tx_buffer_head, 2);
1254 wl3501_get_from_wla(this, 0x492, &this->tx_buffer_size, 2);
1255 this->esbq_req_tail = this->esbq_req_head = this->esbq_req_start;
1256 this->esbq_req_end += this->esbq_req_start;
1257 this->esbq_confirm = this->esbq_confirm_start;
1258 this->esbq_confirm_end += this->esbq_confirm_start;
1259 /* Initial Tx Buffer */
1260 this->tx_buffer_cnt = 1;
1261 ptr = this->tx_buffer_head;
1262 next = ptr + WL3501_BLKSZ;
1263 while ((next - this->tx_buffer_head) < this->tx_buffer_size) {
1264 this->tx_buffer_cnt++;
1265 wl3501_set_to_wla(this, ptr, &next, sizeof(next));
1266 ptr = next;
1267 next = ptr + WL3501_BLKSZ;
1268 }
1269 rc = 0;
1270 next = 0;
1271 wl3501_set_to_wla(this, ptr, &next, sizeof(next));
1272 this->tx_buffer_tail = ptr;
1273out:
1274 return rc;
1275fail:
1276 printk(KERN_WARNING "%s: failed!\n", __FUNCTION__);
1277 goto out;
1278}
1279
1280static int wl3501_close(struct net_device *dev)
1281{
1282 struct wl3501_card *this = dev->priv;
1283 int rc = -ENODEV;
1284 unsigned long flags;
1285 dev_link_t *link;
1286
1287 spin_lock_irqsave(&this->lock, flags);
1288 /* Check if the device is in wl3501_dev_list */
1289 for (link = wl3501_dev_list; link; link = link->next)
1290 if (link->priv == dev)
1291 break;
1292 if (!link)
1293 goto out;
1294 link->open--;
1295
1296 /* Stop wl3501_hard_start_xmit() from now on */
1297 netif_stop_queue(dev);
1298 wl3501_ack_interrupt(this);
1299
1300 /* Mask interrupts from the SUTRO */
1301 wl3501_block_interrupt(this);
1302
1303 rc = 0;
1304 printk(KERN_INFO "%s: WL3501 closed\n", dev->name);
1305out:
1306 spin_unlock_irqrestore(&this->lock, flags);
1307 return rc;
1308}
1309
1310/**
1311 * wl3501_reset - Reset the SUTRO.
1312 * @dev - network device
1313 *
1314 * It is almost the same as wl3501_open(). In fact, we may just wl3501_close()
1315 * and wl3501_open() again, but I wouldn't like to free_irq() when the driver
1316 * is running. It seems to be dangerous.
1317 */
1318static int wl3501_reset(struct net_device *dev)
1319{
1320 struct wl3501_card *this = dev->priv;
1321 int rc = -ENODEV;
1322
1323 wl3501_block_interrupt(this);
1324
1325 if (wl3501_init_firmware(this)) {
1326 printk(KERN_WARNING "%s: Can't initialize Firmware!\n",
1327 dev->name);
1328 /* Free IRQ, and mark IRQ as unused */
1329 free_irq(dev->irq, dev);
1330 goto out;
1331 }
1332
1333 /*
1334 * Queue has to be started only when the Card is Started
1335 */
1336 netif_stop_queue(dev);
1337 this->adhoc_times = 0;
1338 wl3501_ack_interrupt(this);
1339 wl3501_unblock_interrupt(this);
1340 wl3501_mgmt_scan(this, 100);
1341 dprintk(1, "%s: device reset", dev->name);
1342 rc = 0;
1343out:
1344 return rc;
1345}
1346
1347static void wl3501_tx_timeout(struct net_device *dev)
1348{
1349 struct wl3501_card *this = dev->priv;
1350 struct net_device_stats *stats = &this->stats;
1351 unsigned long flags;
1352 int rc;
1353
1354 stats->tx_errors++;
1355 spin_lock_irqsave(&this->lock, flags);
1356 rc = wl3501_reset(dev);
1357 spin_unlock_irqrestore(&this->lock, flags);
1358 if (rc)
1359 printk(KERN_ERR "%s: Error %d resetting card on Tx timeout!\n",
1360 dev->name, rc);
1361 else {
1362 dev->trans_start = jiffies;
1363 netif_wake_queue(dev);
1364 }
1365}
1366
1367/*
1368 * Return : 0 - OK
1369 * 1 - Could not transmit (dev_queue_xmit will queue it)
1370 * and try to sent it later
1371 */
1372static int wl3501_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
1373{
1374 int enabled, rc;
1375 struct wl3501_card *this = dev->priv;
1376 unsigned long flags;
1377
1378 spin_lock_irqsave(&this->lock, flags);
1379 enabled = wl3501_block_interrupt(this);
1380 dev->trans_start = jiffies;
1381 rc = wl3501_send_pkt(this, skb->data, skb->len);
1382 if (enabled)
1383 wl3501_unblock_interrupt(this);
1384 if (rc) {
1385 ++this->stats.tx_dropped;
1386 netif_stop_queue(dev);
1387 } else {
1388 ++this->stats.tx_packets;
1389 this->stats.tx_bytes += skb->len;
1390 kfree_skb(skb);
1391
1392 if (this->tx_buffer_cnt < 2)
1393 netif_stop_queue(dev);
1394 }
1395 spin_unlock_irqrestore(&this->lock, flags);
1396 return rc;
1397}
1398
1399static int wl3501_open(struct net_device *dev)
1400{
1401 int rc = -ENODEV;
1402 struct wl3501_card *this = dev->priv;
1403 unsigned long flags;
1404 dev_link_t *link;
1405
1406 spin_lock_irqsave(&this->lock, flags);
1407 /* Check if the device is in wl3501_dev_list */
1408 for (link = wl3501_dev_list; link; link = link->next)
1409 if (link->priv == dev)
1410 break;
1411 if (!DEV_OK(link))
1412 goto out;
1413 netif_device_attach(dev);
1414 link->open++;
1415
1416 /* Initial WL3501 firmware */
1417 dprintk(1, "%s: Initialize WL3501 firmware...", dev->name);
1418 if (wl3501_init_firmware(this))
1419 goto fail;
1420 /* Initial device variables */
1421 this->adhoc_times = 0;
1422 /* Acknowledge Interrupt, for cleaning last state */
1423 wl3501_ack_interrupt(this);
1424
1425 /* Enable interrupt from card after all */
1426 wl3501_unblock_interrupt(this);
1427 wl3501_mgmt_scan(this, 100);
1428 rc = 0;
1429 dprintk(1, "%s: WL3501 opened", dev->name);
1430 printk(KERN_INFO "%s: Card Name: %s\n"
1431 "%s: Firmware Date: %s\n",
1432 dev->name, this->card_name,
1433 dev->name, this->firmware_date);
1434out:
1435 spin_unlock_irqrestore(&this->lock, flags);
1436 return rc;
1437fail:
1438 printk(KERN_WARNING "%s: Can't initialize firmware!\n", dev->name);
1439 goto out;
1440}
1441
1442struct net_device_stats *wl3501_get_stats(struct net_device *dev)
1443{
1444 struct wl3501_card *this = dev->priv;
1445
1446 return &this->stats;
1447}
1448
1449struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev)
1450{
1451 struct wl3501_card *this = dev->priv;
1452 struct iw_statistics *wstats = &this->wstats;
1453 u32 value; /* size checked: it is u32 */
1454
1455 memset(wstats, 0, sizeof(*wstats));
1456 wstats->status = netif_running(dev);
1457 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_WEP_ICV_ERROR_COUNT,
1458 &value, sizeof(value)))
1459 wstats->discard.code += value;
1460 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_WEP_UNDECRYPTABLE_COUNT,
1461 &value, sizeof(value)))
1462 wstats->discard.code += value;
1463 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_WEP_EXCLUDED_COUNT,
1464 &value, sizeof(value)))
1465 wstats->discard.code += value;
1466 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_RETRY_COUNT,
1467 &value, sizeof(value)))
1468 wstats->discard.retries = value;
1469 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_FAILED_COUNT,
1470 &value, sizeof(value)))
1471 wstats->discard.misc += value;
1472 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_RTS_FAILURE_COUNT,
1473 &value, sizeof(value)))
1474 wstats->discard.misc += value;
1475 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_ACK_FAILURE_COUNT,
1476 &value, sizeof(value)))
1477 wstats->discard.misc += value;
1478 if (!wl3501_get_mib_value(this, WL3501_MIB_ATTR_FRAME_DUPLICATE_COUNT,
1479 &value, sizeof(value)))
1480 wstats->discard.misc += value;
1481 return wstats;
1482}
1483
1484static void wl3501_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
1485{
1486 strlcpy(info->driver, wl3501_dev_info, sizeof(info->driver));
1487}
1488
1489static struct ethtool_ops ops = {
1490 .get_drvinfo = wl3501_get_drvinfo
1491};
1492
1493/**
1494 * wl3501_detach - deletes a driver "instance"
1495 * @link - FILL_IN
1496 *
1497 * This deletes a driver "instance". The device is de-registered with Card
1498 * Services. If it has been released, all local data structures are freed.
1499 * Otherwise, the structures will be freed when the device is released.
1500 */
1501static void wl3501_detach(dev_link_t *link)
1502{
1503 dev_link_t **linkp;
1504
1505 /* Locate device structure */
1506 for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next)
1507 if (*linkp == link)
1508 break;
1509 if (!*linkp)
1510 goto out;
1511
1512 /* If the device is currently configured and active, we won't actually
1513 * delete it yet. Instead, it is marked so that when the release()
1514 * function is called, that will trigger a proper detach(). */
1515
1516 if (link->state & DEV_CONFIG) {
1517#ifdef PCMCIA_DEBUG
1518 printk(KERN_DEBUG "wl3501_cs: detach postponed, '%s' "
1519 "still locked\n", link->dev->dev_name);
1520#endif
1521 goto out;
1522 }
1523
1524 /* Break the link with Card Services */
1525 if (link->handle)
1526 pcmcia_deregister_client(link->handle);
1527
1528 /* Unlink device structure, free pieces */
1529 *linkp = link->next;
1530
1531 if (link->priv)
1532 free_netdev(link->priv);
1533 kfree(link);
1534out:
1535 return;
1536}
1537
1538static int wl3501_get_name(struct net_device *dev, struct iw_request_info *info,
1539 union iwreq_data *wrqu, char *extra)
1540{
1541 strlcpy(wrqu->name, "IEEE 802.11-DS", sizeof(wrqu->name));
1542 return 0;
1543}
1544
1545static int wl3501_set_freq(struct net_device *dev, struct iw_request_info *info,
1546 union iwreq_data *wrqu, char *extra)
1547{
1548 struct wl3501_card *this = dev->priv;
1549 int channel = wrqu->freq.m;
1550 int rc = -EINVAL;
1551
1552 if (iw_valid_channel(this->reg_domain, channel)) {
1553 this->chan = channel;
1554 rc = wl3501_reset(dev);
1555 }
1556 return rc;
1557}
1558
1559static int wl3501_get_freq(struct net_device *dev, struct iw_request_info *info,
1560 union iwreq_data *wrqu, char *extra)
1561{
1562 struct wl3501_card *this = dev->priv;
1563
1564 wrqu->freq.m = wl3501_chan2freq[this->chan - 1] * 100000;
1565 wrqu->freq.e = 1;
1566 return 0;
1567}
1568
1569static int wl3501_set_mode(struct net_device *dev, struct iw_request_info *info,
1570 union iwreq_data *wrqu, char *extra)
1571{
1572 int rc = -EINVAL;
1573
1574 if (wrqu->mode == IW_MODE_INFRA ||
1575 wrqu->mode == IW_MODE_ADHOC ||
1576 wrqu->mode == IW_MODE_AUTO) {
1577 struct wl3501_card *this = dev->priv;
1578
1579 this->net_type = wrqu->mode;
1580 rc = wl3501_reset(dev);
1581 }
1582 return rc;
1583}
1584
1585static int wl3501_get_mode(struct net_device *dev, struct iw_request_info *info,
1586 union iwreq_data *wrqu, char *extra)
1587{
1588 struct wl3501_card *this = dev->priv;
1589
1590 wrqu->mode = this->net_type;
1591 return 0;
1592}
1593
1594static int wl3501_get_sens(struct net_device *dev, struct iw_request_info *info,
1595 union iwreq_data *wrqu, char *extra)
1596{
1597 struct wl3501_card *this = dev->priv;
1598
1599 wrqu->sens.value = this->rssi;
1600 wrqu->sens.disabled = !wrqu->sens.value;
1601 wrqu->sens.fixed = 1;
1602 return 0;
1603}
1604
1605static int wl3501_get_range(struct net_device *dev,
1606 struct iw_request_info *info,
1607 union iwreq_data *wrqu, char *extra)
1608{
1609 struct iw_range *range = (struct iw_range *)extra;
1610
1611 /* Set the length (very important for backward compatibility) */
1612 wrqu->data.length = sizeof(*range);
1613
1614 /* Set all the info we don't care or don't know about to zero */
1615 memset(range, 0, sizeof(*range));
1616
1617 /* Set the Wireless Extension versions */
1618 range->we_version_compiled = WIRELESS_EXT;
1619 range->we_version_source = 1;
1620 range->throughput = 2 * 1000 * 1000; /* ~2 Mb/s */
1621 /* FIXME: study the code to fill in more fields... */
1622 return 0;
1623}
1624
1625static int wl3501_set_wap(struct net_device *dev, struct iw_request_info *info,
1626 union iwreq_data *wrqu, char *extra)
1627{
1628 struct wl3501_card *this = dev->priv;
1629 static const u8 bcast[ETH_ALEN] = { 255, 255, 255, 255, 255, 255 };
1630 int rc = -EINVAL;
1631
1632 /* FIXME: we support other ARPHRDs...*/
1633 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
1634 goto out;
1635 if (!memcmp(bcast, wrqu->ap_addr.sa_data, ETH_ALEN)) {
1636 /* FIXME: rescan? */
1637 } else
1638 memcpy(this->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
1639 /* FIXME: rescan? deassoc & scan? */
1640 rc = 0;
1641out:
1642 return rc;
1643}
1644
1645static int wl3501_get_wap(struct net_device *dev, struct iw_request_info *info,
1646 union iwreq_data *wrqu, char *extra)
1647{
1648 struct wl3501_card *this = dev->priv;
1649
1650 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1651 memcpy(wrqu->ap_addr.sa_data, this->bssid, ETH_ALEN);
1652 return 0;
1653}
1654
1655static int wl3501_set_scan(struct net_device *dev, struct iw_request_info *info,
1656 union iwreq_data *wrqu, char *extra)
1657{
1658 /*
1659 * FIXME: trigger scanning with a reset, yes, I'm lazy
1660 */
1661 return wl3501_reset(dev);
1662}
1663
1664static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
1665 union iwreq_data *wrqu, char *extra)
1666{
1667 struct wl3501_card *this = dev->priv;
1668 int i;
1669 char *current_ev = extra;
1670 struct iw_event iwe;
1671
1672 for (i = 0; i < this->bss_cnt; ++i) {
1673 iwe.cmd = SIOCGIWAP;
1674 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1675 memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN);
1676 current_ev = iwe_stream_add_event(current_ev,
1677 extra + IW_SCAN_MAX_DATA,
1678 &iwe, IW_EV_ADDR_LEN);
1679 iwe.cmd = SIOCGIWESSID;
1680 iwe.u.data.flags = 1;
1681 iwe.u.data.length = this->bss_set[i].ssid.el.len;
1682 current_ev = iwe_stream_add_point(current_ev,
1683 extra + IW_SCAN_MAX_DATA,
1684 &iwe,
1685 this->bss_set[i].ssid.essid);
1686 iwe.cmd = SIOCGIWMODE;
1687 iwe.u.mode = this->bss_set[i].bss_type;
1688 current_ev = iwe_stream_add_event(current_ev,
1689 extra + IW_SCAN_MAX_DATA,
1690 &iwe, IW_EV_UINT_LEN);
1691 iwe.cmd = SIOCGIWFREQ;
1692 iwe.u.freq.m = this->bss_set[i].ds_pset.chan;
1693 iwe.u.freq.e = 0;
1694 current_ev = iwe_stream_add_event(current_ev,
1695 extra + IW_SCAN_MAX_DATA,
1696 &iwe, IW_EV_FREQ_LEN);
1697 iwe.cmd = SIOCGIWENCODE;
1698 if (this->bss_set[i].cap_info & WL3501_MGMT_CAPABILITY_PRIVACY)
1699 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1700 else
1701 iwe.u.data.flags = IW_ENCODE_DISABLED;
1702 iwe.u.data.length = 0;
1703 current_ev = iwe_stream_add_point(current_ev,
1704 extra + IW_SCAN_MAX_DATA,
1705 &iwe, NULL);
1706 }
1707 /* Length of data */
1708 wrqu->data.length = (current_ev - extra);
1709 wrqu->data.flags = 0; /* FIXME: set properly these flags */
1710 return 0;
1711}
1712
1713static int wl3501_set_essid(struct net_device *dev,
1714 struct iw_request_info *info,
1715 union iwreq_data *wrqu, char *extra)
1716{
1717 struct wl3501_card *this = dev->priv;
1718
1719 if (wrqu->data.flags) {
1720 iw_set_mgmt_info_element(IW_MGMT_INFO_ELEMENT_SSID,
1721 &this->essid.el,
1722 extra, wrqu->data.length);
1723 } else { /* We accept any ESSID */
1724 iw_set_mgmt_info_element(IW_MGMT_INFO_ELEMENT_SSID,
1725 &this->essid.el, "ANY", 3);
1726 }
1727 return wl3501_reset(dev);
1728}
1729
1730static int wl3501_get_essid(struct net_device *dev,
1731 struct iw_request_info *info,
1732 union iwreq_data *wrqu, char *extra)
1733{
1734 struct wl3501_card *this = dev->priv;
1735 unsigned long flags;
1736
1737 spin_lock_irqsave(&this->lock, flags);
1738 wrqu->essid.flags = 1;
1739 wrqu->essid.length = this->essid.el.len;
1740 memcpy(extra, this->essid.essid, this->essid.el.len);
1741 spin_unlock_irqrestore(&this->lock, flags);
1742 return 0;
1743}
1744
1745static int wl3501_set_nick(struct net_device *dev, struct iw_request_info *info,
1746 union iwreq_data *wrqu, char *extra)
1747{
1748 struct wl3501_card *this = dev->priv;
1749
1750 if (wrqu->data.length > sizeof(this->nick))
1751 return -E2BIG;
1752 strlcpy(this->nick, extra, wrqu->data.length);
1753 return 0;
1754}
1755
1756static int wl3501_get_nick(struct net_device *dev, struct iw_request_info *info,
1757 union iwreq_data *wrqu, char *extra)
1758{
1759 struct wl3501_card *this = dev->priv;
1760
1761 strlcpy(extra, this->nick, 32);
1762 wrqu->data.length = strlen(extra);
1763 return 0;
1764}
1765
1766static int wl3501_get_rate(struct net_device *dev, struct iw_request_info *info,
1767 union iwreq_data *wrqu, char *extra)
1768{
1769 /*
1770 * FIXME: have to see from where to get this info, perhaps this card
1771 * works at 1 Mbit/s too... for now leave at 2 Mbit/s that is the most
1772 * common with the Planet Access Points. -acme
1773 */
1774 wrqu->bitrate.value = 2000000;
1775 wrqu->bitrate.fixed = 1;
1776 return 0;
1777}
1778
1779static int wl3501_get_rts_threshold(struct net_device *dev,
1780 struct iw_request_info *info,
1781 union iwreq_data *wrqu, char *extra)
1782{
1783 u16 threshold; /* size checked: it is u16 */
1784 struct wl3501_card *this = dev->priv;
1785 int rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_RTS_THRESHOLD,
1786 &threshold, sizeof(threshold));
1787 if (!rc) {
1788 wrqu->rts.value = threshold;
1789 wrqu->rts.disabled = threshold >= 2347;
1790 wrqu->rts.fixed = 1;
1791 }
1792 return rc;
1793}
1794
1795static int wl3501_get_frag_threshold(struct net_device *dev,
1796 struct iw_request_info *info,
1797 union iwreq_data *wrqu, char *extra)
1798{
1799 u16 threshold; /* size checked: it is u16 */
1800 struct wl3501_card *this = dev->priv;
1801 int rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_FRAG_THRESHOLD,
1802 &threshold, sizeof(threshold));
1803 if (!rc) {
1804 wrqu->frag.value = threshold;
1805 wrqu->frag.disabled = threshold >= 2346;
1806 wrqu->frag.fixed = 1;
1807 }
1808 return rc;
1809}
1810
1811static int wl3501_get_txpow(struct net_device *dev,
1812 struct iw_request_info *info,
1813 union iwreq_data *wrqu, char *extra)
1814{
1815 u16 txpow;
1816 struct wl3501_card *this = dev->priv;
1817 int rc = wl3501_get_mib_value(this,
1818 WL3501_MIB_ATTR_CURRENT_TX_PWR_LEVEL,
1819 &txpow, sizeof(txpow));
1820 if (!rc) {
1821 wrqu->txpower.value = txpow;
1822 wrqu->txpower.disabled = 0;
1823 /*
1824 * From the MIB values I think this can be configurable,
1825 * as it lists several tx power levels -acme
1826 */
1827 wrqu->txpower.fixed = 0;
1828 wrqu->txpower.flags = IW_TXPOW_MWATT;
1829 }
1830 return rc;
1831}
1832
1833static int wl3501_get_retry(struct net_device *dev,
1834 struct iw_request_info *info,
1835 union iwreq_data *wrqu, char *extra)
1836{
1837 u8 retry; /* size checked: it is u8 */
1838 struct wl3501_card *this = dev->priv;
1839 int rc = wl3501_get_mib_value(this,
1840 WL3501_MIB_ATTR_LONG_RETRY_LIMIT,
1841 &retry, sizeof(retry));
1842 if (rc)
1843 goto out;
1844 if (wrqu->retry.flags & IW_RETRY_MAX) {
1845 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
1846 goto set_value;
1847 }
1848 rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_SHORT_RETRY_LIMIT,
1849 &retry, sizeof(retry));
1850 if (rc)
1851 goto out;
1852 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
1853set_value:
1854 wrqu->retry.value = retry;
1855 wrqu->retry.disabled = 0;
1856out:
1857 return rc;
1858}
1859
1860static int wl3501_get_encode(struct net_device *dev,
1861 struct iw_request_info *info,
1862 union iwreq_data *wrqu, char *extra)
1863{
1864 u8 implemented, restricted, keys[100], len_keys, tocopy;
1865 struct wl3501_card *this = dev->priv;
1866 int rc = wl3501_get_mib_value(this,
1867 WL3501_MIB_ATTR_PRIV_OPT_IMPLEMENTED,
1868 &implemented, sizeof(implemented));
1869 if (rc)
1870 goto out;
1871 if (!implemented) {
1872 wrqu->encoding.flags = IW_ENCODE_DISABLED;
1873 goto out;
1874 }
1875 rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_EXCLUDE_UNENCRYPTED,
1876 &restricted, sizeof(restricted));
1877 if (rc)
1878 goto out;
1879 wrqu->encoding.flags = restricted ? IW_ENCODE_RESTRICTED :
1880 IW_ENCODE_OPEN;
1881 rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_WEP_KEY_MAPPINGS_LEN,
1882 &len_keys, sizeof(len_keys));
1883 if (rc)
1884 goto out;
1885 rc = wl3501_get_mib_value(this, WL3501_MIB_ATTR_WEP_KEY_MAPPINGS,
1886 keys, len_keys);
1887 if (rc)
1888 goto out;
1889 tocopy = min_t(u8, len_keys, wrqu->encoding.length);
1890 tocopy = min_t(u8, tocopy, 100);
1891 wrqu->encoding.length = tocopy;
1892 memset(extra, 0, tocopy);
1893 memcpy(extra, keys, tocopy);
1894out:
1895 return rc;
1896}
1897
1898static int wl3501_get_power(struct net_device *dev,
1899 struct iw_request_info *info,
1900 union iwreq_data *wrqu, char *extra)
1901{
1902 u8 pwr_state;
1903 struct wl3501_card *this = dev->priv;
1904 int rc = wl3501_get_mib_value(this,
1905 WL3501_MIB_ATTR_CURRENT_PWR_STATE,
1906 &pwr_state, sizeof(pwr_state));
1907 if (rc)
1908 goto out;
1909 wrqu->power.disabled = !pwr_state;
1910 wrqu->power.flags = IW_POWER_ON;
1911out:
1912 return rc;
1913}
1914
1915static const iw_handler wl3501_handler[] = {
1916 [SIOCGIWNAME - SIOCIWFIRST] = wl3501_get_name,
1917 [SIOCSIWFREQ - SIOCIWFIRST] = wl3501_set_freq,
1918 [SIOCGIWFREQ - SIOCIWFIRST] = wl3501_get_freq,
1919 [SIOCSIWMODE - SIOCIWFIRST] = wl3501_set_mode,
1920 [SIOCGIWMODE - SIOCIWFIRST] = wl3501_get_mode,
1921 [SIOCGIWSENS - SIOCIWFIRST] = wl3501_get_sens,
1922 [SIOCGIWRANGE - SIOCIWFIRST] = wl3501_get_range,
1923 [SIOCSIWSPY - SIOCIWFIRST] = iw_handler_set_spy,
1924 [SIOCGIWSPY - SIOCIWFIRST] = iw_handler_get_spy,
1925 [SIOCSIWTHRSPY - SIOCIWFIRST] = iw_handler_set_thrspy,
1926 [SIOCGIWTHRSPY - SIOCIWFIRST] = iw_handler_get_thrspy,
1927 [SIOCSIWAP - SIOCIWFIRST] = wl3501_set_wap,
1928 [SIOCGIWAP - SIOCIWFIRST] = wl3501_get_wap,
1929 [SIOCSIWSCAN - SIOCIWFIRST] = wl3501_set_scan,
1930 [SIOCGIWSCAN - SIOCIWFIRST] = wl3501_get_scan,
1931 [SIOCSIWESSID - SIOCIWFIRST] = wl3501_set_essid,
1932 [SIOCGIWESSID - SIOCIWFIRST] = wl3501_get_essid,
1933 [SIOCSIWNICKN - SIOCIWFIRST] = wl3501_set_nick,
1934 [SIOCGIWNICKN - SIOCIWFIRST] = wl3501_get_nick,
1935 [SIOCGIWRATE - SIOCIWFIRST] = wl3501_get_rate,
1936 [SIOCGIWRTS - SIOCIWFIRST] = wl3501_get_rts_threshold,
1937 [SIOCGIWFRAG - SIOCIWFIRST] = wl3501_get_frag_threshold,
1938 [SIOCGIWTXPOW - SIOCIWFIRST] = wl3501_get_txpow,
1939 [SIOCGIWRETRY - SIOCIWFIRST] = wl3501_get_retry,
1940 [SIOCGIWENCODE - SIOCIWFIRST] = wl3501_get_encode,
1941 [SIOCGIWPOWER - SIOCIWFIRST] = wl3501_get_power,
1942};
1943
1944static const struct iw_handler_def wl3501_handler_def = {
1945 .num_standard = sizeof(wl3501_handler) / sizeof(iw_handler),
1946 .standard = (iw_handler *)wl3501_handler,
1947 .spy_offset = offsetof(struct wl3501_card, spy_data),
1948};
1949
1950/**
1951 * wl3501_attach - creates an "instance" of the driver
1952 *
1953 * Creates an "instance" of the driver, allocating local data structures for
1954 * one device. The device is registered with Card Services.
1955 *
1956 * The dev_link structure is initialized, but we don't actually configure the
1957 * card at this point -- we wait until we receive a card insertion event.
1958 */
1959static dev_link_t *wl3501_attach(void)
1960{
1961 client_reg_t client_reg;
1962 dev_link_t *link;
1963 struct net_device *dev;
1964 int ret;
1965
1966 /* Initialize the dev_link_t structure */
1967 link = kmalloc(sizeof(*link), GFP_KERNEL);
1968 if (!link)
1969 goto out;
1970 memset(link, 0, sizeof(struct dev_link_t));
1971
1972 /* The io structure describes IO port mapping */
1973 link->io.NumPorts1 = 16;
1974 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1975 link->io.IOAddrLines = 5;
1976
1977 /* Interrupt setup */
1978 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
1979 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
1980 link->irq.Handler = wl3501_interrupt;
1981
1982 /* General socket configuration */
1983 link->conf.Attributes = CONF_ENABLE_IRQ;
1984 link->conf.Vcc = 50;
1985 link->conf.IntType = INT_MEMORY_AND_IO;
1986 link->conf.ConfigIndex = 1;
1987 link->conf.Present = PRESENT_OPTION;
1988
1989 dev = alloc_etherdev(sizeof(struct wl3501_card));
1990 if (!dev)
1991 goto out_link;
1992 dev->open = wl3501_open;
1993 dev->stop = wl3501_close;
1994 dev->hard_start_xmit = wl3501_hard_start_xmit;
1995 dev->tx_timeout = wl3501_tx_timeout;
1996 dev->watchdog_timeo = 5 * HZ;
1997 dev->get_stats = wl3501_get_stats;
1998 dev->get_wireless_stats = wl3501_get_wireless_stats;
1999 dev->wireless_handlers = (struct iw_handler_def *)&wl3501_handler_def;
2000 SET_ETHTOOL_OPS(dev, &ops);
2001 netif_stop_queue(dev);
2002 link->priv = link->irq.Instance = dev;
2003
2004 /* Register with Card Services */
2005 link->next = wl3501_dev_list;
2006 wl3501_dev_list = link;
2007 client_reg.dev_info = &wl3501_dev_info;
2008 client_reg.EventMask = CS_EVENT_CARD_INSERTION |
2009 CS_EVENT_RESET_PHYSICAL |
2010 CS_EVENT_CARD_RESET |
2011 CS_EVENT_CARD_REMOVAL |
2012 CS_EVENT_PM_SUSPEND |
2013 CS_EVENT_PM_RESUME;
2014 client_reg.event_handler = wl3501_event;
2015 client_reg.Version = 0x0210;
2016 client_reg.event_callback_args.client_data = link;
2017 ret = pcmcia_register_client(&link->handle, &client_reg);
2018 if (ret) {
2019 cs_error(link->handle, RegisterClient, ret);
2020 wl3501_detach(link);
2021 link = NULL;
2022 }
2023out:
2024 return link;
2025out_link:
2026 kfree(link);
2027 link = NULL;
2028 goto out;
2029}
2030
2031#define CS_CHECK(fn, ret) \
2032do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
2033
2034/**
2035 * wl3501_config - configure the PCMCIA socket and make eth device available
2036 * @link - FILL_IN
2037 *
2038 * wl3501_config() is scheduled to run after a CARD_INSERTION event is
2039 * received, to configure the PCMCIA socket, and to make the ethernet device
2040 * available to the system.
2041 */
2042static void wl3501_config(dev_link_t *link)
2043{
2044 tuple_t tuple;
2045 cisparse_t parse;
2046 client_handle_t handle = link->handle;
2047 struct net_device *dev = link->priv;
2048 int i = 0, j, last_fn, last_ret;
2049 unsigned char bf[64];
2050 struct wl3501_card *this;
2051
2052 /* This reads the card's CONFIG tuple to find its config registers. */
2053 tuple.Attributes = 0;
2054 tuple.DesiredTuple = CISTPL_CONFIG;
2055 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
2056 tuple.TupleData = bf;
2057 tuple.TupleDataMax = sizeof(bf);
2058 tuple.TupleOffset = 0;
2059 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
2060 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
2061 link->conf.ConfigBase = parse.config.base;
2062 link->conf.Present = parse.config.rmask[0];
2063
2064 /* Configure card */
2065 link->state |= DEV_CONFIG;
2066
2067 /* Try allocating IO ports. This tries a few fixed addresses. If you
2068 * want, you can also read the card's config table to pick addresses --
2069 * see the serial driver for an example. */
2070
2071 for (j = 0x280; j < 0x400; j += 0x20) {
2072 /* The '^0x300' is so that we probe 0x300-0x3ff first, then
2073 * 0x200-0x2ff, and so on, because this seems safer */
2074 link->io.BasePort1 = j;
2075 link->io.BasePort2 = link->io.BasePort1 + 0x10;
2076 i = pcmcia_request_io(link->handle, &link->io);
2077 if (i == CS_SUCCESS)
2078 break;
2079 }
2080 if (i != CS_SUCCESS) {
2081 cs_error(link->handle, RequestIO, i);
2082 goto failed;
2083 }
2084
2085 /* Now allocate an interrupt line. Note that this does not actually
2086 * assign a handler to the interrupt. */
2087
2088 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
2089
2090 /* This actually configures the PCMCIA socket -- setting up the I/O
2091 * windows and the interrupt mapping. */
2092
2093 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
2094
2095 dev->irq = link->irq.AssignedIRQ;
2096 dev->base_addr = link->io.BasePort1;
2097 SET_NETDEV_DEV(dev, &handle_to_dev(handle));
2098 if (register_netdev(dev)) {
2099 printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n");
2100 goto failed;
2101 }
2102
2103 SET_MODULE_OWNER(dev);
2104
2105 this = dev->priv;
2106 /*
2107 * At this point, the dev_node_t structure(s) should be initialized and
2108 * arranged in a linked list at link->dev.
2109 */
2110 link->dev = &this->node;
2111 link->state &= ~DEV_CONFIG_PENDING;
2112
2113 this->base_addr = dev->base_addr;
2114
2115 if (!wl3501_get_flash_mac_addr(this)) {
2116 printk(KERN_WARNING "%s: Cant read MAC addr in flash ROM?\n",
2117 dev->name);
2118 goto failed;
2119 }
2120 strcpy(this->node.dev_name, dev->name);
2121
2122 /* print probe information */
2123 printk(KERN_INFO "%s: wl3501 @ 0x%3.3x, IRQ %d, MAC addr in flash ROM:",
2124 dev->name, this->base_addr, (int)dev->irq);
2125 for (i = 0; i < 6; i++) {
2126 dev->dev_addr[i] = ((char *)&this->mac_addr)[i];
2127 printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]);
2128 }
2129 printk("\n");
2130 /*
2131 * Initialize card parameters - added by jss
2132 */
2133 this->net_type = IW_MODE_INFRA;
2134 this->bss_cnt = 0;
2135 this->join_sta_bss = 0;
2136 this->adhoc_times = 0;
2137 iw_set_mgmt_info_element(IW_MGMT_INFO_ELEMENT_SSID, &this->essid.el,
2138 "ANY", 3);
2139 this->card_name[0] = '\0';
2140 this->firmware_date[0] = '\0';
2141 this->rssi = 255;
2142 this->chan = iw_default_channel(this->reg_domain);
2143 strlcpy(this->nick, "Planet WL3501", sizeof(this->nick));
2144 spin_lock_init(&this->lock);
2145 init_waitqueue_head(&this->wait);
2146 netif_start_queue(dev);
2147 goto out;
2148cs_failed:
2149 cs_error(link->handle, last_fn, last_ret);
2150failed:
2151 wl3501_release(link);
2152out:
2153 return;
2154}
2155
2156/**
2157 * wl3501_release - unregister the net, release PCMCIA configuration
2158 * @arg - link
2159 *
2160 * After a card is removed, wl3501_release() will unregister the net device,
2161 * and release the PCMCIA configuration. If the device is still open, this
2162 * will be postponed until it is closed.
2163 */
2164static void wl3501_release(dev_link_t *link)
2165{
2166 struct net_device *dev = link->priv;
2167
2168 /* Unlink the device chain */
2169 if (link->dev) {
2170 unregister_netdev(dev);
2171 link->dev = NULL;
2172 }
2173
2174 /* Don't bother checking to see if these succeed or not */
2175 pcmcia_release_configuration(link->handle);
2176 pcmcia_release_io(link->handle, &link->io);
2177 pcmcia_release_irq(link->handle, &link->irq);
2178 link->state &= ~DEV_CONFIG;
2179}
2180
2181/**
2182 * wl3501_event - The card status event handler
2183 * @event - event
2184 * @pri - priority
2185 * @args - arguments for this event
2186 *
2187 * The card status event handler. Mostly, this schedules other stuff to run
2188 * after an event is received. A CARD_REMOVAL event also sets some flags to
2189 * discourage the net drivers from trying to talk to the card any more.
2190 *
2191 * When a CARD_REMOVAL event is received, we immediately set a flag to block
2192 * future accesses to this device. All the functions that actually access the
2193 * device should check this flag to make sure the card is still present.
2194 */
2195static int wl3501_event(event_t event, int pri, event_callback_args_t *args)
2196{
2197 dev_link_t *link = args->client_data;
2198 struct net_device *dev = link->priv;
2199
2200 switch (event) {
2201 case CS_EVENT_CARD_REMOVAL:
2202 link->state &= ~DEV_PRESENT;
2203 if (link->state & DEV_CONFIG) {
2204 while (link->open > 0)
2205 wl3501_close(dev);
2206 netif_device_detach(dev);
2207 wl3501_release(link);
2208 }
2209 break;
2210 case CS_EVENT_CARD_INSERTION:
2211 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2212 wl3501_config(link);
2213 break;
2214 case CS_EVENT_PM_SUSPEND:
2215 link->state |= DEV_SUSPEND;
2216 wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
2217 /* Fall through... */
2218 case CS_EVENT_RESET_PHYSICAL:
2219 if (link->state & DEV_CONFIG) {
2220 if (link->open)
2221 netif_device_detach(dev);
2222 pcmcia_release_configuration(link->handle);
2223 }
2224 break;
2225 case CS_EVENT_PM_RESUME:
2226 link->state &= ~DEV_SUSPEND;
2227 wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
2228 /* Fall through... */
2229 case CS_EVENT_CARD_RESET:
2230 if (link->state & DEV_CONFIG) {
2231 pcmcia_request_configuration(link->handle, &link->conf);
2232 if (link->open) {
2233 wl3501_reset(dev);
2234 netif_device_attach(dev);
2235 }
2236 }
2237 break;
2238 }
2239 return 0;
2240}
2241
2242static struct pcmcia_driver wl3501_driver = {
2243 .owner = THIS_MODULE,
2244 .drv = {
2245 .name = "wl3501_cs",
2246 },
2247 .attach = wl3501_attach,
2248 .detach = wl3501_detach,
2249};
2250
2251static int __init wl3501_init_module(void)
2252{
2253 return pcmcia_register_driver(&wl3501_driver);
2254}
2255
2256static void __exit wl3501_exit_module(void)
2257{
2258 dprintk(0, ": unloading");
2259 pcmcia_unregister_driver(&wl3501_driver);
2260 BUG_ON(wl3501_dev_list != NULL);
2261}
2262
2263module_init(wl3501_init_module);
2264module_exit(wl3501_exit_module);
2265
2266MODULE_AUTHOR("Fox Chen <mhchen@golf.ccl.itri.org.tw>, "
2267 "Arnaldo Carvalho de Melo <acme@conectiva.com.br>,"
2268 "Gustavo Niemeyer <niemeyer@conectiva.com>");
2269MODULE_DESCRIPTION("Planet wl3501 wireless driver");
2270MODULE_LICENSE("GPL");