[PATCH] orinoco: monitor mode support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / orinoco.c
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/ethtool.h>
466 #include <linux/wireless.h>
467 #include <net/iw_handler.h>
468 #include <net/ieee80211.h>
469
470 #include <asm/uaccess.h>
471 #include <asm/io.h>
472 #include <asm/system.h>
473
474 #include "hermes.h"
475 #include "hermes_rid.h"
476 #include "orinoco.h"
477 #include "ieee802_11.h"
478
479 /********************************************************************/
480 /* Module information                                               */
481 /********************************************************************/
482
483 MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
484 MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
485 MODULE_LICENSE("Dual MPL/GPL");
486
487 /* Level of debugging. Used in the macros in orinoco.h */
488 #ifdef ORINOCO_DEBUG
489 int orinoco_debug = ORINOCO_DEBUG;
490 module_param(orinoco_debug, int, 0644);
491 MODULE_PARM_DESC(orinoco_debug, "Debug level");
492 EXPORT_SYMBOL(orinoco_debug);
493 #endif
494
495 static int suppress_linkstatus; /* = 0 */
496 module_param(suppress_linkstatus, bool, 0644);
497 MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
498 static int ignore_disconnect; /* = 0 */
499 module_param(ignore_disconnect, int, 0644);
500 MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
501
502 static int force_monitor; /* = 0 */
503 module_param(force_monitor, int, 0644);
504 MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
505
506 /********************************************************************/
507 /* Compile time configuration and compatibility stuff               */
508 /********************************************************************/
509
510 /* We do this this way to avoid ifdefs in the actual code */
511 #ifdef WIRELESS_SPY
512 #define SPY_NUMBER(priv)        (priv->spy_number)
513 #else
514 #define SPY_NUMBER(priv)        0
515 #endif /* WIRELESS_SPY */
516
517 /********************************************************************/
518 /* Internal constants                                               */
519 /********************************************************************/
520
521 /* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
522 static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
523 #define ENCAPS_OVERHEAD         (sizeof(encaps_hdr) + 2)
524
525 #define ORINOCO_MIN_MTU         256
526 #define ORINOCO_MAX_MTU         (IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD)
527
528 #define SYMBOL_MAX_VER_LEN      (14)
529 #define USER_BAP                0
530 #define IRQ_BAP                 1
531 #define MAX_IRQLOOPS_PER_IRQ    10
532 #define MAX_IRQLOOPS_PER_JIFFY  (20000/HZ) /* Based on a guestimate of
533                                             * how many events the
534                                             * device could
535                                             * legitimately generate */
536 #define SMALL_KEY_SIZE          5
537 #define LARGE_KEY_SIZE          13
538 #define TX_NICBUF_SIZE_BUG      1585            /* Bug in Symbol firmware */
539
540 #define DUMMY_FID               0xFFFF
541
542 /*#define MAX_MULTICAST(priv)   (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
543   HERMES_MAX_MULTICAST : 0)*/
544 #define MAX_MULTICAST(priv)     (HERMES_MAX_MULTICAST)
545
546 #define ORINOCO_INTEN           (HERMES_EV_RX | HERMES_EV_ALLOC \
547                                  | HERMES_EV_TX | HERMES_EV_TXEXC \
548                                  | HERMES_EV_WTERR | HERMES_EV_INFO \
549                                  | HERMES_EV_INFDROP )
550
551 #define MAX_RID_LEN 1024
552
553 static const struct iw_handler_def orinoco_handler_def;
554 static struct ethtool_ops orinoco_ethtool_ops;
555
556 /********************************************************************/
557 /* Data tables                                                      */
558 /********************************************************************/
559
560 /* The frequency of each channel in MHz */
561 static const long channel_frequency[] = {
562         2412, 2417, 2422, 2427, 2432, 2437, 2442,
563         2447, 2452, 2457, 2462, 2467, 2472, 2484
564 };
565 #define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
566
567 /* This tables gives the actual meanings of the bitrate IDs returned
568  * by the firmware. */
569 static struct {
570         int bitrate; /* in 100s of kilobits */
571         int automatic;
572         u16 agere_txratectrl;
573         u16 intersil_txratectrl;
574 } bitrate_table[] = {
575         {110, 1,  3, 15}, /* Entry 0 is the default */
576         {10,  0,  1,  1},
577         {10,  1,  1,  1},
578         {20,  0,  2,  2},
579         {20,  1,  6,  3},
580         {55,  0,  4,  4},
581         {55,  1,  7,  7},
582         {110, 0,  5,  8},
583 };
584 #define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
585
586 /********************************************************************/
587 /* Data types                                                       */
588 /********************************************************************/
589
590 /* Used in Event handling.
591  * We avoid nested structres as they break on ARM -- Moustafa */
592 struct hermes_tx_descriptor_802_11 {
593         /* hermes_tx_descriptor */
594         u16 status;
595         u16 reserved1;
596         u16 reserved2;
597         u32 sw_support;
598         u8 retry_count;
599         u8 tx_rate;
600         u16 tx_control;
601
602         /* ieee802_11_hdr */
603         u16 frame_ctl;
604         u16 duration_id;
605         u8 addr1[ETH_ALEN];
606         u8 addr2[ETH_ALEN];
607         u8 addr3[ETH_ALEN];
608         u16 seq_ctl;
609         u8 addr4[ETH_ALEN];
610         u16 data_len;
611
612         /* ethhdr */
613         unsigned char   h_dest[ETH_ALEN];       /* destination eth addr */
614         unsigned char   h_source[ETH_ALEN];     /* source ether addr    */
615         unsigned short  h_proto;                /* packet type ID field */
616
617         /* p8022_hdr */
618         u8 dsap;
619         u8 ssap;
620         u8 ctrl;
621         u8 oui[3];
622
623         u16 ethertype;
624 } __attribute__ ((packed));
625
626 /* Rx frame header except compatibility 802.3 header */
627 struct hermes_rx_descriptor {
628         /* Control */
629         u16 status;
630         u32 time;
631         u8 silence;
632         u8 signal;
633         u8 rate;
634         u8 rxflow;
635         u32 reserved;
636
637         /* 802.11 header */
638         u16 frame_ctl;
639         u16 duration_id;
640         u8 addr1[ETH_ALEN];
641         u8 addr2[ETH_ALEN];
642         u8 addr3[ETH_ALEN];
643         u16 seq_ctl;
644         u8 addr4[ETH_ALEN];
645
646         /* Data length */
647         u16 data_len;
648 } __attribute__ ((packed));
649
650 /********************************************************************/
651 /* Function prototypes                                              */
652 /********************************************************************/
653
654 static int __orinoco_program_rids(struct net_device *dev);
655 static void __orinoco_set_multicast_list(struct net_device *dev);
656
657 /********************************************************************/
658 /* Internal helper functions                                        */
659 /********************************************************************/
660
661 static inline void set_port_type(struct orinoco_private *priv)
662 {
663         switch (priv->iw_mode) {
664         case IW_MODE_INFRA:
665                 priv->port_type = 1;
666                 priv->createibss = 0;
667                 break;
668         case IW_MODE_ADHOC:
669                 if (priv->prefer_port3) {
670                         priv->port_type = 3;
671                         priv->createibss = 0;
672                 } else {
673                         priv->port_type = priv->ibss_port;
674                         priv->createibss = 1;
675                 }
676                 break;
677         case IW_MODE_MONITOR:
678                 priv->port_type = 3;
679                 priv->createibss = 0;
680                 break;
681         default:
682                 printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
683                        priv->ndev->name);
684         }
685 }
686
687 /********************************************************************/
688 /* Device methods                                                   */
689 /********************************************************************/
690
691 static int orinoco_open(struct net_device *dev)
692 {
693         struct orinoco_private *priv = netdev_priv(dev);
694         unsigned long flags;
695         int err;
696
697         if (orinoco_lock(priv, &flags) != 0)
698                 return -EBUSY;
699
700         err = __orinoco_up(dev);
701
702         if (! err)
703                 priv->open = 1;
704
705         orinoco_unlock(priv, &flags);
706
707         return err;
708 }
709
710 static int orinoco_stop(struct net_device *dev)
711 {
712         struct orinoco_private *priv = netdev_priv(dev);
713         int err = 0;
714
715         /* We mustn't use orinoco_lock() here, because we need to be
716            able to close the interface even if hw_unavailable is set
717            (e.g. as we're released after a PC Card removal) */
718         spin_lock_irq(&priv->lock);
719
720         priv->open = 0;
721
722         err = __orinoco_down(dev);
723
724         spin_unlock_irq(&priv->lock);
725
726         return err;
727 }
728
729 static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
730 {
731         struct orinoco_private *priv = netdev_priv(dev);
732         
733         return &priv->stats;
734 }
735
736 static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
737 {
738         struct orinoco_private *priv = netdev_priv(dev);
739         hermes_t *hw = &priv->hw;
740         struct iw_statistics *wstats = &priv->wstats;
741         int err;
742         unsigned long flags;
743
744         if (! netif_device_present(dev)) {
745                 printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
746                        dev->name);
747                 return NULL; /* FIXME: Can we do better than this? */
748         }
749
750         /* If busy, return the old stats.  Returning NULL may cause
751          * the interface to disappear from /proc/net/wireless */
752         if (orinoco_lock(priv, &flags) != 0)
753                 return wstats;
754
755         /* We can't really wait for the tallies inquiry command to
756          * complete, so we just use the previous results and trigger
757          * a new tallies inquiry command for next time - Jean II */
758         /* FIXME: Really we should wait for the inquiry to come back -
759          * as it is the stats we give don't make a whole lot of sense.
760          * Unfortunately, it's not clear how to do that within the
761          * wireless extensions framework: I think we're in user
762          * context, but a lock seems to be held by the time we get in
763          * here so we're not safe to sleep here. */
764         hermes_inquire(hw, HERMES_INQ_TALLIES);
765
766         if (priv->iw_mode == IW_MODE_ADHOC) {
767                 memset(&wstats->qual, 0, sizeof(wstats->qual));
768                 /* If a spy address is defined, we report stats of the
769                  * first spy address - Jean II */
770                 if (SPY_NUMBER(priv)) {
771                         wstats->qual.qual = priv->spy_stat[0].qual;
772                         wstats->qual.level = priv->spy_stat[0].level;
773                         wstats->qual.noise = priv->spy_stat[0].noise;
774                         wstats->qual.updated = priv->spy_stat[0].updated;
775                 }
776         } else {
777                 struct {
778                         u16 qual, signal, noise;
779                 } __attribute__ ((packed)) cq;
780
781                 err = HERMES_READ_RECORD(hw, USER_BAP,
782                                          HERMES_RID_COMMSQUALITY, &cq);
783
784                 if (!err) {
785                         wstats->qual.qual = (int)le16_to_cpu(cq.qual);
786                         wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
787                         wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
788                         wstats->qual.updated = 7;
789                 }
790         }
791
792         orinoco_unlock(priv, &flags);
793         return wstats;
794 }
795
796 static void orinoco_set_multicast_list(struct net_device *dev)
797 {
798         struct orinoco_private *priv = netdev_priv(dev);
799         unsigned long flags;
800
801         if (orinoco_lock(priv, &flags) != 0) {
802                 printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
803                        "called when hw_unavailable\n", dev->name);
804                 return;
805         }
806
807         __orinoco_set_multicast_list(dev);
808         orinoco_unlock(priv, &flags);
809 }
810
811 static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
812 {
813         struct orinoco_private *priv = netdev_priv(dev);
814
815         if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
816                 return -EINVAL;
817
818         if ( (new_mtu + ENCAPS_OVERHEAD + IEEE802_11_HLEN) >
819              (priv->nicbuf_size - ETH_HLEN) )
820                 return -EINVAL;
821
822         dev->mtu = new_mtu;
823
824         return 0;
825 }
826
827 /********************************************************************/
828 /* Tx path                                                          */
829 /********************************************************************/
830
831 static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
832 {
833         struct orinoco_private *priv = netdev_priv(dev);
834         struct net_device_stats *stats = &priv->stats;
835         hermes_t *hw = &priv->hw;
836         int err = 0;
837         u16 txfid = priv->txfid;
838         char *p;
839         struct ethhdr *eh;
840         int len, data_len, data_off;
841         struct hermes_tx_descriptor desc;
842         unsigned long flags;
843
844         TRACE_ENTER(dev->name);
845
846         if (! netif_running(dev)) {
847                 printk(KERN_ERR "%s: Tx on stopped device!\n",
848                        dev->name);
849                 TRACE_EXIT(dev->name);
850                 return 1;
851         }
852         
853         if (netif_queue_stopped(dev)) {
854                 printk(KERN_DEBUG "%s: Tx while transmitter busy!\n", 
855                        dev->name);
856                 TRACE_EXIT(dev->name);
857                 return 1;
858         }
859         
860         if (orinoco_lock(priv, &flags) != 0) {
861                 printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
862                        dev->name);
863                 TRACE_EXIT(dev->name);
864                 return 1;
865         }
866
867         if (! netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
868                 /* Oops, the firmware hasn't established a connection,
869                    silently drop the packet (this seems to be the
870                    safest approach). */
871                 stats->tx_errors++;
872                 orinoco_unlock(priv, &flags);
873                 dev_kfree_skb(skb);
874                 TRACE_EXIT(dev->name);
875                 return 0;
876         }
877
878         /* Length of the packet body */
879         /* FIXME: what if the skb is smaller than this? */
880         len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN - ETH_HLEN);
881
882         eh = (struct ethhdr *)skb->data;
883
884         memset(&desc, 0, sizeof(desc));
885         desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX);
886         err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), txfid, 0);
887         if (err) {
888                 if (net_ratelimit())
889                         printk(KERN_ERR "%s: Error %d writing Tx descriptor "
890                                "to BAP\n", dev->name, err);
891                 stats->tx_errors++;
892                 goto fail;
893         }
894
895         /* Clear the 802.11 header and data length fields - some
896          * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
897          * if this isn't done. */
898         hermes_clear_words(hw, HERMES_DATA0,
899                            HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
900
901         /* Encapsulate Ethernet-II frames */
902         if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
903                 struct header_struct hdr;
904                 data_len = len;
905                 data_off = HERMES_802_3_OFFSET + sizeof(hdr);
906                 p = skb->data + ETH_HLEN;
907
908                 /* 802.3 header */
909                 memcpy(hdr.dest, eh->h_dest, ETH_ALEN);
910                 memcpy(hdr.src, eh->h_source, ETH_ALEN);
911                 hdr.len = htons(data_len + ENCAPS_OVERHEAD);
912                 
913                 /* 802.2 header */
914                 memcpy(&hdr.dsap, &encaps_hdr, sizeof(encaps_hdr));
915                         
916                 hdr.ethertype = eh->h_proto;
917                 err  = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
918                                          txfid, HERMES_802_3_OFFSET);
919                 if (err) {
920                         if (net_ratelimit())
921                                 printk(KERN_ERR "%s: Error %d writing packet "
922                                        "header to BAP\n", dev->name, err);
923                         stats->tx_errors++;
924                         goto fail;
925                 }
926         } else { /* IEEE 802.3 frame */
927                 data_len = len + ETH_HLEN;
928                 data_off = HERMES_802_3_OFFSET;
929                 p = skb->data;
930         }
931
932         /* Round up for odd length packets */
933         err = hermes_bap_pwrite(hw, USER_BAP, p, ALIGN(data_len, 2),
934                                 txfid, data_off);
935         if (err) {
936                 printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
937                        dev->name, err);
938                 stats->tx_errors++;
939                 goto fail;
940         }
941
942         /* Finally, we actually initiate the send */
943         netif_stop_queue(dev);
944
945         err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
946                                 txfid, NULL);
947         if (err) {
948                 netif_start_queue(dev);
949                 printk(KERN_ERR "%s: Error %d transmitting packet\n",
950                        dev->name, err);
951                 stats->tx_errors++;
952                 goto fail;
953         }
954
955         dev->trans_start = jiffies;
956         stats->tx_bytes += data_off + data_len;
957
958         orinoco_unlock(priv, &flags);
959
960         dev_kfree_skb(skb);
961
962         TRACE_EXIT(dev->name);
963
964         return 0;
965  fail:
966         TRACE_EXIT(dev->name);
967
968         orinoco_unlock(priv, &flags);
969         return err;
970 }
971
972 static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
973 {
974         struct orinoco_private *priv = netdev_priv(dev);
975         u16 fid = hermes_read_regn(hw, ALLOCFID);
976
977         if (fid != priv->txfid) {
978                 if (fid != DUMMY_FID)
979                         printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
980                                dev->name, fid);
981                 return;
982         }
983
984         hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
985 }
986
987 static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
988 {
989         struct orinoco_private *priv = netdev_priv(dev);
990         struct net_device_stats *stats = &priv->stats;
991
992         stats->tx_packets++;
993
994         netif_wake_queue(dev);
995
996         hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
997 }
998
999 static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
1000 {
1001         struct orinoco_private *priv = netdev_priv(dev);
1002         struct net_device_stats *stats = &priv->stats;
1003         u16 fid = hermes_read_regn(hw, TXCOMPLFID);
1004         struct hermes_tx_descriptor_802_11 hdr;
1005         int err = 0;
1006
1007         if (fid == DUMMY_FID)
1008                 return; /* Nothing's really happened */
1009
1010         /* Read the frame header */
1011         err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
1012                                sizeof(struct hermes_tx_descriptor) +
1013                                sizeof(struct ieee80211_hdr),
1014                                fid, 0);
1015
1016         hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
1017         stats->tx_errors++;
1018
1019         if (err) {
1020                 printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
1021                        "(FID=%04X error %d)\n",
1022                        dev->name, fid, err);
1023                 return;
1024         }
1025         
1026         DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
1027               err, fid);
1028     
1029         /* We produce a TXDROP event only for retry or lifetime
1030          * exceeded, because that's the only status that really mean
1031          * that this particular node went away.
1032          * Other errors means that *we* screwed up. - Jean II */
1033         hdr.status = le16_to_cpu(hdr.status);
1034         if (hdr.status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
1035                 union iwreq_data        wrqu;
1036
1037                 /* Copy 802.11 dest address.
1038                  * We use the 802.11 header because the frame may
1039                  * not be 802.3 or may be mangled...
1040                  * In Ad-Hoc mode, it will be the node address.
1041                  * In managed mode, it will be most likely the AP addr
1042                  * User space will figure out how to convert it to
1043                  * whatever it needs (IP address or else).
1044                  * - Jean II */
1045                 memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
1046                 wrqu.addr.sa_family = ARPHRD_ETHER;
1047
1048                 /* Send event to user space */
1049                 wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
1050         }
1051
1052         netif_wake_queue(dev);
1053 }
1054
1055 static void orinoco_tx_timeout(struct net_device *dev)
1056 {
1057         struct orinoco_private *priv = netdev_priv(dev);
1058         struct net_device_stats *stats = &priv->stats;
1059         struct hermes *hw = &priv->hw;
1060
1061         printk(KERN_WARNING "%s: Tx timeout! "
1062                "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
1063                dev->name, hermes_read_regn(hw, ALLOCFID),
1064                hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
1065
1066         stats->tx_errors++;
1067
1068         schedule_work(&priv->reset_work);
1069 }
1070
1071 /********************************************************************/
1072 /* Rx path (data frames)                                            */
1073 /********************************************************************/
1074
1075 /* Does the frame have a SNAP header indicating it should be
1076  * de-encapsulated to Ethernet-II? */
1077 static inline int is_ethersnap(void *_hdr)
1078 {
1079         u8 *hdr = _hdr;
1080
1081         /* We de-encapsulate all packets which, a) have SNAP headers
1082          * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
1083          * and where b) the OUI of the SNAP header is 00:00:00 or
1084          * 00:00:f8 - we need both because different APs appear to use
1085          * different OUIs for some reason */
1086         return (memcmp(hdr, &encaps_hdr, 5) == 0)
1087                 && ( (hdr[5] == 0x00) || (hdr[5] == 0xf8) );
1088 }
1089
1090 static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
1091                                       int level, int noise)
1092 {
1093         struct orinoco_private *priv = netdev_priv(dev);
1094         int i;
1095
1096         /* Gather wireless spy statistics: for each packet, compare the
1097          * source address with out list, and if match, get the stats... */
1098         for (i = 0; i < priv->spy_number; i++)
1099                 if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {
1100                         priv->spy_stat[i].level = level - 0x95;
1101                         priv->spy_stat[i].noise = noise - 0x95;
1102                         priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0;
1103                         priv->spy_stat[i].updated = 7;
1104                 }
1105 }
1106
1107 static void orinoco_stat_gather(struct net_device *dev,
1108                                 struct sk_buff *skb,
1109                                 struct hermes_rx_descriptor *desc)
1110 {
1111         struct orinoco_private *priv = netdev_priv(dev);
1112
1113         /* Using spy support with lots of Rx packets, like in an
1114          * infrastructure (AP), will really slow down everything, because
1115          * the MAC address must be compared to each entry of the spy list.
1116          * If the user really asks for it (set some address in the
1117          * spy list), we do it, but he will pay the price.
1118          * Note that to get here, you need both WIRELESS_SPY
1119          * compiled in AND some addresses in the list !!!
1120          */
1121         /* Note : gcc will optimise the whole section away if
1122          * WIRELESS_SPY is not defined... - Jean II */
1123         if (SPY_NUMBER(priv)) {
1124                 orinoco_spy_gather(dev, skb->mac.raw + ETH_ALEN,
1125                                    desc->signal, desc->silence);
1126         }
1127 }
1128
1129 /*
1130  * orinoco_rx_monitor - handle received monitor frames.
1131  *
1132  * Arguments:
1133  *      dev             network device
1134  *      rxfid           received FID
1135  *      desc            rx descriptor of the frame
1136  *
1137  * Call context: interrupt
1138  */
1139 static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
1140                                struct hermes_rx_descriptor *desc)
1141 {
1142         u32 hdrlen = 30;        /* return full header by default */
1143         u32 datalen = 0;
1144         u16 fc;
1145         int err;
1146         int len;
1147         struct sk_buff *skb;
1148         struct orinoco_private *priv = netdev_priv(dev);
1149         struct net_device_stats *stats = &priv->stats;
1150         hermes_t *hw = &priv->hw;
1151
1152         len = le16_to_cpu(desc->data_len);
1153
1154         /* Determine the size of the header and the data */
1155         fc = le16_to_cpu(desc->frame_ctl);
1156         switch (fc & IEEE80211_FCTL_FTYPE) {
1157         case IEEE80211_FTYPE_DATA:
1158                 if ((fc & IEEE80211_FCTL_TODS)
1159                     && (fc & IEEE80211_FCTL_FROMDS))
1160                         hdrlen = 30;
1161                 else
1162                         hdrlen = 24;
1163                 datalen = len;
1164                 break;
1165         case IEEE80211_FTYPE_MGMT:
1166                 hdrlen = 24;
1167                 datalen = len;
1168                 break;
1169         case IEEE80211_FTYPE_CTL:
1170                 switch (fc & IEEE80211_FCTL_STYPE) {
1171                 case IEEE80211_STYPE_PSPOLL:
1172                 case IEEE80211_STYPE_RTS:
1173                 case IEEE80211_STYPE_CFEND:
1174                 case IEEE80211_STYPE_CFENDACK:
1175                         hdrlen = 16;
1176                         break;
1177                 case IEEE80211_STYPE_CTS:
1178                 case IEEE80211_STYPE_ACK:
1179                         hdrlen = 10;
1180                         break;
1181                 }
1182                 break;
1183         default:
1184                 /* Unknown frame type */
1185                 break;
1186         }
1187
1188         /* sanity check the length */
1189         if (datalen > IEEE80211_DATA_LEN + 12) {
1190                 printk(KERN_DEBUG "%s: oversized monitor frame, "
1191                        "data length = %d\n", dev->name, datalen);
1192                 err = -EIO;
1193                 stats->rx_length_errors++;
1194                 goto update_stats;
1195         }
1196
1197         skb = dev_alloc_skb(hdrlen + datalen);
1198         if (!skb) {
1199                 printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
1200                        dev->name);
1201                 err = -ENOMEM;
1202                 goto drop;
1203         }
1204
1205         /* Copy the 802.11 header to the skb */
1206         memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
1207         skb->mac.raw = skb->data;
1208
1209         /* If any, copy the data from the card to the skb */
1210         if (datalen > 0) {
1211                 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
1212                                        ALIGN(datalen, 2), rxfid,
1213                                        HERMES_802_2_OFFSET);
1214                 if (err) {
1215                         printk(KERN_ERR "%s: error %d reading monitor frame\n",
1216                                dev->name, err);
1217                         goto drop;
1218                 }
1219         }
1220
1221         skb->dev = dev;
1222         skb->ip_summed = CHECKSUM_NONE;
1223         skb->pkt_type = PACKET_OTHERHOST;
1224         skb->protocol = __constant_htons(ETH_P_802_2);
1225         
1226         dev->last_rx = jiffies;
1227         stats->rx_packets++;
1228         stats->rx_bytes += skb->len;
1229
1230         netif_rx(skb);
1231         return;
1232
1233  drop:
1234         dev_kfree_skb_irq(skb);
1235  update_stats:
1236         stats->rx_errors++;
1237         stats->rx_dropped++;
1238 }
1239
1240 static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
1241 {
1242         struct orinoco_private *priv = netdev_priv(dev);
1243         struct net_device_stats *stats = &priv->stats;
1244         struct iw_statistics *wstats = &priv->wstats;
1245         struct sk_buff *skb = NULL;
1246         u16 rxfid, status, fc;
1247         int length;
1248         struct hermes_rx_descriptor desc;
1249         struct ethhdr *hdr;
1250         int err;
1251
1252         rxfid = hermes_read_regn(hw, RXFID);
1253
1254         err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc),
1255                                rxfid, 0);
1256         if (err) {
1257                 printk(KERN_ERR "%s: error %d reading Rx descriptor. "
1258                        "Frame dropped.\n", dev->name, err);
1259                 goto update_stats;
1260         }
1261
1262         status = le16_to_cpu(desc.status);
1263
1264         if (status & HERMES_RXSTAT_BADCRC) {
1265                 DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
1266                       dev->name);
1267                 stats->rx_crc_errors++;
1268                 goto update_stats;
1269         }
1270
1271         /* Handle frames in monitor mode */
1272         if (priv->iw_mode == IW_MODE_MONITOR) {
1273                 orinoco_rx_monitor(dev, rxfid, &desc);
1274                 return;
1275         }
1276
1277         if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
1278                 DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
1279                       dev->name);
1280                 wstats->discard.code++;
1281                 goto update_stats;
1282         }
1283
1284         length = le16_to_cpu(desc.data_len);
1285         fc = le16_to_cpu(desc.frame_ctl);
1286
1287         /* Sanity checks */
1288         if (length < 3) { /* No for even an 802.2 LLC header */
1289                 /* At least on Symbol firmware with PCF we get quite a
1290                    lot of these legitimately - Poll frames with no
1291                    data. */
1292                 return;
1293         }
1294         if (length > IEEE802_11_DATA_LEN) {
1295                 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
1296                        dev->name, length);
1297                 stats->rx_length_errors++;
1298                 goto update_stats;
1299         }
1300
1301         /* We need space for the packet data itself, plus an ethernet
1302            header, plus 2 bytes so we can align the IP header on a
1303            32bit boundary, plus 1 byte so we can read in odd length
1304            packets from the card, which has an IO granularity of 16
1305            bits */  
1306         skb = dev_alloc_skb(length+ETH_HLEN+2+1);
1307         if (!skb) {
1308                 printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
1309                        dev->name);
1310                 goto update_stats;
1311         }
1312
1313         /* We'll prepend the header, so reserve space for it.  The worst
1314            case is no decapsulation, when 802.3 header is prepended and
1315            nothing is removed.  2 is for aligning the IP header.  */
1316         skb_reserve(skb, ETH_HLEN + 2);
1317
1318         err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
1319                                ALIGN(length, 2), rxfid,
1320                                HERMES_802_2_OFFSET);
1321         if (err) {
1322                 printk(KERN_ERR "%s: error %d reading frame. "
1323                        "Frame dropped.\n", dev->name, err);
1324                 goto drop;
1325         }
1326
1327         /* Handle decapsulation
1328          * In most cases, the firmware tell us about SNAP frames.
1329          * For some reason, the SNAP frames sent by LinkSys APs
1330          * are not properly recognised by most firmwares.
1331          * So, check ourselves */
1332         if (length >= ENCAPS_OVERHEAD &&
1333             (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
1334              ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
1335              is_ethersnap(skb->data))) {
1336                 /* These indicate a SNAP within 802.2 LLC within
1337                    802.11 frame which we'll need to de-encapsulate to
1338                    the original EthernetII frame. */
1339                 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN - ENCAPS_OVERHEAD);
1340         } else {
1341                 /* 802.3 frame - prepend 802.3 header as is */
1342                 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
1343                 hdr->h_proto = htons(length);
1344         }
1345         memcpy(hdr->h_dest, desc.addr1, ETH_ALEN);
1346         if (fc & IEEE80211_FCTL_FROMDS)
1347                 memcpy(hdr->h_source, desc.addr3, ETH_ALEN);
1348         else
1349                 memcpy(hdr->h_source, desc.addr2, ETH_ALEN);
1350
1351         dev->last_rx = jiffies;
1352         skb->dev = dev;
1353         skb->protocol = eth_type_trans(skb, dev);
1354         skb->ip_summed = CHECKSUM_NONE;
1355         if (fc & IEEE80211_FCTL_TODS)
1356                 skb->pkt_type = PACKET_OTHERHOST;
1357         
1358         /* Process the wireless stats if needed */
1359         orinoco_stat_gather(dev, skb, &desc);
1360
1361         /* Pass the packet to the networking stack */
1362         netif_rx(skb);
1363         stats->rx_packets++;
1364         stats->rx_bytes += length;
1365
1366         return;
1367
1368  drop:  
1369         dev_kfree_skb_irq(skb);
1370  update_stats:
1371         stats->rx_errors++;
1372         stats->rx_dropped++;
1373 }
1374
1375 /********************************************************************/
1376 /* Rx path (info frames)                                            */
1377 /********************************************************************/
1378
1379 static void print_linkstatus(struct net_device *dev, u16 status)
1380 {
1381         char * s;
1382
1383         if (suppress_linkstatus)
1384                 return;
1385
1386         switch (status) {
1387         case HERMES_LINKSTATUS_NOT_CONNECTED:
1388                 s = "Not Connected";
1389                 break;
1390         case HERMES_LINKSTATUS_CONNECTED:
1391                 s = "Connected";
1392                 break;
1393         case HERMES_LINKSTATUS_DISCONNECTED:
1394                 s = "Disconnected";
1395                 break;
1396         case HERMES_LINKSTATUS_AP_CHANGE:
1397                 s = "AP Changed";
1398                 break;
1399         case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
1400                 s = "AP Out of Range";
1401                 break;
1402         case HERMES_LINKSTATUS_AP_IN_RANGE:
1403                 s = "AP In Range";
1404                 break;
1405         case HERMES_LINKSTATUS_ASSOC_FAILED:
1406                 s = "Association Failed";
1407                 break;
1408         default:
1409                 s = "UNKNOWN";
1410         }
1411         
1412         printk(KERN_INFO "%s: New link status: %s (%04x)\n",
1413                dev->name, s, status);
1414 }
1415
1416 /* Search scan results for requested BSSID, join it if found */
1417 static void orinoco_join_ap(struct net_device *dev)
1418 {
1419         struct orinoco_private *priv = netdev_priv(dev);
1420         struct hermes *hw = &priv->hw;
1421         int err;
1422         unsigned long flags;
1423         struct join_req {
1424                 u8 bssid[ETH_ALEN];
1425                 u16 channel;
1426         } __attribute__ ((packed)) req;
1427         const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
1428         struct prism2_scan_apinfo *atom;
1429         int offset = 4;
1430         u8 *buf;
1431         u16 len;
1432
1433         /* Allocate buffer for scan results */
1434         buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
1435         if (! buf)
1436                 return;
1437
1438         if (orinoco_lock(priv, &flags) != 0)
1439                 goto out;
1440
1441         /* Sanity checks in case user changed something in the meantime */
1442         if (! priv->bssid_fixed)
1443                 goto out;
1444
1445         if (strlen(priv->desired_essid) == 0)
1446                 goto out;
1447
1448         /* Read scan results from the firmware */
1449         err = hermes_read_ltv(hw, USER_BAP,
1450                               HERMES_RID_SCANRESULTSTABLE,
1451                               MAX_SCAN_LEN, &len, buf);
1452         if (err) {
1453                 printk(KERN_ERR "%s: Cannot read scan results\n",
1454                        dev->name);
1455                 goto out;
1456         }
1457
1458         len = HERMES_RECLEN_TO_BYTES(len);
1459
1460         /* Go through the scan results looking for the channel of the AP
1461          * we were requested to join */
1462         for (; offset + atom_len <= len; offset += atom_len) {
1463                 atom = (struct prism2_scan_apinfo *) (buf + offset);
1464                 if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0)
1465                         goto found;
1466         }
1467
1468         DEBUG(1, "%s: Requested AP not found in scan results\n",
1469               dev->name);
1470         goto out;
1471
1472  found:
1473         memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
1474         req.channel = atom->channel;    /* both are little-endian */
1475         err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
1476                                   &req);
1477         if (err)
1478                 printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
1479
1480  out:
1481         kfree(buf);
1482         orinoco_unlock(priv, &flags);
1483 }
1484
1485 /* Send new BSSID to userspace */
1486 static void orinoco_send_wevents(struct net_device *dev)
1487 {
1488         struct orinoco_private *priv = netdev_priv(dev);
1489         struct hermes *hw = &priv->hw;
1490         union iwreq_data wrqu;
1491         int err;
1492         unsigned long flags;
1493
1494         if (orinoco_lock(priv, &flags) != 0)
1495                 return;
1496
1497         err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
1498                               ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
1499         if (err != 0)
1500                 return;
1501
1502         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1503
1504         /* Send event to user space */
1505         wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
1506         orinoco_unlock(priv, &flags);
1507 }
1508
1509 static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1510 {
1511         struct orinoco_private *priv = netdev_priv(dev);
1512         u16 infofid;
1513         struct {
1514                 u16 len;
1515                 u16 type;
1516         } __attribute__ ((packed)) info;
1517         int len, type;
1518         int err;
1519
1520         /* This is an answer to an INQUIRE command that we did earlier,
1521          * or an information "event" generated by the card
1522          * The controller return to us a pseudo frame containing
1523          * the information in question - Jean II */
1524         infofid = hermes_read_regn(hw, INFOFID);
1525
1526         /* Read the info frame header - don't try too hard */
1527         err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
1528                                infofid, 0);
1529         if (err) {
1530                 printk(KERN_ERR "%s: error %d reading info frame. "
1531                        "Frame dropped.\n", dev->name, err);
1532                 return;
1533         }
1534         
1535         len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
1536         type = le16_to_cpu(info.type);
1537
1538         switch (type) {
1539         case HERMES_INQ_TALLIES: {
1540                 struct hermes_tallies_frame tallies;
1541                 struct iw_statistics *wstats = &priv->wstats;
1542                 
1543                 if (len > sizeof(tallies)) {
1544                         printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
1545                                dev->name, len);
1546                         len = sizeof(tallies);
1547                 }
1548                 
1549                 err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
1550                                        infofid, sizeof(info));
1551                 if (err)
1552                         break;
1553                 
1554                 /* Increment our various counters */
1555                 /* wstats->discard.nwid - no wrong BSSID stuff */
1556                 wstats->discard.code +=
1557                         le16_to_cpu(tallies.RxWEPUndecryptable);
1558                 if (len == sizeof(tallies))  
1559                         wstats->discard.code +=
1560                                 le16_to_cpu(tallies.RxDiscards_WEPICVError) +
1561                                 le16_to_cpu(tallies.RxDiscards_WEPExcluded);
1562                 wstats->discard.misc +=
1563                         le16_to_cpu(tallies.TxDiscardsWrongSA);
1564                 wstats->discard.fragment +=
1565                         le16_to_cpu(tallies.RxMsgInBadMsgFragments);
1566                 wstats->discard.retries +=
1567                         le16_to_cpu(tallies.TxRetryLimitExceeded);
1568                 /* wstats->miss.beacon - no match */
1569         }
1570         break;
1571         case HERMES_INQ_LINKSTATUS: {
1572                 struct hermes_linkstatus linkstatus;
1573                 u16 newstatus;
1574                 int connected;
1575
1576                 if (priv->iw_mode == IW_MODE_MONITOR)
1577                         break;
1578
1579                 if (len != sizeof(linkstatus)) {
1580                         printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
1581                                dev->name, len);
1582                         break;
1583                 }
1584
1585                 err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
1586                                        infofid, sizeof(info));
1587                 if (err)
1588                         break;
1589                 newstatus = le16_to_cpu(linkstatus.linkstatus);
1590
1591                 /* Symbol firmware uses "out of range" to signal that
1592                  * the hostscan frame can be requested.  */
1593                 if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
1594                     priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
1595                     priv->has_hostscan && priv->scan_inprogress) {
1596                         hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
1597                         break;
1598                 }
1599
1600                 connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
1601                         || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
1602                         || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
1603
1604                 if (connected)
1605                         netif_carrier_on(dev);
1606                 else if (!ignore_disconnect)
1607                         netif_carrier_off(dev);
1608
1609                 if (newstatus != priv->last_linkstatus) {
1610                         priv->last_linkstatus = newstatus;
1611                         print_linkstatus(dev, newstatus);
1612                         /* The info frame contains only one word which is the
1613                          * status (see hermes.h). The status is pretty boring
1614                          * in itself, that's why we export the new BSSID...
1615                          * Jean II */
1616                         schedule_work(&priv->wevent_work);
1617                 }
1618         }
1619         break;
1620         case HERMES_INQ_SCAN:
1621                 if (!priv->scan_inprogress && priv->bssid_fixed &&
1622                     priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
1623                         schedule_work(&priv->join_work);
1624                         break;
1625                 }
1626                 /* fall through */
1627         case HERMES_INQ_HOSTSCAN:
1628         case HERMES_INQ_HOSTSCAN_SYMBOL: {
1629                 /* Result of a scanning. Contains information about
1630                  * cells in the vicinity - Jean II */
1631                 union iwreq_data        wrqu;
1632                 unsigned char *buf;
1633
1634                 /* Sanity check */
1635                 if (len > 4096) {
1636                         printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
1637                                dev->name, len);
1638                         break;
1639                 }
1640
1641                 /* We are a strict producer. If the previous scan results
1642                  * have not been consumed, we just have to drop this
1643                  * frame. We can't remove the previous results ourselves,
1644                  * that would be *very* racy... Jean II */
1645                 if (priv->scan_result != NULL) {
1646                         printk(KERN_WARNING "%s: Previous scan results not consumed, dropping info frame.\n", dev->name);
1647                         break;
1648                 }
1649
1650                 /* Allocate buffer for results */
1651                 buf = kmalloc(len, GFP_ATOMIC);
1652                 if (buf == NULL)
1653                         /* No memory, so can't printk()... */
1654                         break;
1655
1656                 /* Read scan data */
1657                 err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
1658                                        infofid, sizeof(info));
1659                 if (err)
1660                         break;
1661
1662 #ifdef ORINOCO_DEBUG
1663                 {
1664                         int     i;
1665                         printk(KERN_DEBUG "Scan result [%02X", buf[0]);
1666                         for(i = 1; i < (len * 2); i++)
1667                                 printk(":%02X", buf[i]);
1668                         printk("]\n");
1669                 }
1670 #endif  /* ORINOCO_DEBUG */
1671
1672                 /* Allow the clients to access the results */
1673                 priv->scan_len = len;
1674                 priv->scan_result = buf;
1675
1676                 /* Send an empty event to user space.
1677                  * We don't send the received data on the event because
1678                  * it would require us to do complex transcoding, and
1679                  * we want to minimise the work done in the irq handler
1680                  * Use a request to extract the data - Jean II */
1681                 wrqu.data.length = 0;
1682                 wrqu.data.flags = 0;
1683                 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
1684         }
1685         break;
1686         case HERMES_INQ_SEC_STAT_AGERE:
1687                 /* Security status (Agere specific) */
1688                 /* Ignore this frame for now */
1689                 if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
1690                         break;
1691                 /* fall through */
1692         default:
1693                 printk(KERN_DEBUG "%s: Unknown information frame received: "
1694                        "type 0x%04x, length %d\n", dev->name, type, len);
1695                 /* We don't actually do anything about it */
1696                 break;
1697         }
1698 }
1699
1700 static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
1701 {
1702         if (net_ratelimit())
1703                 printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
1704 }
1705
1706 /********************************************************************/
1707 /* Internal hardware control routines                               */
1708 /********************************************************************/
1709
1710 int __orinoco_up(struct net_device *dev)
1711 {
1712         struct orinoco_private *priv = netdev_priv(dev);
1713         struct hermes *hw = &priv->hw;
1714         int err;
1715
1716         netif_carrier_off(dev); /* just to make sure */
1717
1718         err = __orinoco_program_rids(dev);
1719         if (err) {
1720                 printk(KERN_ERR "%s: Error %d configuring card\n",
1721                        dev->name, err);
1722                 return err;
1723         }
1724
1725         /* Fire things up again */
1726         hermes_set_irqmask(hw, ORINOCO_INTEN);
1727         err = hermes_enable_port(hw, 0);
1728         if (err) {
1729                 printk(KERN_ERR "%s: Error %d enabling MAC port\n",
1730                        dev->name, err);
1731                 return err;
1732         }
1733
1734         netif_start_queue(dev);
1735
1736         return 0;
1737 }
1738
1739 int __orinoco_down(struct net_device *dev)
1740 {
1741         struct orinoco_private *priv = netdev_priv(dev);
1742         struct hermes *hw = &priv->hw;
1743         int err;
1744
1745         netif_stop_queue(dev);
1746
1747         if (! priv->hw_unavailable) {
1748                 if (! priv->broken_disableport) {
1749                         err = hermes_disable_port(hw, 0);
1750                         if (err) {
1751                                 /* Some firmwares (e.g. Intersil 1.3.x) seem
1752                                  * to have problems disabling the port, oh
1753                                  * well, too bad. */
1754                                 printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
1755                                        dev->name, err);
1756                                 priv->broken_disableport = 1;
1757                         }
1758                 }
1759                 hermes_set_irqmask(hw, 0);
1760                 hermes_write_regn(hw, EVACK, 0xffff);
1761         }
1762         
1763         /* firmware will have to reassociate */
1764         netif_carrier_off(dev);
1765         priv->last_linkstatus = 0xffff;
1766
1767         return 0;
1768 }
1769
1770 int orinoco_reinit_firmware(struct net_device *dev)
1771 {
1772         struct orinoco_private *priv = netdev_priv(dev);
1773         struct hermes *hw = &priv->hw;
1774         int err;
1775
1776         err = hermes_init(hw);
1777         if (err)
1778                 return err;
1779
1780         err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
1781         if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
1782                 /* Try workaround for old Symbol firmware bug */
1783                 printk(KERN_WARNING "%s: firmware ALLOC bug detected "
1784                        "(old Symbol firmware?). Trying to work around... ",
1785                        dev->name);
1786                 
1787                 priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
1788                 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
1789                 if (err)
1790                         printk("failed!\n");
1791                 else
1792                         printk("ok.\n");
1793         }
1794
1795         return err;
1796 }
1797
1798 static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
1799 {
1800         hermes_t *hw = &priv->hw;
1801         int err = 0;
1802
1803         if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
1804                 printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
1805                        priv->ndev->name, priv->bitratemode);
1806                 return -EINVAL;
1807         }
1808
1809         switch (priv->firmware_type) {
1810         case FIRMWARE_TYPE_AGERE:
1811                 err = hermes_write_wordrec(hw, USER_BAP,
1812                                            HERMES_RID_CNFTXRATECONTROL,
1813                                            bitrate_table[priv->bitratemode].agere_txratectrl);
1814                 break;
1815         case FIRMWARE_TYPE_INTERSIL:
1816         case FIRMWARE_TYPE_SYMBOL:
1817                 err = hermes_write_wordrec(hw, USER_BAP,
1818                                            HERMES_RID_CNFTXRATECONTROL,
1819                                            bitrate_table[priv->bitratemode].intersil_txratectrl);
1820                 break;
1821         default:
1822                 BUG();
1823         }
1824
1825         return err;
1826 }
1827
1828 /* Set fixed AP address */
1829 static int __orinoco_hw_set_wap(struct orinoco_private *priv)
1830 {
1831         int roaming_flag;
1832         int err = 0;
1833         hermes_t *hw = &priv->hw;
1834
1835         switch (priv->firmware_type) {
1836         case FIRMWARE_TYPE_AGERE:
1837                 /* not supported */
1838                 break;
1839         case FIRMWARE_TYPE_INTERSIL:
1840                 if (priv->bssid_fixed)
1841                         roaming_flag = 2;
1842                 else
1843                         roaming_flag = 1;
1844
1845                 err = hermes_write_wordrec(hw, USER_BAP,
1846                                            HERMES_RID_CNFROAMINGMODE,
1847                                            roaming_flag);
1848                 break;
1849         case FIRMWARE_TYPE_SYMBOL:
1850                 err = HERMES_WRITE_RECORD(hw, USER_BAP,
1851                                           HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
1852                                           &priv->desired_bssid);
1853                 break;
1854         }
1855         return err;
1856 }
1857
1858 /* Change the WEP keys and/or the current keys.  Can be called
1859  * either from __orinoco_hw_setup_wep() or directly from
1860  * orinoco_ioctl_setiwencode().  In the later case the association
1861  * with the AP is not broken (if the firmware can handle it),
1862  * which is needed for 802.1x implementations. */
1863 static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
1864 {
1865         hermes_t *hw = &priv->hw;
1866         int err = 0;
1867
1868         switch (priv->firmware_type) {
1869         case FIRMWARE_TYPE_AGERE:
1870                 err = HERMES_WRITE_RECORD(hw, USER_BAP,
1871                                           HERMES_RID_CNFWEPKEYS_AGERE,
1872                                           &priv->keys);
1873                 if (err)
1874                         return err;
1875                 err = hermes_write_wordrec(hw, USER_BAP,
1876                                            HERMES_RID_CNFTXKEY_AGERE,
1877                                            priv->tx_key);
1878                 if (err)
1879                         return err;
1880                 break;
1881         case FIRMWARE_TYPE_INTERSIL:
1882         case FIRMWARE_TYPE_SYMBOL:
1883                 {
1884                         int keylen;
1885                         int i;
1886
1887                         /* Force uniform key length to work around firmware bugs */
1888                         keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
1889                         
1890                         if (keylen > LARGE_KEY_SIZE) {
1891                                 printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
1892                                        priv->ndev->name, priv->tx_key, keylen);
1893                                 return -E2BIG;
1894                         }
1895
1896                         /* Write all 4 keys */
1897                         for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
1898                                 err = hermes_write_ltv(hw, USER_BAP,
1899                                                        HERMES_RID_CNFDEFAULTKEY0 + i,
1900                                                        HERMES_BYTES_TO_RECLEN(keylen),
1901                                                        priv->keys[i].data);
1902                                 if (err)
1903                                         return err;
1904                         }
1905
1906                         /* Write the index of the key used in transmission */
1907                         err = hermes_write_wordrec(hw, USER_BAP,
1908                                                    HERMES_RID_CNFWEPDEFAULTKEYID,
1909                                                    priv->tx_key);
1910                         if (err)
1911                                 return err;
1912                 }
1913                 break;
1914         }
1915
1916         return 0;
1917 }
1918
1919 static int __orinoco_hw_setup_wep(struct orinoco_private *priv)
1920 {
1921         hermes_t *hw = &priv->hw;
1922         int err = 0;
1923         int master_wep_flag;
1924         int auth_flag;
1925
1926         if (priv->wep_on)
1927                 __orinoco_hw_setup_wepkeys(priv);
1928
1929         if (priv->wep_restrict)
1930                 auth_flag = HERMES_AUTH_SHARED_KEY;
1931         else
1932                 auth_flag = HERMES_AUTH_OPEN;
1933
1934         switch (priv->firmware_type) {
1935         case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
1936                 if (priv->wep_on) {
1937                         /* Enable the shared-key authentication. */
1938                         err = hermes_write_wordrec(hw, USER_BAP,
1939                                                    HERMES_RID_CNFAUTHENTICATION_AGERE,
1940                                                    auth_flag);
1941                 }
1942                 err = hermes_write_wordrec(hw, USER_BAP,
1943                                            HERMES_RID_CNFWEPENABLED_AGERE,
1944                                            priv->wep_on);
1945                 if (err)
1946                         return err;
1947                 break;
1948
1949         case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
1950         case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
1951                 if (priv->wep_on) {
1952                         if (priv->wep_restrict ||
1953                             (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
1954                                 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
1955                                                   HERMES_WEP_EXCL_UNENCRYPTED;
1956                         else
1957                                 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
1958
1959                         err = hermes_write_wordrec(hw, USER_BAP,
1960                                                    HERMES_RID_CNFAUTHENTICATION,
1961                                                    auth_flag);
1962                         if (err)
1963                                 return err;
1964                 } else
1965                         master_wep_flag = 0;
1966
1967                 if (priv->iw_mode == IW_MODE_MONITOR)
1968                         master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
1969
1970                 /* Master WEP setting : on/off */
1971                 err = hermes_write_wordrec(hw, USER_BAP,
1972                                            HERMES_RID_CNFWEPFLAGS_INTERSIL,
1973                                            master_wep_flag);
1974                 if (err)
1975                         return err;     
1976
1977                 break;
1978         }
1979
1980         return 0;
1981 }
1982
1983 static int __orinoco_program_rids(struct net_device *dev)
1984 {
1985         struct orinoco_private *priv = netdev_priv(dev);
1986         hermes_t *hw = &priv->hw;
1987         int err;
1988         struct hermes_idstring idbuf;
1989
1990         /* Set the MAC address */
1991         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
1992                                HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
1993         if (err) {
1994                 printk(KERN_ERR "%s: Error %d setting MAC address\n",
1995                        dev->name, err);
1996                 return err;
1997         }
1998
1999         /* Set up the link mode */
2000         err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
2001                                    priv->port_type);
2002         if (err) {
2003                 printk(KERN_ERR "%s: Error %d setting port type\n",
2004                        dev->name, err);
2005                 return err;
2006         }
2007         /* Set the channel/frequency */
2008         if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
2009                 err = hermes_write_wordrec(hw, USER_BAP,
2010                                            HERMES_RID_CNFOWNCHANNEL,
2011                                            priv->channel);
2012                 if (err) {
2013                         printk(KERN_ERR "%s: Error %d setting channel %d\n",
2014                                dev->name, err, priv->channel);
2015                         return err;
2016                 }
2017         }
2018
2019         if (priv->has_ibss) {
2020                 u16 createibss;
2021
2022                 if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
2023                         printk(KERN_WARNING "%s: This firmware requires an "
2024                                "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
2025                         /* With wvlan_cs, in this case, we would crash.
2026                          * hopefully, this driver will behave better...
2027                          * Jean II */
2028                         createibss = 0;
2029                 } else {
2030                         createibss = priv->createibss;
2031                 }
2032                 
2033                 err = hermes_write_wordrec(hw, USER_BAP,
2034                                            HERMES_RID_CNFCREATEIBSS,
2035                                            createibss);
2036                 if (err) {
2037                         printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
2038                                dev->name, err);
2039                         return err;
2040                 }
2041         }
2042
2043         /* Set the desired BSSID */
2044         err = __orinoco_hw_set_wap(priv);
2045         if (err) {
2046                 printk(KERN_ERR "%s: Error %d setting AP address\n",
2047                        dev->name, err);
2048                 return err;
2049         }
2050         /* Set the desired ESSID */
2051         idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
2052         memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
2053         /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
2054         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
2055                                HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
2056                                &idbuf);
2057         if (err) {
2058                 printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
2059                        dev->name, err);
2060                 return err;
2061         }
2062         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
2063                                HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
2064                                &idbuf);
2065         if (err) {
2066                 printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
2067                        dev->name, err);
2068                 return err;
2069         }
2070
2071         /* Set the station name */
2072         idbuf.len = cpu_to_le16(strlen(priv->nick));
2073         memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
2074         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
2075                                HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
2076                                &idbuf);
2077         if (err) {
2078                 printk(KERN_ERR "%s: Error %d setting nickname\n",
2079                        dev->name, err);
2080                 return err;
2081         }
2082
2083         /* Set AP density */
2084         if (priv->has_sensitivity) {
2085                 err = hermes_write_wordrec(hw, USER_BAP,
2086                                            HERMES_RID_CNFSYSTEMSCALE,
2087                                            priv->ap_density);
2088                 if (err) {
2089                         printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE.  "
2090                                "Disabling sensitivity control\n",
2091                                dev->name, err);
2092
2093                         priv->has_sensitivity = 0;
2094                 }
2095         }
2096
2097         /* Set RTS threshold */
2098         err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
2099                                    priv->rts_thresh);
2100         if (err) {
2101                 printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
2102                        dev->name, err);
2103                 return err;
2104         }
2105
2106         /* Set fragmentation threshold or MWO robustness */
2107         if (priv->has_mwo)
2108                 err = hermes_write_wordrec(hw, USER_BAP,
2109                                            HERMES_RID_CNFMWOROBUST_AGERE,
2110                                            priv->mwo_robust);
2111         else
2112                 err = hermes_write_wordrec(hw, USER_BAP,
2113                                            HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
2114                                            priv->frag_thresh);
2115         if (err) {
2116                 printk(KERN_ERR "%s: Error %d setting fragmentation\n",
2117                        dev->name, err);
2118                 return err;
2119         }
2120
2121         /* Set bitrate */
2122         err = __orinoco_hw_set_bitrate(priv);
2123         if (err) {
2124                 printk(KERN_ERR "%s: Error %d setting bitrate\n",
2125                        dev->name, err);
2126                 return err;
2127         }
2128
2129         /* Set power management */
2130         if (priv->has_pm) {
2131                 err = hermes_write_wordrec(hw, USER_BAP,
2132                                            HERMES_RID_CNFPMENABLED,
2133                                            priv->pm_on);
2134                 if (err) {
2135                         printk(KERN_ERR "%s: Error %d setting up PM\n",
2136                                dev->name, err);
2137                         return err;
2138                 }
2139
2140                 err = hermes_write_wordrec(hw, USER_BAP,
2141                                            HERMES_RID_CNFMULTICASTRECEIVE,
2142                                            priv->pm_mcast);
2143                 if (err) {
2144                         printk(KERN_ERR "%s: Error %d setting up PM\n",
2145                                dev->name, err);
2146                         return err;
2147                 }
2148                 err = hermes_write_wordrec(hw, USER_BAP,
2149                                            HERMES_RID_CNFMAXSLEEPDURATION,
2150                                            priv->pm_period);
2151                 if (err) {
2152                         printk(KERN_ERR "%s: Error %d setting up PM\n",
2153                                dev->name, err);
2154                         return err;
2155                 }
2156                 err = hermes_write_wordrec(hw, USER_BAP,
2157                                            HERMES_RID_CNFPMHOLDOVERDURATION,
2158                                            priv->pm_timeout);
2159                 if (err) {
2160                         printk(KERN_ERR "%s: Error %d setting up PM\n",
2161                                dev->name, err);
2162                         return err;
2163                 }
2164         }
2165
2166         /* Set preamble - only for Symbol so far... */
2167         if (priv->has_preamble) {
2168                 err = hermes_write_wordrec(hw, USER_BAP,
2169                                            HERMES_RID_CNFPREAMBLE_SYMBOL,
2170                                            priv->preamble);
2171                 if (err) {
2172                         printk(KERN_ERR "%s: Error %d setting preamble\n",
2173                                dev->name, err);
2174                         return err;
2175                 }
2176         }
2177
2178         /* Set up encryption */
2179         if (priv->has_wep) {
2180                 err = __orinoco_hw_setup_wep(priv);
2181                 if (err) {
2182                         printk(KERN_ERR "%s: Error %d activating WEP\n",
2183                                dev->name, err);
2184                         return err;
2185                 }
2186         }
2187
2188         if (priv->iw_mode == IW_MODE_MONITOR) {
2189                 /* Enable monitor mode */
2190                 dev->type = ARPHRD_IEEE80211;
2191                 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 
2192                                             HERMES_TEST_MONITOR, 0, NULL);
2193         } else {
2194                 /* Disable monitor mode */
2195                 dev->type = ARPHRD_ETHER;
2196                 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
2197                                             HERMES_TEST_STOP, 0, NULL);
2198         }
2199         if (err)
2200                 return err;
2201
2202         /* Set promiscuity / multicast*/
2203         priv->promiscuous = 0;
2204         priv->mc_count = 0;
2205         __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */
2206
2207         return 0;
2208 }
2209
2210 /* FIXME: return int? */
2211 static void
2212 __orinoco_set_multicast_list(struct net_device *dev)
2213 {
2214         struct orinoco_private *priv = netdev_priv(dev);
2215         hermes_t *hw = &priv->hw;
2216         int err = 0;
2217         int promisc, mc_count;
2218
2219         /* The Hermes doesn't seem to have an allmulti mode, so we go
2220          * into promiscuous mode and let the upper levels deal. */
2221         if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
2222              (dev->mc_count > MAX_MULTICAST(priv)) ) {
2223                 promisc = 1;
2224                 mc_count = 0;
2225         } else {
2226                 promisc = 0;
2227                 mc_count = dev->mc_count;
2228         }
2229
2230         if (promisc != priv->promiscuous) {
2231                 err = hermes_write_wordrec(hw, USER_BAP,
2232                                            HERMES_RID_CNFPROMISCUOUSMODE,
2233                                            promisc);
2234                 if (err) {
2235                         printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
2236                                dev->name, err);
2237                 } else 
2238                         priv->promiscuous = promisc;
2239         }
2240
2241         if (! promisc && (mc_count || priv->mc_count) ) {
2242                 struct dev_mc_list *p = dev->mc_list;
2243                 struct hermes_multicast mclist;
2244                 int i;
2245
2246                 for (i = 0; i < mc_count; i++) {
2247                         /* paranoia: is list shorter than mc_count? */
2248                         BUG_ON(! p);
2249                         /* paranoia: bad address size in list? */
2250                         BUG_ON(p->dmi_addrlen != ETH_ALEN);
2251                         
2252                         memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
2253                         p = p->next;
2254                 }
2255                 
2256                 if (p)
2257                         printk(KERN_WARNING "%s: Multicast list is "
2258                                "longer than mc_count\n", dev->name);
2259
2260                 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES,
2261                                        HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
2262                                        &mclist);
2263                 if (err)
2264                         printk(KERN_ERR "%s: Error %d setting multicast list.\n",
2265                                dev->name, err);
2266                 else
2267                         priv->mc_count = mc_count;
2268         }
2269
2270         /* Since we can set the promiscuous flag when it wasn't asked
2271            for, make sure the net_device knows about it. */
2272         if (priv->promiscuous)
2273                 dev->flags |= IFF_PROMISC;
2274         else
2275                 dev->flags &= ~IFF_PROMISC;
2276 }
2277
2278 /* This must be called from user context, without locks held - use
2279  * schedule_work() */
2280 static void orinoco_reset(struct net_device *dev)
2281 {
2282         struct orinoco_private *priv = netdev_priv(dev);
2283         struct hermes *hw = &priv->hw;
2284         int err;
2285         unsigned long flags;
2286
2287         if (orinoco_lock(priv, &flags) != 0)
2288                 /* When the hardware becomes available again, whatever
2289                  * detects that is responsible for re-initializing
2290                  * it. So no need for anything further */
2291                 return;
2292
2293         netif_stop_queue(dev);
2294
2295         /* Shut off interrupts.  Depending on what state the hardware
2296          * is in, this might not work, but we'll try anyway */
2297         hermes_set_irqmask(hw, 0);
2298         hermes_write_regn(hw, EVACK, 0xffff);
2299
2300         priv->hw_unavailable++;
2301         priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
2302         netif_carrier_off(dev);
2303
2304         orinoco_unlock(priv, &flags);
2305
2306         /* Scanning support: Cleanup of driver struct */
2307         kfree(priv->scan_result);
2308         priv->scan_result = NULL;
2309         priv->scan_inprogress = 0;
2310
2311         if (priv->hard_reset) {
2312                 err = (*priv->hard_reset)(priv);
2313                 if (err) {
2314                         printk(KERN_ERR "%s: orinoco_reset: Error %d "
2315                                "performing hard reset\n", dev->name, err);
2316                         goto disable;
2317                 }
2318         }
2319
2320         err = orinoco_reinit_firmware(dev);
2321         if (err) {
2322                 printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
2323                        dev->name, err);
2324                 goto disable;
2325         }
2326
2327         spin_lock_irq(&priv->lock); /* This has to be called from user context */
2328
2329         priv->hw_unavailable--;
2330
2331         /* priv->open or priv->hw_unavailable might have changed while
2332          * we dropped the lock */
2333         if (priv->open && (! priv->hw_unavailable)) {
2334                 err = __orinoco_up(dev);
2335                 if (err) {
2336                         printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
2337                                dev->name, err);
2338                 } else
2339                         dev->trans_start = jiffies;
2340         }
2341
2342         spin_unlock_irq(&priv->lock);
2343
2344         return;
2345  disable:
2346         hermes_set_irqmask(hw, 0);
2347         netif_device_detach(dev);
2348         printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
2349 }
2350
2351 /********************************************************************/
2352 /* Interrupt handler                                                */
2353 /********************************************************************/
2354
2355 static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
2356 {
2357         printk(KERN_DEBUG "%s: TICK\n", dev->name);
2358 }
2359
2360 static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
2361 {
2362         /* This seems to happen a fair bit under load, but ignoring it
2363            seems to work fine...*/
2364         printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
2365                dev->name);
2366 }
2367
2368 irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2369 {
2370         struct net_device *dev = (struct net_device *)dev_id;
2371         struct orinoco_private *priv = netdev_priv(dev);
2372         hermes_t *hw = &priv->hw;
2373         int count = MAX_IRQLOOPS_PER_IRQ;
2374         u16 evstat, events;
2375         /* These are used to detect a runaway interrupt situation */
2376         /* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
2377          * we panic and shut down the hardware */
2378         static int last_irq_jiffy = 0; /* jiffies value the last time
2379                                         * we were called */
2380         static int loops_this_jiffy = 0;
2381         unsigned long flags;
2382
2383         if (orinoco_lock(priv, &flags) != 0) {
2384                 /* If hw is unavailable - we don't know if the irq was
2385                  * for us or not */
2386                 return IRQ_HANDLED;
2387         }
2388
2389         evstat = hermes_read_regn(hw, EVSTAT);
2390         events = evstat & hw->inten;
2391         if (! events) {
2392                 orinoco_unlock(priv, &flags);
2393                 return IRQ_NONE;
2394         }
2395         
2396         if (jiffies != last_irq_jiffy)
2397                 loops_this_jiffy = 0;
2398         last_irq_jiffy = jiffies;
2399
2400         while (events && count--) {
2401                 if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
2402                         printk(KERN_WARNING "%s: IRQ handler is looping too "
2403                                "much! Resetting.\n", dev->name);
2404                         /* Disable interrupts for now */
2405                         hermes_set_irqmask(hw, 0);
2406                         schedule_work(&priv->reset_work);
2407                         break;
2408                 }
2409
2410                 /* Check the card hasn't been removed */
2411                 if (! hermes_present(hw)) {
2412                         DEBUG(0, "orinoco_interrupt(): card removed\n");
2413                         break;
2414                 }
2415
2416                 if (events & HERMES_EV_TICK)
2417                         __orinoco_ev_tick(dev, hw);
2418                 if (events & HERMES_EV_WTERR)
2419                         __orinoco_ev_wterr(dev, hw);
2420                 if (events & HERMES_EV_INFDROP)
2421                         __orinoco_ev_infdrop(dev, hw);
2422                 if (events & HERMES_EV_INFO)
2423                         __orinoco_ev_info(dev, hw);
2424                 if (events & HERMES_EV_RX)
2425                         __orinoco_ev_rx(dev, hw);
2426                 if (events & HERMES_EV_TXEXC)
2427                         __orinoco_ev_txexc(dev, hw);
2428                 if (events & HERMES_EV_TX)
2429                         __orinoco_ev_tx(dev, hw);
2430                 if (events & HERMES_EV_ALLOC)
2431                         __orinoco_ev_alloc(dev, hw);
2432                 
2433                 hermes_write_regn(hw, EVACK, evstat);
2434
2435                 evstat = hermes_read_regn(hw, EVSTAT);
2436                 events = evstat & hw->inten;
2437         };
2438
2439         orinoco_unlock(priv, &flags);
2440         return IRQ_HANDLED;
2441 }
2442
2443 /********************************************************************/
2444 /* Initialization                                                   */
2445 /********************************************************************/
2446
2447 struct comp_id {
2448         u16 id, variant, major, minor;
2449 } __attribute__ ((packed));
2450
2451 static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
2452 {
2453         if (nic_id->id < 0x8000)
2454                 return FIRMWARE_TYPE_AGERE;
2455         else if (nic_id->id == 0x8000 && nic_id->major == 0)
2456                 return FIRMWARE_TYPE_SYMBOL;
2457         else
2458                 return FIRMWARE_TYPE_INTERSIL;
2459 }
2460
2461 /* Set priv->firmware type, determine firmware properties */
2462 static int determine_firmware(struct net_device *dev)
2463 {
2464         struct orinoco_private *priv = netdev_priv(dev);
2465         hermes_t *hw = &priv->hw;
2466         int err;
2467         struct comp_id nic_id, sta_id;
2468         unsigned int firmver;
2469         char tmp[SYMBOL_MAX_VER_LEN+1];
2470
2471         /* Get the hardware version */
2472         err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
2473         if (err) {
2474                 printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
2475                        dev->name, err);
2476                 return err;
2477         }
2478
2479         le16_to_cpus(&nic_id.id);
2480         le16_to_cpus(&nic_id.variant);
2481         le16_to_cpus(&nic_id.major);
2482         le16_to_cpus(&nic_id.minor);
2483         printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
2484                dev->name, nic_id.id, nic_id.variant,
2485                nic_id.major, nic_id.minor);
2486
2487         priv->firmware_type = determine_firmware_type(&nic_id);
2488
2489         /* Get the firmware version */
2490         err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
2491         if (err) {
2492                 printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
2493                        dev->name, err);
2494                 return err;
2495         }
2496
2497         le16_to_cpus(&sta_id.id);
2498         le16_to_cpus(&sta_id.variant);
2499         le16_to_cpus(&sta_id.major);
2500         le16_to_cpus(&sta_id.minor);
2501         printk(KERN_DEBUG "%s: Station identity  %04x:%04x:%04x:%04x\n",
2502                dev->name, sta_id.id, sta_id.variant,
2503                sta_id.major, sta_id.minor);
2504
2505         switch (sta_id.id) {
2506         case 0x15:
2507                 printk(KERN_ERR "%s: Primary firmware is active\n",
2508                        dev->name);
2509                 return -ENODEV;
2510         case 0x14b:
2511                 printk(KERN_ERR "%s: Tertiary firmware is active\n",
2512                        dev->name);
2513                 return -ENODEV;
2514         case 0x1f:      /* Intersil, Agere, Symbol Spectrum24 */
2515         case 0x21:      /* Symbol Spectrum24 Trilogy */
2516                 break;
2517         default:
2518                 printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
2519                        dev->name);
2520                 break;
2521         }
2522
2523         /* Default capabilities */
2524         priv->has_sensitivity = 1;
2525         priv->has_mwo = 0;
2526         priv->has_preamble = 0;
2527         priv->has_port3 = 1;
2528         priv->has_ibss = 1;
2529         priv->has_wep = 0;
2530         priv->has_big_wep = 0;
2531
2532         /* Determine capabilities from the firmware version */
2533         switch (priv->firmware_type) {
2534         case FIRMWARE_TYPE_AGERE:
2535                 /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
2536                    ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
2537                 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2538                          "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
2539
2540                 firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
2541
2542                 priv->has_ibss = (firmver >= 0x60006);
2543                 priv->has_wep = (firmver >= 0x40020);
2544                 priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
2545                                           Gold cards from the others? */
2546                 priv->has_mwo = (firmver >= 0x60000);
2547                 priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
2548                 priv->ibss_port = 1;
2549                 priv->has_hostscan = (firmver >= 0x8000a);
2550                 priv->broken_monitor = (firmver >= 0x80000);
2551
2552                 /* Tested with Agere firmware :
2553                  *      1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
2554                  * Tested CableTron firmware : 4.32 => Anton */
2555                 break;
2556         case FIRMWARE_TYPE_SYMBOL:
2557                 /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
2558                 /* Intel MAC : 00:02:B3:* */
2559                 /* 3Com MAC : 00:50:DA:* */
2560                 memset(tmp, 0, sizeof(tmp));
2561                 /* Get the Symbol firmware version */
2562                 err = hermes_read_ltv(hw, USER_BAP,
2563                                       HERMES_RID_SECONDARYVERSION_SYMBOL,
2564                                       SYMBOL_MAX_VER_LEN, NULL, &tmp);
2565                 if (err) {
2566                         printk(KERN_WARNING
2567                                "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",
2568                                dev->name, err);
2569                         firmver = 0;
2570                         tmp[0] = '\0';
2571                 } else {
2572                         /* The firmware revision is a string, the format is
2573                          * something like : "V2.20-01".
2574                          * Quick and dirty parsing... - Jean II
2575                          */
2576                         firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12)
2577                                 | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4)
2578                                 | (tmp[7] - '0');
2579
2580                         tmp[SYMBOL_MAX_VER_LEN] = '\0';
2581                 }
2582
2583                 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2584                          "Symbol %s", tmp);
2585
2586                 priv->has_ibss = (firmver >= 0x20000);
2587                 priv->has_wep = (firmver >= 0x15012);
2588                 priv->has_big_wep = (firmver >= 0x20000);
2589                 priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) || 
2590                                (firmver >= 0x29000 && firmver < 0x30000) ||
2591                                firmver >= 0x31000;
2592                 priv->has_preamble = (firmver >= 0x20000);
2593                 priv->ibss_port = 4;
2594                 priv->broken_disableport = (firmver == 0x25013) ||
2595                                            (firmver >= 0x30000 && firmver <= 0x31000);
2596                 priv->has_hostscan = (firmver >= 0x31001) ||
2597                                      (firmver >= 0x29057 && firmver < 0x30000);
2598                 /* Tested with Intel firmware : 0x20015 => Jean II */
2599                 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
2600                 break;
2601         case FIRMWARE_TYPE_INTERSIL:
2602                 /* D-Link, Linksys, Adtron, ZoomAir, and many others...
2603                  * Samsung, Compaq 100/200 and Proxim are slightly
2604                  * different and less well tested */
2605                 /* D-Link MAC : 00:40:05:* */
2606                 /* Addtron MAC : 00:90:D1:* */
2607                 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2608                          "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
2609                          sta_id.variant);
2610
2611                 firmver = ((unsigned long)sta_id.major << 16) |
2612                         ((unsigned long)sta_id.minor << 8) | sta_id.variant;
2613
2614                 priv->has_ibss = (firmver >= 0x000700); /* FIXME */
2615                 priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
2616                 priv->has_pm = (firmver >= 0x000700);
2617                 priv->has_hostscan = (firmver >= 0x010301);
2618
2619                 if (firmver >= 0x000800)
2620                         priv->ibss_port = 0;
2621                 else {
2622                         printk(KERN_NOTICE "%s: Intersil firmware earlier "
2623                                "than v0.8.x - several features not supported\n",
2624                                dev->name);
2625                         priv->ibss_port = 1;
2626                 }
2627                 break;
2628         }
2629         printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
2630                priv->fw_name);
2631
2632         return 0;
2633 }
2634
2635 static int orinoco_init(struct net_device *dev)
2636 {
2637         struct orinoco_private *priv = netdev_priv(dev);
2638         hermes_t *hw = &priv->hw;
2639         int err = 0;
2640         struct hermes_idstring nickbuf;
2641         u16 reclen;
2642         int len;
2643
2644         TRACE_ENTER(dev->name);
2645
2646         /* No need to lock, the hw_unavailable flag is already set in
2647          * alloc_orinocodev() */
2648         priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
2649
2650         /* Initialize the firmware */
2651         err = orinoco_reinit_firmware(dev);
2652         if (err != 0) {
2653                 printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
2654                        dev->name, err);
2655                 goto out;
2656         }
2657
2658         err = determine_firmware(dev);
2659         if (err != 0) {
2660                 printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
2661                        dev->name);
2662                 goto out;
2663         }
2664
2665         if (priv->has_port3)
2666                 printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
2667         if (priv->has_ibss)
2668                 printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
2669                        dev->name);
2670         if (priv->has_wep) {
2671                 printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
2672                 if (priv->has_big_wep)
2673                         printk("104-bit key\n");
2674                 else
2675                         printk("40-bit key\n");
2676         }
2677
2678         /* Get the MAC address */
2679         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
2680                               ETH_ALEN, NULL, dev->dev_addr);
2681         if (err) {
2682                 printk(KERN_WARNING "%s: failed to read MAC address!\n",
2683                        dev->name);
2684                 goto out;
2685         }
2686
2687         printk(KERN_DEBUG "%s: MAC address %02X:%02X:%02X:%02X:%02X:%02X\n",
2688                dev->name, dev->dev_addr[0], dev->dev_addr[1],
2689                dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4],
2690                dev->dev_addr[5]);
2691
2692         /* Get the station name */
2693         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
2694                               sizeof(nickbuf), &reclen, &nickbuf);
2695         if (err) {
2696                 printk(KERN_ERR "%s: failed to read station name\n",
2697                        dev->name);
2698                 goto out;
2699         }
2700         if (nickbuf.len)
2701                 len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
2702         else
2703                 len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
2704         memcpy(priv->nick, &nickbuf.val, len);
2705         priv->nick[len] = '\0';
2706
2707         printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
2708
2709         /* Get allowed channels */
2710         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
2711                                   &priv->channel_mask);
2712         if (err) {
2713                 printk(KERN_ERR "%s: failed to read channel list!\n",
2714                        dev->name);
2715                 goto out;
2716         }
2717
2718         /* Get initial AP density */
2719         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
2720                                   &priv->ap_density);
2721         if (err || priv->ap_density < 1 || priv->ap_density > 3) {
2722                 priv->has_sensitivity = 0;
2723         }
2724
2725         /* Get initial RTS threshold */
2726         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
2727                                   &priv->rts_thresh);
2728         if (err) {
2729                 printk(KERN_ERR "%s: failed to read RTS threshold!\n",
2730                        dev->name);
2731                 goto out;
2732         }
2733
2734         /* Get initial fragmentation settings */
2735         if (priv->has_mwo)
2736                 err = hermes_read_wordrec(hw, USER_BAP,
2737                                           HERMES_RID_CNFMWOROBUST_AGERE,
2738                                           &priv->mwo_robust);
2739         else
2740                 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
2741                                           &priv->frag_thresh);
2742         if (err) {
2743                 printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
2744                        dev->name);
2745                 goto out;
2746         }
2747
2748         /* Power management setup */
2749         if (priv->has_pm) {
2750                 priv->pm_on = 0;
2751                 priv->pm_mcast = 1;
2752                 err = hermes_read_wordrec(hw, USER_BAP,
2753                                           HERMES_RID_CNFMAXSLEEPDURATION,
2754                                           &priv->pm_period);
2755                 if (err) {
2756                         printk(KERN_ERR "%s: failed to read power management period!\n",
2757                                dev->name);
2758                         goto out;
2759                 }
2760                 err = hermes_read_wordrec(hw, USER_BAP,
2761                                           HERMES_RID_CNFPMHOLDOVERDURATION,
2762                                           &priv->pm_timeout);
2763                 if (err) {
2764                         printk(KERN_ERR "%s: failed to read power management timeout!\n",
2765                                dev->name);
2766                         goto out;
2767                 }
2768         }
2769
2770         /* Preamble setup */
2771         if (priv->has_preamble) {
2772                 err = hermes_read_wordrec(hw, USER_BAP,
2773                                           HERMES_RID_CNFPREAMBLE_SYMBOL,
2774                                           &priv->preamble);
2775                 if (err)
2776                         goto out;
2777         }
2778                 
2779         /* Set up the default configuration */
2780         priv->iw_mode = IW_MODE_INFRA;
2781         /* By default use IEEE/IBSS ad-hoc mode if we have it */
2782         priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
2783         set_port_type(priv);
2784         priv->channel = 0; /* use firmware default */
2785
2786         priv->promiscuous = 0;
2787         priv->wep_on = 0;
2788         priv->tx_key = 0;
2789
2790         /* Make the hardware available, as long as it hasn't been
2791          * removed elsewhere (e.g. by PCMCIA hot unplug) */
2792         spin_lock_irq(&priv->lock);
2793         priv->hw_unavailable--;
2794         spin_unlock_irq(&priv->lock);
2795
2796         printk(KERN_DEBUG "%s: ready\n", dev->name);
2797
2798  out:
2799         TRACE_EXIT(dev->name);
2800         return err;
2801 }
2802
2803 struct net_device *alloc_orinocodev(int sizeof_card,
2804                                     int (*hard_reset)(struct orinoco_private *))
2805 {
2806         struct net_device *dev;
2807         struct orinoco_private *priv;
2808
2809         dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
2810         if (! dev)
2811                 return NULL;
2812         priv = netdev_priv(dev);
2813         priv->ndev = dev;
2814         if (sizeof_card)
2815                 priv->card = (void *)((unsigned long)priv
2816                                       + sizeof(struct orinoco_private));
2817         else
2818                 priv->card = NULL;
2819
2820         /* Setup / override net_device fields */
2821         dev->init = orinoco_init;
2822         dev->hard_start_xmit = orinoco_xmit;
2823         dev->tx_timeout = orinoco_tx_timeout;
2824         dev->watchdog_timeo = HZ; /* 1 second timeout */
2825         dev->get_stats = orinoco_get_stats;
2826         dev->ethtool_ops = &orinoco_ethtool_ops;
2827         dev->get_wireless_stats = orinoco_get_wireless_stats;
2828         dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
2829         dev->change_mtu = orinoco_change_mtu;
2830         dev->set_multicast_list = orinoco_set_multicast_list;
2831         /* we use the default eth_mac_addr for setting the MAC addr */
2832
2833         /* Set up default callbacks */
2834         dev->open = orinoco_open;
2835         dev->stop = orinoco_stop;
2836         priv->hard_reset = hard_reset;
2837
2838         spin_lock_init(&priv->lock);
2839         priv->open = 0;
2840         priv->hw_unavailable = 1; /* orinoco_init() must clear this
2841                                    * before anything else touches the
2842                                    * hardware */
2843         INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev);
2844         INIT_WORK(&priv->join_work, (void (*)(void *))orinoco_join_ap, dev);
2845         INIT_WORK(&priv->wevent_work, (void (*)(void *))orinoco_send_wevents, dev);
2846
2847         netif_carrier_off(dev);
2848         priv->last_linkstatus = 0xffff;
2849
2850         return dev;
2851
2852 }
2853
2854 void free_orinocodev(struct net_device *dev)
2855 {
2856         struct orinoco_private *priv = netdev_priv(dev);
2857
2858         kfree(priv->scan_result);
2859         free_netdev(dev);
2860 }
2861
2862 /********************************************************************/
2863 /* Wireless extensions                                              */
2864 /********************************************************************/
2865
2866 static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
2867                                 char buf[IW_ESSID_MAX_SIZE+1])
2868 {
2869         hermes_t *hw = &priv->hw;
2870         int err = 0;
2871         struct hermes_idstring essidbuf;
2872         char *p = (char *)(&essidbuf.val);
2873         int len;
2874         unsigned long flags;
2875
2876         if (orinoco_lock(priv, &flags) != 0)
2877                 return -EBUSY;
2878
2879         if (strlen(priv->desired_essid) > 0) {
2880                 /* We read the desired SSID from the hardware rather
2881                    than from priv->desired_essid, just in case the
2882                    firmware is allowed to change it on us. I'm not
2883                    sure about this */
2884                 /* My guess is that the OWNSSID should always be whatever
2885                  * we set to the card, whereas CURRENT_SSID is the one that
2886                  * may change... - Jean II */
2887                 u16 rid;
2888
2889                 *active = 1;
2890
2891                 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
2892                         HERMES_RID_CNFDESIREDSSID;
2893                 
2894                 err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
2895                                       NULL, &essidbuf);
2896                 if (err)
2897                         goto fail_unlock;
2898         } else {
2899                 *active = 0;
2900
2901                 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
2902                                       sizeof(essidbuf), NULL, &essidbuf);
2903                 if (err)
2904                         goto fail_unlock;
2905         }
2906
2907         len = le16_to_cpu(essidbuf.len);
2908         BUG_ON(len > IW_ESSID_MAX_SIZE);
2909
2910         memset(buf, 0, IW_ESSID_MAX_SIZE+1);
2911         memcpy(buf, p, len);
2912         buf[len] = '\0';
2913
2914  fail_unlock:
2915         orinoco_unlock(priv, &flags);
2916
2917         return err;       
2918 }
2919
2920 static long orinoco_hw_get_freq(struct orinoco_private *priv)
2921 {
2922         
2923         hermes_t *hw = &priv->hw;
2924         int err = 0;
2925         u16 channel;
2926         long freq = 0;
2927         unsigned long flags;
2928
2929         if (orinoco_lock(priv, &flags) != 0)
2930                 return -EBUSY;
2931         
2932         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
2933         if (err)
2934                 goto out;
2935
2936         /* Intersil firmware 1.3.5 returns 0 when the interface is down */
2937         if (channel == 0) {
2938                 err = -EBUSY;
2939                 goto out;
2940         }
2941
2942         if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
2943                 printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
2944                        priv->ndev->name, channel);
2945                 err = -EBUSY;
2946                 goto out;
2947
2948         }
2949         freq = channel_frequency[channel-1] * 100000;
2950
2951  out:
2952         orinoco_unlock(priv, &flags);
2953
2954         if (err > 0)
2955                 err = -EBUSY;
2956         return err ? err : freq;
2957 }
2958
2959 static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
2960                                       int *numrates, s32 *rates, int max)
2961 {
2962         hermes_t *hw = &priv->hw;
2963         struct hermes_idstring list;
2964         unsigned char *p = (unsigned char *)&list.val;
2965         int err = 0;
2966         int num;
2967         int i;
2968         unsigned long flags;
2969
2970         if (orinoco_lock(priv, &flags) != 0)
2971                 return -EBUSY;
2972
2973         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
2974                               sizeof(list), NULL, &list);
2975         orinoco_unlock(priv, &flags);
2976
2977         if (err)
2978                 return err;
2979         
2980         num = le16_to_cpu(list.len);
2981         *numrates = num;
2982         num = min(num, max);
2983
2984         for (i = 0; i < num; i++) {
2985                 rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
2986         }
2987
2988         return 0;
2989 }
2990
2991 static int orinoco_ioctl_getname(struct net_device *dev,
2992                                  struct iw_request_info *info,
2993                                  char *name,
2994                                  char *extra)
2995 {
2996         struct orinoco_private *priv = netdev_priv(dev);
2997         int numrates;
2998         int err;
2999
3000         err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
3001
3002         if (!err && (numrates > 2))
3003                 strcpy(name, "IEEE 802.11b");
3004         else
3005                 strcpy(name, "IEEE 802.11-DS");
3006
3007         return 0;
3008 }
3009
3010 static int orinoco_ioctl_setwap(struct net_device *dev,
3011                                 struct iw_request_info *info,
3012                                 struct sockaddr *ap_addr,
3013                                 char *extra)
3014 {
3015         struct orinoco_private *priv = netdev_priv(dev);
3016         int err = -EINPROGRESS;         /* Call commit handler */
3017         unsigned long flags;
3018         static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3019         static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
3020
3021         if (orinoco_lock(priv, &flags) != 0)
3022                 return -EBUSY;
3023
3024         /* Enable automatic roaming - no sanity checks are needed */
3025         if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
3026             memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
3027                 priv->bssid_fixed = 0;
3028                 memset(priv->desired_bssid, 0, ETH_ALEN);
3029
3030                 /* "off" means keep existing connection */
3031                 if (ap_addr->sa_data[0] == 0) {
3032                         __orinoco_hw_set_wap(priv);
3033                         err = 0;
3034                 }
3035                 goto out;
3036         }
3037
3038         if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
3039                 printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
3040                        "support manual roaming\n",
3041                        dev->name);
3042                 err = -EOPNOTSUPP;
3043                 goto out;
3044         }
3045
3046         if (priv->iw_mode != IW_MODE_INFRA) {
3047                 printk(KERN_WARNING "%s: Manual roaming supported only in "
3048                        "managed mode\n", dev->name);
3049                 err = -EOPNOTSUPP;
3050                 goto out;
3051         }
3052
3053         /* Intersil firmware hangs without Desired ESSID */
3054         if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
3055             strlen(priv->desired_essid) == 0) {
3056                 printk(KERN_WARNING "%s: Desired ESSID must be set for "
3057                        "manual roaming\n", dev->name);
3058                 err = -EOPNOTSUPP;
3059                 goto out;
3060         }
3061
3062         /* Finally, enable manual roaming */
3063         priv->bssid_fixed = 1;
3064         memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
3065
3066  out:
3067         orinoco_unlock(priv, &flags);
3068         return err;
3069 }
3070
3071 static int orinoco_ioctl_getwap(struct net_device *dev,
3072                                 struct iw_request_info *info,
3073                                 struct sockaddr *ap_addr,
3074                                 char *extra)
3075 {
3076         struct orinoco_private *priv = netdev_priv(dev);
3077
3078         hermes_t *hw = &priv->hw;
3079         int err = 0;
3080         unsigned long flags;
3081
3082         if (orinoco_lock(priv, &flags) != 0)
3083                 return -EBUSY;
3084
3085         ap_addr->sa_family = ARPHRD_ETHER;
3086         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
3087                               ETH_ALEN, NULL, ap_addr->sa_data);
3088
3089         orinoco_unlock(priv, &flags);
3090
3091         return err;
3092 }
3093
3094 static int orinoco_ioctl_setmode(struct net_device *dev,
3095                                  struct iw_request_info *info,
3096                                  u32 *mode,
3097                                  char *extra)
3098 {
3099         struct orinoco_private *priv = netdev_priv(dev);
3100         int err = -EINPROGRESS;         /* Call commit handler */
3101         unsigned long flags;
3102
3103         if (priv->iw_mode == *mode)
3104                 return 0;
3105
3106         if (orinoco_lock(priv, &flags) != 0)
3107                 return -EBUSY;
3108
3109         switch (*mode) {
3110         case IW_MODE_ADHOC:
3111                 if (!priv->has_ibss && !priv->has_port3)
3112                         err = -EOPNOTSUPP;
3113                 break;
3114
3115         case IW_MODE_INFRA:
3116                 break;
3117
3118         case IW_MODE_MONITOR:
3119                 if (priv->broken_monitor && !force_monitor) {
3120                         printk(KERN_WARNING "%s: Monitor mode support is "
3121                                "buggy in this firmware, not enabling\n",
3122                                dev->name);
3123                         err = -EOPNOTSUPP;
3124                 }
3125                 break;
3126
3127         default:
3128                 err = -EOPNOTSUPP;
3129                 break;
3130         }
3131
3132         if (err == -EINPROGRESS) {
3133                 priv->iw_mode = *mode;
3134                 set_port_type(priv);
3135         }
3136
3137         orinoco_unlock(priv, &flags);
3138
3139         return err;
3140 }
3141
3142 static int orinoco_ioctl_getmode(struct net_device *dev,
3143                                  struct iw_request_info *info,
3144                                  u32 *mode,
3145                                  char *extra)
3146 {
3147         struct orinoco_private *priv = netdev_priv(dev);
3148
3149         *mode = priv->iw_mode;
3150         return 0;
3151 }
3152
3153 static int orinoco_ioctl_getiwrange(struct net_device *dev,
3154                                     struct iw_request_info *info,
3155                                     struct iw_point *rrq,
3156                                     char *extra)
3157 {
3158         struct orinoco_private *priv = netdev_priv(dev);
3159         int err = 0;
3160         struct iw_range *range = (struct iw_range *) extra;
3161         int numrates;
3162         int i, k;
3163
3164         TRACE_ENTER(dev->name);
3165
3166         rrq->length = sizeof(struct iw_range);
3167         memset(range, 0, sizeof(struct iw_range));
3168
3169         range->we_version_compiled = WIRELESS_EXT;
3170         range->we_version_source = 14;
3171
3172         /* Set available channels/frequencies */
3173         range->num_channels = NUM_CHANNELS;
3174         k = 0;
3175         for (i = 0; i < NUM_CHANNELS; i++) {
3176                 if (priv->channel_mask & (1 << i)) {
3177                         range->freq[k].i = i + 1;
3178                         range->freq[k].m = channel_frequency[i] * 100000;
3179                         range->freq[k].e = 1;
3180                         k++;
3181                 }
3182                 
3183                 if (k >= IW_MAX_FREQUENCIES)
3184                         break;
3185         }
3186         range->num_frequency = k;
3187         range->sensitivity = 3;
3188
3189         if (priv->has_wep) {
3190                 range->max_encoding_tokens = ORINOCO_MAX_KEYS;
3191                 range->encoding_size[0] = SMALL_KEY_SIZE;
3192                 range->num_encoding_sizes = 1;
3193
3194                 if (priv->has_big_wep) {
3195                         range->encoding_size[1] = LARGE_KEY_SIZE;
3196                         range->num_encoding_sizes = 2;
3197                 }
3198         }
3199
3200         if ((priv->iw_mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
3201                 /* Quality stats meaningless in ad-hoc mode */
3202         } else {
3203                 range->max_qual.qual = 0x8b - 0x2f;
3204                 range->max_qual.level = 0x2f - 0x95 - 1;
3205                 range->max_qual.noise = 0x2f - 0x95 - 1;
3206                 /* Need to get better values */
3207                 range->avg_qual.qual = 0x24;
3208                 range->avg_qual.level = 0xC2;
3209                 range->avg_qual.noise = 0x9E;
3210         }
3211
3212         err = orinoco_hw_get_bitratelist(priv, &numrates,
3213                                          range->bitrate, IW_MAX_BITRATES);
3214         if (err)
3215                 return err;
3216         range->num_bitrates = numrates;
3217
3218         /* Set an indication of the max TCP throughput in bit/s that we can
3219          * expect using this interface. May be use for QoS stuff...
3220          * Jean II */
3221         if (numrates > 2)
3222                 range->throughput = 5 * 1000 * 1000;    /* ~5 Mb/s */
3223         else
3224                 range->throughput = 1.5 * 1000 * 1000;  /* ~1.5 Mb/s */
3225
3226         range->min_rts = 0;
3227         range->max_rts = 2347;
3228         range->min_frag = 256;
3229         range->max_frag = 2346;
3230
3231         range->min_pmp = 0;
3232         range->max_pmp = 65535000;
3233         range->min_pmt = 0;
3234         range->max_pmt = 65535 * 1000;  /* ??? */
3235         range->pmp_flags = IW_POWER_PERIOD;
3236         range->pmt_flags = IW_POWER_TIMEOUT;
3237         range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
3238
3239         range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
3240         range->retry_flags = IW_RETRY_LIMIT;
3241         range->r_time_flags = IW_RETRY_LIFETIME;
3242         range->min_retry = 0;
3243         range->max_retry = 65535;       /* ??? */
3244         range->min_r_time = 0;
3245         range->max_r_time = 65535 * 1000;       /* ??? */
3246
3247         TRACE_EXIT(dev->name);
3248
3249         return 0;
3250 }
3251
3252 static int orinoco_ioctl_setiwencode(struct net_device *dev,
3253                                      struct iw_request_info *info,
3254                                      struct iw_point *erq,
3255                                      char *keybuf)
3256 {
3257         struct orinoco_private *priv = netdev_priv(dev);
3258         int index = (erq->flags & IW_ENCODE_INDEX) - 1;
3259         int setindex = priv->tx_key;
3260         int enable = priv->wep_on;
3261         int restricted = priv->wep_restrict;
3262         u16 xlen = 0;
3263         int err = -EINPROGRESS;         /* Call commit handler */
3264         unsigned long flags;
3265
3266         if (! priv->has_wep)
3267                 return -EOPNOTSUPP;
3268
3269         if (erq->pointer) {
3270                 /* We actually have a key to set - check its length */
3271                 if (erq->length > LARGE_KEY_SIZE)
3272                         return -E2BIG;
3273
3274                 if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
3275                         return -E2BIG;
3276         }
3277
3278         if (orinoco_lock(priv, &flags) != 0)
3279                 return -EBUSY;
3280
3281         if (erq->pointer) {
3282                 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
3283                         index = priv->tx_key;
3284
3285                 /* Adjust key length to a supported value */
3286                 if (erq->length > SMALL_KEY_SIZE) {
3287                         xlen = LARGE_KEY_SIZE;
3288                 } else if (erq->length > 0) {
3289                         xlen = SMALL_KEY_SIZE;
3290                 } else
3291                         xlen = 0;
3292
3293                 /* Switch on WEP if off */
3294                 if ((!enable) && (xlen > 0)) {
3295                         setindex = index;
3296                         enable = 1;
3297                 }
3298         } else {
3299                 /* Important note : if the user do "iwconfig eth0 enc off",
3300                  * we will arrive there with an index of -1. This is valid
3301                  * but need to be taken care off... Jean II */
3302                 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
3303                         if((index != -1) || (erq->flags == 0)) {
3304                                 err = -EINVAL;
3305                                 goto out;
3306                         }
3307                 } else {
3308                         /* Set the index : Check that the key is valid */
3309                         if(priv->keys[index].len == 0) {
3310                                 err = -EINVAL;
3311                                 goto out;
3312                         }
3313                         setindex = index;
3314                 }
3315         }
3316
3317         if (erq->flags & IW_ENCODE_DISABLED)
3318                 enable = 0;
3319         if (erq->flags & IW_ENCODE_OPEN)
3320                 restricted = 0;
3321         if (erq->flags & IW_ENCODE_RESTRICTED)
3322                 restricted = 1;
3323
3324         if (erq->pointer) {
3325                 priv->keys[index].len = cpu_to_le16(xlen);
3326                 memset(priv->keys[index].data, 0,
3327                        sizeof(priv->keys[index].data));
3328                 memcpy(priv->keys[index].data, keybuf, erq->length);
3329         }
3330         priv->tx_key = setindex;
3331
3332         /* Try fast key change if connected and only keys are changed */
3333         if (priv->wep_on && enable && (priv->wep_restrict == restricted) &&
3334             netif_carrier_ok(dev)) {
3335                 err = __orinoco_hw_setup_wepkeys(priv);
3336                 /* No need to commit if successful */
3337                 goto out;
3338         }
3339
3340         priv->wep_on = enable;
3341         priv->wep_restrict = restricted;
3342
3343  out:
3344         orinoco_unlock(priv, &flags);
3345
3346         return err;
3347 }
3348
3349 static int orinoco_ioctl_getiwencode(struct net_device *dev,
3350                                      struct iw_request_info *info,
3351                                      struct iw_point *erq,
3352                                      char *keybuf)
3353 {
3354         struct orinoco_private *priv = netdev_priv(dev);
3355         int index = (erq->flags & IW_ENCODE_INDEX) - 1;
3356         u16 xlen = 0;
3357         unsigned long flags;
3358
3359         if (! priv->has_wep)
3360                 return -EOPNOTSUPP;
3361
3362         if (orinoco_lock(priv, &flags) != 0)
3363                 return -EBUSY;
3364
3365         if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
3366                 index = priv->tx_key;
3367
3368         erq->flags = 0;
3369         if (! priv->wep_on)
3370                 erq->flags |= IW_ENCODE_DISABLED;
3371         erq->flags |= index + 1;
3372
3373         if (priv->wep_restrict)
3374                 erq->flags |= IW_ENCODE_RESTRICTED;
3375         else
3376                 erq->flags |= IW_ENCODE_OPEN;
3377
3378         xlen = le16_to_cpu(priv->keys[index].len);
3379
3380         erq->length = xlen;
3381
3382         memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
3383
3384         orinoco_unlock(priv, &flags);
3385         return 0;
3386 }
3387
3388 static int orinoco_ioctl_setessid(struct net_device *dev,
3389                                   struct iw_request_info *info,
3390                                   struct iw_point *erq,
3391                                   char *essidbuf)
3392 {
3393         struct orinoco_private *priv = netdev_priv(dev);
3394         unsigned long flags;
3395
3396         /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
3397          * anyway... - Jean II */
3398
3399         /* Hum... Should not use Wireless Extension constant (may change),
3400          * should use our own... - Jean II */
3401         if (erq->length > IW_ESSID_MAX_SIZE)
3402                 return -E2BIG;
3403
3404         if (orinoco_lock(priv, &flags) != 0)
3405                 return -EBUSY;
3406
3407         /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
3408         memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
3409
3410         /* If not ANY, get the new ESSID */
3411         if (erq->flags) {
3412                 memcpy(priv->desired_essid, essidbuf, erq->length);
3413         }
3414
3415         orinoco_unlock(priv, &flags);
3416
3417         return -EINPROGRESS;            /* Call commit handler */
3418 }
3419
3420 static int orinoco_ioctl_getessid(struct net_device *dev,
3421                                   struct iw_request_info *info,
3422                                   struct iw_point *erq,
3423                                   char *essidbuf)
3424 {
3425         struct orinoco_private *priv = netdev_priv(dev);
3426         int active;
3427         int err = 0;
3428         unsigned long flags;
3429
3430         TRACE_ENTER(dev->name);
3431
3432         if (netif_running(dev)) {
3433                 err = orinoco_hw_get_essid(priv, &active, essidbuf);
3434                 if (err)
3435                         return err;
3436         } else {
3437                 if (orinoco_lock(priv, &flags) != 0)
3438                         return -EBUSY;
3439                 memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE + 1);
3440                 orinoco_unlock(priv, &flags);
3441         }
3442
3443         erq->flags = 1;
3444         erq->length = strlen(essidbuf) + 1;
3445
3446         TRACE_EXIT(dev->name);
3447         
3448         return 0;
3449 }
3450
3451 static int orinoco_ioctl_setnick(struct net_device *dev,
3452                                  struct iw_request_info *info,
3453                                  struct iw_point *nrq,
3454                                  char *nickbuf)
3455 {
3456         struct orinoco_private *priv = netdev_priv(dev);
3457         unsigned long flags;
3458
3459         if (nrq->length > IW_ESSID_MAX_SIZE)
3460                 return -E2BIG;
3461
3462         if (orinoco_lock(priv, &flags) != 0)
3463                 return -EBUSY;
3464
3465         memset(priv->nick, 0, sizeof(priv->nick));
3466         memcpy(priv->nick, nickbuf, nrq->length);
3467
3468         orinoco_unlock(priv, &flags);
3469
3470         return -EINPROGRESS;            /* Call commit handler */
3471 }
3472
3473 static int orinoco_ioctl_getnick(struct net_device *dev,
3474                                  struct iw_request_info *info,
3475                                  struct iw_point *nrq,
3476                                  char *nickbuf)
3477 {
3478         struct orinoco_private *priv = netdev_priv(dev);
3479         unsigned long flags;
3480
3481         if (orinoco_lock(priv, &flags) != 0)
3482                 return -EBUSY;
3483
3484         memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
3485         orinoco_unlock(priv, &flags);
3486
3487         nrq->length = strlen(nickbuf)+1;
3488
3489         return 0;
3490 }
3491
3492 static int orinoco_ioctl_setfreq(struct net_device *dev,
3493                                  struct iw_request_info *info,
3494                                  struct iw_freq *frq,
3495                                  char *extra)
3496 {
3497         struct orinoco_private *priv = netdev_priv(dev);
3498         int chan = -1;
3499         unsigned long flags;
3500         int err = -EINPROGRESS;         /* Call commit handler */
3501
3502         /* In infrastructure mode the AP sets the channel */
3503         if (priv->iw_mode == IW_MODE_INFRA)
3504                 return -EBUSY;
3505
3506         if ( (frq->e == 0) && (frq->m <= 1000) ) {
3507                 /* Setting by channel number */
3508                 chan = frq->m;
3509         } else {
3510                 /* Setting by frequency - search the table */
3511                 int mult = 1;
3512                 int i;
3513
3514                 for (i = 0; i < (6 - frq->e); i++)
3515                         mult *= 10;
3516
3517                 for (i = 0; i < NUM_CHANNELS; i++)
3518                         if (frq->m == (channel_frequency[i] * mult))
3519                                 chan = i+1;
3520         }
3521
3522         if ( (chan < 1) || (chan > NUM_CHANNELS) ||
3523              ! (priv->channel_mask & (1 << (chan-1)) ) )
3524                 return -EINVAL;
3525
3526         if (orinoco_lock(priv, &flags) != 0)
3527                 return -EBUSY;
3528
3529         priv->channel = chan;
3530         if (priv->iw_mode == IW_MODE_MONITOR) {
3531                 /* Fast channel change - no commit if successful */
3532                 hermes_t *hw = &priv->hw;
3533                 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
3534                                             HERMES_TEST_SET_CHANNEL,
3535                                         chan, NULL);
3536         }
3537         orinoco_unlock(priv, &flags);
3538
3539         return err;
3540 }
3541
3542 static int orinoco_ioctl_getfreq(struct net_device *dev,
3543                                  struct iw_request_info *info,
3544                                  struct iw_freq *frq,
3545                                  char *extra)
3546 {
3547         struct orinoco_private *priv = netdev_priv(dev);
3548         int tmp;
3549
3550         /* Locking done in there */
3551         tmp = orinoco_hw_get_freq(priv);
3552         if (tmp < 0) {
3553                 return tmp;
3554         }
3555
3556         frq->m = tmp;
3557         frq->e = 1;
3558
3559         return 0;
3560 }
3561
3562 static int orinoco_ioctl_getsens(struct net_device *dev,
3563                                  struct iw_request_info *info,
3564                                  struct iw_param *srq,
3565                                  char *extra)
3566 {
3567         struct orinoco_private *priv = netdev_priv(dev);
3568         hermes_t *hw = &priv->hw;
3569         u16 val;
3570         int err;
3571         unsigned long flags;
3572
3573         if (!priv->has_sensitivity)
3574                 return -EOPNOTSUPP;
3575
3576         if (orinoco_lock(priv, &flags) != 0)
3577                 return -EBUSY;
3578         err = hermes_read_wordrec(hw, USER_BAP,
3579                                   HERMES_RID_CNFSYSTEMSCALE, &val);
3580         orinoco_unlock(priv, &flags);
3581
3582         if (err)
3583                 return err;
3584
3585         srq->value = val;
3586         srq->fixed = 0; /* auto */
3587
3588         return 0;
3589 }
3590
3591 static int orinoco_ioctl_setsens(struct net_device *dev,
3592                                  struct iw_request_info *info,
3593                                  struct iw_param *srq,
3594                                  char *extra)
3595 {
3596         struct orinoco_private *priv = netdev_priv(dev);
3597         int val = srq->value;
3598         unsigned long flags;
3599
3600         if (!priv->has_sensitivity)
3601                 return -EOPNOTSUPP;
3602
3603         if ((val < 1) || (val > 3))
3604                 return -EINVAL;
3605         
3606         if (orinoco_lock(priv, &flags) != 0)
3607                 return -EBUSY;
3608         priv->ap_density = val;
3609         orinoco_unlock(priv, &flags);
3610
3611         return -EINPROGRESS;            /* Call commit handler */
3612 }
3613
3614 static int orinoco_ioctl_setrts(struct net_device *dev,
3615                                 struct iw_request_info *info,
3616                                 struct iw_param *rrq,
3617                                 char *extra)
3618 {
3619         struct orinoco_private *priv = netdev_priv(dev);
3620         int val = rrq->value;
3621         unsigned long flags;
3622
3623         if (rrq->disabled)
3624                 val = 2347;
3625
3626         if ( (val < 0) || (val > 2347) )
3627                 return -EINVAL;
3628
3629         if (orinoco_lock(priv, &flags) != 0)
3630                 return -EBUSY;
3631
3632         priv->rts_thresh = val;
3633         orinoco_unlock(priv, &flags);
3634
3635         return -EINPROGRESS;            /* Call commit handler */
3636 }
3637
3638 static int orinoco_ioctl_getrts(struct net_device *dev,
3639                                 struct iw_request_info *info,
3640                                 struct iw_param *rrq,
3641                                 char *extra)
3642 {
3643         struct orinoco_private *priv = netdev_priv(dev);
3644
3645         rrq->value = priv->rts_thresh;
3646         rrq->disabled = (rrq->value == 2347);
3647         rrq->fixed = 1;
3648
3649         return 0;
3650 }
3651
3652 static int orinoco_ioctl_setfrag(struct net_device *dev,
3653                                  struct iw_request_info *info,
3654                                  struct iw_param *frq,
3655                                  char *extra)
3656 {
3657         struct orinoco_private *priv = netdev_priv(dev);
3658         int err = -EINPROGRESS;         /* Call commit handler */
3659         unsigned long flags;
3660
3661         if (orinoco_lock(priv, &flags) != 0)
3662                 return -EBUSY;
3663
3664         if (priv->has_mwo) {
3665                 if (frq->disabled)
3666                         priv->mwo_robust = 0;
3667                 else {
3668                         if (frq->fixed)
3669                                 printk(KERN_WARNING "%s: Fixed fragmentation is "
3670                                        "not supported on this firmware. "
3671                                        "Using MWO robust instead.\n", dev->name);
3672                         priv->mwo_robust = 1;
3673                 }
3674         } else {
3675                 if (frq->disabled)
3676                         priv->frag_thresh = 2346;
3677                 else {
3678                         if ( (frq->value < 256) || (frq->value > 2346) )
3679                                 err = -EINVAL;
3680                         else
3681                                 priv->frag_thresh = frq->value & ~0x1; /* must be even */
3682                 }
3683         }
3684
3685         orinoco_unlock(priv, &flags);
3686
3687         return err;
3688 }
3689
3690 static int orinoco_ioctl_getfrag(struct net_device *dev,
3691                                  struct iw_request_info *info,
3692                                  struct iw_param *frq,
3693                                  char *extra)
3694 {
3695         struct orinoco_private *priv = netdev_priv(dev);
3696         hermes_t *hw = &priv->hw;
3697         int err;
3698         u16 val;
3699         unsigned long flags;
3700
3701         if (orinoco_lock(priv, &flags) != 0)
3702                 return -EBUSY;
3703         
3704         if (priv->has_mwo) {
3705                 err = hermes_read_wordrec(hw, USER_BAP,
3706                                           HERMES_RID_CNFMWOROBUST_AGERE,
3707                                           &val);
3708                 if (err)
3709                         val = 0;
3710
3711                 frq->value = val ? 2347 : 0;
3712                 frq->disabled = ! val;
3713                 frq->fixed = 0;
3714         } else {
3715                 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
3716                                           &val);
3717                 if (err)
3718                         val = 0;
3719
3720                 frq->value = val;
3721                 frq->disabled = (val >= 2346);
3722                 frq->fixed = 1;
3723         }
3724
3725         orinoco_unlock(priv, &flags);
3726         
3727         return err;
3728 }
3729
3730 static int orinoco_ioctl_setrate(struct net_device *dev,
3731                                  struct iw_request_info *info,
3732                                  struct iw_param *rrq,
3733                                  char *extra)
3734 {
3735         struct orinoco_private *priv = netdev_priv(dev);
3736         int ratemode = -1;
3737         int bitrate; /* 100s of kilobits */
3738         int i;
3739         unsigned long flags;
3740         
3741         /* As the user space doesn't know our highest rate, it uses -1
3742          * to ask us to set the highest rate.  Test it using "iwconfig
3743          * ethX rate auto" - Jean II */
3744         if (rrq->value == -1)
3745                 bitrate = 110;
3746         else {
3747                 if (rrq->value % 100000)
3748                         return -EINVAL;
3749                 bitrate = rrq->value / 100000;
3750         }
3751
3752         if ( (bitrate != 10) && (bitrate != 20) &&
3753              (bitrate != 55) && (bitrate != 110) )
3754                 return -EINVAL;
3755
3756         for (i = 0; i < BITRATE_TABLE_SIZE; i++)
3757                 if ( (bitrate_table[i].bitrate == bitrate) &&
3758                      (bitrate_table[i].automatic == ! rrq->fixed) ) {
3759                         ratemode = i;
3760                         break;
3761                 }
3762         
3763         if (ratemode == -1)
3764                 return -EINVAL;
3765
3766         if (orinoco_lock(priv, &flags) != 0)
3767                 return -EBUSY;
3768         priv->bitratemode = ratemode;
3769         orinoco_unlock(priv, &flags);
3770
3771         return -EINPROGRESS;
3772 }
3773
3774 static int orinoco_ioctl_getrate(struct net_device *dev,
3775                                  struct iw_request_info *info,
3776                                  struct iw_param *rrq,
3777                                  char *extra)
3778 {
3779         struct orinoco_private *priv = netdev_priv(dev);
3780         hermes_t *hw = &priv->hw;
3781         int err = 0;
3782         int ratemode;
3783         int i;
3784         u16 val;
3785         unsigned long flags;
3786
3787         if (orinoco_lock(priv, &flags) != 0)
3788                 return -EBUSY;
3789
3790         ratemode = priv->bitratemode;
3791
3792         BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
3793
3794         rrq->value = bitrate_table[ratemode].bitrate * 100000;
3795         rrq->fixed = ! bitrate_table[ratemode].automatic;
3796         rrq->disabled = 0;
3797
3798         /* If the interface is running we try to find more about the
3799            current mode */
3800         if (netif_running(dev)) {
3801                 err = hermes_read_wordrec(hw, USER_BAP,
3802                                           HERMES_RID_CURRENTTXRATE, &val);
3803                 if (err)
3804                         goto out;
3805                 
3806                 switch (priv->firmware_type) {
3807                 case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
3808                         /* Note : in Lucent firmware, the return value of
3809                          * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
3810                          * and therefore is totally different from the
3811                          * encoding of HERMES_RID_CNFTXRATECONTROL.
3812                          * Don't forget that 6Mb/s is really 5.5Mb/s */
3813                         if (val == 6)
3814                                 rrq->value = 5500000;
3815                         else
3816                                 rrq->value = val * 1000000;
3817                         break;
3818                 case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
3819                 case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
3820                         for (i = 0; i < BITRATE_TABLE_SIZE; i++)
3821                                 if (bitrate_table[i].intersil_txratectrl == val) {
3822                                         ratemode = i;
3823                                         break;
3824                                 }
3825                         if (i >= BITRATE_TABLE_SIZE)
3826                                 printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
3827                                        dev->name, val);
3828
3829                         rrq->value = bitrate_table[ratemode].bitrate * 100000;
3830                         break;
3831                 default:
3832                         BUG();
3833                 }
3834         }
3835
3836  out:
3837         orinoco_unlock(priv, &flags);
3838
3839         return err;
3840 }
3841
3842 static int orinoco_ioctl_setpower(struct net_device *dev,
3843                                   struct iw_request_info *info,
3844                                   struct iw_param *prq,
3845                                   char *extra)
3846 {
3847         struct orinoco_private *priv = netdev_priv(dev);
3848         int err = -EINPROGRESS;         /* Call commit handler */
3849         unsigned long flags;
3850
3851         if (orinoco_lock(priv, &flags) != 0)
3852                 return -EBUSY;
3853
3854         if (prq->disabled) {
3855                 priv->pm_on = 0;
3856         } else {
3857                 switch (prq->flags & IW_POWER_MODE) {
3858                 case IW_POWER_UNICAST_R:
3859                         priv->pm_mcast = 0;
3860                         priv->pm_on = 1;
3861                         break;
3862                 case IW_POWER_ALL_R:
3863                         priv->pm_mcast = 1;
3864                         priv->pm_on = 1;
3865                         break;
3866                 case IW_POWER_ON:
3867                         /* No flags : but we may have a value - Jean II */
3868                         break;
3869                 default:
3870                         err = -EINVAL;
3871                 }
3872                 if (err)
3873                         goto out;
3874                 
3875                 if (prq->flags & IW_POWER_TIMEOUT) {
3876                         priv->pm_on = 1;
3877                         priv->pm_timeout = prq->value / 1000;
3878                 }
3879                 if (prq->flags & IW_POWER_PERIOD) {
3880                         priv->pm_on = 1;
3881                         priv->pm_period = prq->value / 1000;
3882                 }
3883                 /* It's valid to not have a value if we are just toggling
3884                  * the flags... Jean II */
3885                 if(!priv->pm_on) {
3886                         err = -EINVAL;
3887                         goto out;
3888                 }                       
3889         }
3890
3891  out:
3892         orinoco_unlock(priv, &flags);
3893
3894         return err;
3895 }
3896
3897 static int orinoco_ioctl_getpower(struct net_device *dev,
3898                                   struct iw_request_info *info,
3899                                   struct iw_param *prq,
3900                                   char *extra)
3901 {
3902         struct orinoco_private *priv = netdev_priv(dev);
3903         hermes_t *hw = &priv->hw;
3904         int err = 0;
3905         u16 enable, period, timeout, mcast;
3906         unsigned long flags;
3907
3908         if (orinoco_lock(priv, &flags) != 0)
3909                 return -EBUSY;
3910         
3911         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
3912         if (err)
3913                 goto out;
3914
3915         err = hermes_read_wordrec(hw, USER_BAP,
3916                                   HERMES_RID_CNFMAXSLEEPDURATION, &period);
3917         if (err)
3918                 goto out;
3919
3920         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
3921         if (err)
3922                 goto out;
3923
3924         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
3925         if (err)
3926                 goto out;
3927
3928         prq->disabled = !enable;
3929         /* Note : by default, display the period */
3930         if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
3931                 prq->flags = IW_POWER_TIMEOUT;
3932                 prq->value = timeout * 1000;
3933         } else {
3934                 prq->flags = IW_POWER_PERIOD;
3935                 prq->value = period * 1000;
3936         }
3937         if (mcast)
3938                 prq->flags |= IW_POWER_ALL_R;
3939         else
3940                 prq->flags |= IW_POWER_UNICAST_R;
3941
3942  out:
3943         orinoco_unlock(priv, &flags);
3944
3945         return err;
3946 }
3947
3948 static int orinoco_ioctl_getretry(struct net_device *dev,
3949                                   struct iw_request_info *info,
3950                                   struct iw_param *rrq,
3951                                   char *extra)
3952 {
3953         struct orinoco_private *priv = netdev_priv(dev);
3954         hermes_t *hw = &priv->hw;
3955         int err = 0;
3956         u16 short_limit, long_limit, lifetime;
3957         unsigned long flags;
3958
3959         if (orinoco_lock(priv, &flags) != 0)
3960                 return -EBUSY;
3961         
3962         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
3963                                   &short_limit);
3964         if (err)
3965                 goto out;
3966
3967         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
3968                                   &long_limit);
3969         if (err)
3970                 goto out;
3971
3972         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
3973                                   &lifetime);
3974         if (err)
3975                 goto out;
3976
3977         rrq->disabled = 0;              /* Can't be disabled */
3978
3979         /* Note : by default, display the retry number */
3980         if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
3981                 rrq->flags = IW_RETRY_LIFETIME;
3982                 rrq->value = lifetime * 1000;   /* ??? */
3983         } else {
3984                 /* By default, display the min number */
3985                 if ((rrq->flags & IW_RETRY_MAX)) {
3986                         rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
3987                         rrq->value = long_limit;
3988                 } else {
3989                         rrq->flags = IW_RETRY_LIMIT;
3990                         rrq->value = short_limit;
3991                         if(short_limit != long_limit)
3992                                 rrq->flags |= IW_RETRY_MIN;
3993                 }
3994         }
3995
3996  out:
3997         orinoco_unlock(priv, &flags);
3998
3999         return err;
4000 }
4001
4002 static int orinoco_ioctl_reset(struct net_device *dev,
4003                                struct iw_request_info *info,
4004                                void *wrqu,
4005                                char *extra)
4006 {
4007         struct orinoco_private *priv = netdev_priv(dev);
4008
4009         if (! capable(CAP_NET_ADMIN))
4010                 return -EPERM;
4011
4012         if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
4013                 printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
4014
4015                 /* Firmware reset */
4016                 orinoco_reset(dev);
4017         } else {
4018                 printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
4019
4020                 schedule_work(&priv->reset_work);
4021         }
4022
4023         return 0;
4024 }
4025
4026 static int orinoco_ioctl_setibssport(struct net_device *dev,
4027                                      struct iw_request_info *info,
4028                                      void *wrqu,
4029                                      char *extra)
4030
4031 {
4032         struct orinoco_private *priv = netdev_priv(dev);
4033         int val = *( (int *) extra );
4034         unsigned long flags;
4035
4036         if (orinoco_lock(priv, &flags) != 0)
4037                 return -EBUSY;
4038
4039         priv->ibss_port = val ;
4040
4041         /* Actually update the mode we are using */
4042         set_port_type(priv);
4043
4044         orinoco_unlock(priv, &flags);
4045         return -EINPROGRESS;            /* Call commit handler */
4046 }
4047
4048 static int orinoco_ioctl_getibssport(struct net_device *dev,
4049                                      struct iw_request_info *info,
4050                                      void *wrqu,
4051                                      char *extra)
4052 {
4053         struct orinoco_private *priv = netdev_priv(dev);
4054         int *val = (int *) extra;
4055
4056         *val = priv->ibss_port;
4057         return 0;
4058 }
4059
4060 static int orinoco_ioctl_setport3(struct net_device *dev,
4061                                   struct iw_request_info *info,
4062                                   void *wrqu,
4063                                   char *extra)
4064 {
4065         struct orinoco_private *priv = netdev_priv(dev);
4066         int val = *( (int *) extra );
4067         int err = 0;
4068         unsigned long flags;
4069
4070         if (orinoco_lock(priv, &flags) != 0)
4071                 return -EBUSY;
4072
4073         switch (val) {
4074         case 0: /* Try to do IEEE ad-hoc mode */
4075                 if (! priv->has_ibss) {
4076                         err = -EINVAL;
4077                         break;
4078                 }
4079                 priv->prefer_port3 = 0;
4080                         
4081                 break;
4082
4083         case 1: /* Try to do Lucent proprietary ad-hoc mode */
4084                 if (! priv->has_port3) {
4085                         err = -EINVAL;
4086                         break;
4087                 }
4088                 priv->prefer_port3 = 1;
4089                 break;
4090
4091         default:
4092                 err = -EINVAL;
4093         }
4094
4095         if (! err) {
4096                 /* Actually update the mode we are using */
4097                 set_port_type(priv);
4098                 err = -EINPROGRESS;
4099         }
4100
4101         orinoco_unlock(priv, &flags);
4102
4103         return err;
4104 }
4105
4106 static int orinoco_ioctl_getport3(struct net_device *dev,
4107                                   struct iw_request_info *info,
4108                                   void *wrqu,
4109                                   char *extra)
4110 {
4111         struct orinoco_private *priv = netdev_priv(dev);
4112         int *val = (int *) extra;
4113
4114         *val = priv->prefer_port3;
4115         return 0;
4116 }
4117
4118 static int orinoco_ioctl_setpreamble(struct net_device *dev,
4119                                      struct iw_request_info *info,
4120                                      void *wrqu,
4121                                      char *extra)
4122 {
4123         struct orinoco_private *priv = netdev_priv(dev);
4124         unsigned long flags;
4125         int val;
4126
4127         if (! priv->has_preamble)
4128                 return -EOPNOTSUPP;
4129
4130         /* 802.11b has recently defined some short preamble.
4131          * Basically, the Phy header has been reduced in size.
4132          * This increase performance, especially at high rates
4133          * (the preamble is transmitted at 1Mb/s), unfortunately
4134          * this give compatibility troubles... - Jean II */
4135         val = *( (int *) extra );
4136
4137         if (orinoco_lock(priv, &flags) != 0)
4138                 return -EBUSY;
4139
4140         if (val)
4141                 priv->preamble = 1;
4142         else
4143                 priv->preamble = 0;
4144
4145         orinoco_unlock(priv, &flags);
4146
4147         return -EINPROGRESS;            /* Call commit handler */
4148 }
4149
4150 static int orinoco_ioctl_getpreamble(struct net_device *dev,
4151                                      struct iw_request_info *info,
4152                                      void *wrqu,
4153                                      char *extra)
4154 {
4155         struct orinoco_private *priv = netdev_priv(dev);
4156         int *val = (int *) extra;
4157
4158         if (! priv->has_preamble)
4159                 return -EOPNOTSUPP;
4160
4161         *val = priv->preamble;
4162         return 0;
4163 }
4164
4165 /* ioctl interface to hermes_read_ltv()
4166  * To use with iwpriv, pass the RID as the token argument, e.g.
4167  * iwpriv get_rid [0xfc00]
4168  * At least Wireless Tools 25 is required to use iwpriv.
4169  * For Wireless Tools 25 and 26 append "dummy" are the end. */
4170 static int orinoco_ioctl_getrid(struct net_device *dev,
4171                                 struct iw_request_info *info,
4172                                 struct iw_point *data,
4173                                 char *extra)
4174 {
4175         struct orinoco_private *priv = netdev_priv(dev);
4176         hermes_t *hw = &priv->hw;
4177         int rid = data->flags;
4178         u16 length;
4179         int err;
4180         unsigned long flags;
4181
4182         /* It's a "get" function, but we don't want users to access the
4183          * WEP key and other raw firmware data */
4184         if (! capable(CAP_NET_ADMIN))
4185                 return -EPERM;
4186
4187         if (rid < 0xfc00 || rid > 0xffff)
4188                 return -EINVAL;
4189
4190         if (orinoco_lock(priv, &flags) != 0)
4191                 return -EBUSY;
4192
4193         err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
4194                               extra);
4195         if (err)
4196                 goto out;
4197
4198         data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
4199                              MAX_RID_LEN);
4200
4201  out:
4202         orinoco_unlock(priv, &flags);
4203         return err;
4204 }
4205
4206 /* Spy is used for link quality/strength measurements in Ad-Hoc mode
4207  * Jean II */
4208 static int orinoco_ioctl_setspy(struct net_device *dev,
4209                                 struct iw_request_info *info,
4210                                 struct iw_point *srq,
4211                                 char *extra)
4212
4213 {
4214         struct orinoco_private *priv = netdev_priv(dev);
4215         struct sockaddr *address = (struct sockaddr *) extra;
4216         int number = srq->length;
4217         int i;
4218         unsigned long flags;
4219
4220         /* Make sure nobody mess with the structure while we do */
4221         if (orinoco_lock(priv, &flags) != 0)
4222                 return -EBUSY;
4223
4224         /* orinoco_lock() doesn't disable interrupts, so make sure the
4225          * interrupt rx path don't get confused while we copy */
4226         priv->spy_number = 0;
4227
4228         if (number > 0) {
4229                 /* Extract the addresses */
4230                 for (i = 0; i < number; i++)
4231                         memcpy(priv->spy_address[i], address[i].sa_data,
4232                                ETH_ALEN);
4233                 /* Reset stats */
4234                 memset(priv->spy_stat, 0,
4235                        sizeof(struct iw_quality) * IW_MAX_SPY);
4236                 /* Set number of addresses */
4237                 priv->spy_number = number;
4238         }
4239
4240         /* Now, let the others play */
4241         orinoco_unlock(priv, &flags);
4242
4243         /* Do NOT call commit handler */
4244         return 0;
4245 }
4246
4247 static int orinoco_ioctl_getspy(struct net_device *dev,
4248                                 struct iw_request_info *info,
4249                                 struct iw_point *srq,
4250                                 char *extra)
4251 {
4252         struct orinoco_private *priv = netdev_priv(dev);
4253         struct sockaddr *address = (struct sockaddr *) extra;
4254         int number;
4255         int i;
4256         unsigned long flags;
4257
4258         if (orinoco_lock(priv, &flags) != 0)
4259                 return -EBUSY;
4260
4261         number = priv->spy_number;
4262         /* Create address struct */
4263         for (i = 0; i < number; i++) {
4264                 memcpy(address[i].sa_data, priv->spy_address[i], ETH_ALEN);
4265                 address[i].sa_family = AF_UNIX;
4266         }
4267         if (number > 0) {
4268                 /* Create address struct */
4269                 for (i = 0; i < number; i++) {
4270                         memcpy(address[i].sa_data, priv->spy_address[i],
4271                                ETH_ALEN);
4272                         address[i].sa_family = AF_UNIX;
4273                 }
4274                 /* Copy stats */
4275                 /* In theory, we should disable irqs while copying the stats
4276                  * because the rx path might update it in the middle...
4277                  * Bah, who care ? - Jean II */
4278                 memcpy(extra  + (sizeof(struct sockaddr) * number),
4279                        priv->spy_stat, sizeof(struct iw_quality) * number);
4280         }
4281         /* Reset updated flags. */
4282         for (i = 0; i < number; i++)
4283                 priv->spy_stat[i].updated = 0;
4284
4285         orinoco_unlock(priv, &flags);
4286
4287         srq->length = number;
4288
4289         return 0;
4290 }
4291
4292 /* Trigger a scan (look for other cells in the vicinity */
4293 static int orinoco_ioctl_setscan(struct net_device *dev,
4294                                  struct iw_request_info *info,
4295                                  struct iw_param *srq,
4296                                  char *extra)
4297 {
4298         struct orinoco_private *priv = netdev_priv(dev);
4299         hermes_t *hw = &priv->hw;
4300         int err = 0;
4301         unsigned long flags;
4302
4303         /* Note : you may have realised that, as this is a SET operation,
4304          * this is priviledged and therefore a normal user can't
4305          * perform scanning.
4306          * This is not an error, while the device perform scanning,
4307          * traffic doesn't flow, so it's a perfect DoS...
4308          * Jean II */
4309
4310         if (orinoco_lock(priv, &flags) != 0)
4311                 return -EBUSY;
4312
4313         /* Scanning with port 0 disabled would fail */
4314         if (!netif_running(dev)) {
4315                 err = -ENETDOWN;
4316                 goto out;
4317         }
4318
4319         /* In monitor mode, the scan results are always empty.
4320          * Probe responses are passed to the driver as received
4321          * frames and could be processed in software. */
4322         if (priv->iw_mode == IW_MODE_MONITOR) {
4323                 err = -EOPNOTSUPP;
4324                 goto out;
4325         }
4326
4327         /* Note : because we don't lock out the irq handler, the way
4328          * we access scan variables in priv is critical.
4329          *      o scan_inprogress : not touched by irq handler
4330          *      o scan_mode : not touched by irq handler
4331          *      o scan_result : irq is strict producer, non-irq is strict
4332          *              consumer.
4333          *      o scan_len : synchronised with scan_result
4334          * Before modifying anything on those variables, please think hard !
4335          * Jean II */
4336
4337         /* If there is still some left-over scan results, get rid of it */
4338         if (priv->scan_result != NULL) {
4339                 /* What's likely is that a client did crash or was killed
4340                  * between triggering the scan request and reading the
4341                  * results, so we need to reset everything.
4342                  * Some clients that are too slow may suffer from that...
4343                  * Jean II */
4344                 kfree(priv->scan_result);
4345                 priv->scan_result = NULL;
4346         }
4347
4348         /* Save flags */
4349         priv->scan_mode = srq->flags;
4350
4351         /* Always trigger scanning, even if it's in progress.
4352          * This way, if the info frame get lost, we will recover somewhat
4353          * gracefully  - Jean II */
4354
4355         if (priv->has_hostscan) {
4356                 switch (priv->firmware_type) {
4357                 case FIRMWARE_TYPE_SYMBOL:
4358                         err = hermes_write_wordrec(hw, USER_BAP,
4359                                                    HERMES_RID_CNFHOSTSCAN_SYMBOL,
4360                                                    HERMES_HOSTSCAN_SYMBOL_ONCE |
4361                                                    HERMES_HOSTSCAN_SYMBOL_BCAST);
4362                         break;
4363                 case FIRMWARE_TYPE_INTERSIL: {
4364                         u16 req[3];
4365
4366                         req[0] = cpu_to_le16(0x3fff);   /* All channels */
4367                         req[1] = cpu_to_le16(0x0001);   /* rate 1 Mbps */
4368                         req[2] = 0;                     /* Any ESSID */
4369                         err = HERMES_WRITE_RECORD(hw, USER_BAP,
4370                                                   HERMES_RID_CNFHOSTSCAN, &req);
4371                 }
4372                 break;
4373                 case FIRMWARE_TYPE_AGERE:
4374                         err = hermes_write_wordrec(hw, USER_BAP,
4375                                                    HERMES_RID_CNFSCANSSID_AGERE,
4376                                                    0);  /* Any ESSID */
4377                         if (err)
4378                                 break;
4379
4380                         err = hermes_inquire(hw, HERMES_INQ_SCAN);
4381                         break;
4382                 }
4383         } else
4384                 err = hermes_inquire(hw, HERMES_INQ_SCAN);
4385
4386         /* One more client */
4387         if (! err)
4388                 priv->scan_inprogress = 1;
4389
4390  out:
4391         orinoco_unlock(priv, &flags);
4392         return err;
4393 }
4394
4395 /* Translate scan data returned from the card to a card independant
4396  * format that the Wireless Tools will understand - Jean II */
4397 static inline int orinoco_translate_scan(struct net_device *dev,
4398                                          char *buffer,
4399                                          char *scan,
4400                                          int scan_len)
4401 {
4402         struct orinoco_private *priv = netdev_priv(dev);
4403         int                     offset;         /* In the scan data */
4404         union hermes_scan_info *atom;
4405         int                     atom_len;
4406         u16                     capabilities;
4407         u16                     channel;
4408         struct iw_event         iwe;            /* Temporary buffer */
4409         char *                  current_ev = buffer;
4410         char *                  end_buf = buffer + IW_SCAN_MAX_DATA;
4411
4412         switch (priv->firmware_type) {
4413         case FIRMWARE_TYPE_AGERE:
4414                 atom_len = sizeof(struct agere_scan_apinfo);
4415                 offset = 0;
4416                 break;
4417         case FIRMWARE_TYPE_SYMBOL:
4418                 /* Lack of documentation necessitates this hack.
4419                  * Different firmwares have 68 or 76 byte long atoms.
4420                  * We try modulo first.  If the length divides by both,
4421                  * we check what would be the channel in the second
4422                  * frame for a 68-byte atom.  76-byte atoms have 0 there.
4423                  * Valid channel cannot be 0.  */
4424                 if (scan_len % 76)
4425                         atom_len = 68;
4426                 else if (scan_len % 68)
4427                         atom_len = 76;
4428                 else if (scan_len >= 1292 && scan[68] == 0)
4429                         atom_len = 76;
4430                 else
4431                         atom_len = 68;
4432                 offset = 0;
4433                 break;
4434         case FIRMWARE_TYPE_INTERSIL:
4435                 offset = 4;
4436                 if (priv->has_hostscan)
4437                         atom_len = scan[0] + (scan[1] << 8);
4438                 else
4439                         atom_len = offsetof(struct prism2_scan_apinfo, atim);
4440                 break;
4441         default:
4442                 return 0;
4443         }
4444
4445         /* Check that we got an whole number of atoms */
4446         if ((scan_len - offset) % atom_len) {
4447                 printk(KERN_ERR "%s: Unexpected scan data length %d, "
4448                        "atom_len %d, offset %d\n", dev->name, scan_len,
4449                        atom_len, offset);
4450                 return 0;
4451         }
4452
4453         /* Read the entries one by one */
4454         for (; offset + atom_len <= scan_len; offset += atom_len) {
4455                 /* Get next atom */
4456                 atom = (union hermes_scan_info *) (scan + offset);
4457
4458                 /* First entry *MUST* be the AP MAC address */
4459                 iwe.cmd = SIOCGIWAP;
4460                 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
4461                 memcpy(iwe.u.ap_addr.sa_data, atom->a.bssid, ETH_ALEN);
4462                 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
4463
4464                 /* Other entries will be displayed in the order we give them */
4465
4466                 /* Add the ESSID */
4467                 iwe.u.data.length = le16_to_cpu(atom->a.essid_len);
4468                 if (iwe.u.data.length > 32)
4469                         iwe.u.data.length = 32;
4470                 iwe.cmd = SIOCGIWESSID;
4471                 iwe.u.data.flags = 1;
4472                 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
4473
4474                 /* Add mode */
4475                 iwe.cmd = SIOCGIWMODE;
4476                 capabilities = le16_to_cpu(atom->a.capabilities);
4477                 if (capabilities & 0x3) {
4478                         if (capabilities & 0x1)
4479                                 iwe.u.mode = IW_MODE_MASTER;
4480                         else
4481                                 iwe.u.mode = IW_MODE_ADHOC;
4482                         current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
4483                 }
4484
4485                 channel = atom->s.channel;
4486                 if ( (channel >= 1) && (channel <= NUM_CHANNELS) ) {
4487                         /* Add frequency */
4488                         iwe.cmd = SIOCGIWFREQ;
4489                         iwe.u.freq.m = channel_frequency[channel-1] * 100000;
4490                         iwe.u.freq.e = 1;
4491                         current_ev = iwe_stream_add_event(current_ev, end_buf,
4492                                                           &iwe, IW_EV_FREQ_LEN);
4493                 }
4494
4495                 /* Add quality statistics */
4496                 iwe.cmd = IWEVQUAL;
4497                 iwe.u.qual.updated = 0x10;      /* no link quality */
4498                 iwe.u.qual.level = (__u8) le16_to_cpu(atom->a.level) - 0x95;
4499                 iwe.u.qual.noise = (__u8) le16_to_cpu(atom->a.noise) - 0x95;
4500                 /* Wireless tools prior to 27.pre22 will show link quality
4501                  * anyway, so we provide a reasonable value. */
4502                 if (iwe.u.qual.level > iwe.u.qual.noise)
4503                         iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
4504                 else
4505                         iwe.u.qual.qual = 0;
4506                 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
4507
4508                 /* Add encryption capability */
4509                 iwe.cmd = SIOCGIWENCODE;
4510                 if (capabilities & 0x10)
4511                         iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
4512                 else
4513                         iwe.u.data.flags = IW_ENCODE_DISABLED;
4514                 iwe.u.data.length = 0;
4515                 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
4516
4517                 /* Bit rate is not available in Lucent/Agere firmwares */
4518                 if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
4519                         char *  current_val = current_ev + IW_EV_LCP_LEN;
4520                         int     i;
4521                         int     step;
4522
4523                         if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
4524                                 step = 2;
4525                         else
4526                                 step = 1;
4527
4528                         iwe.cmd = SIOCGIWRATE;
4529                         /* Those two flags are ignored... */
4530                         iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
4531                         /* Max 10 values */
4532                         for (i = 0; i < 10; i += step) {
4533                                 /* NULL terminated */
4534                                 if (atom->p.rates[i] == 0x0)
4535                                         break;
4536                                 /* Bit rate given in 500 kb/s units (+ 0x80) */
4537                                 iwe.u.bitrate.value = ((atom->p.rates[i] & 0x7f) * 500000);
4538                                 current_val = iwe_stream_add_value(current_ev, current_val,
4539                                                                    end_buf, &iwe,
4540                                                                    IW_EV_PARAM_LEN);
4541                         }
4542                         /* Check if we added any event */
4543                         if ((current_val - current_ev) > IW_EV_LCP_LEN)
4544                                 current_ev = current_val;
4545                 }
4546
4547                 /* The other data in the scan result are not really
4548                  * interesting, so for now drop it - Jean II */
4549         }
4550         return current_ev - buffer;
4551 }
4552
4553 /* Return results of a scan */
4554 static int orinoco_ioctl_getscan(struct net_device *dev,
4555                                  struct iw_request_info *info,
4556                                  struct iw_point *srq,
4557                                  char *extra)
4558 {
4559         struct orinoco_private *priv = netdev_priv(dev);
4560         int err = 0;
4561         unsigned long flags;
4562
4563         if (orinoco_lock(priv, &flags) != 0)
4564                 return -EBUSY;
4565
4566         /* If no results yet, ask to try again later */
4567         if (priv->scan_result == NULL) {
4568                 if (priv->scan_inprogress)
4569                         /* Important note : we don't want to block the caller
4570                          * until results are ready for various reasons.
4571                          * First, managing wait queues is complex and racy.
4572                          * Second, we grab some rtnetlink lock before comming
4573                          * here (in dev_ioctl()).
4574                          * Third, we generate an Wireless Event, so the
4575                          * caller can wait itself on that - Jean II */
4576                         err = -EAGAIN;
4577                 else
4578                         /* Client error, no scan results...
4579                          * The caller need to restart the scan. */
4580                         err = -ENODATA;
4581         } else {
4582                 /* We have some results to push back to user space */
4583
4584                 /* Translate to WE format */
4585                 srq->length = orinoco_translate_scan(dev, extra,
4586                                                      priv->scan_result,
4587                                                      priv->scan_len);
4588
4589                 /* Return flags */
4590                 srq->flags = (__u16) priv->scan_mode;
4591
4592                 /* Results are here, so scan no longer in progress */
4593                 priv->scan_inprogress = 0;
4594
4595                 /* In any case, Scan results will be cleaned up in the
4596                  * reset function and when exiting the driver.
4597                  * The person triggering the scanning may never come to
4598                  * pick the results, so we need to do it in those places.
4599                  * Jean II */
4600
4601 #ifdef SCAN_SINGLE_READ
4602                 /* If you enable this option, only one client (the first
4603                  * one) will be able to read the result (and only one
4604                  * time). If there is multiple concurent clients that
4605                  * want to read scan results, this behavior is not
4606                  * advisable - Jean II */
4607                 kfree(priv->scan_result);
4608                 priv->scan_result = NULL;
4609 #endif /* SCAN_SINGLE_READ */
4610                 /* Here, if too much time has elapsed since last scan,
4611                  * we may want to clean up scan results... - Jean II */
4612         }
4613           
4614         orinoco_unlock(priv, &flags);
4615         return err;
4616 }
4617
4618 /* Commit handler, called after set operations */
4619 static int orinoco_ioctl_commit(struct net_device *dev,
4620                                 struct iw_request_info *info,
4621                                 void *wrqu,
4622                                 char *extra)
4623 {
4624         struct orinoco_private *priv = netdev_priv(dev);
4625         struct hermes *hw = &priv->hw;
4626         unsigned long flags;
4627         int err = 0;
4628
4629         if (!priv->open)
4630                 return 0;
4631
4632         if (priv->broken_disableport) {
4633                 orinoco_reset(dev);
4634                 return 0;
4635         }
4636
4637         if (orinoco_lock(priv, &flags) != 0)
4638                 return err;
4639
4640         err = hermes_disable_port(hw, 0);
4641         if (err) {
4642                 printk(KERN_WARNING "%s: Unable to disable port "
4643                        "while reconfiguring card\n", dev->name);
4644                 priv->broken_disableport = 1;
4645                 goto out;
4646         }
4647
4648         err = __orinoco_program_rids(dev);
4649         if (err) {
4650                 printk(KERN_WARNING "%s: Unable to reconfigure card\n",
4651                        dev->name);
4652                 goto out;
4653         }
4654
4655         err = hermes_enable_port(hw, 0);
4656         if (err) {
4657                 printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
4658                        dev->name);
4659                 goto out;
4660         }
4661
4662  out:
4663         if (err) {
4664                 printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
4665                 schedule_work(&priv->reset_work);
4666                 err = 0;
4667         }
4668
4669         orinoco_unlock(priv, &flags);
4670         return err;
4671 }
4672
4673 static const struct iw_priv_args orinoco_privtab[] = {
4674         { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
4675         { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
4676         { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4677           0, "set_port3" },
4678         { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4679           "get_port3" },
4680         { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4681           0, "set_preamble" },
4682         { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4683           "get_preamble" },
4684         { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4685           0, "set_ibssport" },
4686         { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4687           "get_ibssport" },
4688         { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
4689           "get_rid" },
4690 };
4691
4692
4693 /*
4694  * Structures to export the Wireless Handlers
4695  */
4696
4697 static const iw_handler orinoco_handler[] = {
4698         [SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) orinoco_ioctl_commit,
4699         [SIOCGIWNAME  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getname,
4700         [SIOCSIWFREQ  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setfreq,
4701         [SIOCGIWFREQ  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getfreq,
4702         [SIOCSIWMODE  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setmode,
4703         [SIOCGIWMODE  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getmode,
4704         [SIOCSIWSENS  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setsens,
4705         [SIOCGIWSENS  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getsens,
4706         [SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getiwrange,
4707         [SIOCSIWSPY   -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setspy,
4708         [SIOCGIWSPY   -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getspy,
4709         [SIOCSIWAP    -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setwap,
4710         [SIOCGIWAP    -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getwap,
4711         [SIOCSIWSCAN  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setscan,
4712         [SIOCGIWSCAN  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getscan,
4713         [SIOCSIWESSID -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setessid,
4714         [SIOCGIWESSID -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getessid,
4715         [SIOCSIWNICKN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setnick,
4716         [SIOCGIWNICKN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getnick,
4717         [SIOCSIWRATE  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setrate,
4718         [SIOCGIWRATE  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getrate,
4719         [SIOCSIWRTS   -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setrts,
4720         [SIOCGIWRTS   -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getrts,
4721         [SIOCSIWFRAG  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setfrag,
4722         [SIOCGIWFRAG  -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getfrag,
4723         [SIOCGIWRETRY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getretry,
4724         [SIOCSIWENCODE-SIOCIWFIRST] (iw_handler) orinoco_ioctl_setiwencode,
4725         [SIOCGIWENCODE-SIOCIWFIRST] (iw_handler) orinoco_ioctl_getiwencode,
4726         [SIOCSIWPOWER -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setpower,
4727         [SIOCGIWPOWER -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getpower,
4728 };
4729
4730
4731 /*
4732   Added typecasting since we no longer use iwreq_data -- Moustafa
4733  */
4734 static const iw_handler orinoco_private_handler[] = {
4735         [0] (iw_handler) orinoco_ioctl_reset,
4736         [1] (iw_handler) orinoco_ioctl_reset,
4737         [2] (iw_handler) orinoco_ioctl_setport3,
4738         [3] (iw_handler) orinoco_ioctl_getport3,
4739         [4] (iw_handler) orinoco_ioctl_setpreamble,
4740         [5] (iw_handler) orinoco_ioctl_getpreamble,
4741         [6] (iw_handler) orinoco_ioctl_setibssport,
4742         [7] (iw_handler) orinoco_ioctl_getibssport,
4743         [9] (iw_handler) orinoco_ioctl_getrid,
4744 };
4745
4746 static const struct iw_handler_def orinoco_handler_def = {
4747         .num_standard = ARRAY_SIZE(orinoco_handler),
4748         .num_private = ARRAY_SIZE(orinoco_private_handler),
4749         .num_private_args = ARRAY_SIZE(orinoco_privtab),
4750         .standard = orinoco_handler,
4751         .private = orinoco_private_handler,
4752         .private_args = orinoco_privtab,
4753 };
4754
4755 static void orinoco_get_drvinfo(struct net_device *dev,
4756                                 struct ethtool_drvinfo *info)
4757 {
4758         struct orinoco_private *priv = netdev_priv(dev);
4759
4760         strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
4761         strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
4762         strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
4763         if (dev->class_dev.dev)
4764                 strncpy(info->bus_info, dev->class_dev.dev->bus_id,
4765                         sizeof(info->bus_info) - 1);
4766         else
4767                 snprintf(info->bus_info, sizeof(info->bus_info) - 1,
4768                          "PCMCIA %p", priv->hw.iobase);
4769 }
4770
4771 static struct ethtool_ops orinoco_ethtool_ops = {
4772         .get_drvinfo = orinoco_get_drvinfo,
4773         .get_link = ethtool_op_get_link,
4774 };
4775
4776 /********************************************************************/
4777 /* Debugging                                                        */
4778 /********************************************************************/
4779
4780 #if 0
4781 static void show_rx_frame(struct orinoco_rxframe_hdr *frame)
4782 {
4783         printk(KERN_DEBUG "RX descriptor:\n");
4784         printk(KERN_DEBUG "  status      = 0x%04x\n", frame->desc.status);
4785         printk(KERN_DEBUG "  time        = 0x%08x\n", frame->desc.time);
4786         printk(KERN_DEBUG "  silence     = 0x%02x\n", frame->desc.silence);
4787         printk(KERN_DEBUG "  signal      = 0x%02x\n", frame->desc.signal);
4788         printk(KERN_DEBUG "  rate        = 0x%02x\n", frame->desc.rate);
4789         printk(KERN_DEBUG "  rxflow      = 0x%02x\n", frame->desc.rxflow);
4790         printk(KERN_DEBUG "  reserved    = 0x%08x\n", frame->desc.reserved);
4791
4792         printk(KERN_DEBUG "IEEE 802.11 header:\n");
4793         printk(KERN_DEBUG "  frame_ctl   = 0x%04x\n",
4794                frame->p80211.frame_ctl);
4795         printk(KERN_DEBUG "  duration_id = 0x%04x\n",
4796                frame->p80211.duration_id);
4797         printk(KERN_DEBUG "  addr1       = %02x:%02x:%02x:%02x:%02x:%02x\n",
4798                frame->p80211.addr1[0], frame->p80211.addr1[1],
4799                frame->p80211.addr1[2], frame->p80211.addr1[3],
4800                frame->p80211.addr1[4], frame->p80211.addr1[5]);
4801         printk(KERN_DEBUG "  addr2       = %02x:%02x:%02x:%02x:%02x:%02x\n",
4802                frame->p80211.addr2[0], frame->p80211.addr2[1],
4803                frame->p80211.addr2[2], frame->p80211.addr2[3],
4804                frame->p80211.addr2[4], frame->p80211.addr2[5]);
4805         printk(KERN_DEBUG "  addr3       = %02x:%02x:%02x:%02x:%02x:%02x\n",
4806                frame->p80211.addr3[0], frame->p80211.addr3[1],
4807                frame->p80211.addr3[2], frame->p80211.addr3[3],
4808                frame->p80211.addr3[4], frame->p80211.addr3[5]);
4809         printk(KERN_DEBUG "  seq_ctl     = 0x%04x\n",
4810                frame->p80211.seq_ctl);
4811         printk(KERN_DEBUG "  addr4       = %02x:%02x:%02x:%02x:%02x:%02x\n",
4812                frame->p80211.addr4[0], frame->p80211.addr4[1],
4813                frame->p80211.addr4[2], frame->p80211.addr4[3],
4814                frame->p80211.addr4[4], frame->p80211.addr4[5]);
4815         printk(KERN_DEBUG "  data_len    = 0x%04x\n",
4816                frame->p80211.data_len);
4817
4818         printk(KERN_DEBUG "IEEE 802.3 header:\n");
4819         printk(KERN_DEBUG "  dest        = %02x:%02x:%02x:%02x:%02x:%02x\n",
4820                frame->p8023.h_dest[0], frame->p8023.h_dest[1],
4821                frame->p8023.h_dest[2], frame->p8023.h_dest[3],
4822                frame->p8023.h_dest[4], frame->p8023.h_dest[5]);
4823         printk(KERN_DEBUG "  src         = %02x:%02x:%02x:%02x:%02x:%02x\n",
4824                frame->p8023.h_source[0], frame->p8023.h_source[1],
4825                frame->p8023.h_source[2], frame->p8023.h_source[3],
4826                frame->p8023.h_source[4], frame->p8023.h_source[5]);
4827         printk(KERN_DEBUG "  len         = 0x%04x\n", frame->p8023.h_proto);
4828
4829         printk(KERN_DEBUG "IEEE 802.2 LLC/SNAP header:\n");
4830         printk(KERN_DEBUG "  DSAP        = 0x%02x\n", frame->p8022.dsap);
4831         printk(KERN_DEBUG "  SSAP        = 0x%02x\n", frame->p8022.ssap);
4832         printk(KERN_DEBUG "  ctrl        = 0x%02x\n", frame->p8022.ctrl);
4833         printk(KERN_DEBUG "  OUI         = %02x:%02x:%02x\n",
4834                frame->p8022.oui[0], frame->p8022.oui[1], frame->p8022.oui[2]);
4835         printk(KERN_DEBUG "  ethertype  = 0x%04x\n", frame->ethertype);
4836 }
4837 #endif /* 0 */
4838
4839 /********************************************************************/
4840 /* Module initialization                                            */
4841 /********************************************************************/
4842
4843 EXPORT_SYMBOL(alloc_orinocodev);
4844 EXPORT_SYMBOL(free_orinocodev);
4845
4846 EXPORT_SYMBOL(__orinoco_up);
4847 EXPORT_SYMBOL(__orinoco_down);
4848 EXPORT_SYMBOL(orinoco_reinit_firmware);
4849
4850 EXPORT_SYMBOL(orinoco_interrupt);
4851
4852 /* Can't be declared "const" or the whole __initdata section will
4853  * become const */
4854 static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
4855         " (David Gibson <hermes@gibson.dropbear.id.au>, "
4856         "Pavel Roskin <proski@gnu.org>, et al)";
4857
4858 static int __init init_orinoco(void)
4859 {
4860         printk(KERN_DEBUG "%s\n", version);
4861         return 0;
4862 }
4863
4864 static void __exit exit_orinoco(void)
4865 {
4866 }
4867
4868 module_init(init_orinoco);
4869 module_exit(exit_orinoco);