7adbb331067c2703261d623e00d36cfdf9015c4e
[linux-flexiantxendom0-3.2.10.git] / drivers / net / wireless / orinoco.c
1 /* orinoco.c 0.13e      - (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  * Copyright (C) 2000 David Gibson, Linuxcare Australia <hermes@gibson.dropbear.id.au>
7  *      With some help from :
8  * Copyright (C) 2001 Jean Tourrilhes, HP Labs <jt@hpl.hp.com>
9  * Copyright (C) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
10  *
11  * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
12  *
13  * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy@fasta.fh-dortmund.de>
14  *      http://www.fasta.fh-dortmund.de/users/andy/wvlan/
15  *
16  * The contents of this file are subject to the Mozilla Public License
17  * Version 1.1 (the "License"); you may not use this file except in
18  * compliance with the License. You may obtain a copy of the License
19  * at http://www.mozilla.org/MPL/
20  *
21  * Software distributed under the License is distributed on an "AS IS"
22  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
23  * the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * The initial developer of the original code is David A. Hinds
27  * <dahinds@users.sourceforge.net>.  Portions created by David
28  * A. Hinds are Copyright (C) 1999 David A. Hinds.  All Rights
29  * Reserved.
30  *
31  * Alternatively, the contents of this file may be used under the
32  * terms of the GNU General Public License version 2 (the "GPL"), in
33  * which case the provisions of the GPL are applicable instead of the
34  * above.  If you wish to allow the use of your version of this file
35  * only under the terms of the GPL and not to allow others to use your
36  * version of this file under the MPL, indicate your decision by
37  * deleting the provisions above and replace them with the notice and
38  * other provisions required by the GPL.  If you do not delete the
39  * provisions above, a recipient may use your version of this file
40  * under either the MPL or the GPL.  */
41
42 /*
43  * v0.01 -> v0.02 - 21/3/2001 - Jean II
44  *      o Allow to use regular ethX device name instead of dldwdX
45  *      o Warning on IBSS with ESSID=any for firmware 6.06
46  *      o Put proper range.throughput values (optimistic)
47  *      o IWSPY support (IOCTL and stat gather in Rx path)
48  *      o Allow setting frequency in Ad-Hoc mode
49  *      o Disable WEP setting if !has_wep to work on old firmware
50  *      o Fix txpower range
51  *      o Start adding support for Samsung/Compaq firmware
52  *
53  * v0.02 -> v0.03 - 23/3/2001 - Jean II
54  *      o Start adding Symbol support - need to check all that
55  *      o Fix Prism2/Symbol WEP to accept 128 bits keys
56  *      o Add Symbol WEP (add authentication type)
57  *      o Add Prism2/Symbol rate
58  *      o Add PM timeout (holdover duration)
59  *      o Enable "iwconfig eth0 key off" and friends (toggle flags)
60  *      o Enable "iwconfig eth0 power unicast/all" (toggle flags)
61  *      o Try with an intel card. It report firmware 1.01, behave like
62  *        an antiquated firmware, however on windows it says 2.00. Yuck !
63  *      o Workaround firmware bug in allocate buffer (Intel 1.01)
64  *      o Finish external renaming to orinoco...
65  *      o Testing with various Wavelan firmwares
66  *
67  * v0.03 -> v0.04 - 30/3/2001 - Jean II
68  *      o Update to Wireless 11 -> add retry limit/lifetime support
69  *      o Tested with a D-Link DWL 650 card, fill in firmware support
70  *      o Warning on Vcc mismatch (D-Link 3.3v card in Lucent 5v only slot)
71  *      o Fixed the Prims2 WEP bugs that I introduced in v0.03 :-(
72  *        It work on D-Link *only* after a tcpdump. Weird...
73  *        And still doesn't work on Intel card. Grrrr...
74  *      o Update the mode after a setport3
75  *      o Add preamble setting for Symbol cards (not yet enabled)
76  *      o Don't complain as much about Symbol cards...
77  *
78  * v0.04 -> v0.04b - 22/4/2001 - David Gibson
79  *      o Removed the 'eth' parameter - always use ethXX as the
80  *        interface name instead of dldwdXX.  The other was racy
81  *        anyway.
82  *      o Clean up RID definitions in hermes.h, other cleanups
83  *
84  * v0.04b -> v0.04c - 24/4/2001 - Jean II
85  *      o Tim Hurley <timster@seiki.bliztech.com> reported a D-Link card
86  *        with vendor 02 and firmware 0.08. Added in the capabilities...
87  *      o Tested Lucent firmware 7.28, everything works...
88  *
89  * v0.04c -> v0.05 - 3/5/2001 - Benjamin Herrenschmidt
90  *      o Spin-off Pcmcia code. This file is renamed orinoco.c,
91  *        and orinoco_cs.c now contains only the Pcmcia specific stuff
92  *      o Add Airport driver support on top of orinoco.c (see airport.c)
93  *
94  * v0.05 -> v0.05a - 4/5/2001 - Jean II
95  *      o Revert to old Pcmcia code to fix breakage of Ben's changes...
96  *
97  * v0.05a -> v0.05b - 4/5/2001 - Jean II
98  *      o add module parameter 'ignore_cis_vcc' for D-Link @ 5V
99  *      o D-Link firmware doesn't support multicast. We just print a few
100  *        error messages, but otherwise everything works...
101  *      o For David : set/getport3 works fine, just upgrade iwpriv...
102  *
103  * v0.05b -> v0.05c - 5/5/2001 - Benjamin Herrenschmidt
104  *      o Adapt airport.c to latest changes in orinoco.c
105  *      o Remove deferred power enabling code
106  *
107  * v0.05c -> v0.05d - 5/5/2001 - Jean II
108  *      o Workaround to SNAP decapsulate frame from LinkSys AP
109  *        original patch from : Dong Liu <dliu@research.bell-labs.com>
110  *        (note : the memcmp bug was mine - fixed)
111  *      o Remove set_retry stuff, no firmware support it (bloat--).
112  *
113  * v0.05d -> v0.06 - 25/5/2001 - Jean II
114  *              Original patch from "Hong Lin" <alin@redhat.com>,
115  *              "Ian Kinner" <ikinner@redhat.com>
116  *              and "David Smith" <dsmith@redhat.com>
117  *      o Init of priv->tx_rate_ctrl in firmware specific section.
118  *      o Prism2/Symbol rate, upto should be 0xF and not 0x15. Doh !
119  *      o Spectrum card always need cor_reset (for every reset)
120  *      o Fix cor_reset to not lose bit 7 in the register
121  *      o flush_stale_links to remove zombie Pcmcia instances
122  *      o Ack previous hermes event before reset
123  *              Me (with my little hands)
124  *      o Allow orinoco.c to call cor_reset via priv->card_reset_handler
125  *      o Add priv->need_card_reset to toggle this feature
126  *      o Fix various buglets when setting WEP in Symbol firmware
127  *        Now, encryption is fully functional on Symbol cards. Youpi !
128  *
129  * v0.06 -> v0.06b - 25/5/2001 - Jean II
130  *      o IBSS on Symbol use port_mode = 4. Please don't ask...
131  *
132  * v0.06b -> v0.06c - 29/5/2001 - Jean II
133  *      o Show first spy address in /proc/net/wireless for IBSS mode as well
134  *
135  * v0.06c -> v0.06d - 6/7/2001 - David Gibson
136  *      o Change a bunch of KERN_INFO messages to KERN_DEBUG, as per Linus'
137  *        wishes to reduce the number of unecessary messages.
138  *      o Removed bogus message on CRC error.
139  *      o Merged fixeds for v0.08 Prism 2 firmware from William Waghorn
140  *        <willwaghorn@yahoo.co.uk>
141  *      o Slight cleanup/re-arrangement of firmware detection code.
142  *
143  * v0.06d -> v0.06e - 1/8/2001 - David Gibson
144  *      o Removed some redundant global initializers (orinoco_cs.c).
145  *      o Added some module metadataa
146  *
147  * v0.06e -> v0.06f - 14/8/2001 - David Gibson
148  *      o Wording fix to license
149  *      o Added a 'use_alternate_encaps' module parameter for APs which need an
150  *        oui of 00:00:00.  We really need a better way of handling this, but
151  *        the module flag is better than nothing for now.
152  *
153  * v0.06f -> v0.07 - 20/8/2001 - David Gibson
154  *      o Removed BAP error retries from hermes_bap_seek().  For Tx we now
155  *        let the upper layers handle the retry, we retry explicitly in the
156  *        Rx path, but don't make as much noise about it.
157  *      o Firmware detection cleanups.
158  *
159  * v0.07 -> v0.07a - 1/10/3001 - Jean II
160  *      o Add code to read Symbol firmware revision, inspired by latest code
161  *        in Spectrum24 by Lee John Keyser-Allen - Thanks Lee !
162  *      o Thanks to Jared Valentine <hidden@xmission.com> for "providing" me
163  *        a 3Com card with a recent firmware, fill out Symbol firmware
164  *        capabilities of latest rev (2.20), as well as older Symbol cards.
165  *      o Disable Power Management in newer Symbol firmware, the API 
166  *        has changed (documentation needed).
167  *
168  * v0.07a -> v0.08 - 3/10/2001 - David Gibson
169  *      o Fixed a possible buffer overrun found by the Stanford checker (in
170  *        dldwd_ioctl_setiwencode()).  Can only be called by root anyway, so not
171  *        a big problem.
172  *      o Turned has_big_wep on for Intersil cards.  That's not true for all of
173  *        them but we should at least let the capable ones try.
174  *      o Wait for BUSY to clear at the beginning of hermes_bap_seek().  I
175  *        realised that my assumption that the driver's serialization
176  *        would prevent the BAP being busy on entry was possibly false, because
177  *        things other than seeks may make the BAP busy.
178  *      o Use "alternate" (oui 00:00:00) encapsulation by default.
179  *        Setting use_old_encaps will mimic the old behaviour, but I think we
180  *        will be able to eliminate this.
181  *      o Don't try to make __initdata const (the version string).  This can't
182  *        work because of the way the __initdata sectioning works.
183  *      o Added MODULE_LICENSE tags.
184  *      o Support for PLX (transparent PCMCIA->PCI brdge) cards.
185  *      o Changed to using the new type-facist min/max.
186  *
187  * v0.08 -> v0.08a - 9/10/2001 - David Gibson
188  *      o Inserted some missing acknowledgements/info into the Changelog.
189  *      o Fixed some bugs in the normalisation of signel level reporting.
190  *      o Fixed bad bug in WEP key handling on Intersil and Symbol firmware,
191  *        which led to an instant crash on big-endian machines.
192  *
193  * v0.08a -> v0.08b - 20/11/2001 - David Gibson
194  *      o Lots of cleanup and bugfixes in orinoco_plx.c
195  *      o Cleanup to handling of Tx rate setting.
196  *      o Removed support for old encapsulation method.
197  *      o Removed old "dldwd" names.
198  *      o Split RID constants into a new file hermes_rid.h
199  *      o Renamed RID constants to match linux-wlan-ng and prism2.o
200  *      o Bugfixes in hermes.c
201  *      o Poke the PLX's INTCSR register, so it actually starts
202  *        generating interrupts.  These cards might actually work now.
203  *      o Update to wireless extensions v12 (Jean II)
204  *      o Support for tallies and inquire command (Jean II)
205  *      o Airport updates for newer PPC kernels (BenH)
206  *
207  * v0.08b -> v0.09 - 21/12/2001 - David Gibson
208  *      o Some new PCI IDs for PLX cards.
209  *      o Removed broken attempt to do ALLMULTI reception.  Just use
210  *        promiscuous mode instead
211  *      o Preliminary work for list-AP (Jean II)
212  *      o Airport updates from (BenH)
213  *      o Eliminated racy hw_ready stuff
214  *      o Fixed generation of fake events in irq handler.  This should
215  *        finally kill the EIO problems (Jean II & dgibson)
216  *      o Fixed breakage of bitrate set/get on Agere firmware (Jean II)
217  *
218  * v0.09 -> v0.09a - 2/1/2002 - David Gibson
219  *      o Fixed stupid mistake in multicast list handling, triggering
220  *        a BUG()
221  *
222  * v0.09a -> v0.09b - 16/1/2002 - David Gibson
223  *      o Fixed even stupider mistake in new interrupt handling, which
224  *        seriously broke things on big-endian machines.
225  *      o Removed a bunch of redundant includes and exports.
226  *      o Removed a redundant MOD_{INC,DEC}_USE_COUNT pair in airport.c
227  *      o Don't attempt to do hardware level multicast reception on
228  *        Intersil firmware, just go promisc instead.
229  *      o Typo fixed in hermes_issue_cmd()
230  *      o Eliminated WIRELESS_SPY #ifdefs
231  *      o Status code reported on Tx exceptions
232  *      o Moved netif_wake_queue() from ALLOC interrupts to TX and TXEXC
233  *        interrupts, which should fix the timeouts we're seeing.
234  *
235  * v0.09b -> v0.10 - 25 Feb 2002 - David Gibson
236  *      o Removed nested structures used for header parsing, so the
237  *        driver should now work without hackery on ARM
238  *      o Fix for WEP handling on Intersil (Hawk Newton)
239  *      o Eliminated the /proc/hermes/ethXX/regs debugging file.  It
240  *        was never very useful.
241  *      o Make Rx errors less noisy.
242  *
243  * v0.10 -> v0.11 - 5 Apr 2002 - David Gibson
244  *      o Laid the groundwork in hermes.[ch] for devices which map
245  *        into PCI memory space rather than IO space.
246  *      o Fixed bug in multicast handling (cleared multicast list when
247  *        leaving promiscuous mode).
248  *      o Relegated Tx error messages to debug.
249  *      o Cleaned up / corrected handling of allocation lengths.
250  *      o Set OWNSSID in IBSS mode for WinXP interoperability (jimc).
251  *      o Change to using alloc_etherdev() for structure allocations. 
252  *      o Check for and drop undersized packets.
253  *      o Fixed a race in stopping/waking the queue.  This should fix
254  *        the timeout problems (Pavel Roskin)
255  *      o Reverted to netif_wake_queue() on the ALLOC event.
256  *      o Fixes for recent Symbol firmwares which lack AP density
257  *        (Pavel Roskin).
258  *
259  * v0.11 -> v0.11a - 29 Apr 2002 - David Gibson
260  *      o Handle different register spacing, necessary for Prism 2.5
261  *        PCI adaptors (Steve Hill).
262  *      o Cleaned up initialization of card structures in orinoco_cs
263  *        and airport.  Removed card->priv field.
264  *      o Make response structure optional for hermes_docmd_wait()
265  *        Pavel Roskin)
266  *      o Added PCI id for Nortel emobility to orinoco_plx.c.
267  *      o Cleanup to handling of Symbol's allocation bug. (Pavel Roskin)
268  *      o Cleanups to firmware capability detection.
269  *      o Arrange for orinoco_pci.c to override firmware detection.
270  *        We should be able to support the PCI Intersil cards now.
271  *      o Cleanup handling of reset_cor and hard_reset (Pavel Roskin).
272  *      o Remove erroneous use of USER_BAP in the TxExc handler (Jouni
273  *        Malinen).
274  *      o Makefile changes for better integration into David Hinds
275  *        pcmcia-cs package.
276  *
277  * v0.11a -> v0.11b - 1 May 2002 - David Gibson
278  *      o Better error reporting in orinoco_plx_init_one()
279  *      o Fixed multiple bad kfree() bugs introduced by the
280  *        alloc_orinocodev() changes.
281  *
282  * v0.11b -> v0.12 - 19 Jun 2002 - David Gibson
283  *      o Support changing the MAC address.
284  *      o Correct display of Intersil firmware revision numbers.
285  *      o Entirely revised locking scheme.  Should be both simpler and
286  *         better.
287  *      o Merged some common code in orinoco_plx, orinoco_pci and
288  *        airport by creating orinoco_default_{open,stop,reset}()
289  *        which are used as the dev->open, dev->stop, priv->reset
290  *        callbacks if none are specified when alloc_orinocodev() is
291  *        called.
292  *      o Removed orinoco_plx_interrupt() and orinoco_pci_interrupt().
293  *        They didn't do anything.
294  *
295  * v0.12 -> v0.12a - 4 Jul 2002 - David Gibson
296  *      o Some rearrangement of code.
297  *      o Numerous fixups to locking and rest handling, particularly
298  *        for PCMCIA.
299  *      o This allows open and stop net_device methods to be in
300  *        orinoco.c now, rather than in the init modules.
301  *      o In orinoco_cs.c link->priv now points to the struct
302  *        net_device not to the struct orinoco_private.
303  *      o Added a check for undersized SNAP frames, which could cause
304  *        crashes.
305  *
306  * v0.12a -> v0.12b - 11 Jul 2002 - David Gibson
307  *      o Fix hw->num_init testing code, so num_init is actually
308  *        incremented.
309  *      o Fix very stupid bug in orinoco_cs which broke compile with
310  *        CONFIG_SMP.
311  *      o Squashed a warning.
312  *
313  * v0.12b -> v0.12c - 26 Jul 2002 - David Gibson
314  *      o Change to C9X style designated initializers.
315  *      o Add support for 3Com AirConnect PCI.
316  *      o No longer ignore the hard_reset argument to
317  *        alloc_orinocodev().  Oops.
318  *
319  * v0.12c -> v0.13beta1 - 13 Sep 2002 - David Gibson
320  *      o Revert the broken 0.12* locking scheme and go to a new yet
321  *        simpler scheme.
322  *      o Do firmware resets only in orinoco_init() and when waking
323  *        the card from hard sleep.
324  *
325  * v0.13beta1 -> v0.13 - 27 Sep 2002 - David Gibson
326  *      o Re-introduced full resets (via schedule_task()) on Tx
327  *        timeout.
328  *
329  * v0.13 -> v0.13a - 30 Sep 2002 - David Gibson
330  *      o Minor cleanups to info frame handling.  Add basic support
331  *        for linkstatus info frames.
332  *      o Include required kernel headers in orinoco.h, to avoid
333  *        compile problems.
334  *
335  * v0.13a -> v0.13b - 10 Feb 2003 - David Gibson
336  *      o Implemented hard reset for Airport cards
337  *      o Experimental suspend/resume implementation for orinoco_pci
338  *      o Abolished /proc debugging support, replaced with a debugging
339  *        iwpriv.  Now it's ugly and simple instead of ugly and complex.
340  *      o Bugfix in hermes.c if the firmware returned a record length
341  *        of 0, we could go clobbering memory.
342  *      o Bugfix in orinoco_stop() - it used to fail if hw_unavailable
343  *        was set, which was usually true on PCMCIA hot removes.
344  *      o Track LINKSTATUS messages, silently drop Tx packets before
345  *        we are connected (avoids cofusing the firmware), and only
346  *        give LINKSTATUS printk()s if the status has changed.
347  *
348  * v0.13b -> v0.13c - 11 Mar 2003 - David Gibson
349  *      o Cleanup: use dev instead of priv in various places.
350  *      o Bug fix: Don't ReleaseConfiguration on RESET_PHYSICAL event
351  *        if we're in the middle of a (driver initiated) hard reset.
352  *      o Bug fix: ETH_ZLEN is supposed to include the header
353  *        (Dionysus Blazakis & Manish Karir)
354  *      o Convert to using workqueues instead of taskqueues (and
355  *        backwards compatibility macros for pre 2.5.41 kernels).
356  *      o Drop redundant (I think...) MOD_{INC,DEC}_USE_COUNT in
357  *        airport.c
358  *      o New orinoco_tmd.c init module from Joerg Dorchain for
359  *        TMD7160 based PCI to PCMCIA bridges (similar to
360  *        orinoco_plx.c).
361  *
362  * v0.13c -> v0.13d - 22 Apr 2003 - David Gibson
363  *      o Make hw_unavailable a counter, rather than just a flag, this
364  *        is necessary to avoid some races (such as a card being
365  *        removed in the middle of orinoco_reset().
366  *      o Restore Release/RequestConfiguration in the PCMCIA event handler
367  *        when dealing with a driver initiated hard reset.  This is
368  *        necessary to prevent hangs due to a spurious interrupt while
369  *        the reset is in progress.
370  *      o Clear the 802.11 header when transmitting, even though we
371  *        don't use it.  This fixes a long standing bug on some
372  *        firmwares, which seem to get confused if that isn't done.
373  *      o Be less eager to de-encapsulate SNAP frames, only do so if
374  *        the OUI is 00:00:00 or 00:00:f8, leave others alone.  The old
375  *        behaviour broke CDP (Cisco Discovery Protocol).
376  *      o Use dev instead of priv for free_irq() as well as
377  *        request_irq() (oops).
378  *      o Attempt to reset rather than giving up if we get too many
379  *        IRQs.
380  *      o Changed semantics of __orinoco_down() so it can be called
381  *        safely with hw_unavailable set.  It also now clears the
382  *        linkstatus (since we're going to have to reassociate).
383  *
384  * v0.13d -> v0.13e - 12 May 2003 - David Gibson
385  *      o Support for post-2.5.68 return values from irq handler.
386  *      o Fixed bug where underlength packets would be double counted
387  *        in the rx_dropped statistics.
388  *      o Provided a module parameter to suppress linkstatus messages.
389  *
390  * TODO
391  *      o New wireless extensions API (patch from Moustafa
392  *        Youssef, updated by Jim Carter and Pavel Roskin).
393  *      o Handle de-encapsulation within network layer, provide 802.11
394  *        headers (patch from Thomas 'Dent' Mirlacher)
395  *      o RF monitor mode support
396  *      o Fix possible races in SPY handling.
397  *      o Disconnect wireless extensions from fundamental configuration.
398  *      o (maybe) Software WEP support (patch from Stano Meduna).
399  *      o (maybe) Use multiple Tx buffers - driver handling queue
400  *        rather than firmware. */
401
402 /* Locking and synchronization:
403  *
404  * The basic principle is that everything is serialized through a
405  * single spinlock, priv->lock.  The lock is used in user, bh and irq
406  * context, so when taken outside hardirq context it should always be
407  * taken with interrupts disabled.  The lock protects both the
408  * hardware and the struct orinoco_private.
409  *
410  * Another flag, priv->hw_unavailable indicates that the hardware is
411  * unavailable for an extended period of time (e.g. suspended, or in
412  * the middle of a hard reset).  This flag is protected by the
413  * spinlock.  All code which touches the hardware should check the
414  * flag after taking the lock, and if it is set, give up on whatever
415  * they are doing and drop the lock again.  The orinoco_lock()
416  * function handles this (it unlocks and returns -EBUSY if
417  * hw_unavailable is non-zero). */
418
419 #include <linux/config.h>
420
421 #include <linux/module.h>
422 #include <linux/kernel.h>
423 #include <linux/init.h>
424 #include <linux/ptrace.h>
425 #include <linux/slab.h>
426 #include <linux/string.h>
427 #include <linux/timer.h>
428 #include <linux/ioport.h>
429 #include <linux/netdevice.h>
430 #include <linux/if_arp.h>
431 #include <linux/etherdevice.h>
432 #include <linux/wireless.h>
433
434 #include <asm/uaccess.h>
435 #include <asm/io.h>
436 #include <asm/system.h>
437
438 #include "hermes.h"
439 #include "hermes_rid.h"
440 #include "orinoco.h"
441 #include "ieee802_11.h"
442
443 /********************************************************************/
444 /* Module information                                               */
445 /********************************************************************/
446
447 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
448 MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
449 #ifdef MODULE_LICENSE
450 MODULE_LICENSE("Dual MPL/GPL");
451 #endif
452
453 /* Level of debugging. Used in the macros in orinoco.h */
454 #ifdef ORINOCO_DEBUG
455 int orinoco_debug = ORINOCO_DEBUG;
456 MODULE_PARM(orinoco_debug, "i");
457 EXPORT_SYMBOL(orinoco_debug);
458 #endif
459
460 static int suppress_linkstatus; /* = 0 */
461 MODULE_PARM(suppress_linkstatus, "i");
462
463 /********************************************************************/
464 /* Compile time configuration and compatibility stuff               */
465 /********************************************************************/
466
467 /* Wireless extensions backwards compatibility */
468 #ifndef SIOCIWFIRSTPRIV
469 #define SIOCIWFIRSTPRIV         SIOCDEVPRIVATE
470 #endif /* SIOCIWFIRSTPRIV */
471
472 /* We do this this way to avoid ifdefs in the actual code */
473 #ifdef WIRELESS_SPY
474 #define SPY_NUMBER(priv)        (priv->spy_number)
475 #else
476 #define SPY_NUMBER(priv)        0
477 #endif /* WIRELESS_SPY */
478
479 /********************************************************************/
480 /* Internal constants                                               */
481 /********************************************************************/
482
483 #define ORINOCO_MIN_MTU         256
484 #define ORINOCO_MAX_MTU         (IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD)
485
486 #define SYMBOL_MAX_VER_LEN      (14)
487 #define USER_BAP                0
488 #define IRQ_BAP                 1
489 #define MAX_IRQLOOPS_PER_IRQ    10
490 #define MAX_IRQLOOPS_PER_JIFFY  (20000/HZ) /* Based on a guestimate of
491                                             * how many events the
492                                             * device could
493                                             * legitimately generate */
494 #define SMALL_KEY_SIZE          5
495 #define LARGE_KEY_SIZE          13
496 #define TX_NICBUF_SIZE_BUG      1585            /* Bug in Symbol firmware */
497
498 #define DUMMY_FID               0xFFFF
499
500 #define RUP_EVEN(a) (((a) + 1) & (~1))
501
502 /*#define MAX_MULTICAST(priv)   (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
503   HERMES_MAX_MULTICAST : 0)*/
504 #define MAX_MULTICAST(priv)     (HERMES_MAX_MULTICAST)
505
506 /********************************************************************/
507 /* Data tables                                                      */
508 /********************************************************************/
509
510 /* The frequency of each channel in MHz */
511 const long channel_frequency[] = {
512         2412, 2417, 2422, 2427, 2432, 2437, 2442,
513         2447, 2452, 2457, 2462, 2467, 2472, 2484
514 };
515 #define NUM_CHANNELS ( sizeof(channel_frequency) / sizeof(channel_frequency[0]) )
516
517 /* This tables gives the actual meanings of the bitrate IDs returned by the firmware. */
518 struct {
519         int bitrate; /* in 100s of kilobits */
520         int automatic;
521         u16 agere_txratectrl;
522         u16 intersil_txratectrl;
523 } bitrate_table[] = {
524         {110, 1,  3, 15}, /* Entry 0 is the default */
525         {10,  0,  1,  1},
526         {10,  1,  1,  1},
527         {20,  0,  2,  2},
528         {20,  1,  6,  3},
529         {55,  0,  4,  4},
530         {55,  1,  7,  7},
531         {110, 0,  5,  8},
532 };
533 #define BITRATE_TABLE_SIZE (sizeof(bitrate_table) / sizeof(bitrate_table[0]))
534
535 /********************************************************************/
536 /* Data types                                                       */
537 /********************************************************************/
538
539 struct header_struct {
540         /* 802.3 */
541         u8 dest[ETH_ALEN];
542         u8 src[ETH_ALEN];
543         u16 len;
544         /* 802.2 */
545         u8 dsap;
546         u8 ssap;
547         u8 ctrl;
548         /* SNAP */
549         u8 oui[3];
550         u16 ethertype;
551 } __attribute__ ((packed));
552
553 /* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
554 u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
555
556 #define ENCAPS_OVERHEAD         (sizeof(encaps_hdr) + 2)
557
558 /********************************************************************/
559 /* Function prototypes                                              */
560 /********************************************************************/
561
562 static void orinoco_stat_gather(struct net_device *dev,
563                                 struct sk_buff *skb,
564                                 struct hermes_rx_descriptor *desc);
565
566 static struct net_device_stats *orinoco_get_stats(struct net_device *dev);
567 static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev);
568
569 /* Hardware control routines */
570
571 static int __orinoco_program_rids(struct net_device *dev);
572
573 static int __orinoco_hw_set_bitrate(struct orinoco_private *priv);
574 static int __orinoco_hw_setup_wep(struct orinoco_private *priv);
575 static int orinoco_hw_get_bssid(struct orinoco_private *priv, char buf[ETH_ALEN]);
576 static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
577                                 char buf[IW_ESSID_MAX_SIZE+1]);
578 static long orinoco_hw_get_freq(struct orinoco_private *priv);
579 static int orinoco_hw_get_bitratelist(struct orinoco_private *priv, int *numrates,
580                                       s32 *rates, int max);
581 static void __orinoco_set_multicast_list(struct net_device *dev);
582
583 /* Interrupt handling routines */
584 static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw);
585 static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw);
586 static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw);
587 static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw);
588 static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw);
589 static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw);
590 static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw);
591 static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw);
592
593 /* ioctl() routines */
594 static int orinoco_debug_dump_recs(struct net_device *dev);
595
596 /********************************************************************/
597 /* Function prototypes                                              */
598 /********************************************************************/
599
600 int __orinoco_up(struct net_device *dev)
601 {
602         struct orinoco_private *priv = netdev_priv(dev);
603         struct hermes *hw = &priv->hw;
604         int err;
605
606         err = __orinoco_program_rids(dev);
607         if (err) {
608                 printk(KERN_ERR "%s: Error %d configuring card\n",
609                        dev->name, err);
610                 return err;
611         }
612
613         /* Fire things up again */
614         hermes_set_irqmask(hw, ORINOCO_INTEN);
615         err = hermes_enable_port(hw, 0);
616         if (err) {
617                 printk(KERN_ERR "%s: Error %d enabling MAC port\n",
618                        dev->name, err);
619                 return err;
620         }
621
622         netif_start_queue(dev);
623
624         return 0;
625 }
626
627 int __orinoco_down(struct net_device *dev)
628 {
629         struct orinoco_private *priv = netdev_priv(dev);
630         struct hermes *hw = &priv->hw;
631         int err;
632
633         netif_stop_queue(dev);
634
635         if (! priv->hw_unavailable) {
636                 if (! priv->broken_disableport) {
637                         err = hermes_disable_port(hw, 0);
638                         if (err) {
639                                 /* Some firmwares (e.g. Intersil 1.3.x) seem
640                                  * to have problems disabling the port, oh
641                                  * well, too bad. */
642                                 printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
643                                        dev->name, err);
644                                 priv->broken_disableport = 1;
645                         }
646                 }
647                 hermes_set_irqmask(hw, 0);
648                 hermes_write_regn(hw, EVACK, 0xffff);
649         }
650         
651         /* firmware will have to reassociate */
652         priv->last_linkstatus = 0xffff;
653         priv->connected = 0;
654
655         return 0;
656 }
657
658 int orinoco_reinit_firmware(struct net_device *dev)
659 {
660         struct orinoco_private *priv = netdev_priv(dev);
661         struct hermes *hw = &priv->hw;
662         int err;
663
664         err = hermes_init(hw);
665         if (err)
666                 return err;
667
668         err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
669         if (err == -EIO) {
670                 /* Try workaround for old Symbol firmware bug */
671                 printk(KERN_WARNING "%s: firmware ALLOC bug detected "
672                        "(old Symbol firmware?). Trying to work around... ",
673                        dev->name);
674                 
675                 priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
676                 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
677                 if (err)
678                         printk("failed!\n");
679                 else
680                         printk("ok.\n");
681         }
682
683         return err;
684 }
685
686 static int orinoco_open(struct net_device *dev)
687 {
688         struct orinoco_private *priv = netdev_priv(dev);
689         unsigned long flags;
690         int err;
691
692         err = orinoco_lock(priv, &flags);
693         if (err)
694                 return err;
695
696         err = __orinoco_up(dev);
697
698         if (! err)
699                 priv->open = 1;
700
701         orinoco_unlock(priv, &flags);
702
703         return err;
704 }
705
706 int orinoco_stop(struct net_device *dev)
707 {
708         struct orinoco_private *priv = netdev_priv(dev);
709         int err = 0;
710
711         /* We mustn't use orinoco_lock() here, because we need to be
712            able to close the interface even if hw_unavailable is set
713            (e.g. as we're released after a PC Card removal) */
714         spin_lock_irq(&priv->lock);
715
716         priv->open = 0;
717
718         err = __orinoco_down(dev);
719
720         spin_unlock_irq(&priv->lock);
721
722         return err;
723 }
724
725 static int __orinoco_program_rids(struct net_device *dev)
726 {
727         struct orinoco_private *priv = netdev_priv(dev);
728         hermes_t *hw = &priv->hw;
729         int err;
730         struct hermes_idstring idbuf;
731
732         /* Set the MAC address */
733         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
734                                HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
735         if (err) {
736                 printk(KERN_ERR "%s: Error %d setting MAC address\n", dev->name, err);
737                 return err;
738         }
739
740         /* Set up the link mode */
741         err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE, priv->port_type);
742         if (err) {
743                 printk(KERN_ERR "%s: Error %d setting port type\n", dev->name, err);
744                 return err;
745         }
746         /* Set the channel/frequency */
747         if (priv->channel == 0) {
748                 printk(KERN_DEBUG "%s: Channel is 0 in __orinoco_program_rids()\n", dev->name);
749                 if (priv->createibss)
750                         priv->channel = 10;
751         }
752         err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFOWNCHANNEL, priv->channel);
753         if (err) {
754                 printk(KERN_ERR "%s: Error %d setting channel\n", dev->name, err);
755                 return err;
756         }
757
758         if (priv->has_ibss) {
759                 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFCREATEIBSS,
760                                            priv->createibss);
761                 if (err) {
762                         printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n", dev->name, err);
763                         return err;
764                 }
765
766                 if ((strlen(priv->desired_essid) == 0) && (priv->createibss)
767                    && (!priv->has_ibss_any)) {
768                         printk(KERN_WARNING "%s: This firmware requires an \
769 ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
770                         /* With wvlan_cs, in this case, we would crash.
771                          * hopefully, this driver will behave better...
772                          * Jean II */
773                 }
774         }
775
776         /* Set the desired ESSID */
777         idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
778         memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
779         /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
780         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
781                                HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
782                                &idbuf);
783         if (err) {
784                 printk(KERN_ERR "%s: Error %d setting OWNSSID\n", dev->name, err);
785                 return err;
786         }
787         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
788                                HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
789                                &idbuf);
790         if (err) {
791                 printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n", dev->name, err);
792                 return err;
793         }
794
795         /* Set the station name */
796         idbuf.len = cpu_to_le16(strlen(priv->nick));
797         memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
798         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
799                                HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
800                                &idbuf);
801         if (err) {
802                 printk(KERN_ERR "%s: Error %d setting nickname\n", dev->name, err);
803                 return err;
804         }
805
806         /* Set AP density */
807         if (priv->has_sensitivity) {
808                 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
809                                            priv->ap_density);
810                 if (err) {
811                         printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE.  "
812                                "Disabling sensitivity control\n", dev->name, err);
813
814                         priv->has_sensitivity = 0;
815                 }
816         }
817
818         /* Set RTS threshold */
819         err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD, priv->rts_thresh);
820         if (err) {
821                 printk(KERN_ERR "%s: Error %d setting RTS threshold\n", dev->name, err);
822                 return err;
823         }
824
825         /* Set fragmentation threshold or MWO robustness */
826         if (priv->has_mwo)
827                 err = hermes_write_wordrec(hw, USER_BAP,
828                                            HERMES_RID_CNFMWOROBUST_AGERE,
829                                            priv->mwo_robust);
830         else
831                 err = hermes_write_wordrec(hw, USER_BAP,
832                                            HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
833                                            priv->frag_thresh);
834         if (err) {
835                 printk(KERN_ERR "%s: Error %d setting framentation\n", dev->name, err);
836                 return err;
837         }
838
839         /* Set bitrate */
840         err = __orinoco_hw_set_bitrate(priv);
841         if (err) {
842                 printk(KERN_ERR "%s: Error %d setting bitrate\n", dev->name, err);
843                 return err;
844         }
845
846         /* Set power management */
847         if (priv->has_pm) {
848                 err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED,
849                                            priv->pm_on);
850                 if (err) {
851                         printk(KERN_ERR "%s: Error %d setting up PM\n",
852                                dev->name, err);
853                         return err;
854                 }
855
856                 err = hermes_write_wordrec(hw, USER_BAP,
857                                            HERMES_RID_CNFMULTICASTRECEIVE,
858                                            priv->pm_mcast);
859                 if (err) {
860                         printk(KERN_ERR "%s: Error %d setting up PM\n",
861                                dev->name, err);
862                         return err;
863                 }
864                 err = hermes_write_wordrec(hw, USER_BAP,
865                                            HERMES_RID_CNFMAXSLEEPDURATION,
866                                            priv->pm_period);
867                 if (err) {
868                         printk(KERN_ERR "%s: Error %d setting up PM\n",
869                                dev->name, err);
870                         return err;
871                 }
872                 err = hermes_write_wordrec(hw, USER_BAP,
873                                            HERMES_RID_CNFPMHOLDOVERDURATION,
874                                            priv->pm_timeout);
875                 if (err) {
876                         printk(KERN_ERR "%s: Error %d setting up PM\n",
877                                dev->name, err);
878                         return err;
879                 }
880         }
881
882         /* Set preamble - only for Symbol so far... */
883         if (priv->has_preamble) {
884                 err = hermes_write_wordrec(hw, USER_BAP,
885                                            HERMES_RID_CNFPREAMBLE_SYMBOL,
886                                            priv->preamble);
887                 if (err) {
888                         printk(KERN_ERR "%s: Error %d setting preamble\n",
889                                dev->name, err);
890                         return err;
891                 }
892         }
893
894         /* Set up encryption */
895         if (priv->has_wep) {
896                 err = __orinoco_hw_setup_wep(priv);
897                 if (err) {
898                         printk(KERN_ERR "%s: Error %d activating WEP\n",
899                                dev->name, err);
900                         return err;
901                 }
902         }
903
904         /* Set promiscuity / multicast*/
905         priv->promiscuous = 0;
906         priv->mc_count = 0;
907         __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */
908
909         return 0;
910 }
911
912 /* xyzzy */
913 static int orinoco_reconfigure(struct net_device *dev)
914 {
915         struct orinoco_private *priv = netdev_priv(dev);
916         struct hermes *hw = &priv->hw;
917         unsigned long flags;
918         int err = 0;
919
920         if (priv->broken_disableport) {
921                 schedule_work(&priv->reset_work);
922                 return 0;
923         }
924
925         err = orinoco_lock(priv, &flags);
926         if (err)
927                 return err;
928
929                 
930         err = hermes_disable_port(hw, 0);
931         if (err) {
932                 printk(KERN_WARNING "%s: Unable to disable port while reconfiguring card\n",
933                        dev->name);
934                 priv->broken_disableport = 1;
935                 goto out;
936         }
937
938         err = __orinoco_program_rids(dev);
939         if (err) {
940                 printk(KERN_WARNING "%s: Unable to reconfigure card\n",
941                        dev->name);
942                 goto out;
943         }
944
945         err = hermes_enable_port(hw, 0);
946         if (err) {
947                 printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
948                        dev->name);
949                 goto out;
950         }
951
952  out:
953         if (err) {
954                 printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
955                 schedule_work(&priv->reset_work);
956                 err = 0;
957         }
958
959         orinoco_unlock(priv, &flags);
960         return err;
961
962 }
963
964 /* This must be called from user context, without locks held - use
965  * schedule_work() */
966 static void orinoco_reset(struct net_device *dev)
967 {
968         struct orinoco_private *priv = netdev_priv(dev);
969         struct hermes *hw = &priv->hw;
970         int err;
971         unsigned long flags;
972
973         err = orinoco_lock(priv, &flags);
974         if (err)
975                 /* When the hardware becomes available again, whatever
976                  * detects that is responsible for re-initializing
977                  * it. So no need for anything further*/
978                 return;
979
980         netif_stop_queue(dev);
981
982         /* Shut off interrupts.  Depending on what state the hardware
983          * is in, this might not work, but we'll try anyway */
984         hermes_set_irqmask(hw, 0);
985         hermes_write_regn(hw, EVACK, 0xffff);
986
987         priv->hw_unavailable++;
988         priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
989         priv->connected = 0;
990
991         orinoco_unlock(priv, &flags);
992
993         if (priv->hard_reset)
994                 err = (*priv->hard_reset)(priv);
995         if (err) {
996                 printk(KERN_ERR "%s: orinoco_reset: Error %d performing hard reset\n",
997                        dev->name, err);
998                 /* FIXME: shutdown of some sort */
999                 return;
1000         }
1001
1002         err = orinoco_reinit_firmware(dev);
1003         if (err) {
1004                 printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
1005                        dev->name, err);
1006                 return;
1007         }
1008
1009         spin_lock_irq(&priv->lock); /* This has to be called from user context */
1010
1011         priv->hw_unavailable--;
1012
1013         /* priv->open or priv->hw_unavailable might have changed while
1014          * we dropped the lock */
1015         if (priv->open && (! priv->hw_unavailable)) {
1016                 err = __orinoco_up(dev);
1017                 if (err) {
1018                         printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
1019                                dev->name, err);
1020                 } else
1021                         dev->trans_start = jiffies;
1022         }
1023
1024         spin_unlock_irq(&priv->lock);
1025
1026         return;
1027 }
1028
1029 /********************************************************************/
1030 /* Internal helper functions                                        */
1031 /********************************************************************/
1032
1033 static inline void
1034 set_port_type(struct orinoco_private *priv)
1035 {
1036         switch (priv->iw_mode) {
1037         case IW_MODE_INFRA:
1038                 priv->port_type = 1;
1039                 priv->createibss = 0;
1040                 break;
1041         case IW_MODE_ADHOC:
1042                 if (priv->prefer_port3) {
1043                         priv->port_type = 3;
1044                         priv->createibss = 0;
1045                 } else {
1046                         priv->port_type = priv->ibss_port;
1047                         priv->createibss = 1;
1048                 }
1049                 break;
1050         default:
1051                 printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
1052                        priv->ndev->name);
1053         }
1054 }
1055
1056 /* Does the frame have a SNAP header indicating it should be
1057  * de-encapsulated to Ethernet-II? */
1058 static inline int
1059 is_ethersnap(struct header_struct *hdr)
1060 {
1061         /* We de-encapsulate all packets which, a) have SNAP headers
1062          * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
1063          * and where b) the OUI of the SNAP header is 00:00:00 or
1064          * 00:00:f8 - we need both because different APs appear to use
1065          * different OUIs for some reason */
1066         return (memcmp(&hdr->dsap, &encaps_hdr, 5) == 0)
1067                 && ( (hdr->oui[2] == 0x00) || (hdr->oui[2] == 0xf8) );
1068 }
1069
1070 static void
1071 orinoco_set_multicast_list(struct net_device *dev)
1072 {
1073         struct orinoco_private *priv = netdev_priv(dev);
1074         unsigned long flags;
1075
1076         if (orinoco_lock(priv, &flags) != 0) {
1077                 printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
1078                        "called when hw_unavailable\n", dev->name);
1079                 return;
1080         }
1081
1082         __orinoco_set_multicast_list(dev);
1083         orinoco_unlock(priv, &flags);
1084 }
1085
1086 /********************************************************************/
1087 /* Hardware control functions                                       */
1088 /********************************************************************/
1089
1090
1091 static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
1092 {
1093         hermes_t *hw = &priv->hw;
1094         int err = 0;
1095
1096         if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
1097                 printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
1098                        priv->ndev->name, priv->bitratemode);
1099                 return -EINVAL;
1100         }
1101
1102         switch (priv->firmware_type) {
1103         case FIRMWARE_TYPE_AGERE:
1104                 err = hermes_write_wordrec(hw, USER_BAP,
1105                                            HERMES_RID_CNFTXRATECONTROL,
1106                                            bitrate_table[priv->bitratemode].agere_txratectrl);
1107                 break;
1108         case FIRMWARE_TYPE_INTERSIL:
1109         case FIRMWARE_TYPE_SYMBOL:
1110                 err = hermes_write_wordrec(hw, USER_BAP,
1111                                            HERMES_RID_CNFTXRATECONTROL,
1112                                            bitrate_table[priv->bitratemode].intersil_txratectrl);
1113                 break;
1114         default:
1115                 BUG();
1116         }
1117
1118         return err;
1119 }
1120
1121
1122 static int __orinoco_hw_setup_wep(struct orinoco_private *priv)
1123 {
1124         hermes_t *hw = &priv->hw;
1125         int err = 0;
1126         int     master_wep_flag;
1127         int     auth_flag;
1128
1129         switch (priv->firmware_type) {
1130         case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
1131                 if (priv->wep_on) {
1132                         err = hermes_write_wordrec(hw, USER_BAP,
1133                                                    HERMES_RID_CNFTXKEY_AGERE,
1134                                                    priv->tx_key);
1135                         if (err)
1136                                 return err;
1137                         
1138                         err = HERMES_WRITE_RECORD(hw, USER_BAP,
1139                                                   HERMES_RID_CNFWEPKEYS_AGERE,
1140                                                   &priv->keys);
1141                         if (err)
1142                                 return err;
1143                 }
1144                 err = hermes_write_wordrec(hw, USER_BAP,
1145                                            HERMES_RID_CNFWEPENABLED_AGERE,
1146                                            priv->wep_on);
1147                 if (err)
1148                         return err;
1149                 break;
1150
1151         case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
1152         case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
1153                 master_wep_flag = 0;            /* Off */
1154                 if (priv->wep_on) {
1155                         int keylen;
1156                         int i;
1157
1158                         /* Fudge around firmware weirdness */
1159                         keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
1160                         
1161                         /* Write all 4 keys */
1162                         for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
1163 /*                              int keylen = le16_to_cpu(priv->keys[i].len); */
1164                                 
1165                                 if (keylen > LARGE_KEY_SIZE) {
1166                                         printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
1167                                                priv->ndev->name, i, keylen);
1168                                         return -E2BIG;
1169                                 }
1170
1171                                 err = hermes_write_ltv(hw, USER_BAP,
1172                                                        HERMES_RID_CNFDEFAULTKEY0 + i,
1173                                                        HERMES_BYTES_TO_RECLEN(keylen),
1174                                                        priv->keys[i].data);
1175                                 if (err)
1176                                         return err;
1177                         }
1178
1179                         /* Write the index of the key used in transmission */
1180                         err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFWEPDEFAULTKEYID,
1181                                                    priv->tx_key);
1182                         if (err)
1183                                 return err;
1184                         
1185                         if (priv->wep_restrict) {
1186                                 auth_flag = 2;
1187                                 master_wep_flag = 3;
1188                         } else {
1189                                 /* Authentication is where Intersil and Symbol
1190                                  * firmware differ... */
1191                                 auth_flag = 1;
1192                                 if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
1193                                         master_wep_flag = 3; /* Symbol */ 
1194                                 else 
1195                                         master_wep_flag = 1; /* Intersil */
1196                         }
1197
1198
1199                         err = hermes_write_wordrec(hw, USER_BAP,
1200                                                    HERMES_RID_CNFAUTHENTICATION, auth_flag);
1201                         if (err)
1202                                 return err;
1203                 }
1204                 
1205                 /* Master WEP setting : on/off */
1206                 err = hermes_write_wordrec(hw, USER_BAP,
1207                                            HERMES_RID_CNFWEPFLAGS_INTERSIL,
1208                                            master_wep_flag);
1209                 if (err)
1210                         return err;     
1211
1212                 break;
1213
1214         default:
1215                 if (priv->wep_on) {
1216                         printk(KERN_ERR "%s: WEP enabled, although not supported!\n",
1217                                priv->ndev->name);
1218                         return -EINVAL;
1219                 }
1220         }
1221
1222         return 0;
1223 }
1224
1225 static int orinoco_hw_get_bssid(struct orinoco_private *priv,
1226                                 char buf[ETH_ALEN])
1227 {
1228         hermes_t *hw = &priv->hw;
1229         int err = 0;
1230         unsigned long flags;
1231
1232         err = orinoco_lock(priv, &flags);
1233         if (err)
1234                 return err;
1235
1236         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
1237                               ETH_ALEN, NULL, buf);
1238
1239         orinoco_unlock(priv, &flags);
1240
1241         return err;
1242 }
1243
1244 static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
1245                                 char buf[IW_ESSID_MAX_SIZE+1])
1246 {
1247         hermes_t *hw = &priv->hw;
1248         int err = 0;
1249         struct hermes_idstring essidbuf;
1250         char *p = (char *)(&essidbuf.val);
1251         int len;
1252         unsigned long flags;
1253
1254         err = orinoco_lock(priv, &flags);
1255         if (err)
1256                 return err;
1257
1258         if (strlen(priv->desired_essid) > 0) {
1259                 /* We read the desired SSID from the hardware rather
1260                    than from priv->desired_essid, just in case the
1261                    firmware is allowed to change it on us. I'm not
1262                    sure about this */
1263                 /* My guess is that the OWNSSID should always be whatever
1264                  * we set to the card, whereas CURRENT_SSID is the one that
1265                  * may change... - Jean II */
1266                 u16 rid;
1267
1268                 *active = 1;
1269
1270                 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
1271                         HERMES_RID_CNFDESIREDSSID;
1272                 
1273                 err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
1274                                       NULL, &essidbuf);
1275                 if (err)
1276                         goto fail_unlock;
1277         } else {
1278                 *active = 0;
1279
1280                 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
1281                                       sizeof(essidbuf), NULL, &essidbuf);
1282                 if (err)
1283                         goto fail_unlock;
1284         }
1285
1286         len = le16_to_cpu(essidbuf.len);
1287
1288         memset(buf, 0, IW_ESSID_MAX_SIZE+1);
1289         memcpy(buf, p, len);
1290         buf[len] = '\0';
1291
1292  fail_unlock:
1293         orinoco_unlock(priv, &flags);
1294
1295         return err;       
1296 }
1297
1298 static long orinoco_hw_get_freq(struct orinoco_private *priv)
1299 {
1300         
1301         hermes_t *hw = &priv->hw;
1302         int err = 0;
1303         u16 channel;
1304         long freq = 0;
1305         unsigned long flags;
1306
1307         err = orinoco_lock(priv, &flags);
1308         if (err)
1309                 return err;
1310         
1311         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
1312         if (err)
1313                 goto out;
1314
1315         /* Intersil firmware 1.3.5 returns 0 when the interface is down */
1316         if (channel == 0) {
1317                 err = -EBUSY;
1318                 goto out;
1319         }
1320
1321         if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
1322                 printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
1323                        priv->ndev->name, channel);
1324                 err = -EBUSY;
1325                 goto out;
1326
1327         }
1328         freq = channel_frequency[channel-1] * 100000;
1329
1330  out:
1331         orinoco_unlock(priv, &flags);
1332
1333         if (err > 0)
1334                 err = -EBUSY;
1335         return err ? err : freq;
1336 }
1337
1338 static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
1339                                       int *numrates, s32 *rates, int max)
1340 {
1341         hermes_t *hw = &priv->hw;
1342         struct hermes_idstring list;
1343         unsigned char *p = (unsigned char *)&list.val;
1344         int err = 0;
1345         int num;
1346         int i;
1347         unsigned long flags;
1348
1349         err = orinoco_lock(priv, &flags);
1350         if (err)
1351                 return err;
1352
1353         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
1354                               sizeof(list), NULL, &list);
1355         orinoco_unlock(priv, &flags);
1356
1357         if (err)
1358                 return err;
1359         
1360         num = le16_to_cpu(list.len);
1361         *numrates = num;
1362         num = min(num, max);
1363
1364         for (i = 0; i < num; i++) {
1365                 rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
1366         }
1367
1368         return 0;
1369 }
1370
1371 #if 0
1372 static void show_rx_frame(struct orinoco_rxframe_hdr *frame)
1373 {
1374         printk(KERN_DEBUG "RX descriptor:\n");
1375         printk(KERN_DEBUG "  status      = 0x%04x\n", frame->desc.status);
1376         printk(KERN_DEBUG "  time        = 0x%08x\n", frame->desc.time);
1377         printk(KERN_DEBUG "  silence     = 0x%02x\n", frame->desc.silence);
1378         printk(KERN_DEBUG "  signal      = 0x%02x\n", frame->desc.signal);
1379         printk(KERN_DEBUG "  rate        = 0x%02x\n", frame->desc.rate);
1380         printk(KERN_DEBUG "  rxflow      = 0x%02x\n", frame->desc.rxflow);
1381         printk(KERN_DEBUG "  reserved    = 0x%08x\n", frame->desc.reserved);
1382
1383         printk(KERN_DEBUG "IEEE 802.11 header:\n");
1384         printk(KERN_DEBUG "  frame_ctl   = 0x%04x\n",
1385                frame->p80211.frame_ctl);
1386         printk(KERN_DEBUG "  duration_id = 0x%04x\n",
1387                frame->p80211.duration_id);
1388         printk(KERN_DEBUG "  addr1       = %02x:%02x:%02x:%02x:%02x:%02x\n",
1389                frame->p80211.addr1[0], frame->p80211.addr1[1],
1390                frame->p80211.addr1[2], frame->p80211.addr1[3],
1391                frame->p80211.addr1[4], frame->p80211.addr1[5]);
1392         printk(KERN_DEBUG "  addr2       = %02x:%02x:%02x:%02x:%02x:%02x\n",
1393                frame->p80211.addr2[0], frame->p80211.addr2[1],
1394                frame->p80211.addr2[2], frame->p80211.addr2[3],
1395                frame->p80211.addr2[4], frame->p80211.addr2[5]);
1396         printk(KERN_DEBUG "  addr3       = %02x:%02x:%02x:%02x:%02x:%02x\n",
1397                frame->p80211.addr3[0], frame->p80211.addr3[1],
1398                frame->p80211.addr3[2], frame->p80211.addr3[3],
1399                frame->p80211.addr3[4], frame->p80211.addr3[5]);
1400         printk(KERN_DEBUG "  seq_ctl     = 0x%04x\n",
1401                frame->p80211.seq_ctl);
1402         printk(KERN_DEBUG "  addr4       = %02x:%02x:%02x:%02x:%02x:%02x\n",
1403                frame->p80211.addr4[0], frame->p80211.addr4[1],
1404                frame->p80211.addr4[2], frame->p80211.addr4[3],
1405                frame->p80211.addr4[4], frame->p80211.addr4[5]);
1406         printk(KERN_DEBUG "  data_len    = 0x%04x\n",
1407                frame->p80211.data_len);
1408
1409         printk(KERN_DEBUG "IEEE 802.3 header:\n");
1410         printk(KERN_DEBUG "  dest        = %02x:%02x:%02x:%02x:%02x:%02x\n",
1411                frame->p8023.h_dest[0], frame->p8023.h_dest[1],
1412                frame->p8023.h_dest[2], frame->p8023.h_dest[3],
1413                frame->p8023.h_dest[4], frame->p8023.h_dest[5]);
1414         printk(KERN_DEBUG "  src         = %02x:%02x:%02x:%02x:%02x:%02x\n",
1415                frame->p8023.h_source[0], frame->p8023.h_source[1],
1416                frame->p8023.h_source[2], frame->p8023.h_source[3],
1417                frame->p8023.h_source[4], frame->p8023.h_source[5]);
1418         printk(KERN_DEBUG "  len         = 0x%04x\n", frame->p8023.h_proto);
1419
1420         printk(KERN_DEBUG "IEEE 802.2 LLC/SNAP header:\n");
1421         printk(KERN_DEBUG "  DSAP        = 0x%02x\n", frame->p8022.dsap);
1422         printk(KERN_DEBUG "  SSAP        = 0x%02x\n", frame->p8022.ssap);
1423         printk(KERN_DEBUG "  ctrl        = 0x%02x\n", frame->p8022.ctrl);
1424         printk(KERN_DEBUG "  OUI         = %02x:%02x:%02x\n",
1425                frame->p8022.oui[0], frame->p8022.oui[1], frame->p8022.oui[2]);
1426         printk(KERN_DEBUG "  ethertype  = 0x%04x\n", frame->ethertype);
1427 }
1428 #endif /* 0 */
1429
1430 /*
1431  * Interrupt handler
1432  */
1433 irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1434 {
1435         struct net_device *dev = (struct net_device *)dev_id;
1436         struct orinoco_private *priv = netdev_priv(dev);
1437         hermes_t *hw = &priv->hw;
1438         int count = MAX_IRQLOOPS_PER_IRQ;
1439         u16 evstat, events;
1440         /* These are used to detect a runaway interrupt situation */
1441         /* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
1442          * we panic and shut down the hardware */
1443         static int last_irq_jiffy = 0; /* jiffies value the last time we were called */
1444         static int loops_this_jiffy = 0;
1445         unsigned long flags;
1446
1447         if (orinoco_lock(priv, &flags) != 0) {
1448                 /* If hw is unavailable - we don't know if the irq was
1449                  * for us or not */
1450                 return IRQ_HANDLED;
1451         }
1452
1453         evstat = hermes_read_regn(hw, EVSTAT);
1454         events = evstat & hw->inten;
1455         if (! events) {
1456                 orinoco_unlock(priv, &flags);
1457                 return IRQ_NONE;
1458         }
1459         
1460         if (jiffies != last_irq_jiffy)
1461                 loops_this_jiffy = 0;
1462         last_irq_jiffy = jiffies;
1463
1464         while (events && count--) {
1465                 if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
1466                         printk(KERN_WARNING "%s: IRQ handler is looping too "
1467                                "much! Resetting.\n", dev->name);
1468                         /* Disable interrupts for now */
1469                         hermes_set_irqmask(hw, 0);
1470                         schedule_work(&priv->reset_work);
1471                         break;
1472                 }
1473
1474                 /* Check the card hasn't been removed */
1475                 if (! hermes_present(hw)) {
1476                         DEBUG(0, "orinoco_interrupt(): card removed\n");
1477                         break;
1478                 }
1479
1480                 if (events & HERMES_EV_TICK)
1481                         __orinoco_ev_tick(dev, hw);
1482                 if (events & HERMES_EV_WTERR)
1483                         __orinoco_ev_wterr(dev, hw);
1484                 if (events & HERMES_EV_INFDROP)
1485                         __orinoco_ev_infdrop(dev, hw);
1486                 if (events & HERMES_EV_INFO)
1487                         __orinoco_ev_info(dev, hw);
1488                 if (events & HERMES_EV_RX)
1489                         __orinoco_ev_rx(dev, hw);
1490                 if (events & HERMES_EV_TXEXC)
1491                         __orinoco_ev_txexc(dev, hw);
1492                 if (events & HERMES_EV_TX)
1493                         __orinoco_ev_tx(dev, hw);
1494                 if (events & HERMES_EV_ALLOC)
1495                         __orinoco_ev_alloc(dev, hw);
1496                 
1497                 hermes_write_regn(hw, EVACK, events);
1498
1499                 evstat = hermes_read_regn(hw, EVSTAT);
1500                 events = evstat & hw->inten;
1501         };
1502
1503         orinoco_unlock(priv, &flags);
1504         return IRQ_HANDLED;
1505 }
1506
1507 static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
1508 {
1509         printk(KERN_DEBUG "%s: TICK\n", dev->name);
1510 }
1511
1512 static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
1513 {
1514         /* This seems to happen a fair bit under load, but ignoring it
1515            seems to work fine...*/
1516         printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
1517                dev->name);
1518 }
1519
1520 static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
1521 {
1522         if (net_ratelimit())
1523                 printk(KERN_WARNING "%s: Information frame lost.\n", dev->name);
1524 }
1525
1526 static void print_linkstatus(struct net_device *dev, u16 status)
1527 {
1528         char * s;
1529
1530         if (suppress_linkstatus)
1531                 return;
1532
1533         switch (status) {
1534         case HERMES_LINKSTATUS_NOT_CONNECTED:
1535                 s = "Not Connected";
1536                 break;
1537         case HERMES_LINKSTATUS_CONNECTED:
1538                 s = "Connected";
1539                 break;
1540         case HERMES_LINKSTATUS_DISCONNECTED:
1541                 s = "Disconnected";
1542                 break;
1543         case HERMES_LINKSTATUS_AP_CHANGE:
1544                 s = "AP Changed";
1545                 break;
1546         case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
1547                 s = "AP Out of Range";
1548                 break;
1549         case HERMES_LINKSTATUS_AP_IN_RANGE:
1550                 s = "AP In Range";
1551                 break;
1552         case HERMES_LINKSTATUS_ASSOC_FAILED:
1553                 s = "Association Failed";
1554                 break;
1555         default:
1556                 s = "UNKNOWN";
1557         }
1558         
1559         printk(KERN_INFO "%s: New link status: %s (%04x)\n",
1560                dev->name, s, status);
1561 }
1562
1563 static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1564 {
1565         struct orinoco_private *priv = netdev_priv(dev);
1566         u16 infofid;
1567         struct {
1568                 u16 len;
1569                 u16 type;
1570         } __attribute__ ((packed)) info;
1571         int len, type;
1572         int err;
1573
1574         /* This is an answer to an INQUIRE command that we did earlier,
1575          * or an information "event" generated by the card
1576          * The controller return to us a pseudo frame containing
1577          * the information in question - Jean II */
1578         infofid = hermes_read_regn(hw, INFOFID);
1579
1580         /* Read the info frame header - don't try too hard */
1581         err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
1582                                infofid, 0);
1583         if (err) {
1584                 printk(KERN_ERR "%s: error %d reading info frame. "
1585                        "Frame dropped.\n", dev->name, err);
1586                 return;
1587         }
1588         
1589         len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
1590         type = le16_to_cpu(info.type);
1591
1592         switch (type) {
1593         case HERMES_INQ_TALLIES: {
1594                 struct hermes_tallies_frame tallies;
1595                 struct iw_statistics *wstats = &priv->wstats;
1596                 
1597                 if (len > sizeof(tallies)) {
1598                         printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
1599                                dev->name, len);
1600                         len = sizeof(tallies);
1601                 }
1602                 
1603                 /* Read directly the data (no seek) */
1604                 hermes_read_words(hw, HERMES_DATA1, (void *) &tallies,
1605                                   len / 2); /* FIXME: blech! */
1606                 
1607                 /* Increment our various counters */
1608                 /* wstats->discard.nwid - no wrong BSSID stuff */
1609                 wstats->discard.code +=
1610                         le16_to_cpu(tallies.RxWEPUndecryptable);
1611                 if (len == sizeof(tallies))  
1612                         wstats->discard.code +=
1613                                 le16_to_cpu(tallies.RxDiscards_WEPICVError) +
1614                                 le16_to_cpu(tallies.RxDiscards_WEPExcluded);
1615                 wstats->discard.misc +=
1616                         le16_to_cpu(tallies.TxDiscardsWrongSA);
1617 #if WIRELESS_EXT > 11
1618                 wstats->discard.fragment +=
1619                         le16_to_cpu(tallies.RxMsgInBadMsgFragments);
1620                 wstats->discard.retries +=
1621                         le16_to_cpu(tallies.TxRetryLimitExceeded);
1622                 /* wstats->miss.beacon - no match */
1623 #endif /* WIRELESS_EXT > 11 */
1624         }
1625         break;
1626         case HERMES_INQ_LINKSTATUS: {
1627                 struct hermes_linkstatus linkstatus;
1628                 u16 newstatus;
1629                 
1630                 if (len != sizeof(linkstatus)) {
1631                         printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
1632                                dev->name, len);
1633                         break;
1634                 }
1635
1636                 hermes_read_words(hw, HERMES_DATA1, (void *) &linkstatus,
1637                                   len / 2);
1638                 newstatus = le16_to_cpu(linkstatus.linkstatus);
1639
1640                 if ( (newstatus == HERMES_LINKSTATUS_CONNECTED)
1641                      || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
1642                      || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE) )
1643                         priv->connected = 1;
1644                 else if ( (newstatus == HERMES_LINKSTATUS_NOT_CONNECTED)
1645                           || (newstatus == HERMES_LINKSTATUS_DISCONNECTED)
1646                           || (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE)
1647                           || (newstatus == HERMES_LINKSTATUS_ASSOC_FAILED) )
1648                         priv->connected = 0;
1649
1650                 if (newstatus != priv->last_linkstatus)
1651                         print_linkstatus(dev, newstatus);
1652
1653                 priv->last_linkstatus = newstatus;
1654         }
1655         break;
1656         default:
1657                 printk(KERN_DEBUG "%s: Unknown information frame received (type %04x).\n",
1658                       dev->name, type);
1659                 /* We don't actually do anything about it */
1660                 break;
1661         }
1662 }
1663
1664 static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
1665 {
1666         struct orinoco_private *priv = netdev_priv(dev);
1667         struct net_device_stats *stats = &priv->stats;
1668         struct iw_statistics *wstats = &priv->wstats;
1669         struct sk_buff *skb = NULL;
1670         u16 rxfid, status;
1671         int length, data_len, data_off;
1672         char *p;
1673         struct hermes_rx_descriptor desc;
1674         struct header_struct hdr;
1675         struct ethhdr *eh;
1676         int err;
1677         struct ieee802_11_hdr hdr80211;
1678
1679         rxfid = hermes_read_regn(hw, RXFID);
1680
1681         err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc),
1682                                rxfid, 0);
1683         if (err) {
1684                 printk(KERN_ERR "%s: error %d reading Rx descriptor. "
1685                        "Frame dropped.\n", dev->name, err);
1686                 stats->rx_errors++;
1687                 goto drop;
1688         }
1689
1690         status = le16_to_cpu(desc.status);
1691         
1692         if (status & HERMES_RXSTAT_ERR) {
1693                 if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
1694                     if (dev->type != ARPHRD_ETHER) goto sniffing;
1695                         wstats->discard.code++;
1696                         DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
1697                                dev->name);
1698                 } else {
1699                         stats->rx_crc_errors++;
1700                         DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", dev->name);
1701                 }
1702                 stats->rx_errors++;
1703                 goto drop;
1704         }
1705 sniffing:
1706         /* For now we ignore the 802.11 header completely, assuming
1707            that the card's firmware has handled anything vital */
1708
1709         err = hermes_bap_pread(hw, IRQ_BAP, &hdr, sizeof(hdr),
1710                                rxfid, HERMES_802_3_OFFSET);
1711         if (err) {
1712                 printk(KERN_ERR "%s: error %d reading frame header. "
1713                        "Frame dropped.\n", dev->name, err);
1714                 stats->rx_errors++;
1715                 goto drop;
1716         }
1717
1718         length = ntohs(hdr.len);
1719         
1720         /* Sanity checks */
1721         if (length < 3) { /* No for even an 802.2 LLC header */
1722                 /* At least on Symbol firmware with PCF we get quite a
1723                    lot of these legitimately - Poll frames with no
1724                    data. */
1725                 stats->rx_dropped++;
1726                 goto drop;
1727         }
1728         if (length > IEEE802_11_DATA_LEN) {
1729                 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
1730                        dev->name, length);
1731                 stats->rx_length_errors++;
1732                 stats->rx_errors++;
1733                 goto drop;
1734         }
1735
1736         /* Now handle frame based on port# */
1737         switch( HERMES_RXSTATUS_MACPORT_GET(status) )
1738         {
1739         case 0:
1740
1741         /* We need space for the packet data itself, plus an ethernet
1742            header, plus 2 bytes so we can align the IP header on a
1743            32bit boundary, plus 1 byte so we can read in odd length
1744            packets from the card, which has an IO granularity of 16
1745            bits */  
1746         skb = dev_alloc_skb(length+ETH_HLEN+2+1);
1747         if (!skb) {
1748                 printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
1749                        dev->name);
1750                 goto drop;
1751         }
1752
1753         skb_reserve(skb, 2); /* This way the IP header is aligned */
1754
1755         /* Handle decapsulation
1756          * In most cases, the firmware tell us about SNAP frames.
1757          * For some reason, the SNAP frames sent by LinkSys APs
1758          * are not properly recognised by most firmwares.
1759          * So, check ourselves */
1760         if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
1761            ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
1762            is_ethersnap(&hdr)) {
1763                 /* These indicate a SNAP within 802.2 LLC within
1764                    802.11 frame which we'll need to de-encapsulate to
1765                    the original EthernetII frame. */
1766
1767                 if (length < ENCAPS_OVERHEAD) { /* No room for full LLC+SNAP */
1768                         stats->rx_length_errors++;
1769                         goto drop;
1770                 }
1771
1772                 /* Remove SNAP header, reconstruct EthernetII frame */
1773                 data_len = length - ENCAPS_OVERHEAD;
1774                 data_off = HERMES_802_3_OFFSET + sizeof(hdr);
1775
1776                 eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);
1777
1778                 memcpy(eh, &hdr, 2 * ETH_ALEN);
1779                 eh->h_proto = hdr.ethertype;
1780         } else {
1781                 /* All other cases indicate a genuine 802.3 frame.  No
1782                    decapsulation needed.  We just throw the whole
1783                    thing in, and hope the protocol layer can deal with
1784                    it as 802.3 */
1785                 data_len = length;
1786                 data_off = HERMES_802_3_OFFSET;
1787                 /* FIXME: we re-read from the card data we already read here */
1788         }
1789
1790         p = skb_put(skb, data_len);
1791         err = hermes_bap_pread(hw, IRQ_BAP, p, RUP_EVEN(data_len),
1792                                rxfid, data_off);
1793         if (err) {
1794                 printk(KERN_ERR "%s: error %d reading frame. "
1795                        "Frame dropped.\n", dev->name, err);
1796                 stats->rx_errors++;
1797                 goto drop;
1798         }
1799
1800         dev->last_rx = jiffies;
1801         skb->dev = dev;
1802         skb->protocol = eth_type_trans(skb, dev);
1803         skb->ip_summed = CHECKSUM_NONE;
1804         
1805         /* Process the wireless stats if needed */
1806         orinoco_stat_gather(dev, skb, &desc);
1807
1808         /* Pass the packet to the networking stack */
1809         netif_rx(skb);
1810         stats->rx_packets++;
1811         stats->rx_bytes += length;
1812
1813         return;
1814
1815         case 7:
1816                 if ( ! HERMES_RXSTATUS_ISFCSERR(status) ) {
1817                    if (hermes_bap_pread(hw, IRQ_BAP, &hdr80211, sizeof(hdr80211), 
1818                                        rxfid, HERMES_RX_80211HDR_OFF)) {
1819                       stats->rx_errors++;
1820                    }
1821                    else {
1822                         /* Copy to wlansnif skb */
1823                         orinoco_int_rxmonitor( priv, rxfid, length, &desc, &hdr80211);
1824                    }
1825                 } else {
1826                         printk("Received monitor frame: FCSerr set\n");
1827                 }
1828                 break;
1829         default:
1830                 printk("Received frame on unsupported port=%d\n",
1831                         HERMES_RXSTATUS_MACPORT_GET(status) );
1832                 break;
1833         }
1834
1835  drop:  
1836         stats->rx_dropped++;
1837
1838         if (skb)
1839                 dev_kfree_skb_irq(skb);
1840         return;
1841 }
1842
1843 static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
1844 {
1845         struct orinoco_private *priv = netdev_priv(dev);
1846         struct net_device_stats *stats = &priv->stats;
1847         u16 fid = hermes_read_regn(hw, TXCOMPLFID);
1848         struct hermes_tx_descriptor desc;
1849         int err = 0;
1850
1851         if (fid == DUMMY_FID)
1852                 return; /* Nothing's really happened */
1853
1854         err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc), fid, 0);
1855         if (err) {
1856                 printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
1857                        "(FID=%04X error %d)\n",
1858                        dev->name, fid, err);
1859         } else {
1860                 DEBUG(1, "%s: Tx error, status %d\n",
1861                       dev->name, le16_to_cpu(desc.status));
1862         }
1863         
1864         stats->tx_errors++;
1865
1866         hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
1867 }
1868
1869 static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
1870 {
1871         struct orinoco_private *priv = netdev_priv(dev);
1872         struct net_device_stats *stats = &priv->stats;
1873
1874         stats->tx_packets++;
1875
1876         hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
1877 }
1878
1879 static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
1880 {
1881         struct orinoco_private *priv = netdev_priv(dev);
1882
1883         u16 fid = hermes_read_regn(hw, ALLOCFID);
1884
1885         if (fid != priv->txfid) {
1886                 if (fid != DUMMY_FID)
1887                         printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
1888                                dev->name, fid);
1889                 return;
1890         } else {
1891                 netif_wake_queue(dev);
1892         }
1893
1894         hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
1895 }
1896
1897 struct sta_id {
1898         u16 id, variant, major, minor;
1899 } __attribute__ ((packed));
1900
1901 static int determine_firmware_type(struct net_device *dev, struct sta_id *sta_id)
1902 {
1903         /* FIXME: this is fundamentally broken */
1904         unsigned int firmver = ((u32)sta_id->major << 16) | sta_id->minor;
1905         
1906         if (sta_id->variant == 1)
1907                 return FIRMWARE_TYPE_AGERE;
1908         else if ((sta_id->variant == 2) &&
1909                    ((firmver == 0x10001) || (firmver == 0x20001)))
1910                 return FIRMWARE_TYPE_SYMBOL;
1911         else
1912                 return FIRMWARE_TYPE_INTERSIL;
1913 }
1914
1915 static void determine_firmware(struct net_device *dev)
1916 {
1917         struct orinoco_private *priv = netdev_priv(dev);
1918         hermes_t *hw = &priv->hw;
1919         int err;
1920         struct sta_id sta_id;
1921         unsigned int firmver;
1922         char tmp[SYMBOL_MAX_VER_LEN+1];
1923
1924         /* Get the firmware version */
1925         err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
1926         if (err) {
1927                 printk(KERN_WARNING "%s: Error %d reading firmware info. Wildly guessing capabilities...\n",
1928                        dev->name, err);
1929                 memset(&sta_id, 0, sizeof(sta_id));
1930         }
1931         le16_to_cpus(&sta_id.id);
1932         le16_to_cpus(&sta_id.variant);
1933         le16_to_cpus(&sta_id.major);
1934         le16_to_cpus(&sta_id.minor);
1935
1936         printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
1937                dev->name, sta_id.id, sta_id.variant,
1938                sta_id.major, sta_id.minor);
1939
1940         if (! priv->firmware_type)
1941                 priv->firmware_type = determine_firmware_type(dev, &sta_id);
1942
1943         /* Default capabilities */
1944         priv->has_sensitivity = 1;
1945         priv->has_mwo = 0;
1946         priv->has_preamble = 0;
1947         priv->has_port3 = 1;
1948         priv->has_ibss = 1;
1949         priv->has_ibss_any = 0;
1950         priv->has_wep = 0;
1951         priv->has_big_wep = 0;
1952
1953         /* Determine capabilities from the firmware version */
1954         switch (priv->firmware_type) {
1955         case FIRMWARE_TYPE_AGERE:
1956                 /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
1957                    ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
1958                 printk(KERN_DEBUG "%s: Looks like a Lucent/Agere firmware "
1959                        "version %d.%02d\n", dev->name,
1960                        sta_id.major, sta_id.minor);
1961
1962                 firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
1963
1964                 priv->has_ibss = (firmver >= 0x60006);
1965                 priv->has_ibss_any = (firmver >= 0x60010);
1966                 priv->has_wep = (firmver >= 0x40020);
1967                 priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
1968                                           Gold cards from the others? */
1969                 priv->has_mwo = (firmver >= 0x60000);
1970                 priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
1971                 priv->ibss_port = 1;
1972
1973                 /* Tested with Agere firmware :
1974                  *      1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
1975                  * Tested CableTron firmware : 4.32 => Anton */
1976                 break;
1977         case FIRMWARE_TYPE_SYMBOL:
1978                 /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
1979                 /* Intel MAC : 00:02:B3:* */
1980                 /* 3Com MAC : 00:50:DA:* */
1981                 memset(tmp, 0, sizeof(tmp));
1982                 /* Get the Symbol firmware version */
1983                 err = hermes_read_ltv(hw, USER_BAP,
1984                                       HERMES_RID_SECONDARYVERSION_SYMBOL,
1985                                       SYMBOL_MAX_VER_LEN, NULL, &tmp);
1986                 if (err) {
1987                         printk(KERN_WARNING
1988                                "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",
1989                                dev->name, err);
1990                         firmver = 0;
1991                         tmp[0] = '\0';
1992                 } else {
1993                         /* The firmware revision is a string, the format is
1994                          * something like : "V2.20-01".
1995                          * Quick and dirty parsing... - Jean II
1996                          */
1997                         firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12)
1998                                 | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4)
1999                                 | (tmp[7] - '0');
2000
2001                         tmp[SYMBOL_MAX_VER_LEN] = '\0';
2002                 }
2003
2004                 printk(KERN_DEBUG "%s: Looks like a Symbol firmware "
2005                        "version [%s] (parsing to %X)\n", dev->name,
2006                        tmp, firmver);
2007
2008                 priv->has_ibss = (firmver >= 0x20000);
2009                 priv->has_wep = (firmver >= 0x15012);
2010                 priv->has_big_wep = (firmver >= 0x20000);
2011                 priv->has_pm = (firmver >= 0x20000) && (firmver < 0x22000);
2012                 priv->has_preamble = (firmver >= 0x20000);
2013                 priv->ibss_port = 4;
2014                 /* Tested with Intel firmware : 0x20015 => Jean II */
2015                 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
2016                 break;
2017         case FIRMWARE_TYPE_INTERSIL:
2018                 /* D-Link, Linksys, Adtron, ZoomAir, and many others...
2019                  * Samsung, Compaq 100/200 and Proxim are slightly
2020                  * different and less well tested */
2021                 /* D-Link MAC : 00:40:05:* */
2022                 /* Addtron MAC : 00:90:D1:* */
2023                 printk(KERN_DEBUG "%s: Looks like an Intersil firmware "
2024                        "version %d.%d.%d\n", dev->name,
2025                        sta_id.major, sta_id.minor, sta_id.variant);
2026
2027                 firmver = ((unsigned long)sta_id.major << 16) |
2028                         ((unsigned long)sta_id.minor << 8) | sta_id.variant;
2029
2030                 priv->has_ibss = (firmver >= 0x000700); /* FIXME */
2031                 priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
2032                 priv->has_pm = (firmver >= 0x000700);
2033
2034                 if (firmver >= 0x000800)
2035                         priv->ibss_port = 0;
2036                 else {
2037                         printk(KERN_NOTICE "%s: Intersil firmware earlier "
2038                                "than v0.8.x - several features not supported\n",
2039                                dev->name);
2040                         priv->ibss_port = 1;
2041                 }
2042                 break;
2043         default:
2044                 break;
2045         }
2046 }
2047
2048 /*
2049  * struct net_device methods
2050  */
2051
2052 static int
2053 orinoco_init(struct net_device *dev)
2054 {
2055         struct orinoco_private *priv = netdev_priv(dev);
2056         hermes_t *hw = &priv->hw;
2057         int err = 0;
2058         struct hermes_idstring nickbuf;
2059         u16 reclen;
2060         int len;
2061
2062         TRACE_ENTER(dev->name);
2063
2064         /* No need to lock, the hw_unavailable flag is already set in
2065          * alloc_orinocodev() */
2066         priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
2067
2068         /* Initialize the firmware */
2069         err = hermes_init(hw);
2070         if (err != 0) {
2071                 printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
2072                        dev->name, err);
2073                 goto out;
2074         }
2075
2076         determine_firmware(dev);
2077
2078         if (priv->has_port3)
2079                 printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
2080         if (priv->has_ibss)
2081                 printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
2082                        dev->name);
2083         if (priv->has_wep) {
2084                 printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
2085                 if (priv->has_big_wep)
2086                         printk("104-bit key\n");
2087                 else
2088                         printk("40-bit key\n");
2089         }
2090
2091         /* Get the MAC address */
2092         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
2093                               ETH_ALEN, NULL, dev->dev_addr);
2094         if (err) {
2095                 printk(KERN_WARNING "%s: failed to read MAC address!\n",
2096                        dev->name);
2097                 goto out;
2098         }
2099
2100         printk(KERN_DEBUG "%s: MAC address %02X:%02X:%02X:%02X:%02X:%02X\n",
2101                dev->name, dev->dev_addr[0], dev->dev_addr[1],
2102                dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4],
2103                dev->dev_addr[5]);
2104
2105         /* Get the station name */
2106         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
2107                               sizeof(nickbuf), &reclen, &nickbuf);
2108         if (err) {
2109                 printk(KERN_ERR "%s: failed to read station name\n",
2110                        dev->name);
2111                 goto out;
2112         }
2113         if (nickbuf.len)
2114                 len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
2115         else
2116                 len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
2117         memcpy(priv->nick, &nickbuf.val, len);
2118         priv->nick[len] = '\0';
2119
2120         printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
2121
2122         /* Get allowed channels */
2123         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
2124                                   &priv->channel_mask);
2125         if (err) {
2126                 printk(KERN_ERR "%s: failed to read channel list!\n",
2127                        dev->name);
2128                 goto out;
2129         }
2130
2131         /* Get initial AP density */
2132         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
2133                                   &priv->ap_density);
2134         if (err || priv->ap_density < 1 || priv->ap_density > 3) {
2135                 priv->has_sensitivity = 0;
2136         }
2137
2138         /* Get initial RTS threshold */
2139         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
2140                                   &priv->rts_thresh);
2141         if (err) {
2142                 printk(KERN_ERR "%s: failed to read RTS threshold!\n", dev->name);
2143                 goto out;
2144         }
2145
2146         /* Get initial fragmentation settings */
2147         if (priv->has_mwo)
2148                 err = hermes_read_wordrec(hw, USER_BAP,
2149                                           HERMES_RID_CNFMWOROBUST_AGERE,
2150                                           &priv->mwo_robust);
2151         else
2152                 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
2153                                           &priv->frag_thresh);
2154         if (err) {
2155                 printk(KERN_ERR "%s: failed to read fragmentation settings!\n", dev->name);
2156                 goto out;
2157         }
2158
2159         /* Power management setup */
2160         if (priv->has_pm) {
2161                 priv->pm_on = 0;
2162                 priv->pm_mcast = 1;
2163                 err = hermes_read_wordrec(hw, USER_BAP,
2164                                           HERMES_RID_CNFMAXSLEEPDURATION,
2165                                           &priv->pm_period);
2166                 if (err) {
2167                         printk(KERN_ERR "%s: failed to read power management period!\n",
2168                                dev->name);
2169                         goto out;
2170                 }
2171                 err = hermes_read_wordrec(hw, USER_BAP,
2172                                           HERMES_RID_CNFPMHOLDOVERDURATION,
2173                                           &priv->pm_timeout);
2174                 if (err) {
2175                         printk(KERN_ERR "%s: failed to read power management timeout!\n",
2176                                dev->name);
2177                         goto out;
2178                 }
2179         }
2180
2181         /* Preamble setup */
2182         if (priv->has_preamble) {
2183                 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPREAMBLE_SYMBOL,
2184                                           &priv->preamble);
2185                 if (err)
2186                         goto out;
2187         }
2188                 
2189         /* Set up the default configuration */
2190         priv->iw_mode = IW_MODE_INFRA;
2191         /* By default use IEEE/IBSS ad-hoc mode if we have it */
2192         priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
2193         set_port_type(priv);
2194         priv->channel = 10; /* default channel, more-or-less arbitrary */
2195
2196         priv->promiscuous = 0;
2197         priv->wep_on = 0;
2198         priv->tx_key = 0;
2199
2200         err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
2201         if (err == -EIO) {
2202                 /* Try workaround for old Symbol firmware bug */
2203                 printk(KERN_WARNING "%s: firmware ALLOC bug detected "
2204                        "(old Symbol firmware?). Trying to work around... ",
2205                        dev->name);
2206                 
2207                 priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
2208                 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
2209                 if (err)
2210                         printk("failed!\n");
2211                 else
2212                         printk("ok.\n");
2213         }
2214         if (err) {
2215                 printk("%s: Error %d allocating Tx buffer\n", dev->name, err);
2216                 goto out;
2217         }
2218
2219         /* Make the hardware available, as long as it hasn't been
2220          * removed elsewhere (e.g. by PCMCIA hot unplug) */
2221         spin_lock_irq(&priv->lock);
2222         priv->hw_unavailable--;
2223         spin_unlock_irq(&priv->lock);
2224
2225         printk(KERN_DEBUG "%s: ready\n", dev->name);
2226
2227  out:
2228         TRACE_EXIT(dev->name);
2229         return err;
2230 }
2231
2232 struct net_device_stats *
2233 orinoco_get_stats(struct net_device *dev)
2234 {
2235         struct orinoco_private *priv = netdev_priv(dev);
2236         
2237         return &priv->stats;
2238 }
2239
2240 struct iw_statistics *
2241 orinoco_get_wireless_stats(struct net_device *dev)
2242 {
2243         struct orinoco_private *priv = netdev_priv(dev);
2244         hermes_t *hw = &priv->hw;
2245         struct iw_statistics *wstats = &priv->wstats;
2246         int err = 0;
2247         unsigned long flags;
2248
2249         if (! netif_device_present(dev)) {
2250                 printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
2251                        dev->name);
2252                 return NULL; /* FIXME: Can we do better than this? */
2253         }
2254
2255         err = orinoco_lock(priv, &flags);
2256         if (err)
2257                 return NULL; /* FIXME: Erg, we've been signalled, how
2258                               * do we propagate this back up? */
2259
2260         if (priv->iw_mode == IW_MODE_ADHOC) {
2261                 memset(&wstats->qual, 0, sizeof(wstats->qual));
2262                 /* If a spy address is defined, we report stats of the
2263                  * first spy address - Jean II */
2264                 if (SPY_NUMBER(priv)) {
2265                         wstats->qual.qual = priv->spy_stat[0].qual;
2266                         wstats->qual.level = priv->spy_stat[0].level;
2267                         wstats->qual.noise = priv->spy_stat[0].noise;
2268                         wstats->qual.updated = priv->spy_stat[0].updated;
2269                 }
2270         } else {
2271                 struct {
2272                         u16 qual, signal, noise;
2273                 } __attribute__ ((packed)) cq;
2274
2275                 err = HERMES_READ_RECORD(hw, USER_BAP,
2276                                          HERMES_RID_COMMSQUALITY, &cq);
2277                 
2278                 wstats->qual.qual = (int)le16_to_cpu(cq.qual);
2279                 wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
2280                 wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
2281                 wstats->qual.updated = 7;
2282         }
2283
2284         /* We can't really wait for the tallies inquiry command to
2285          * complete, so we just use the previous results and trigger
2286          * a new tallies inquiry command for next time - Jean II */
2287         /* FIXME: We're in user context (I think?), so we should just
2288            wait for the tallies to come through */
2289         err = hermes_inquire(hw, HERMES_INQ_TALLIES);
2290                
2291         orinoco_unlock(priv, &flags);
2292
2293         if (err)
2294                 return NULL;
2295                 
2296         return wstats;
2297 }
2298
2299 static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
2300                                     int level, int noise)
2301 {
2302         struct orinoco_private *priv = netdev_priv(dev);
2303         int i;
2304
2305         /* Gather wireless spy statistics: for each packet, compare the
2306          * source address with out list, and if match, get the stats... */
2307         for (i = 0; i < priv->spy_number; i++)
2308                 if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {
2309                         priv->spy_stat[i].level = level - 0x95;
2310                         priv->spy_stat[i].noise = noise - 0x95;
2311                         priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0;
2312                         priv->spy_stat[i].updated = 7;
2313                 }
2314 }
2315
2316 void
2317 orinoco_stat_gather(struct net_device *dev,
2318                     struct sk_buff *skb,
2319                     struct hermes_rx_descriptor *desc)
2320 {
2321         struct orinoco_private *priv = netdev_priv(dev);
2322
2323         /* Using spy support with lots of Rx packets, like in an
2324          * infrastructure (AP), will really slow down everything, because
2325          * the MAC address must be compared to each entry of the spy list.
2326          * If the user really asks for it (set some address in the
2327          * spy list), we do it, but he will pay the price.
2328          * Note that to get here, you need both WIRELESS_SPY
2329          * compiled in AND some addresses in the list !!!
2330          */
2331         /* Note : gcc will optimise the whole section away if
2332          * WIRELESS_SPY is not defined... - Jean II */
2333         if (SPY_NUMBER(priv)) {
2334                 orinoco_spy_gather(dev, skb->mac.raw + ETH_ALEN,
2335                                    desc->signal, desc->silence);
2336         }
2337 }
2338
2339 static int
2340 orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
2341 {
2342         struct orinoco_private *priv = netdev_priv(dev);
2343         struct net_device_stats *stats = &priv->stats;
2344         hermes_t *hw = &priv->hw;
2345         int err = 0;
2346         u16 txfid = priv->txfid;
2347         char *p;
2348         struct ethhdr *eh;
2349         int len, data_len, data_off;
2350         struct hermes_tx_descriptor desc;
2351         unsigned long flags;
2352
2353         TRACE_ENTER(dev->name);
2354
2355         if (! netif_running(dev)) {
2356                 printk(KERN_ERR "%s: Tx on stopped device!\n",
2357                        dev->name);
2358                 TRACE_EXIT(dev->name);
2359                 return 1;
2360         }
2361         
2362         if (netif_queue_stopped(dev)) {
2363                 printk(KERN_DEBUG "%s: Tx while transmitter busy!\n", 
2364                        dev->name);
2365                 TRACE_EXIT(dev->name);
2366                 return 1;
2367         }
2368         
2369         if (orinoco_lock(priv, &flags) != 0) {
2370                 printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
2371                        dev->name);
2372                 TRACE_EXIT(dev->name);
2373 /*              BUG(); */
2374                 return 1;
2375         }
2376
2377         if (! priv->connected) {
2378                 /* Oops, the firmware hasn't established a connection,
2379                    silently drop the packet (this seems to be the
2380                    safest approach). */
2381                 stats->tx_errors++;
2382                 orinoco_unlock(priv, &flags);
2383                 dev_kfree_skb(skb);
2384                 TRACE_EXIT(dev->name);
2385                 return 0;
2386         }
2387
2388         /* Length of the packet body */
2389         /* FIXME: what if the skb is smaller than this? */
2390         len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN - ETH_HLEN);
2391
2392         eh = (struct ethhdr *)skb->data;
2393
2394         memset(&desc, 0, sizeof(desc));
2395         desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX);
2396         err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), txfid, 0);
2397         if (err) {
2398                 printk(KERN_ERR "%s: Error %d writing Tx descriptor to BAP\n",
2399                        dev->name, err);
2400                 stats->tx_errors++;
2401                 goto fail;
2402         }
2403
2404         /* Clear the 802.11 header and data length fields - some
2405          * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
2406          * if this isn't done. */
2407         hermes_clear_words(hw, HERMES_DATA0,
2408                            HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
2409
2410         /* Encapsulate Ethernet-II frames */
2411         if (ntohs(eh->h_proto) > 1500) { /* Ethernet-II frame */
2412                 struct header_struct hdr;
2413                 data_len = len;
2414                 data_off = HERMES_802_3_OFFSET + sizeof(hdr);
2415                 p = skb->data + ETH_HLEN;
2416
2417                 /* 802.3 header */
2418                 memcpy(hdr.dest, eh->h_dest, ETH_ALEN);
2419                 memcpy(hdr.src, eh->h_source, ETH_ALEN);
2420                 hdr.len = htons(data_len + ENCAPS_OVERHEAD);
2421                 
2422                 /* 802.2 header */
2423                 memcpy(&hdr.dsap, &encaps_hdr, sizeof(encaps_hdr));
2424                         
2425                 hdr.ethertype = eh->h_proto;
2426                 err  = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
2427                                          txfid, HERMES_802_3_OFFSET);
2428                 if (err) {
2429                         printk(KERN_ERR "%s: Error %d writing packet header to BAP\n",
2430                                dev->name, err);
2431                         stats->tx_errors++;
2432                         goto fail;
2433                 }
2434         } else { /* IEEE 802.3 frame */
2435                 data_len = len + ETH_HLEN;
2436                 data_off = HERMES_802_3_OFFSET;
2437                 p = skb->data;
2438         }
2439
2440         /* Round up for odd length packets */
2441         err = hermes_bap_pwrite(hw, USER_BAP, p, RUP_EVEN(data_len), txfid, data_off);
2442         if (err) {
2443                 printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
2444                        dev->name, err);
2445                 stats->tx_errors++;
2446                 goto fail;
2447         }
2448
2449         /* Finally, we actually initiate the send */
2450         netif_stop_queue(dev);
2451
2452         err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, txfid, NULL);
2453         if (err) {
2454                 netif_start_queue(dev);
2455                 printk(KERN_ERR "%s: Error %d transmitting packet\n", dev->name, err);
2456                 stats->tx_errors++;
2457                 goto fail;
2458         }
2459
2460         dev->trans_start = jiffies;
2461         stats->tx_bytes += data_off + data_len;
2462
2463         orinoco_unlock(priv, &flags);
2464
2465         dev_kfree_skb(skb);
2466
2467         TRACE_EXIT(dev->name);
2468
2469         return 0;
2470  fail:
2471         TRACE_EXIT(dev->name);
2472
2473         orinoco_unlock(priv, &flags);
2474         return err;
2475 }
2476
2477 //#define SET_MAC_ADDRESS
2478 #ifdef SET_MAC_ADDRESS
2479 static int
2480 orinoco_set_mac_address(struct net_device *dev, void *addr)
2481 {
2482   struct orinoco_private *priv = dev->priv;
2483   struct sockaddr *mac = addr;
2484
2485   /* Copy the address */
2486   memcpy(dev->dev_addr, mac->sa_data, WLAN_ADDR_LEN);
2487
2488   /* Reconfig the beast */
2489   orinoco_reset(priv);
2490
2491   return 0;
2492 }
2493 #endif  /* SET_MAC_ADDRESS */
2494
2495 static void
2496 orinoco_tx_timeout(struct net_device *dev)
2497 {
2498         struct orinoco_private *priv = netdev_priv(dev);
2499         struct net_device_stats *stats = &priv->stats;
2500         struct hermes *hw = &priv->hw;
2501
2502         printk(KERN_WARNING "%s: Tx timeout! "
2503                "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
2504                dev->name, hermes_read_regn(hw, ALLOCFID),
2505                hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
2506
2507         stats->tx_errors++;
2508
2509         schedule_work(&priv->reset_work);
2510 }
2511
2512 static int
2513 orinoco_change_mtu(struct net_device *dev, int new_mtu)
2514 {
2515         struct orinoco_private *priv = netdev_priv(dev);
2516
2517         if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
2518                 return -EINVAL;
2519
2520         if ( (new_mtu + ENCAPS_OVERHEAD + IEEE802_11_HLEN) >
2521              (priv->nicbuf_size - ETH_HLEN) )
2522                 return -EINVAL;
2523
2524         dev->mtu = new_mtu;
2525
2526         return 0;
2527 }
2528
2529 /* FIXME: return int? */
2530 static void
2531 __orinoco_set_multicast_list(struct net_device *dev)
2532 {
2533         struct orinoco_private *priv = netdev_priv(dev);
2534         hermes_t *hw = &priv->hw;
2535         int err = 0;
2536         int promisc, mc_count;
2537
2538         /* The Hermes doesn't seem to have an allmulti mode, so we go
2539          * into promiscuous mode and let the upper levels deal. */
2540         if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
2541              (dev->mc_count > MAX_MULTICAST(priv)) ) {
2542                 promisc = 1;
2543                 mc_count = 0;
2544         } else {
2545                 promisc = 0;
2546                 mc_count = dev->mc_count;
2547         }
2548
2549         if (promisc != priv->promiscuous) {
2550                 err = hermes_write_wordrec(hw, USER_BAP,
2551                                            HERMES_RID_CNFPROMISCUOUSMODE,
2552                                            promisc);
2553                 if (err) {
2554                         printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
2555                                dev->name, err);
2556                 } else 
2557                         priv->promiscuous = promisc;
2558         }
2559
2560         if (! promisc && (mc_count || priv->mc_count) ) {
2561                 struct dev_mc_list *p = dev->mc_list;
2562                 hermes_multicast_t mclist;
2563                 int i;
2564
2565                 for (i = 0; i < mc_count; i++) {
2566                         /* Paranoia: */
2567                         if (! p)
2568                                 BUG(); /* Multicast list shorter than mc_count */
2569                         if (p->dmi_addrlen != ETH_ALEN)
2570                                 BUG(); /* Bad address size in multicast list */
2571                         
2572                         memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
2573                         p = p->next;
2574                 }
2575                 
2576                 if (p)
2577                         printk(KERN_WARNING "Multicast list is longer than mc_count\n");
2578
2579                 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES,
2580                                        HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
2581                                        &mclist);
2582                 if (err)
2583                         printk(KERN_ERR "%s: Error %d setting multicast list.\n",
2584                                dev->name, err);
2585                 else
2586                         priv->mc_count = mc_count;
2587         }
2588
2589         /* Since we can set the promiscuous flag when it wasn't asked
2590            for, make sure the net_device knows about it. */
2591         if (priv->promiscuous)
2592                 dev->flags |= IFF_PROMISC;
2593         else
2594                 dev->flags &= ~IFF_PROMISC;
2595 }
2596
2597 /********************************************************************/
2598 /* Wireless extensions support                                      */
2599 /********************************************************************/
2600
2601 static int orinoco_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq)
2602 {
2603         struct orinoco_private *priv = netdev_priv(dev);
2604         int err = 0;
2605         int mode;
2606         struct iw_range range;
2607         int numrates;
2608         int i, k;
2609         unsigned long flags;
2610
2611         TRACE_ENTER(dev->name);
2612
2613         err = verify_area(VERIFY_WRITE, rrq->pointer, sizeof(range));
2614         if (err)
2615                 return err;
2616
2617         rrq->length = sizeof(range);
2618
2619         err = orinoco_lock(priv, &flags);
2620         if (err)
2621                 return err;
2622
2623         mode = priv->iw_mode;
2624         orinoco_unlock(priv, &flags);
2625
2626         memset(&range, 0, sizeof(range));
2627
2628         /* Much of this shamelessly taken from wvlan_cs.c. No idea
2629          * what it all means -dgibson */
2630 #if WIRELESS_EXT > 10
2631         range.we_version_compiled = WIRELESS_EXT;
2632         range.we_version_source = 11;
2633 #endif /* WIRELESS_EXT > 10 */
2634
2635         range.min_nwid = range.max_nwid = 0; /* We don't use nwids */
2636
2637         /* Set available channels/frequencies */
2638         range.num_channels = NUM_CHANNELS;
2639         k = 0;
2640         for (i = 0; i < NUM_CHANNELS; i++) {
2641                 if (priv->channel_mask & (1 << i)) {
2642                         range.freq[k].i = i + 1;
2643                         range.freq[k].m = channel_frequency[i] * 100000;
2644                         range.freq[k].e = 1;
2645                         k++;
2646                 }
2647                 
2648                 if (k >= IW_MAX_FREQUENCIES)
2649                         break;
2650         }
2651         range.num_frequency = k;
2652
2653         range.sensitivity = 3;
2654
2655         if ((mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
2656                 /* Quality stats meaningless in ad-hoc mode */
2657                 range.max_qual.qual = 0;
2658                 range.max_qual.level = 0;
2659                 range.max_qual.noise = 0;
2660 #if WIRELESS_EXT > 11
2661                 range.avg_qual.qual = 0;
2662                 range.avg_qual.level = 0;
2663                 range.avg_qual.noise = 0;
2664 #endif /* WIRELESS_EXT > 11 */
2665
2666         } else {
2667                 range.max_qual.qual = 0x8b - 0x2f;
2668                 range.max_qual.level = 0x2f - 0x95 - 1;
2669                 range.max_qual.noise = 0x2f - 0x95 - 1;
2670 #if WIRELESS_EXT > 11
2671                 /* Need to get better values */
2672                 range.avg_qual.qual = 0x24;
2673                 range.avg_qual.level = 0xC2;
2674                 range.avg_qual.noise = 0x9E;
2675 #endif /* WIRELESS_EXT > 11 */
2676         }
2677
2678         err = orinoco_hw_get_bitratelist(priv, &numrates,
2679                                          range.bitrate, IW_MAX_BITRATES);
2680         if (err)
2681                 return err;
2682         range.num_bitrates = numrates;
2683         
2684         /* Set an indication of the max TCP throughput in bit/s that we can
2685          * expect using this interface. May be use for QoS stuff...
2686          * Jean II */
2687         if(numrates > 2)
2688                 range.throughput = 5 * 1000 * 1000;     /* ~5 Mb/s */
2689         else
2690                 range.throughput = 1.5 * 1000 * 1000;   /* ~1.5 Mb/s */
2691
2692         range.min_rts = 0;
2693         range.max_rts = 2347;
2694         range.min_frag = 256;
2695         range.max_frag = 2346;
2696
2697         err = orinoco_lock(priv, &flags);
2698         if (err)
2699                 return err;
2700         if (priv->has_wep) {
2701                 range.max_encoding_tokens = ORINOCO_MAX_KEYS;
2702
2703                 range.encoding_size[0] = SMALL_KEY_SIZE;
2704                 range.num_encoding_sizes = 1;
2705
2706                 if (priv->has_big_wep) {
2707                         range.encoding_size[1] = LARGE_KEY_SIZE;
2708                         range.num_encoding_sizes = 2;
2709                 }
2710         } else {
2711                 range.num_encoding_sizes = 0;
2712                 range.max_encoding_tokens = 0;
2713         }
2714         orinoco_unlock(priv, &flags);
2715                 
2716         range.min_pmp = 0;
2717         range.max_pmp = 65535000;
2718         range.min_pmt = 0;
2719         range.max_pmt = 65535 * 1000;   /* ??? */
2720         range.pmp_flags = IW_POWER_PERIOD;
2721         range.pmt_flags = IW_POWER_TIMEOUT;
2722         range.pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
2723
2724         range.num_txpower = 1;
2725         range.txpower[0] = 15; /* 15dBm */
2726         range.txpower_capa = IW_TXPOW_DBM;
2727
2728 #if WIRELESS_EXT > 10
2729         range.retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
2730         range.retry_flags = IW_RETRY_LIMIT;
2731         range.r_time_flags = IW_RETRY_LIFETIME;
2732         range.min_retry = 0;
2733         range.max_retry = 65535;        /* ??? */
2734         range.min_r_time = 0;
2735         range.max_r_time = 65535 * 1000;        /* ??? */
2736 #endif /* WIRELESS_EXT > 10 */
2737
2738         if (copy_to_user(rrq->pointer, &range, sizeof(range)))
2739                 return -EFAULT;
2740
2741         TRACE_EXIT(dev->name);
2742
2743         return 0;
2744 }
2745
2746 static int orinoco_ioctl_setiwencode(struct net_device *dev, struct iw_point *erq)
2747 {
2748         struct orinoco_private *priv = netdev_priv(dev);
2749         int index = (erq->flags & IW_ENCODE_INDEX) - 1;
2750         int setindex = priv->tx_key;
2751         int enable = priv->wep_on;
2752         int restricted = priv->wep_restrict;
2753         u16 xlen = 0;
2754         int err = 0;
2755         char keybuf[ORINOCO_MAX_KEY_SIZE];
2756         unsigned long flags;
2757         
2758         if (erq->pointer) {
2759                 /* We actually have a key to set */
2760                 if ( (erq->length < SMALL_KEY_SIZE) || (erq->length > ORINOCO_MAX_KEY_SIZE) )
2761                         return -EINVAL;
2762                 
2763                 if (copy_from_user(keybuf, erq->pointer, erq->length))
2764                         return -EFAULT;
2765         }
2766         
2767         err = orinoco_lock(priv, &flags);
2768         if (err)
2769                 return err;
2770         
2771         if (erq->pointer) {
2772                 if (erq->length > ORINOCO_MAX_KEY_SIZE) {
2773                         err = -E2BIG;
2774                         goto out;
2775                 }
2776                 
2777                 if ( (erq->length > LARGE_KEY_SIZE)
2778                      || ( ! priv->has_big_wep && (erq->length > SMALL_KEY_SIZE))  ) {
2779                         err = -EINVAL;
2780                         goto out;
2781                 }
2782                 
2783                 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
2784                         index = priv->tx_key;
2785                 
2786                 if (erq->length > SMALL_KEY_SIZE) {
2787                         xlen = LARGE_KEY_SIZE;
2788                 } else if (erq->length > 0) {
2789                         xlen = SMALL_KEY_SIZE;
2790                 } else
2791                         xlen = 0;
2792                 
2793                 /* Switch on WEP if off */
2794                 if ((!enable) && (xlen > 0)) {
2795                         setindex = index;
2796                         enable = 1;
2797                 }
2798         } else {
2799                 /* Important note : if the user do "iwconfig eth0 enc off",
2800                  * we will arrive there with an index of -1. This is valid
2801                  * but need to be taken care off... Jean II */
2802                 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
2803                         if((index != -1) || (erq->flags == 0)) {
2804                                 err = -EINVAL;
2805                                 goto out;
2806                         }
2807                 } else {
2808                         /* Set the index : Check that the key is valid */
2809                         if(priv->keys[index].len == 0) {
2810                                 err = -EINVAL;
2811                                 goto out;
2812                         }
2813                         setindex = index;
2814                 }
2815         }
2816         
2817         if (erq->flags & IW_ENCODE_DISABLED)
2818                 enable = 0;
2819         /* Only for Prism2 & Symbol cards (so far) - Jean II */
2820         if (erq->flags & IW_ENCODE_OPEN)
2821                 restricted = 0;
2822         if (erq->flags & IW_ENCODE_RESTRICTED)
2823                 restricted = 1;
2824
2825         if (erq->pointer) {
2826                 priv->keys[index].len = cpu_to_le16(xlen);
2827                 memset(priv->keys[index].data, 0, sizeof(priv->keys[index].data));
2828                 memcpy(priv->keys[index].data, keybuf, erq->length);
2829         }
2830         priv->tx_key = setindex;
2831         priv->wep_on = enable;
2832         priv->wep_restrict = restricted;
2833
2834         
2835  out:
2836         orinoco_unlock(priv, &flags);
2837
2838         return err;
2839 }
2840
2841 static int orinoco_ioctl_getiwencode(struct net_device *dev, struct iw_point *erq)
2842 {
2843         struct orinoco_private *priv = netdev_priv(dev);
2844         int index = (erq->flags & IW_ENCODE_INDEX) - 1;
2845         u16 xlen = 0;
2846         char keybuf[ORINOCO_MAX_KEY_SIZE];
2847         int err;
2848         unsigned long flags;
2849         
2850         err = orinoco_lock(priv, &flags);
2851         if (err)
2852                 return err;
2853
2854         if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
2855                 index = priv->tx_key;
2856
2857         erq->flags = 0;
2858         if (! priv->wep_on)
2859                 erq->flags |= IW_ENCODE_DISABLED;
2860         erq->flags |= index + 1;
2861         
2862         /* Only for symbol cards - Jean II */
2863         if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
2864                 if(priv->wep_restrict)
2865                         erq->flags |= IW_ENCODE_RESTRICTED;
2866                 else
2867                         erq->flags |= IW_ENCODE_OPEN;
2868         }
2869
2870         xlen = le16_to_cpu(priv->keys[index].len);
2871
2872         erq->length = xlen;
2873
2874         if (erq->pointer) {
2875                 memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
2876         }
2877         
2878         orinoco_unlock(priv, &flags);
2879
2880         if (erq->pointer) {
2881                 if (copy_to_user(erq->pointer, keybuf, xlen))
2882                         return -EFAULT;
2883         }
2884
2885         return 0;
2886 }
2887
2888 static int orinoco_ioctl_setessid(struct net_device *dev, struct iw_point *erq)
2889 {
2890         struct orinoco_private *priv = netdev_priv(dev);
2891         char essidbuf[IW_ESSID_MAX_SIZE+1];
2892         int err;
2893         unsigned long flags;
2894
2895         /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
2896          * anyway... - Jean II */
2897
2898         memset(&essidbuf, 0, sizeof(essidbuf));
2899
2900         if (erq->flags) {
2901                 if (erq->length > IW_ESSID_MAX_SIZE)
2902                         return -E2BIG;
2903                 
2904                 if (copy_from_user(&essidbuf, erq->pointer, erq->length))
2905                         return -EFAULT;
2906
2907                 essidbuf[erq->length] = '\0';
2908         }
2909
2910         err = orinoco_lock(priv, &flags);
2911         if (err)
2912                 return err;
2913
2914         memcpy(priv->desired_essid, essidbuf, sizeof(priv->desired_essid));
2915
2916         orinoco_unlock(priv, &flags);
2917
2918         return 0;
2919 }
2920
2921 static int orinoco_ioctl_getessid(struct net_device *dev, struct iw_point *erq)
2922 {
2923         struct orinoco_private *priv = netdev_priv(dev);
2924         char essidbuf[IW_ESSID_MAX_SIZE+1];
2925         int active;
2926         int err = 0;
2927         unsigned long flags;
2928
2929         TRACE_ENTER(dev->name);
2930
2931         if (netif_running(dev)) {
2932                 err = orinoco_hw_get_essid(priv, &active, essidbuf);
2933                 if (err)
2934                         return err;
2935         } else {
2936                 err = orinoco_lock(priv, &flags);
2937                 if (err)
2938                         return err;
2939                 memcpy(essidbuf, priv->desired_essid, sizeof(essidbuf));
2940                 orinoco_unlock(priv, &flags);
2941         }
2942
2943         erq->flags = 1;
2944         erq->length = strlen(essidbuf) + 1;
2945         if (erq->pointer)
2946                 if (copy_to_user(erq->pointer, essidbuf, erq->length))
2947                         return -EFAULT;
2948
2949         TRACE_EXIT(dev->name);
2950         
2951         return 0;
2952 }
2953
2954 static int orinoco_ioctl_setnick(struct net_device *dev, struct iw_point *nrq)
2955 {
2956         struct orinoco_private *priv = netdev_priv(dev);
2957         char nickbuf[IW_ESSID_MAX_SIZE+1];
2958         int err;
2959         unsigned long flags;
2960
2961         if (nrq->length > IW_ESSID_MAX_SIZE)
2962                 return -E2BIG;
2963
2964         memset(nickbuf, 0, sizeof(nickbuf));
2965
2966         if (copy_from_user(nickbuf, nrq->pointer, nrq->length))
2967                 return -EFAULT;
2968
2969         nickbuf[nrq->length] = '\0';
2970         
2971         err = orinoco_lock(priv, &flags);
2972         if (err)
2973                 return err;
2974
2975         memcpy(priv->nick, nickbuf, sizeof(priv->nick));
2976
2977         orinoco_unlock(priv, &flags);
2978
2979         return 0;
2980 }
2981
2982 static int orinoco_ioctl_getnick(struct net_device *dev, struct iw_point *nrq)
2983 {
2984         struct orinoco_private *priv = netdev_priv(dev);
2985         char nickbuf[IW_ESSID_MAX_SIZE+1];
2986         int err;
2987         unsigned long flags;
2988
2989         err = orinoco_lock(priv, &flags);
2990         if (err)
2991                 return err;
2992
2993         memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
2994         orinoco_unlock(priv, &flags);
2995
2996         nrq->length = strlen(nickbuf)+1;
2997
2998         if (copy_to_user(nrq->pointer, nickbuf, sizeof(nickbuf)))
2999                 return -EFAULT;
3000
3001         return 0;
3002 }
3003
3004 static int orinoco_ioctl_setfreq(struct net_device *dev, struct iw_freq *frq)
3005 {
3006         struct orinoco_private *priv = netdev_priv(dev);
3007         int chan = -1;
3008         int err;
3009         unsigned long flags;
3010
3011         /* We can only use this in Ad-Hoc demo mode to set the operating
3012          * frequency, or in IBSS mode to set the frequency where the IBSS
3013          * will be created - Jean II */
3014         if (priv->iw_mode != IW_MODE_ADHOC)
3015                 return -EOPNOTSUPP;
3016
3017         if ( (frq->e == 0) && (frq->m <= 1000) ) {
3018                 /* Setting by channel number */
3019                 chan = frq->m;
3020         } else {
3021                 /* Setting by frequency - search the table */
3022                 int mult = 1;
3023                 int i;
3024
3025                 for (i = 0; i < (6 - frq->e); i++)
3026                         mult *= 10;
3027
3028                 for (i = 0; i < NUM_CHANNELS; i++)
3029                         if (frq->m == (channel_frequency[i] * mult))
3030                                 chan = i+1;
3031         }
3032
3033         if ( (chan < 1) || (chan > NUM_CHANNELS) ||
3034              ! (priv->channel_mask & (1 << (chan-1)) ) )
3035                 return -EINVAL;
3036
3037         err = orinoco_lock(priv, &flags);
3038         if (err)
3039                 return err;
3040         priv->channel = chan;
3041         orinoco_unlock(priv, &flags);
3042
3043         return 0;
3044 }
3045
3046 static int orinoco_ioctl_getsens(struct net_device *dev, struct iw_param *srq)
3047 {
3048         struct orinoco_private *priv = netdev_priv(dev);
3049         hermes_t *hw = &priv->hw;
3050         u16 val;
3051         int err;
3052         unsigned long flags;
3053
3054         if (!priv->has_sensitivity)
3055                 return -EOPNOTSUPP;
3056
3057         err = orinoco_lock(priv, &flags);
3058         if (err)
3059                 return err;
3060         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE, &val);
3061         orinoco_unlock(priv, &flags);
3062
3063         if (err)
3064                 return err;
3065
3066         srq->value = val;
3067         srq->fixed = 0; /* auto */
3068
3069         return 0;
3070 }
3071
3072 static int orinoco_ioctl_setsens(struct net_device *dev, struct iw_param *srq)
3073 {
3074         struct orinoco_private *priv = netdev_priv(dev);
3075         int val = srq->value;
3076         int err;
3077         unsigned long flags;
3078
3079         if (!priv->has_sensitivity)
3080                 return -EOPNOTSUPP;
3081
3082         if ((val < 1) || (val > 3))
3083                 return -EINVAL;
3084         
3085         err = orinoco_lock(priv, &flags);
3086         if (err)
3087                 return err;
3088         priv->ap_density = val;
3089         orinoco_unlock(priv, &flags);
3090
3091         return 0;
3092 }
3093
3094 static int orinoco_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
3095 {
3096         struct orinoco_private *priv = netdev_priv(dev);
3097         int val = rrq->value;
3098         int err;
3099         unsigned long flags;
3100
3101         if (rrq->disabled)
3102                 val = 2347;
3103
3104         if ( (val < 0) || (val > 2347) )
3105                 return -EINVAL;
3106
3107         err = orinoco_lock(priv, &flags);
3108         if (err)
3109                 return err;
3110
3111         priv->rts_thresh = val;
3112         orinoco_unlock(priv, &flags);
3113
3114         return 0;
3115 }
3116
3117 static int orinoco_ioctl_setfrag(struct net_device *dev, struct iw_param *frq)
3118 {
3119         struct orinoco_private *priv = netdev_priv(dev);
3120         int err = 0;
3121         unsigned long flags;
3122
3123         err = orinoco_lock(priv, &flags);
3124         if (err)
3125                 return err;
3126
3127         if (priv->has_mwo) {
3128                 if (frq->disabled)
3129                         priv->mwo_robust = 0;
3130                 else {
3131                         if (frq->fixed)
3132                                 printk(KERN_WARNING "%s: Fixed fragmentation not \
3133 supported on this firmware. Using MWO robust instead.\n", dev->name);
3134                         priv->mwo_robust = 1;
3135                 }
3136         } else {
3137                 if (frq->disabled)
3138                         priv->frag_thresh = 2346;
3139                 else {
3140                         if ( (frq->value < 256) || (frq->value > 2346) )
3141                                 err = -EINVAL;
3142                         else
3143                                 priv->frag_thresh = frq->value & ~0x1; /* must be even */
3144                 }
3145         }
3146
3147         orinoco_unlock(priv, &flags);
3148
3149         return err;
3150 }
3151
3152 static int orinoco_ioctl_getfrag(struct net_device *dev, struct iw_param *frq)
3153 {
3154         struct orinoco_private *priv = netdev_priv(dev);
3155         hermes_t *hw = &priv->hw;
3156         int err = 0;
3157         u16 val;
3158         unsigned long flags;
3159
3160         err = orinoco_lock(priv, &flags);
3161         if (err)
3162                 return err;
3163         
3164         if (priv->has_mwo) {
3165                 err = hermes_read_wordrec(hw, USER_BAP,
3166                                           HERMES_RID_CNFMWOROBUST_AGERE,
3167                                           &val);
3168                 if (err)
3169                         val = 0;
3170
3171                 frq->value = val ? 2347 : 0;
3172                 frq->disabled = ! val;
3173                 frq->fixed = 0;
3174         } else {
3175                 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
3176                                           &val);
3177                 if (err)
3178                         val = 0;
3179
3180                 frq->value = val;
3181                 frq->disabled = (val >= 2346);
3182                 frq->fixed = 1;
3183         }
3184
3185         orinoco_unlock(priv, &flags);
3186         
3187         return err;
3188 }
3189
3190 static int orinoco_ioctl_setrate(struct net_device *dev, struct iw_param *rrq)
3191 {
3192         struct orinoco_private *priv = netdev_priv(dev);
3193         int err = 0;
3194         int ratemode = -1;
3195         int bitrate; /* 100s of kilobits */
3196         int i;
3197         unsigned long flags;
3198         
3199         /* As the user space doesn't know our highest rate, it uses -1
3200          * to ask us to set the highest rate.  Test it using "iwconfig
3201          * ethX rate auto" - Jean II */
3202         if (rrq->value == -1)
3203                 bitrate = 110;
3204         else {
3205                 if (rrq->value % 100000)
3206                         return -EINVAL;
3207                 bitrate = rrq->value / 100000;
3208         }
3209
3210         if ( (bitrate != 10) && (bitrate != 20) &&
3211              (bitrate != 55) && (bitrate != 110) )
3212                 return -EINVAL;
3213
3214         for (i = 0; i < BITRATE_TABLE_SIZE; i++)
3215                 if ( (bitrate_table[i].bitrate == bitrate) &&
3216                      (bitrate_table[i].automatic == ! rrq->fixed) ) {
3217                         ratemode = i;
3218                         break;
3219                 }
3220         
3221         if (ratemode == -1)
3222                 return -EINVAL;
3223
3224         err = orinoco_lock(priv, &flags);
3225         if (err)
3226                 return err;
3227         priv->bitratemode = ratemode;
3228         orinoco_unlock(priv, &flags);
3229
3230         return err;
3231 }
3232
3233 static int orinoco_ioctl_getrate(struct net_device *dev, struct iw_param *rrq)
3234 {
3235         struct orinoco_private *priv = netdev_priv(dev);
3236         hermes_t *hw = &priv->hw;
3237         int err = 0;
3238         int ratemode;
3239         int i;
3240         u16 val;
3241         unsigned long flags;
3242
3243         err = orinoco_lock(priv, &flags);
3244         if (err)
3245                 return err;
3246
3247         ratemode = priv->bitratemode;
3248
3249         if ( (ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE) )
3250                 BUG();
3251
3252         rrq->value = bitrate_table[ratemode].bitrate * 100000;
3253         rrq->fixed = ! bitrate_table[ratemode].automatic;
3254         rrq->disabled = 0;
3255
3256         /* If the interface is running we try to find more about the
3257            current mode */
3258         if (netif_running(dev)) {
3259                 err = hermes_read_wordrec(hw, USER_BAP,
3260                                           HERMES_RID_CURRENTTXRATE, &val);
3261                 if (err)
3262                         goto out;
3263                 
3264                 switch (priv->firmware_type) {
3265                 case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
3266                         /* Note : in Lucent firmware, the return value of
3267                          * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
3268                          * and therefore is totally different from the
3269                          * encoding of HERMES_RID_CNFTXRATECONTROL.
3270                          * Don't forget that 6Mb/s is really 5.5Mb/s */
3271                         if (val == 6)
3272                                 rrq->value = 5500000;
3273                         else
3274                                 rrq->value = val * 1000000;
3275                         break;
3276                 case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
3277                 case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
3278                         for (i = 0; i < BITRATE_TABLE_SIZE; i++)
3279                                 if (bitrate_table[i].intersil_txratectrl == val) {
3280                                         ratemode = i;
3281                                         break;
3282                                 }
3283                         if (i >= BITRATE_TABLE_SIZE)
3284                                 printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
3285                                        dev->name, val);
3286
3287                         rrq->value = bitrate_table[ratemode].bitrate * 100000;
3288                         break;
3289                 default:
3290                         BUG();
3291                 }
3292         }
3293
3294  out:
3295         orinoco_unlock(priv, &flags);
3296
3297         return err;
3298 }
3299
3300 static int orinoco_ioctl_setpower(struct net_device *dev, struct iw_param *prq)
3301 {
3302         struct orinoco_private *priv = netdev_priv(dev);
3303         int err = 0;
3304         unsigned long flags;
3305
3306         err = orinoco_lock(priv, &flags);
3307         if (err)
3308                 return err;
3309
3310         if (prq->disabled) {
3311                 priv->pm_on = 0;
3312         } else {
3313                 switch (prq->flags & IW_POWER_MODE) {
3314                 case IW_POWER_UNICAST_R:
3315                         priv->pm_mcast = 0;
3316                         priv->pm_on = 1;
3317                         break;
3318                 case IW_POWER_ALL_R:
3319                         priv->pm_mcast = 1;
3320                         priv->pm_on = 1;
3321                         break;
3322                 case IW_POWER_ON:
3323                         /* No flags : but we may have a value - Jean II */
3324                         break;
3325                 default:
3326                         err = -EINVAL;
3327                 }
3328                 if (err)
3329                         goto out;
3330                 
3331                 if (prq->flags & IW_POWER_TIMEOUT) {
3332                         priv->pm_on = 1;
3333                         priv->pm_timeout = prq->value / 1000;
3334                 }
3335                 if (prq->flags & IW_POWER_PERIOD) {
3336                         priv->pm_on = 1;
3337                         priv->pm_period = prq->value / 1000;
3338                 }
3339                 /* It's valid to not have a value if we are just toggling
3340                  * the flags... Jean II */
3341                 if(!priv->pm_on) {
3342                         err = -EINVAL;
3343                         goto out;
3344                 }                       
3345         }
3346
3347  out:
3348         orinoco_unlock(priv, &flags);
3349
3350         return err;
3351 }
3352
3353 static int orinoco_ioctl_getpower(struct net_device *dev, struct iw_param *prq)
3354 {
3355         struct orinoco_private *priv = netdev_priv(dev);
3356         hermes_t *hw = &priv->hw;
3357         int err = 0;
3358         u16 enable, period, timeout, mcast;
3359         unsigned long flags;
3360
3361         err = orinoco_lock(priv, &flags);
3362         if (err)
3363                 return err;
3364         
3365         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
3366         if (err)
3367                 goto out;
3368
3369         err = hermes_read_wordrec(hw, USER_BAP,
3370                                   HERMES_RID_CNFMAXSLEEPDURATION, &period);
3371         if (err)
3372                 goto out;
3373
3374         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
3375         if (err)
3376                 goto out;
3377
3378         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
3379         if (err)
3380                 goto out;
3381
3382         prq->disabled = !enable;
3383         /* Note : by default, display the period */
3384         if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
3385                 prq->flags = IW_POWER_TIMEOUT;
3386                 prq->value = timeout * 1000;
3387         } else {
3388                 prq->flags = IW_POWER_PERIOD;
3389                 prq->value = period * 1000;
3390         }
3391         if (mcast)
3392                 prq->flags |= IW_POWER_ALL_R;
3393         else
3394                 prq->flags |= IW_POWER_UNICAST_R;
3395
3396  out:
3397         orinoco_unlock(priv, &flags);
3398
3399         return err;
3400 }
3401
3402 #if WIRELESS_EXT > 10
3403 static int orinoco_ioctl_getretry(struct net_device *dev, struct iw_param *rrq)
3404 {
3405         struct orinoco_private *priv = netdev_priv(dev);
3406         hermes_t *hw = &priv->hw;
3407         int err = 0;
3408         u16 short_limit, long_limit, lifetime;
3409         unsigned long flags;
3410
3411         err = orinoco_lock(priv, &flags);
3412         if (err)
3413                 return err;
3414         
3415         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
3416                                   &short_limit);
3417         if (err)
3418                 goto out;
3419
3420         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
3421                                   &long_limit);
3422         if (err)
3423                 goto out;
3424
3425         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
3426                                   &lifetime);
3427         if (err)
3428                 goto out;
3429
3430         rrq->disabled = 0;              /* Can't be disabled */
3431
3432         /* Note : by default, display the retry number */
3433         if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
3434                 rrq->flags = IW_RETRY_LIFETIME;
3435                 rrq->value = lifetime * 1000;   /* ??? */
3436         } else {
3437                 /* By default, display the min number */
3438                 if ((rrq->flags & IW_RETRY_MAX)) {
3439                         rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
3440                         rrq->value = long_limit;
3441                 } else {
3442                         rrq->flags = IW_RETRY_LIMIT;
3443                         rrq->value = short_limit;
3444                         if(short_limit != long_limit)
3445                                 rrq->flags |= IW_RETRY_MIN;
3446                 }
3447         }
3448
3449  out:
3450         orinoco_unlock(priv, &flags);
3451
3452         return err;
3453 }
3454 #endif /* WIRELESS_EXT > 10 */
3455
3456 static int orinoco_ioctl_setibssport(struct net_device *dev, struct iwreq *wrq)
3457 {
3458         struct orinoco_private *priv = netdev_priv(dev);
3459         int val = *( (int *) wrq->u.name );
3460         int err;
3461         unsigned long flags;
3462
3463         err = orinoco_lock(priv, &flags);
3464         if (err)
3465                 return err;
3466
3467         priv->ibss_port = val ;
3468
3469         /* Actually update the mode we are using */
3470         set_port_type(priv);
3471
3472         orinoco_unlock(priv, &flags);
3473         return 0;
3474 }
3475
3476 static int orinoco_ioctl_getibssport(struct net_device *dev, struct iwreq *wrq)
3477 {
3478         struct orinoco_private *priv = netdev_priv(dev);
3479         int *val = (int *)wrq->u.name;
3480         int err;
3481         unsigned long flags;
3482
3483         err = orinoco_lock(priv, &flags);
3484         if (err)
3485                 return err;
3486
3487         *val = priv->ibss_port;
3488         orinoco_unlock(priv, &flags);
3489
3490         return 0;
3491 }
3492
3493 static int orinoco_ioctl_setport3(struct net_device *dev, struct iwreq *wrq)
3494 {
3495         struct orinoco_private *priv = netdev_priv(dev);
3496         int val = *( (int *) wrq->u.name );
3497         int err = 0;
3498         unsigned long flags;
3499
3500         err = orinoco_lock(priv, &flags);
3501         if (err)
3502                 return err;
3503
3504         switch (val) {
3505         case 0: /* Try to do IEEE ad-hoc mode */
3506                 if (! priv->has_ibss) {
3507                         err = -EINVAL;
3508                         break;
3509                 }
3510                 priv->prefer_port3 = 0;
3511                         
3512                 break;
3513
3514         case 1: /* Try to do Lucent proprietary ad-hoc mode */
3515                 if (! priv->has_port3) {
3516                         err = -EINVAL;
3517                         break;
3518                 }
3519                 priv->prefer_port3 = 1;
3520                 break;
3521
3522         default:
3523                 err = -EINVAL;
3524         }
3525
3526         if (! err)
3527                 /* Actually update the mode we are using */
3528                 set_port_type(priv);
3529
3530         orinoco_unlock(priv, &flags);
3531
3532         return err;
3533 }
3534
3535 static int orinoco_ioctl_getport3(struct net_device *dev, struct iwreq *wrq)
3536 {
3537         struct orinoco_private *priv = netdev_priv(dev);
3538         int *val = (int *)wrq->u.name;
3539         int err;
3540         unsigned long flags;
3541
3542         err = orinoco_lock(priv, &flags);
3543         if (err)
3544                 return err;
3545
3546         *val = priv->prefer_port3;
3547         orinoco_unlock(priv, &flags);
3548
3549         return 0;
3550 }
3551
3552 /* Spy is used for link quality/strength measurements in Ad-Hoc mode
3553  * Jean II */
3554 static int orinoco_ioctl_setspy(struct net_device *dev, struct iw_point *srq)
3555 {
3556         struct orinoco_private *priv = netdev_priv(dev);
3557         struct sockaddr address[IW_MAX_SPY];
3558         int number = srq->length;
3559         int i;
3560         int err = 0;
3561         unsigned long flags;
3562
3563         /* Check the number of addresses */
3564         if (number > IW_MAX_SPY)
3565                 return -E2BIG;
3566
3567         /* Get the data in the driver */
3568         if (srq->pointer) {
3569                 if (copy_from_user(address, srq->pointer,
3570                                    sizeof(struct sockaddr) * number))
3571                         return -EFAULT;
3572         }
3573
3574         /* Make sure nobody mess with the structure while we do */
3575         err = orinoco_lock(priv, &flags);
3576         if (err)
3577                 return err;
3578
3579         /* orinoco_lock() doesn't disable interrupts, so make sure the
3580          * interrupt rx path don't get confused while we copy */
3581         priv->spy_number = 0;
3582
3583         if (number > 0) {
3584                 /* Extract the addresses */
3585                 for (i = 0; i < number; i++)
3586                         memcpy(priv->spy_address[i], address[i].sa_data,
3587                                ETH_ALEN);
3588                 /* Reset stats */
3589                 memset(priv->spy_stat, 0,
3590                        sizeof(struct iw_quality) * IW_MAX_SPY);
3591                 /* Set number of addresses */
3592                 priv->spy_number = number;
3593         }
3594
3595         /* Now, let the others play */
3596         orinoco_unlock(priv, &flags);
3597
3598         return err;
3599 }
3600
3601 static int orinoco_ioctl_getspy(struct net_device *dev, struct iw_point *srq)
3602 {
3603         struct orinoco_private *priv = netdev_priv(dev);
3604         struct sockaddr address[IW_MAX_SPY];
3605         struct iw_quality spy_stat[IW_MAX_SPY];
3606         int number;
3607         int i;
3608         int err;
3609         unsigned long flags;
3610
3611         err = orinoco_lock(priv, &flags);
3612         if (err)
3613                 return err;
3614
3615         number = priv->spy_number;
3616         if ((number > 0) && (srq->pointer)) {
3617                 /* Create address struct */
3618                 for (i = 0; i < number; i++) {
3619                         memcpy(address[i].sa_data, priv->spy_address[i],
3620                                ETH_ALEN);
3621                         address[i].sa_family = AF_UNIX;
3622                 }
3623                 /* Copy stats */
3624                 /* In theory, we should disable irqs while copying the stats
3625                  * because the rx path migh update it in the middle...
3626                  * Bah, who care ? - Jean II */
3627                 memcpy(&spy_stat, priv->spy_stat,
3628                        sizeof(struct iw_quality) * IW_MAX_SPY);
3629                 for (i=0; i < number; i++)
3630                         priv->spy_stat[i].updated = 0;
3631         }
3632
3633         orinoco_unlock(priv, &flags);
3634
3635         /* Push stuff to user space */
3636         srq->length = number;
3637         if(copy_to_user(srq->pointer, address,
3638                          sizeof(struct sockaddr) * number))
3639                 return -EFAULT;
3640         if(copy_to_user(srq->pointer + (sizeof(struct sockaddr)*number),
3641                         &spy_stat, sizeof(struct iw_quality) * number))
3642                 return -EFAULT;
3643
3644         return 0;
3645 }
3646
3647 /*----------------------------------------------------------------
3648 * orinoco_wlansniff
3649 *
3650 * Start or stop sniffing.
3651 *
3652 * Arguments:
3653 *       wlandev         wlan device structure
3654 *       msgp            ptr to msg buffer
3655 *
3656 * Returns: 
3657 *       0       success and done
3658 *       <0      success, but we're waiting for something to finish.
3659 *       >0      an error occurred while handling the message.
3660 * Side effects:
3661 *
3662 * Call context:
3663 *       process thread  (usually)
3664 *       interrupt
3665 ----------------------------------------------------------------*/
3666 static int orinoco_wlansniff(struct net_device *dev, struct iwreq *wrq)
3667 {
3668         struct orinoco_private *priv = dev->priv;
3669
3670         hermes_t                *hw = &(priv->hw);
3671         hermes_response_t  resp;
3672         int                     result = 0;
3673         uint16_t                        word;
3674
3675         int *parms = (int *) wrq->u.name;
3676         int enable = parms[0] > 0;
3677         unsigned long flags;
3678
3679         orinoco_lock(priv, &flags);
3680
3681         switch (enable)
3682         {
3683         case P80211ENUM_truth_false:
3684                 /* Confirm that we're in monitor mode */
3685                 if ( dev->type == ARPHRD_ETHER ) {
3686                         result = -EFAULT;
3687                 }
3688                 /* Disable monitor mode */
3689                 word =  HERMES_CMD_MONITOR | (HERMES_MONITOR_DISABLE << 8);
3690                 result = hermes_docmd_wait(hw, word, 0, &resp);
3691
3692                 if ( result ) break;
3693
3694                 /* Disable port 0 */
3695                 result = hermes_disable_port(hw, 0);
3696                 if ( result ) break;
3697
3698                 /* Clear the driver state */
3699                 dev->type = ARPHRD_ETHER;
3700
3701                 /* Restore the wepflags */   //Orinoco doesn't like this
3702 /*
3703                 result = hermes_write_wordrec(hw, USER_BAP,
3704                                 HERMES_RID_CNF_PRISM2_WEP_ON, 
3705                                 priv->presniff_wepflags);
3706                 if ( result ) break;
3707
3708 */
3709                 /* Set the port to its prior type and enable (if necessary) */
3710                 if (priv->presniff_port_type != 0 ) {
3711                         word = priv->presniff_port_type;
3712                         result = hermes_write_wordrec(hw, USER_BAP, 
3713                                 HERMES_RID_CNF_PORTTYPE, word);
3714                     if ( result ) break;
3715
3716                         /* Enable the port */
3717                         result = hermes_enable_port(hw, 0);
3718                     if ( result ) break;
3719
3720                 }
3721
3722                 break;
3723         case P80211ENUM_truth_true:
3724              /* Re-initialize the card before changing channel as advised at
3725               * http://lists.samba.org/pipermail/wireless/2002-June/004491.html
3726               * by Ian Goldberg.  Implementation by Pat Swieskowski.
3727               */
3728 //              __orinoco_down(dev);
3729                 hermes_set_irqmask(hw, 0);
3730                 hermes_init(hw);
3731 //              _orinoco_up(dev);
3732                 hermes_set_irqmask(hw, ORINOCO_INTEN);
3733 /*
3734                 __orinoco_stop_irqs(priv);
3735                 hermes_reset(hw);
3736                 __orinoco_start_irqs(priv, HERMES_EV_RX | HERMES_EV_ALLOC |
3737                                    HERMES_EV_TX | HERMES_EV_TXEXC |
3738                                    HERMES_EV_WTERR | HERMES_EV_INFO |
3739                                    HERMES_EV_INFDROP);
3740 */
3741                 /* Disable the port (if enabled), only check Port 0 */
3742                 if ( hw->port_enabled[0] ) {
3743                         /* Save macport 0 state */
3744                         result = hermes_read_wordrec(hw, USER_BAP,
3745                                         HERMES_RID_CNF_PORTTYPE,
3746                                         &(priv->presniff_port_type));
3747                     if ( result ) break;
3748
3749                         /* Save the wepflags state */
3750                         result = hermes_read_wordrec(hw, USER_BAP,
3751                                         HERMES_RID_CNF_PRISM2_WEP_ON,
3752                                         &(priv->presniff_wepflags));
3753                     if ( result ) break;
3754                         result = hermes_disable_port(hw, 0);
3755                     if ( result ) break;
3756                 }
3757                 else {
3758                         priv->presniff_port_type = 0;
3759                 }
3760
3761                 /* Set the channel we wish to sniff  */
3762                 if (parms[1] > 0 && parms[1] < 15) {
3763                   word = parms[1];
3764                   result = hermes_write_wordrec(hw, USER_BAP, 
3765                                   HERMES_RID_CNF_CHANNEL, word);
3766                 } else {
3767                   result = -EFAULT;
3768                 }
3769
3770                 if ( result ) break;
3771
3772                 /* Set the port type to pIbss */
3773                 word = HFA384x_PORTTYPE_IBSS;
3774                 result = hermes_write_wordrec(hw, USER_BAP, 
3775                                 HERMES_RID_CNF_PORTTYPE, word);
3776                 if ( result ) break;
3777
3778 /*
3779                 if ( (msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) && 
3780                      (msg->keepwepflags.data != P80211ENUM_truth_true)) {
3781                   // Set the wepflags for no decryption   //Orinoco doesn't like this
3782                   word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT | 
3783                              HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
3784                   result = hermes_write_wordrec(hw, USER_BAP, 
3785                                  HERMES_RID_CNF_PRISM2_WEP_ON, word); //won't work with the bits above
3786                 }
3787                 if ( result ) break;
3788
3789 */
3790                 /* Enable the port */
3791                 result = hermes_enable_port(hw, 0);
3792                 if ( result ) break;
3793
3794                 /* Enable monitor mode */
3795                 word =  HERMES_CMD_MONITOR | (HERMES_MONITOR_ENABLE << 8);
3796                 result = hermes_docmd_wait(hw, word, 0, &resp);
3797                 if ( result ) break;
3798
3799                 /* Set the driver state */
3800                 /* Do we want the prism2 header? */
3801                 if (parms[0] == 1)
3802                   dev->type = ARPHRD_IEEE80211_PRISM;
3803                 else 
3804                   dev->type = ARPHRD_IEEE80211;
3805                 break;
3806         default:
3807                 result = -EFAULT;
3808                 break;
3809         }
3810         orinoco_unlock(priv, &flags);
3811         return result;
3812 }
3813
3814 static int
3815 orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3816 {
3817         struct orinoco_private *priv = netdev_priv(dev);
3818         struct iwreq *wrq = (struct iwreq *)rq;
3819         int err = 0;
3820         int tmp;
3821         int changed = 0;
3822         unsigned long flags;
3823
3824         TRACE_ENTER(dev->name);
3825
3826         /* In theory, we could allow most of the the SET stuff to be
3827          * done. In practice, the lapse of time at startup when the
3828          * card is not ready is very short, so why bother...  Note
3829          * that netif_device_present is different from up/down
3830          * (ifconfig), when the device is not yet up, it is usually
3831          * already ready...  Jean II */
3832         if (! netif_device_present(dev))
3833                 return -ENODEV;
3834
3835         switch (cmd) {
3836         case SIOCGIWNAME:
3837                 strcpy(wrq->u.name, "IEEE 802.11-DS");
3838                 break;
3839                 
3840         case SIOCGIWAP:
3841                 wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
3842                 err = orinoco_hw_get_bssid(priv, wrq->u.ap_addr.sa_data);
3843                 break;
3844
3845         case SIOCGIWRANGE:
3846                 err = orinoco_ioctl_getiwrange(dev, &wrq->u.data);
3847                 break;
3848
3849         case SIOCSIWMODE:
3850                 err = orinoco_lock(priv, &flags);
3851                 if (err)
3852                         return err;
3853                 switch (wrq->u.mode) {
3854                 case IW_MODE_ADHOC:
3855                         if (! (priv->has_ibss || priv->has_port3) )
3856                                 err = -EINVAL;
3857                         else {
3858                                 priv->iw_mode = IW_MODE_ADHOC;
3859                                 changed = 1;
3860                         }
3861                         break;
3862
3863                 case IW_MODE_INFRA:
3864                         priv->iw_mode = IW_MODE_INFRA;
3865                         changed = 1;
3866                         break;
3867
3868                 default:
3869                         err = -EINVAL;
3870                         break;
3871                 }
3872                 set_port_type(priv);
3873                 orinoco_unlock(priv, &flags);
3874                 break;
3875
3876         case SIOCGIWMODE:
3877                 err = orinoco_lock(priv, &flags);
3878                 if (err)
3879                         return err;
3880                 wrq->u.mode = priv->iw_mode;
3881                 orinoco_unlock(priv, &flags);
3882                 break;
3883
3884         case SIOCSIWENCODE:
3885                 if (! priv->has_wep) {
3886                         err = -EOPNOTSUPP;
3887                         break;
3888                 }
3889
3890                 err = orinoco_ioctl_setiwencode(dev, &wrq->u.encoding);
3891                 if (! err)
3892                         changed = 1;
3893                 break;
3894
3895         case SIOCGIWENCODE:
3896                 if (! priv->has_wep) {
3897                         err = -EOPNOTSUPP;
3898                         break;
3899                 }
3900
3901                 if (! capable(CAP_NET_ADMIN)) {
3902                         err = -EPERM;
3903                         break;
3904                 }
3905
3906                 err = orinoco_ioctl_getiwencode(dev, &wrq->u.encoding);
3907                 break;
3908
3909         case SIOCSIWESSID:
3910                 err = orinoco_ioctl_setessid(dev, &wrq->u.essid);
3911                 if (! err)
3912                         changed = 1;
3913                 break;
3914
3915         case SIOCGIWESSID:
3916                 err = orinoco_ioctl_getessid(dev, &wrq->u.essid);
3917                 break;
3918
3919         case SIOCSIWNICKN:
3920                 err = orinoco_ioctl_setnick(dev, &wrq->u.data);
3921                 if (! err)
3922                         changed = 1;
3923                 break;
3924
3925         case SIOCGIWNICKN:
3926                 err = orinoco_ioctl_getnick(dev, &wrq->u.data);
3927                 break;
3928
3929         case SIOCGIWFREQ:
3930                 tmp = orinoco_hw_get_freq(priv);
3931                 if (tmp < 0) {
3932                         err = tmp;
3933                 } else {
3934                         wrq->u.freq.m = tmp;
3935                         wrq->u.freq.e = 1;
3936                 }
3937                 break;
3938
3939         case SIOCSIWFREQ:
3940                 err = orinoco_ioctl_setfreq(dev, &wrq->u.freq);
3941                 if (! err)
3942                         changed = 1;
3943                 break;
3944
3945         case SIOCGIWSENS:
3946                 err = orinoco_ioctl_getsens(dev, &wrq->u.sens);
3947                 break;
3948
3949         case SIOCSIWSENS:
3950                 err = orinoco_ioctl_setsens(dev, &wrq->u.sens);
3951                 if (! err)
3952                         changed = 1;
3953                 break;
3954
3955         case SIOCGIWRTS:
3956                 wrq->u.rts.value = priv->rts_thresh;
3957                 wrq->u.rts.disabled = (wrq->u.rts.value == 2347);
3958                 wrq->u.rts.fixed = 1;
3959                 break;
3960
3961         case SIOCSIWRTS:
3962                 err = orinoco_ioctl_setrts(dev, &wrq->u.rts);
3963                 if (! err)
3964                         changed = 1;
3965                 break;
3966
3967         case SIOCSIWFRAG:
3968                 err = orinoco_ioctl_setfrag(dev, &wrq->u.frag);
3969                 if (! err)
3970                         changed = 1;
3971                 break;
3972
3973         case SIOCGIWFRAG:
3974                 err = orinoco_ioctl_getfrag(dev, &wrq->u.frag);
3975                 break;
3976
3977         case SIOCSIWRATE:
3978                 err = orinoco_ioctl_setrate(dev, &wrq->u.bitrate);
3979                 if (! err)
3980                         changed = 1;
3981                 break;
3982
3983         case SIOCGIWRATE:
3984                 err = orinoco_ioctl_getrate(dev, &wrq->u.bitrate);
3985                 break;
3986
3987         case SIOCSIWPOWER:
3988                 err = orinoco_ioctl_setpower(dev, &wrq->u.power);
3989                 if (! err)
3990                         changed = 1;
3991                 break;
3992
3993         case SIOCGIWPOWER:
3994                 err = orinoco_ioctl_getpower(dev, &wrq->u.power);
3995                 break;
3996
3997         case SIOCGIWTXPOW:
3998                 /* The card only supports one tx power, so this is easy */
3999                 wrq->u.txpower.value = 15; /* dBm */
4000                 wrq->u.txpower.fixed = 1;
4001                 wrq->u.txpower.disabled = 0;
4002                 wrq->u.txpower.flags = IW_TXPOW_DBM;
4003                 break;
4004
4005 #if WIRELESS_EXT > 10
4006         case SIOCSIWRETRY:
4007                 err = -EOPNOTSUPP;
4008                 break;
4009
4010         case SIOCGIWRETRY:
4011                 err = orinoco_ioctl_getretry(dev, &wrq->u.retry);
4012                 break;
4013 #endif /* WIRELESS_EXT > 10 */
4014
4015         case SIOCSIWSPY:
4016                 err = orinoco_ioctl_setspy(dev, &wrq->u.data);
4017                 break;
4018
4019         case SIOCGIWSPY:
4020                 err = orinoco_ioctl_getspy(dev, &wrq->u.data);
4021                 break;
4022
4023         case SIOCGIWPRIV:
4024                 if (wrq->u.data.pointer) {
4025                         struct iw_priv_args privtab[] = {
4026                                 { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
4027                                 { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
4028                                 { SIOCIWFIRSTPRIV + 0x2,
4029                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4030                                   0, "set_port3" },
4031                                 { SIOCIWFIRSTPRIV + 0x3, 0,
4032                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4033                                   "get_port3" },
4034                                 { SIOCIWFIRSTPRIV + 0x4,
4035                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4036                                   0, "set_preamble" },
4037                                 { SIOCIWFIRSTPRIV + 0x5, 0,
4038                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4039                                   "get_preamble" },
4040                                 { SIOCIWFIRSTPRIV + 0x6,
4041                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4042                                   0, "set_ibssport" },
4043                                 { SIOCIWFIRSTPRIV + 0x7, 0,
4044                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4045                                   "get_ibssport" },
4046                                 { SIOCIWFIRSTPRIV + 0x8,
4047                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
4048                                   0, "monitor" },
4049                                 { SIOCIWLASTPRIV, 0, 0, "dump_recs" },
4050                         };
4051
4052                         wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
4053                         if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
4054                                 err = -EFAULT;
4055                 }
4056                 break;
4057                
4058         case SIOCIWFIRSTPRIV + 0x0: /* force_reset */
4059         case SIOCIWFIRSTPRIV + 0x1: /* card_reset */
4060                 if (! capable(CAP_NET_ADMIN)) {
4061                         err = -EPERM;
4062                         break;
4063                 }
4064                 
4065                 printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
4066
4067                 schedule_work(&priv->reset_work);
4068                 break;
4069
4070         case SIOCIWFIRSTPRIV + 0x2: /* set_port3 */
4071                 if (! capable(CAP_NET_ADMIN)) {
4072                         err = -EPERM;
4073                         break;
4074                 }
4075
4076                 err = orinoco_ioctl_setport3(dev, wrq);
4077                 if (! err)
4078                         changed = 1;
4079                 break;
4080
4081         case SIOCIWFIRSTPRIV + 0x3: /* get_port3 */
4082                 err = orinoco_ioctl_getport3(dev, wrq);
4083                 break;
4084
4085         case SIOCIWFIRSTPRIV + 0x4: /* set_preamble */
4086                 if (! capable(CAP_NET_ADMIN)) {
4087                         err = -EPERM;
4088                         break;
4089                 }
4090
4091                 /* 802.11b has recently defined some short preamble.
4092                  * Basically, the Phy header has been reduced in size.
4093                  * This increase performance, especially at high rates
4094                  * (the preamble is transmitted at 1Mb/s), unfortunately
4095                  * this give compatibility troubles... - Jean II */
4096                 if(priv->has_preamble) {
4097                         int val = *( (int *) wrq->u.name );
4098
4099                         err = orinoco_lock(priv, &flags);
4100                         if (err)
4101                                 return err;
4102                         if (val)
4103                                 priv->preamble = 1;
4104                         else
4105                                 priv->preamble = 0;
4106                         orinoco_unlock(priv, &flags);
4107                         changed = 1;
4108                 } else
4109                         err = -EOPNOTSUPP;
4110                 break;
4111
4112         case SIOCIWFIRSTPRIV + 0x5: /* get_preamble */
4113                 if(priv->has_preamble) {
4114                         int *val = (int *)wrq->u.name;
4115
4116                         err = orinoco_lock(priv, &flags);
4117                         if (err)
4118                                 return err;
4119                         *val = priv->preamble;
4120                         orinoco_unlock(priv, &flags);
4121                 } else
4122                         err = -EOPNOTSUPP;
4123                 break;
4124         case SIOCIWFIRSTPRIV + 0x6: /* set_ibssport */
4125                 if (! capable(CAP_NET_ADMIN)) {
4126                         err = -EPERM;
4127                         break;
4128                 }
4129
4130                 err = orinoco_ioctl_setibssport(dev, wrq);
4131                 if (! err)
4132                         changed = 1;
4133                 break;
4134
4135         case SIOCIWFIRSTPRIV + 0x7: /* get_ibssport */
4136                 err = orinoco_ioctl_getibssport(dev, wrq);
4137                 break;
4138
4139         case SIOCIWFIRSTPRIV + 0x8: /* set sniff (monitor) mode */ 
4140                 DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x8 (monitor)\n",
4141                       dev->name);
4142                 if (! capable(CAP_NET_ADMIN)) {
4143                         err = -EPERM;
4144                         break;
4145                 }
4146                 err = orinoco_wlansniff(dev, wrq);
4147                 break;
4148
4149         case SIOCIWLASTPRIV:
4150                 err = orinoco_debug_dump_recs(dev);
4151                 if (err)
4152                         printk(KERN_ERR "%s: Unable to dump records (%d)\n",
4153                                dev->name, err);
4154                 break;
4155
4156
4157         default:
4158                 err = -EOPNOTSUPP;
4159         }
4160         
4161         if (! err && changed && netif_running(dev)) {
4162                 err = orinoco_reconfigure(dev);
4163         }               
4164
4165         TRACE_EXIT(dev->name);
4166
4167         return err;
4168 }
4169
4170 struct {
4171         u16 rid;
4172         char *name;
4173         int displaytype;
4174 #define DISPLAY_WORDS   0
4175 #define DISPLAY_BYTES   1
4176 #define DISPLAY_STRING  2
4177 #define DISPLAY_XSTRING 3
4178 } record_table[] = {
4179 #define DEBUG_REC(name,type) { HERMES_RID_##name, #name, DISPLAY_##type }
4180         DEBUG_REC(CNFPORTTYPE,WORDS),
4181         DEBUG_REC(CNFOWNMACADDR,BYTES),
4182         DEBUG_REC(CNFDESIREDSSID,STRING),
4183         DEBUG_REC(CNFOWNCHANNEL,WORDS),
4184         DEBUG_REC(CNFOWNSSID,STRING),
4185         DEBUG_REC(CNFOWNATIMWINDOW,WORDS),
4186         DEBUG_REC(CNFSYSTEMSCALE,WORDS),
4187         DEBUG_REC(CNFMAXDATALEN,WORDS),
4188         DEBUG_REC(CNFPMENABLED,WORDS),
4189         DEBUG_REC(CNFPMEPS,WORDS),
4190         DEBUG_REC(CNFMULTICASTRECEIVE,WORDS),
4191         DEBUG_REC(CNFMAXSLEEPDURATION,WORDS),
4192         DEBUG_REC(CNFPMHOLDOVERDURATION,WORDS),
4193         DEBUG_REC(CNFOWNNAME,STRING),
4194         DEBUG_REC(CNFOWNDTIMPERIOD,WORDS),
4195         DEBUG_REC(CNFMULTICASTPMBUFFERING,WORDS),
4196         DEBUG_REC(CNFWEPENABLED_AGERE,WORDS),
4197         DEBUG_REC(CNFMANDATORYBSSID_SYMBOL,WORDS),
4198         DEBUG_REC(CNFWEPDEFAULTKEYID,WORDS),
4199         DEBUG_REC(CNFDEFAULTKEY0,BYTES),
4200         DEBUG_REC(CNFDEFAULTKEY1,BYTES),
4201         DEBUG_REC(CNFMWOROBUST_AGERE,WORDS),
4202         DEBUG_REC(CNFDEFAULTKEY2,BYTES),
4203         DEBUG_REC(CNFDEFAULTKEY3,BYTES),
4204         DEBUG_REC(CNFWEPFLAGS_INTERSIL,WORDS),
4205         DEBUG_REC(CNFWEPKEYMAPPINGTABLE,WORDS),
4206         DEBUG_REC(CNFAUTHENTICATION,WORDS),
4207         DEBUG_REC(CNFMAXASSOCSTA,WORDS),
4208         DEBUG_REC(CNFKEYLENGTH_SYMBOL,WORDS),
4209         DEBUG_REC(CNFTXCONTROL,WORDS),
4210         DEBUG_REC(CNFROAMINGMODE,WORDS),
4211         DEBUG_REC(CNFHOSTAUTHENTICATION,WORDS),
4212         DEBUG_REC(CNFRCVCRCERROR,WORDS),
4213         DEBUG_REC(CNFMMLIFE,WORDS),
4214         DEBUG_REC(CNFALTRETRYCOUNT,WORDS),
4215         DEBUG_REC(CNFBEACONINT,WORDS),
4216         DEBUG_REC(CNFAPPCFINFO,WORDS),
4217         DEBUG_REC(CNFSTAPCFINFO,WORDS),
4218         DEBUG_REC(CNFPRIORITYQUSAGE,WORDS),
4219         DEBUG_REC(CNFTIMCTRL,WORDS),
4220         DEBUG_REC(CNFTHIRTY2TALLY,WORDS),
4221         DEBUG_REC(CNFENHSECURITY,WORDS),
4222         DEBUG_REC(CNFGROUPADDRESSES,BYTES),
4223         DEBUG_REC(CNFCREATEIBSS,WORDS),
4224         DEBUG_REC(CNFFRAGMENTATIONTHRESHOLD,WORDS),
4225         DEBUG_REC(CNFRTSTHRESHOLD,WORDS),
4226         DEBUG_REC(CNFTXRATECONTROL,WORDS),
4227         DEBUG_REC(CNFPROMISCUOUSMODE,WORDS),
4228         DEBUG_REC(CNFBASICRATES_SYMBOL,WORDS),
4229         DEBUG_REC(CNFPREAMBLE_SYMBOL,WORDS),
4230         DEBUG_REC(CNFSHORTPREAMBLE,WORDS),
4231         DEBUG_REC(CNFWEPKEYS_AGERE,BYTES),
4232         DEBUG_REC(CNFEXCLUDELONGPREAMBLE,WORDS),
4233         DEBUG_REC(CNFTXKEY_AGERE,WORDS),
4234         DEBUG_REC(CNFAUTHENTICATIONRSPTO,WORDS),
4235         DEBUG_REC(CNFBASICRATES,WORDS),
4236         DEBUG_REC(CNFSUPPORTEDRATES,WORDS),
4237         DEBUG_REC(CNFTICKTIME,WORDS),
4238         DEBUG_REC(CNFSCANREQUEST,WORDS),
4239         DEBUG_REC(CNFJOINREQUEST,WORDS),
4240         DEBUG_REC(CNFAUTHENTICATESTATION,WORDS),
4241         DEBUG_REC(CNFCHANNELINFOREQUEST,WORDS),
4242         DEBUG_REC(MAXLOADTIME,WORDS),
4243         DEBUG_REC(DOWNLOADBUFFER,WORDS),
4244         DEBUG_REC(PRIID,WORDS),
4245         DEBUG_REC(PRISUPRANGE,WORDS),
4246         DEBUG_REC(CFIACTRANGES,WORDS),
4247         DEBUG_REC(NICSERNUM,XSTRING),
4248         DEBUG_REC(NICID,WORDS),
4249         DEBUG_REC(MFISUPRANGE,WORDS),
4250         DEBUG_REC(CFISUPRANGE,WORDS),
4251         DEBUG_REC(CHANNELLIST,WORDS),
4252         DEBUG_REC(REGULATORYDOMAINS,WORDS),
4253         DEBUG_REC(TEMPTYPE,WORDS),
4254 /*      DEBUG_REC(CIS,BYTES), */
4255         DEBUG_REC(STAID,WORDS),
4256         DEBUG_REC(CURRENTSSID,STRING),
4257         DEBUG_REC(CURRENTBSSID,BYTES),
4258         DEBUG_REC(COMMSQUALITY,WORDS),
4259         DEBUG_REC(CURRENTTXRATE,WORDS),
4260         DEBUG_REC(CURRENTBEACONINTERVAL,WORDS),
4261         DEBUG_REC(CURRENTSCALETHRESHOLDS,WORDS),
4262         DEBUG_REC(PROTOCOLRSPTIME,WORDS),
4263         DEBUG_REC(SHORTRETRYLIMIT,WORDS),
4264         DEBUG_REC(LONGRETRYLIMIT,WORDS),
4265         DEBUG_REC(MAXTRANSMITLIFETIME,WORDS),
4266         DEBUG_REC(MAXRECEIVELIFETIME,WORDS),
4267         DEBUG_REC(CFPOLLABLE,WORDS),
4268         DEBUG_REC(AUTHENTICATIONALGORITHMS,WORDS),
4269         DEBUG_REC(PRIVACYOPTIONIMPLEMENTED,WORDS),
4270         DEBUG_REC(OWNMACADDR,BYTES),
4271         DEBUG_REC(SCANRESULTSTABLE,WORDS),
4272         DEBUG_REC(PHYTYPE,WORDS),
4273         DEBUG_REC(CURRENTCHANNEL,WORDS),
4274         DEBUG_REC(CURRENTPOWERSTATE,WORDS),
4275         DEBUG_REC(CCAMODE,WORDS),
4276         DEBUG_REC(SUPPORTEDDATARATES,WORDS),
4277         DEBUG_REC(BUILDSEQ,BYTES),
4278         DEBUG_REC(FWID,XSTRING)
4279 #undef DEBUG_REC
4280 };
4281
4282 #define DEBUG_LTV_SIZE          128
4283
4284 static int orinoco_debug_dump_recs(struct net_device *dev)
4285 {
4286         struct orinoco_private *priv = netdev_priv(dev);
4287         hermes_t *hw = &priv->hw;
4288         u8 *val8;
4289         u16 *val16;
4290         int i,j;
4291         u16 length;
4292         int err;
4293
4294         /* I'm not sure: we might have a lock here, so we'd better go
4295            atomic, just in case. */
4296         val8 = kmalloc(DEBUG_LTV_SIZE + 2, GFP_ATOMIC);
4297         if (! val8)
4298                 return -ENOMEM;
4299         val16 = (u16 *)val8;
4300
4301         for (i = 0; i < ARRAY_SIZE(record_table); i++) {
4302                 u16 rid = record_table[i].rid;
4303                 int len;
4304
4305                 memset(val8, 0, DEBUG_LTV_SIZE + 2);
4306
4307                 err = hermes_read_ltv(hw, USER_BAP, rid, DEBUG_LTV_SIZE,
4308                                       &length, val8);
4309                 if (err) {
4310                         DEBUG(0, "Error %d reading RID 0x%04x\n", err, rid);
4311                         continue;
4312                 }
4313                 val16 = (u16 *)val8;
4314                 if (length == 0)
4315                         continue;
4316
4317                 printk(KERN_DEBUG "%-15s (0x%04x): length=%d (%d bytes)\tvalue=",
4318                        record_table[i].name,
4319                        rid, length, (length-1)*2);
4320                 len = min(((int)length-1)*2, DEBUG_LTV_SIZE);
4321
4322                 switch (record_table[i].displaytype) {
4323                 case DISPLAY_WORDS:
4324                         for (j = 0; j < len / 2; j++)
4325                                 printk("%04X-", le16_to_cpu(val16[j]));
4326                         break;
4327
4328                 case DISPLAY_BYTES:
4329                 default:
4330                         for (j = 0; j < len; j++)
4331                                 printk("%02X:", val8[j]);
4332                         break;
4333
4334                 case DISPLAY_STRING:
4335                         len = min(len, le16_to_cpu(val16[0])+2);
4336                         val8[len] = '\0';
4337                         printk("\"%s\"", (char *)&val16[1]);
4338                         break;
4339
4340                 case DISPLAY_XSTRING:
4341                         printk("'%s'", (char *)val8);
4342                 }
4343
4344                 printk("\n");
4345         }
4346
4347         kfree(val8);
4348
4349         return 0;
4350 }
4351
4352 struct net_device *alloc_orinocodev(int sizeof_card, int (*hard_reset)(struct orinoco_private *))
4353 {
4354         struct net_device *dev;
4355         struct orinoco_private *priv;
4356
4357         dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
4358         if (!dev)
4359                 return NULL;
4360         priv = netdev_priv(dev);
4361         priv->ndev = dev;
4362         if (sizeof_card)
4363                 priv->card = (void *)((unsigned long)dev->priv + sizeof(struct orinoco_private));
4364         else
4365                 priv->card = NULL;
4366
4367         /* Setup / override net_device fields */
4368         dev->init = orinoco_init;
4369         dev->hard_start_xmit = orinoco_xmit;
4370         dev->tx_timeout = orinoco_tx_timeout;
4371         dev->watchdog_timeo = HZ; /* 1 second timeout */
4372         dev->get_stats = orinoco_get_stats;
4373 #ifdef SET_MAC_ADDRESS
4374         dev->set_mac_address = orinoco_set_mac_address;
4375 #endif  /* SET_MAC_ADDRESS */
4376         dev->get_wireless_stats = orinoco_get_wireless_stats;
4377         dev->do_ioctl = orinoco_ioctl;
4378         dev->change_mtu = orinoco_change_mtu;
4379         dev->set_multicast_list = orinoco_set_multicast_list;
4380         /* we use the default eth_mac_addr for setting the MAC addr */
4381
4382         /* Set up default callbacks */
4383         dev->open = orinoco_open;
4384         dev->stop = orinoco_stop;
4385         priv->hard_reset = hard_reset;
4386
4387         spin_lock_init(&priv->lock);
4388         priv->open = 0;
4389         priv->hw_unavailable = 1; /* orinoco_init() must clear this
4390                                    * before anything else touches the
4391                                    * hardware */
4392         INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev);
4393
4394         priv->last_linkstatus = 0xffff;
4395         priv->connected = 0;
4396
4397         return dev;
4398
4399 }
4400
4401 /*----------------------------------------------------------------
4402 * orinoco_int_rxmonitor
4403 *
4404 * Helper function for int_rx.  Handles monitor frames.
4405 * Note that this function allocates space for the FCS and sets it
4406 * to 0xffffffff.  The hfa384x doesn't give us the FCS value but the
4407 * higher layers expect it.  0xffffffff is used as a flag to indicate
4408 * the FCS is bogus.
4409 *
4410 * Arguments:
4411 *       dev             wlan device structure
4412 *       rxfid           received FID
4413 *       rxdesc          rx descriptor read from card in int_rx
4414 *
4415 * Returns: 
4416 *       nothing
4417 *
4418 * Side effects:
4419 *       Allocates an skb and passes it up via the PF_PACKET interface.
4420 * Call context:
4421 *       interrupt
4422 ----------------------------------------------------------------*/
4423 void orinoco_int_rxmonitor( struct orinoco_private *dev, uint16_t rxfid, int len,
4424                             struct hermes_rx_descriptor *rxdesc, struct ieee802_11_hdr *hdr)
4425 {
4426         hermes_t                        *hw = &(dev->hw);
4427         uint32_t                                hdrlen = 0;
4428         uint32_t                                datalen = 0;
4429         uint32_t                                skblen = 0;
4430         p80211msg_lnxind_wlansniffrm_t  *msg;
4431         struct net_device_stats *stats = &dev->stats;
4432
4433
4434         uint8_t                         *datap;
4435         uint16_t                                fc;
4436         struct sk_buff                  *skb;
4437
4438         /* Don't forget the status, time, and data_len fields are in host order */
4439         /* Figure out how big the frame is */
4440         fc = le16_to_cpu(hdr->frame_ctl);
4441         switch ( WLAN_GET_FC_FTYPE(fc) )
4442         {
4443         case WLAN_FTYPE_DATA:
4444                 if ( WLAN_GET_FC_TODS(fc) && WLAN_GET_FC_FROMDS(fc) ) {
4445                         hdrlen = WLAN_HDR_A4_LEN;
4446                 } else {
4447                         hdrlen = WLAN_HDR_A3_LEN;
4448                 }
4449                 datalen = len;
4450                 break;
4451         case WLAN_FTYPE_MGMT:
4452                 hdrlen = WLAN_HDR_A3_LEN;
4453                 datalen = len;
4454                 break;
4455         case WLAN_FTYPE_CTL:
4456                 switch ( WLAN_GET_FC_FSTYPE(fc) )
4457                 {
4458                 case WLAN_FSTYPE_PSPOLL:
4459                 case WLAN_FSTYPE_RTS:
4460                 case WLAN_FSTYPE_CFEND:
4461                 case WLAN_FSTYPE_CFENDCFACK:
4462                         hdrlen = 16;
4463                         break;
4464                 case WLAN_FSTYPE_CTS:
4465                 case WLAN_FSTYPE_ACK:
4466                         hdrlen = 10;
4467                         break;
4468                 }
4469                 datalen = 0;
4470                 break;
4471         default:
4472                 printk("unknown frm: fc=0x%04x\n", fc);
4473                 return;
4474         }
4475
4476         /* Allocate an ind message+framesize skb */
4477         skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) + 
4478           hdrlen + datalen;
4479         
4480         /* sanity check the length */
4481         if ( skblen > 
4482                 (sizeof(p80211msg_lnxind_wlansniffrm_t) + 
4483                 WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) {
4484                 printk("overlen frm: len=%d\n", 
4485                         skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
4486         }
4487                         
4488         if ( (skb = dev_alloc_skb(skblen)) == NULL ) {
4489                 printk("alloc_skb failed trying to allocate %d bytes\n", skblen);
4490                 return;
4491         }
4492
4493         /* only prepend the prism header if in the right mode */
4494         if (dev->ndev->type != ARPHRD_IEEE80211_PRISM) {
4495           skb_put(skb, skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
4496           datap = skb->data;
4497         } else {
4498           skb_put(skb, skblen);
4499           datap = skb->data + sizeof(p80211msg_lnxind_wlansniffrm_t);
4500           msg = (p80211msg_lnxind_wlansniffrm_t*)skb->data;
4501           
4502           /* Initialize the message members */
4503           msg->msgcode = DIDmsg_lnxind_wlansniffrm;
4504           msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t);
4505           strcpy(msg->devname, dev->ndev->name);
4506           
4507           msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
4508           msg->hosttime.status = 0;
4509           msg->hosttime.len = 4;
4510           msg->hosttime.data = jiffies;
4511           
4512           msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
4513           msg->mactime.status = 0;
4514           msg->mactime.len = 4;
4515           msg->mactime.data = rxdesc->time;
4516           
4517           msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
4518           msg->channel.status = P80211ENUM_msgitem_status_no_value;
4519           msg->channel.len = 4;
4520           msg->channel.data = 0;
4521
4522           msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
4523           msg->rssi.status = P80211ENUM_msgitem_status_no_value;
4524           msg->rssi.len = 4;
4525           msg->rssi.data = 0;
4526           
4527           msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq;
4528           msg->sq.status = P80211ENUM_msgitem_status_no_value;
4529           msg->sq.len = 4;
4530           msg->sq.data = 0;
4531           
4532           msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
4533           msg->signal.status = 0;
4534           msg->signal.len = 4;
4535           msg->signal.data = rxdesc->signal;
4536           
4537           msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
4538           msg->noise.status = 0;
4539           msg->noise.len = 4;
4540           msg->noise.data = rxdesc->silence;
4541
4542           msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
4543           msg->rate.status = 0;
4544           msg->rate.len = 4;
4545           msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */
4546   
4547           msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
4548           msg->istx.status = 0;
4549           msg->istx.len = 4;
4550           msg->istx.data = P80211ENUM_truth_false;
4551           
4552           msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
4553           msg->frmlen.status = 0;
4554           msg->frmlen.len = 4;
4555           msg->frmlen.data = hdrlen + datalen;
4556         }         
4557
4558         /* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */
4559         memcpy( datap, &(hdr->frame_ctl), hdrlen);
4560
4561         /* If any, copy the data from the card to the skb */
4562         if ( datalen > 0 )
4563         {
4564                 hermes_bap_pread(hw, IRQ_BAP, datap + hdrlen, (datalen+1)&~1,
4565                                        rxfid, HERMES_RX_DATA_OFF);
4566
4567                 /* check for unencrypted stuff if WEP bit set. */
4568                 if (*(datap+1) & 0x40) // wep set
4569                   if ((*(datap+hdrlen) == 0xaa) && (*(datap+hdrlen+1) == 0xaa))
4570                     *(datap+1) &= 0xbf; // clear wep; it's the 802.2 header!
4571         }
4572
4573        /* pass it up via the PF_PACKET interface */
4574        {
4575            skb->dev = dev->ndev;
4576            skb->dev->last_rx = jiffies;
4577
4578            skb->mac.raw = skb->data ;
4579            skb->ip_summed = CHECKSUM_NONE;
4580            skb->pkt_type = PACKET_OTHERHOST;
4581            skb->protocol = htons(ETH_P_80211_RAW);  /* XXX ETH_P_802_2? */
4582
4583            stats->rx_packets++;
4584            stats->rx_bytes += skb->len;
4585
4586            netif_rx(skb);
4587        }
4588
4589         return;
4590 }
4591
4592 /********************************************************************/
4593 /* Module initialization                                            */
4594 /********************************************************************/
4595
4596 EXPORT_SYMBOL(alloc_orinocodev);
4597
4598 EXPORT_SYMBOL(__orinoco_up);
4599 EXPORT_SYMBOL(__orinoco_down);
4600 EXPORT_SYMBOL(orinoco_stop);
4601 EXPORT_SYMBOL(orinoco_reinit_firmware);
4602
4603 EXPORT_SYMBOL(orinoco_interrupt);
4604
4605 /* Can't be declared "const" or the whole __initdata section will
4606  * become const */
4607 static char version[] __initdata = "orinoco.c 0.13e (David Gibson <hermes@gibson.dropbear.id.au> and others)";
4608
4609 static int __init init_orinoco(void)
4610 {
4611         printk(KERN_DEBUG "%s\n", version);
4612         return 0;
4613 }
4614
4615 static void __exit exit_orinoco(void)
4616 {
4617 }
4618
4619 module_init(init_orinoco);
4620 module_exit(exit_orinoco);