VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.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
1678         rxfid = hermes_read_regn(hw, RXFID);
1679
1680         err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc),
1681                                rxfid, 0);
1682         if (err) {
1683                 printk(KERN_ERR "%s: error %d reading Rx descriptor. "
1684                        "Frame dropped.\n", dev->name, err);
1685                 stats->rx_errors++;
1686                 goto drop;
1687         }
1688
1689         status = le16_to_cpu(desc.status);
1690         
1691         if (status & HERMES_RXSTAT_ERR) {
1692                 if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
1693                         wstats->discard.code++;
1694                         DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
1695                                dev->name);
1696                 } else {
1697                         stats->rx_crc_errors++;
1698                         DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", dev->name);
1699                 }
1700                 stats->rx_errors++;
1701                 goto drop;
1702         }
1703
1704         /* For now we ignore the 802.11 header completely, assuming
1705            that the card's firmware has handled anything vital */
1706
1707         err = hermes_bap_pread(hw, IRQ_BAP, &hdr, sizeof(hdr),
1708                                rxfid, HERMES_802_3_OFFSET);
1709         if (err) {
1710                 printk(KERN_ERR "%s: error %d reading frame header. "
1711                        "Frame dropped.\n", dev->name, err);
1712                 stats->rx_errors++;
1713                 goto drop;
1714         }
1715
1716         length = ntohs(hdr.len);
1717         
1718         /* Sanity checks */
1719         if (length < 3) { /* No for even an 802.2 LLC header */
1720                 /* At least on Symbol firmware with PCF we get quite a
1721                    lot of these legitimately - Poll frames with no
1722                    data. */
1723                 stats->rx_dropped++;
1724                 goto drop;
1725         }
1726         if (length > IEEE802_11_DATA_LEN) {
1727                 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
1728                        dev->name, length);
1729                 stats->rx_length_errors++;
1730                 stats->rx_errors++;
1731                 goto drop;
1732         }
1733
1734         /* We need space for the packet data itself, plus an ethernet
1735            header, plus 2 bytes so we can align the IP header on a
1736            32bit boundary, plus 1 byte so we can read in odd length
1737            packets from the card, which has an IO granularity of 16
1738            bits */  
1739         skb = dev_alloc_skb(length+ETH_HLEN+2+1);
1740         if (!skb) {
1741                 printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
1742                        dev->name);
1743                 goto drop;
1744         }
1745
1746         skb_reserve(skb, 2); /* This way the IP header is aligned */
1747
1748         /* Handle decapsulation
1749          * In most cases, the firmware tell us about SNAP frames.
1750          * For some reason, the SNAP frames sent by LinkSys APs
1751          * are not properly recognised by most firmwares.
1752          * So, check ourselves */
1753         if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
1754            ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
1755            is_ethersnap(&hdr)) {
1756                 /* These indicate a SNAP within 802.2 LLC within
1757                    802.11 frame which we'll need to de-encapsulate to
1758                    the original EthernetII frame. */
1759
1760                 if (length < ENCAPS_OVERHEAD) { /* No room for full LLC+SNAP */
1761                         stats->rx_length_errors++;
1762                         goto drop;
1763                 }
1764
1765                 /* Remove SNAP header, reconstruct EthernetII frame */
1766                 data_len = length - ENCAPS_OVERHEAD;
1767                 data_off = HERMES_802_3_OFFSET + sizeof(hdr);
1768
1769                 eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);
1770
1771                 memcpy(eh, &hdr, 2 * ETH_ALEN);
1772                 eh->h_proto = hdr.ethertype;
1773         } else {
1774                 /* All other cases indicate a genuine 802.3 frame.  No
1775                    decapsulation needed.  We just throw the whole
1776                    thing in, and hope the protocol layer can deal with
1777                    it as 802.3 */
1778                 data_len = length;
1779                 data_off = HERMES_802_3_OFFSET;
1780                 /* FIXME: we re-read from the card data we already read here */
1781         }
1782
1783         p = skb_put(skb, data_len);
1784         err = hermes_bap_pread(hw, IRQ_BAP, p, RUP_EVEN(data_len),
1785                                rxfid, data_off);
1786         if (err) {
1787                 printk(KERN_ERR "%s: error %d reading frame. "
1788                        "Frame dropped.\n", dev->name, err);
1789                 stats->rx_errors++;
1790                 goto drop;
1791         }
1792
1793         dev->last_rx = jiffies;
1794         skb->dev = dev;
1795         skb->protocol = eth_type_trans(skb, dev);
1796         skb->ip_summed = CHECKSUM_NONE;
1797         
1798         /* Process the wireless stats if needed */
1799         orinoco_stat_gather(dev, skb, &desc);
1800
1801         /* Pass the packet to the networking stack */
1802         netif_rx(skb);
1803         stats->rx_packets++;
1804         stats->rx_bytes += length;
1805
1806         return;
1807
1808  drop:  
1809         stats->rx_dropped++;
1810
1811         if (skb)
1812                 dev_kfree_skb_irq(skb);
1813         return;
1814 }
1815
1816 static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
1817 {
1818         struct orinoco_private *priv = netdev_priv(dev);
1819         struct net_device_stats *stats = &priv->stats;
1820         u16 fid = hermes_read_regn(hw, TXCOMPLFID);
1821         struct hermes_tx_descriptor desc;
1822         int err = 0;
1823
1824         if (fid == DUMMY_FID)
1825                 return; /* Nothing's really happened */
1826
1827         err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc), fid, 0);
1828         if (err) {
1829                 printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
1830                        "(FID=%04X error %d)\n",
1831                        dev->name, fid, err);
1832         } else {
1833                 DEBUG(1, "%s: Tx error, status %d\n",
1834                       dev->name, le16_to_cpu(desc.status));
1835         }
1836         
1837         stats->tx_errors++;
1838
1839         hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
1840 }
1841
1842 static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
1843 {
1844         struct orinoco_private *priv = netdev_priv(dev);
1845         struct net_device_stats *stats = &priv->stats;
1846
1847         stats->tx_packets++;
1848
1849         hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
1850 }
1851
1852 static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
1853 {
1854         struct orinoco_private *priv = netdev_priv(dev);
1855
1856         u16 fid = hermes_read_regn(hw, ALLOCFID);
1857
1858         if (fid != priv->txfid) {
1859                 if (fid != DUMMY_FID)
1860                         printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
1861                                dev->name, fid);
1862                 return;
1863         } else {
1864                 netif_wake_queue(dev);
1865         }
1866
1867         hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
1868 }
1869
1870 struct sta_id {
1871         u16 id, variant, major, minor;
1872 } __attribute__ ((packed));
1873
1874 static int determine_firmware_type(struct net_device *dev, struct sta_id *sta_id)
1875 {
1876         /* FIXME: this is fundamentally broken */
1877         unsigned int firmver = ((u32)sta_id->major << 16) | sta_id->minor;
1878         
1879         if (sta_id->variant == 1)
1880                 return FIRMWARE_TYPE_AGERE;
1881         else if ((sta_id->variant == 2) &&
1882                    ((firmver == 0x10001) || (firmver == 0x20001)))
1883                 return FIRMWARE_TYPE_SYMBOL;
1884         else
1885                 return FIRMWARE_TYPE_INTERSIL;
1886 }
1887
1888 static void determine_firmware(struct net_device *dev)
1889 {
1890         struct orinoco_private *priv = netdev_priv(dev);
1891         hermes_t *hw = &priv->hw;
1892         int err;
1893         struct sta_id sta_id;
1894         unsigned int firmver;
1895         char tmp[SYMBOL_MAX_VER_LEN+1];
1896
1897         /* Get the firmware version */
1898         err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
1899         if (err) {
1900                 printk(KERN_WARNING "%s: Error %d reading firmware info. Wildly guessing capabilities...\n",
1901                        dev->name, err);
1902                 memset(&sta_id, 0, sizeof(sta_id));
1903         }
1904         le16_to_cpus(&sta_id.id);
1905         le16_to_cpus(&sta_id.variant);
1906         le16_to_cpus(&sta_id.major);
1907         le16_to_cpus(&sta_id.minor);
1908
1909         printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
1910                dev->name, sta_id.id, sta_id.variant,
1911                sta_id.major, sta_id.minor);
1912
1913         if (! priv->firmware_type)
1914                 priv->firmware_type = determine_firmware_type(dev, &sta_id);
1915
1916         /* Default capabilities */
1917         priv->has_sensitivity = 1;
1918         priv->has_mwo = 0;
1919         priv->has_preamble = 0;
1920         priv->has_port3 = 1;
1921         priv->has_ibss = 1;
1922         priv->has_ibss_any = 0;
1923         priv->has_wep = 0;
1924         priv->has_big_wep = 0;
1925
1926         /* Determine capabilities from the firmware version */
1927         switch (priv->firmware_type) {
1928         case FIRMWARE_TYPE_AGERE:
1929                 /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
1930                    ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
1931                 printk(KERN_DEBUG "%s: Looks like a Lucent/Agere firmware "
1932                        "version %d.%02d\n", dev->name,
1933                        sta_id.major, sta_id.minor);
1934
1935                 firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
1936
1937                 priv->has_ibss = (firmver >= 0x60006);
1938                 priv->has_ibss_any = (firmver >= 0x60010);
1939                 priv->has_wep = (firmver >= 0x40020);
1940                 priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
1941                                           Gold cards from the others? */
1942                 priv->has_mwo = (firmver >= 0x60000);
1943                 priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
1944                 priv->ibss_port = 1;
1945
1946                 /* Tested with Agere firmware :
1947                  *      1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
1948                  * Tested CableTron firmware : 4.32 => Anton */
1949                 break;
1950         case FIRMWARE_TYPE_SYMBOL:
1951                 /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
1952                 /* Intel MAC : 00:02:B3:* */
1953                 /* 3Com MAC : 00:50:DA:* */
1954                 memset(tmp, 0, sizeof(tmp));
1955                 /* Get the Symbol firmware version */
1956                 err = hermes_read_ltv(hw, USER_BAP,
1957                                       HERMES_RID_SECONDARYVERSION_SYMBOL,
1958                                       SYMBOL_MAX_VER_LEN, NULL, &tmp);
1959                 if (err) {
1960                         printk(KERN_WARNING
1961                                "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",
1962                                dev->name, err);
1963                         firmver = 0;
1964                         tmp[0] = '\0';
1965                 } else {
1966                         /* The firmware revision is a string, the format is
1967                          * something like : "V2.20-01".
1968                          * Quick and dirty parsing... - Jean II
1969                          */
1970                         firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12)
1971                                 | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4)
1972                                 | (tmp[7] - '0');
1973
1974                         tmp[SYMBOL_MAX_VER_LEN] = '\0';
1975                 }
1976
1977                 printk(KERN_DEBUG "%s: Looks like a Symbol firmware "
1978                        "version [%s] (parsing to %X)\n", dev->name,
1979                        tmp, firmver);
1980
1981                 priv->has_ibss = (firmver >= 0x20000);
1982                 priv->has_wep = (firmver >= 0x15012);
1983                 priv->has_big_wep = (firmver >= 0x20000);
1984                 priv->has_pm = (firmver >= 0x20000) && (firmver < 0x22000);
1985                 priv->has_preamble = (firmver >= 0x20000);
1986                 priv->ibss_port = 4;
1987                 /* Tested with Intel firmware : 0x20015 => Jean II */
1988                 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
1989                 break;
1990         case FIRMWARE_TYPE_INTERSIL:
1991                 /* D-Link, Linksys, Adtron, ZoomAir, and many others...
1992                  * Samsung, Compaq 100/200 and Proxim are slightly
1993                  * different and less well tested */
1994                 /* D-Link MAC : 00:40:05:* */
1995                 /* Addtron MAC : 00:90:D1:* */
1996                 printk(KERN_DEBUG "%s: Looks like an Intersil firmware "
1997                        "version %d.%d.%d\n", dev->name,
1998                        sta_id.major, sta_id.minor, sta_id.variant);
1999
2000                 firmver = ((unsigned long)sta_id.major << 16) |
2001                         ((unsigned long)sta_id.minor << 8) | sta_id.variant;
2002
2003                 priv->has_ibss = (firmver >= 0x000700); /* FIXME */
2004                 priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
2005                 priv->has_pm = (firmver >= 0x000700);
2006
2007                 if (firmver >= 0x000800)
2008                         priv->ibss_port = 0;
2009                 else {
2010                         printk(KERN_NOTICE "%s: Intersil firmware earlier "
2011                                "than v0.8.x - several features not supported\n",
2012                                dev->name);
2013                         priv->ibss_port = 1;
2014                 }
2015                 break;
2016         default:
2017                 break;
2018         }
2019 }
2020
2021 /*
2022  * struct net_device methods
2023  */
2024
2025 static int
2026 orinoco_init(struct net_device *dev)
2027 {
2028         struct orinoco_private *priv = netdev_priv(dev);
2029         hermes_t *hw = &priv->hw;
2030         int err = 0;
2031         struct hermes_idstring nickbuf;
2032         u16 reclen;
2033         int len;
2034
2035         TRACE_ENTER(dev->name);
2036
2037         /* No need to lock, the hw_unavailable flag is already set in
2038          * alloc_orinocodev() */
2039         priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
2040
2041         /* Initialize the firmware */
2042         err = hermes_init(hw);
2043         if (err != 0) {
2044                 printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
2045                        dev->name, err);
2046                 goto out;
2047         }
2048
2049         determine_firmware(dev);
2050
2051         if (priv->has_port3)
2052                 printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
2053         if (priv->has_ibss)
2054                 printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
2055                        dev->name);
2056         if (priv->has_wep) {
2057                 printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
2058                 if (priv->has_big_wep)
2059                         printk("104-bit key\n");
2060                 else
2061                         printk("40-bit key\n");
2062         }
2063
2064         /* Get the MAC address */
2065         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
2066                               ETH_ALEN, NULL, dev->dev_addr);
2067         if (err) {
2068                 printk(KERN_WARNING "%s: failed to read MAC address!\n",
2069                        dev->name);
2070                 goto out;
2071         }
2072
2073         printk(KERN_DEBUG "%s: MAC address %02X:%02X:%02X:%02X:%02X:%02X\n",
2074                dev->name, dev->dev_addr[0], dev->dev_addr[1],
2075                dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4],
2076                dev->dev_addr[5]);
2077
2078         /* Get the station name */
2079         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
2080                               sizeof(nickbuf), &reclen, &nickbuf);
2081         if (err) {
2082                 printk(KERN_ERR "%s: failed to read station name\n",
2083                        dev->name);
2084                 goto out;
2085         }
2086         if (nickbuf.len)
2087                 len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
2088         else
2089                 len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
2090         memcpy(priv->nick, &nickbuf.val, len);
2091         priv->nick[len] = '\0';
2092
2093         printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
2094
2095         /* Get allowed channels */
2096         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
2097                                   &priv->channel_mask);
2098         if (err) {
2099                 printk(KERN_ERR "%s: failed to read channel list!\n",
2100                        dev->name);
2101                 goto out;
2102         }
2103
2104         /* Get initial AP density */
2105         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
2106                                   &priv->ap_density);
2107         if (err || priv->ap_density < 1 || priv->ap_density > 3) {
2108                 priv->has_sensitivity = 0;
2109         }
2110
2111         /* Get initial RTS threshold */
2112         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
2113                                   &priv->rts_thresh);
2114         if (err) {
2115                 printk(KERN_ERR "%s: failed to read RTS threshold!\n", dev->name);
2116                 goto out;
2117         }
2118
2119         /* Get initial fragmentation settings */
2120         if (priv->has_mwo)
2121                 err = hermes_read_wordrec(hw, USER_BAP,
2122                                           HERMES_RID_CNFMWOROBUST_AGERE,
2123                                           &priv->mwo_robust);
2124         else
2125                 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
2126                                           &priv->frag_thresh);
2127         if (err) {
2128                 printk(KERN_ERR "%s: failed to read fragmentation settings!\n", dev->name);
2129                 goto out;
2130         }
2131
2132         /* Power management setup */
2133         if (priv->has_pm) {
2134                 priv->pm_on = 0;
2135                 priv->pm_mcast = 1;
2136                 err = hermes_read_wordrec(hw, USER_BAP,
2137                                           HERMES_RID_CNFMAXSLEEPDURATION,
2138                                           &priv->pm_period);
2139                 if (err) {
2140                         printk(KERN_ERR "%s: failed to read power management period!\n",
2141                                dev->name);
2142                         goto out;
2143                 }
2144                 err = hermes_read_wordrec(hw, USER_BAP,
2145                                           HERMES_RID_CNFPMHOLDOVERDURATION,
2146                                           &priv->pm_timeout);
2147                 if (err) {
2148                         printk(KERN_ERR "%s: failed to read power management timeout!\n",
2149                                dev->name);
2150                         goto out;
2151                 }
2152         }
2153
2154         /* Preamble setup */
2155         if (priv->has_preamble) {
2156                 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPREAMBLE_SYMBOL,
2157                                           &priv->preamble);
2158                 if (err)
2159                         goto out;
2160         }
2161                 
2162         /* Set up the default configuration */
2163         priv->iw_mode = IW_MODE_INFRA;
2164         /* By default use IEEE/IBSS ad-hoc mode if we have it */
2165         priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
2166         set_port_type(priv);
2167         priv->channel = 10; /* default channel, more-or-less arbitrary */
2168
2169         priv->promiscuous = 0;
2170         priv->wep_on = 0;
2171         priv->tx_key = 0;
2172
2173         err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
2174         if (err == -EIO) {
2175                 /* Try workaround for old Symbol firmware bug */
2176                 printk(KERN_WARNING "%s: firmware ALLOC bug detected "
2177                        "(old Symbol firmware?). Trying to work around... ",
2178                        dev->name);
2179                 
2180                 priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
2181                 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
2182                 if (err)
2183                         printk("failed!\n");
2184                 else
2185                         printk("ok.\n");
2186         }
2187         if (err) {
2188                 printk("%s: Error %d allocating Tx buffer\n", dev->name, err);
2189                 goto out;
2190         }
2191
2192         /* Make the hardware available, as long as it hasn't been
2193          * removed elsewhere (e.g. by PCMCIA hot unplug) */
2194         spin_lock_irq(&priv->lock);
2195         priv->hw_unavailable--;
2196         spin_unlock_irq(&priv->lock);
2197
2198         printk(KERN_DEBUG "%s: ready\n", dev->name);
2199
2200  out:
2201         TRACE_EXIT(dev->name);
2202         return err;
2203 }
2204
2205 struct net_device_stats *
2206 orinoco_get_stats(struct net_device *dev)
2207 {
2208         struct orinoco_private *priv = netdev_priv(dev);
2209         
2210         return &priv->stats;
2211 }
2212
2213 struct iw_statistics *
2214 orinoco_get_wireless_stats(struct net_device *dev)
2215 {
2216         struct orinoco_private *priv = netdev_priv(dev);
2217         hermes_t *hw = &priv->hw;
2218         struct iw_statistics *wstats = &priv->wstats;
2219         int err = 0;
2220         unsigned long flags;
2221
2222         if (! netif_device_present(dev)) {
2223                 printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
2224                        dev->name);
2225                 return NULL; /* FIXME: Can we do better than this? */
2226         }
2227
2228         err = orinoco_lock(priv, &flags);
2229         if (err)
2230                 return NULL; /* FIXME: Erg, we've been signalled, how
2231                               * do we propagate this back up? */
2232
2233         if (priv->iw_mode == IW_MODE_ADHOC) {
2234                 memset(&wstats->qual, 0, sizeof(wstats->qual));
2235                 /* If a spy address is defined, we report stats of the
2236                  * first spy address - Jean II */
2237                 if (SPY_NUMBER(priv)) {
2238                         wstats->qual.qual = priv->spy_stat[0].qual;
2239                         wstats->qual.level = priv->spy_stat[0].level;
2240                         wstats->qual.noise = priv->spy_stat[0].noise;
2241                         wstats->qual.updated = priv->spy_stat[0].updated;
2242                 }
2243         } else {
2244                 struct {
2245                         u16 qual, signal, noise;
2246                 } __attribute__ ((packed)) cq;
2247
2248                 err = HERMES_READ_RECORD(hw, USER_BAP,
2249                                          HERMES_RID_COMMSQUALITY, &cq);
2250                 
2251                 wstats->qual.qual = (int)le16_to_cpu(cq.qual);
2252                 wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
2253                 wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
2254                 wstats->qual.updated = 7;
2255         }
2256
2257         /* We can't really wait for the tallies inquiry command to
2258          * complete, so we just use the previous results and trigger
2259          * a new tallies inquiry command for next time - Jean II */
2260         /* FIXME: We're in user context (I think?), so we should just
2261            wait for the tallies to come through */
2262         err = hermes_inquire(hw, HERMES_INQ_TALLIES);
2263                
2264         orinoco_unlock(priv, &flags);
2265
2266         if (err)
2267                 return NULL;
2268                 
2269         return wstats;
2270 }
2271
2272 static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
2273                                     int level, int noise)
2274 {
2275         struct orinoco_private *priv = netdev_priv(dev);
2276         int i;
2277
2278         /* Gather wireless spy statistics: for each packet, compare the
2279          * source address with out list, and if match, get the stats... */
2280         for (i = 0; i < priv->spy_number; i++)
2281                 if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {
2282                         priv->spy_stat[i].level = level - 0x95;
2283                         priv->spy_stat[i].noise = noise - 0x95;
2284                         priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0;
2285                         priv->spy_stat[i].updated = 7;
2286                 }
2287 }
2288
2289 void
2290 orinoco_stat_gather(struct net_device *dev,
2291                     struct sk_buff *skb,
2292                     struct hermes_rx_descriptor *desc)
2293 {
2294         struct orinoco_private *priv = netdev_priv(dev);
2295
2296         /* Using spy support with lots of Rx packets, like in an
2297          * infrastructure (AP), will really slow down everything, because
2298          * the MAC address must be compared to each entry of the spy list.
2299          * If the user really asks for it (set some address in the
2300          * spy list), we do it, but he will pay the price.
2301          * Note that to get here, you need both WIRELESS_SPY
2302          * compiled in AND some addresses in the list !!!
2303          */
2304         /* Note : gcc will optimise the whole section away if
2305          * WIRELESS_SPY is not defined... - Jean II */
2306         if (SPY_NUMBER(priv)) {
2307                 orinoco_spy_gather(dev, skb->mac.raw + ETH_ALEN,
2308                                    desc->signal, desc->silence);
2309         }
2310 }
2311
2312 static int
2313 orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
2314 {
2315         struct orinoco_private *priv = netdev_priv(dev);
2316         struct net_device_stats *stats = &priv->stats;
2317         hermes_t *hw = &priv->hw;
2318         int err = 0;
2319         u16 txfid = priv->txfid;
2320         char *p;
2321         struct ethhdr *eh;
2322         int len, data_len, data_off;
2323         struct hermes_tx_descriptor desc;
2324         unsigned long flags;
2325
2326         TRACE_ENTER(dev->name);
2327
2328         if (! netif_running(dev)) {
2329                 printk(KERN_ERR "%s: Tx on stopped device!\n",
2330                        dev->name);
2331                 TRACE_EXIT(dev->name);
2332                 return 1;
2333         }
2334         
2335         if (netif_queue_stopped(dev)) {
2336                 printk(KERN_DEBUG "%s: Tx while transmitter busy!\n", 
2337                        dev->name);
2338                 TRACE_EXIT(dev->name);
2339                 return 1;
2340         }
2341         
2342         if (orinoco_lock(priv, &flags) != 0) {
2343                 printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
2344                        dev->name);
2345                 TRACE_EXIT(dev->name);
2346 /*              BUG(); */
2347                 return 1;
2348         }
2349
2350         if (! priv->connected) {
2351                 /* Oops, the firmware hasn't established a connection,
2352                    silently drop the packet (this seems to be the
2353                    safest approach). */
2354                 stats->tx_errors++;
2355                 orinoco_unlock(priv, &flags);
2356                 dev_kfree_skb(skb);
2357                 TRACE_EXIT(dev->name);
2358                 return 0;
2359         }
2360
2361         /* Length of the packet body */
2362         /* FIXME: what if the skb is smaller than this? */
2363         len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN - ETH_HLEN);
2364
2365         eh = (struct ethhdr *)skb->data;
2366
2367         memset(&desc, 0, sizeof(desc));
2368         desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX);
2369         err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), txfid, 0);
2370         if (err) {
2371                 printk(KERN_ERR "%s: Error %d writing Tx descriptor to BAP\n",
2372                        dev->name, err);
2373                 stats->tx_errors++;
2374                 goto fail;
2375         }
2376
2377         /* Clear the 802.11 header and data length fields - some
2378          * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
2379          * if this isn't done. */
2380         hermes_clear_words(hw, HERMES_DATA0,
2381                            HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
2382
2383         /* Encapsulate Ethernet-II frames */
2384         if (ntohs(eh->h_proto) > 1500) { /* Ethernet-II frame */
2385                 struct header_struct hdr;
2386                 data_len = len;
2387                 data_off = HERMES_802_3_OFFSET + sizeof(hdr);
2388                 p = skb->data + ETH_HLEN;
2389
2390                 /* 802.3 header */
2391                 memcpy(hdr.dest, eh->h_dest, ETH_ALEN);
2392                 memcpy(hdr.src, eh->h_source, ETH_ALEN);
2393                 hdr.len = htons(data_len + ENCAPS_OVERHEAD);
2394                 
2395                 /* 802.2 header */
2396                 memcpy(&hdr.dsap, &encaps_hdr, sizeof(encaps_hdr));
2397                         
2398                 hdr.ethertype = eh->h_proto;
2399                 err  = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
2400                                          txfid, HERMES_802_3_OFFSET);
2401                 if (err) {
2402                         printk(KERN_ERR "%s: Error %d writing packet header to BAP\n",
2403                                dev->name, err);
2404                         stats->tx_errors++;
2405                         goto fail;
2406                 }
2407         } else { /* IEEE 802.3 frame */
2408                 data_len = len + ETH_HLEN;
2409                 data_off = HERMES_802_3_OFFSET;
2410                 p = skb->data;
2411         }
2412
2413         /* Round up for odd length packets */
2414         err = hermes_bap_pwrite(hw, USER_BAP, p, RUP_EVEN(data_len), txfid, data_off);
2415         if (err) {
2416                 printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
2417                        dev->name, err);
2418                 stats->tx_errors++;
2419                 goto fail;
2420         }
2421
2422         /* Finally, we actually initiate the send */
2423         netif_stop_queue(dev);
2424
2425         err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, txfid, NULL);
2426         if (err) {
2427                 netif_start_queue(dev);
2428                 printk(KERN_ERR "%s: Error %d transmitting packet\n", dev->name, err);
2429                 stats->tx_errors++;
2430                 goto fail;
2431         }
2432
2433         dev->trans_start = jiffies;
2434         stats->tx_bytes += data_off + data_len;
2435
2436         orinoco_unlock(priv, &flags);
2437
2438         dev_kfree_skb(skb);
2439
2440         TRACE_EXIT(dev->name);
2441
2442         return 0;
2443  fail:
2444         TRACE_EXIT(dev->name);
2445
2446         orinoco_unlock(priv, &flags);
2447         return err;
2448 }
2449
2450 static void
2451 orinoco_tx_timeout(struct net_device *dev)
2452 {
2453         struct orinoco_private *priv = netdev_priv(dev);
2454         struct net_device_stats *stats = &priv->stats;
2455         struct hermes *hw = &priv->hw;
2456
2457         printk(KERN_WARNING "%s: Tx timeout! "
2458                "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
2459                dev->name, hermes_read_regn(hw, ALLOCFID),
2460                hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
2461
2462         stats->tx_errors++;
2463
2464         schedule_work(&priv->reset_work);
2465 }
2466
2467 static int
2468 orinoco_change_mtu(struct net_device *dev, int new_mtu)
2469 {
2470         struct orinoco_private *priv = netdev_priv(dev);
2471
2472         if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
2473                 return -EINVAL;
2474
2475         if ( (new_mtu + ENCAPS_OVERHEAD + IEEE802_11_HLEN) >
2476              (priv->nicbuf_size - ETH_HLEN) )
2477                 return -EINVAL;
2478
2479         dev->mtu = new_mtu;
2480
2481         return 0;
2482 }
2483
2484 /* FIXME: return int? */
2485 static void
2486 __orinoco_set_multicast_list(struct net_device *dev)
2487 {
2488         struct orinoco_private *priv = netdev_priv(dev);
2489         hermes_t *hw = &priv->hw;
2490         int err = 0;
2491         int promisc, mc_count;
2492
2493         /* The Hermes doesn't seem to have an allmulti mode, so we go
2494          * into promiscuous mode and let the upper levels deal. */
2495         if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
2496              (dev->mc_count > MAX_MULTICAST(priv)) ) {
2497                 promisc = 1;
2498                 mc_count = 0;
2499         } else {
2500                 promisc = 0;
2501                 mc_count = dev->mc_count;
2502         }
2503
2504         if (promisc != priv->promiscuous) {
2505                 err = hermes_write_wordrec(hw, USER_BAP,
2506                                            HERMES_RID_CNFPROMISCUOUSMODE,
2507                                            promisc);
2508                 if (err) {
2509                         printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
2510                                dev->name, err);
2511                 } else 
2512                         priv->promiscuous = promisc;
2513         }
2514
2515         if (! promisc && (mc_count || priv->mc_count) ) {
2516                 struct dev_mc_list *p = dev->mc_list;
2517                 hermes_multicast_t mclist;
2518                 int i;
2519
2520                 for (i = 0; i < mc_count; i++) {
2521                         /* Paranoia: */
2522                         if (! p)
2523                                 BUG(); /* Multicast list shorter than mc_count */
2524                         if (p->dmi_addrlen != ETH_ALEN)
2525                                 BUG(); /* Bad address size in multicast list */
2526                         
2527                         memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
2528                         p = p->next;
2529                 }
2530                 
2531                 if (p)
2532                         printk(KERN_WARNING "Multicast list is longer than mc_count\n");
2533
2534                 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES,
2535                                        HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
2536                                        &mclist);
2537                 if (err)
2538                         printk(KERN_ERR "%s: Error %d setting multicast list.\n",
2539                                dev->name, err);
2540                 else
2541                         priv->mc_count = mc_count;
2542         }
2543
2544         /* Since we can set the promiscuous flag when it wasn't asked
2545            for, make sure the net_device knows about it. */
2546         if (priv->promiscuous)
2547                 dev->flags |= IFF_PROMISC;
2548         else
2549                 dev->flags &= ~IFF_PROMISC;
2550 }
2551
2552 /********************************************************************/
2553 /* Wireless extensions support                                      */
2554 /********************************************************************/
2555
2556 static int orinoco_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq)
2557 {
2558         struct orinoco_private *priv = netdev_priv(dev);
2559         int err = 0;
2560         int mode;
2561         struct iw_range range;
2562         int numrates;
2563         int i, k;
2564         unsigned long flags;
2565
2566         TRACE_ENTER(dev->name);
2567
2568         err = verify_area(VERIFY_WRITE, rrq->pointer, sizeof(range));
2569         if (err)
2570                 return err;
2571
2572         rrq->length = sizeof(range);
2573
2574         err = orinoco_lock(priv, &flags);
2575         if (err)
2576                 return err;
2577
2578         mode = priv->iw_mode;
2579         orinoco_unlock(priv, &flags);
2580
2581         memset(&range, 0, sizeof(range));
2582
2583         /* Much of this shamelessly taken from wvlan_cs.c. No idea
2584          * what it all means -dgibson */
2585 #if WIRELESS_EXT > 10
2586         range.we_version_compiled = WIRELESS_EXT;
2587         range.we_version_source = 11;
2588 #endif /* WIRELESS_EXT > 10 */
2589
2590         range.min_nwid = range.max_nwid = 0; /* We don't use nwids */
2591
2592         /* Set available channels/frequencies */
2593         range.num_channels = NUM_CHANNELS;
2594         k = 0;
2595         for (i = 0; i < NUM_CHANNELS; i++) {
2596                 if (priv->channel_mask & (1 << i)) {
2597                         range.freq[k].i = i + 1;
2598                         range.freq[k].m = channel_frequency[i] * 100000;
2599                         range.freq[k].e = 1;
2600                         k++;
2601                 }
2602                 
2603                 if (k >= IW_MAX_FREQUENCIES)
2604                         break;
2605         }
2606         range.num_frequency = k;
2607
2608         range.sensitivity = 3;
2609
2610         if ((mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
2611                 /* Quality stats meaningless in ad-hoc mode */
2612                 range.max_qual.qual = 0;
2613                 range.max_qual.level = 0;
2614                 range.max_qual.noise = 0;
2615 #if WIRELESS_EXT > 11
2616                 range.avg_qual.qual = 0;
2617                 range.avg_qual.level = 0;
2618                 range.avg_qual.noise = 0;
2619 #endif /* WIRELESS_EXT > 11 */
2620
2621         } else {
2622                 range.max_qual.qual = 0x8b - 0x2f;
2623                 range.max_qual.level = 0x2f - 0x95 - 1;
2624                 range.max_qual.noise = 0x2f - 0x95 - 1;
2625 #if WIRELESS_EXT > 11
2626                 /* Need to get better values */
2627                 range.avg_qual.qual = 0x24;
2628                 range.avg_qual.level = 0xC2;
2629                 range.avg_qual.noise = 0x9E;
2630 #endif /* WIRELESS_EXT > 11 */
2631         }
2632
2633         err = orinoco_hw_get_bitratelist(priv, &numrates,
2634                                          range.bitrate, IW_MAX_BITRATES);
2635         if (err)
2636                 return err;
2637         range.num_bitrates = numrates;
2638         
2639         /* Set an indication of the max TCP throughput in bit/s that we can
2640          * expect using this interface. May be use for QoS stuff...
2641          * Jean II */
2642         if(numrates > 2)
2643                 range.throughput = 5 * 1000 * 1000;     /* ~5 Mb/s */
2644         else
2645                 range.throughput = 1.5 * 1000 * 1000;   /* ~1.5 Mb/s */
2646
2647         range.min_rts = 0;
2648         range.max_rts = 2347;
2649         range.min_frag = 256;
2650         range.max_frag = 2346;
2651
2652         err = orinoco_lock(priv, &flags);
2653         if (err)
2654                 return err;
2655         if (priv->has_wep) {
2656                 range.max_encoding_tokens = ORINOCO_MAX_KEYS;
2657
2658                 range.encoding_size[0] = SMALL_KEY_SIZE;
2659                 range.num_encoding_sizes = 1;
2660
2661                 if (priv->has_big_wep) {
2662                         range.encoding_size[1] = LARGE_KEY_SIZE;
2663                         range.num_encoding_sizes = 2;
2664                 }
2665         } else {
2666                 range.num_encoding_sizes = 0;
2667                 range.max_encoding_tokens = 0;
2668         }
2669         orinoco_unlock(priv, &flags);
2670                 
2671         range.min_pmp = 0;
2672         range.max_pmp = 65535000;
2673         range.min_pmt = 0;
2674         range.max_pmt = 65535 * 1000;   /* ??? */
2675         range.pmp_flags = IW_POWER_PERIOD;
2676         range.pmt_flags = IW_POWER_TIMEOUT;
2677         range.pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
2678
2679         range.num_txpower = 1;
2680         range.txpower[0] = 15; /* 15dBm */
2681         range.txpower_capa = IW_TXPOW_DBM;
2682
2683 #if WIRELESS_EXT > 10
2684         range.retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
2685         range.retry_flags = IW_RETRY_LIMIT;
2686         range.r_time_flags = IW_RETRY_LIFETIME;
2687         range.min_retry = 0;
2688         range.max_retry = 65535;        /* ??? */
2689         range.min_r_time = 0;
2690         range.max_r_time = 65535 * 1000;        /* ??? */
2691 #endif /* WIRELESS_EXT > 10 */
2692
2693         if (copy_to_user(rrq->pointer, &range, sizeof(range)))
2694                 return -EFAULT;
2695
2696         TRACE_EXIT(dev->name);
2697
2698         return 0;
2699 }
2700
2701 static int orinoco_ioctl_setiwencode(struct net_device *dev, struct iw_point *erq)
2702 {
2703         struct orinoco_private *priv = netdev_priv(dev);
2704         int index = (erq->flags & IW_ENCODE_INDEX) - 1;
2705         int setindex = priv->tx_key;
2706         int enable = priv->wep_on;
2707         int restricted = priv->wep_restrict;
2708         u16 xlen = 0;
2709         int err = 0;
2710         char keybuf[ORINOCO_MAX_KEY_SIZE];
2711         unsigned long flags;
2712         
2713         if (erq->pointer) {
2714                 /* We actually have a key to set */
2715                 if ( (erq->length < SMALL_KEY_SIZE) || (erq->length > ORINOCO_MAX_KEY_SIZE) )
2716                         return -EINVAL;
2717                 
2718                 if (copy_from_user(keybuf, erq->pointer, erq->length))
2719                         return -EFAULT;
2720         }
2721         
2722         err = orinoco_lock(priv, &flags);
2723         if (err)
2724                 return err;
2725         
2726         if (erq->pointer) {
2727                 if (erq->length > ORINOCO_MAX_KEY_SIZE) {
2728                         err = -E2BIG;
2729                         goto out;
2730                 }
2731                 
2732                 if ( (erq->length > LARGE_KEY_SIZE)
2733                      || ( ! priv->has_big_wep && (erq->length > SMALL_KEY_SIZE))  ) {
2734                         err = -EINVAL;
2735                         goto out;
2736                 }
2737                 
2738                 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
2739                         index = priv->tx_key;
2740                 
2741                 if (erq->length > SMALL_KEY_SIZE) {
2742                         xlen = LARGE_KEY_SIZE;
2743                 } else if (erq->length > 0) {
2744                         xlen = SMALL_KEY_SIZE;
2745                 } else
2746                         xlen = 0;
2747                 
2748                 /* Switch on WEP if off */
2749                 if ((!enable) && (xlen > 0)) {
2750                         setindex = index;
2751                         enable = 1;
2752                 }
2753         } else {
2754                 /* Important note : if the user do "iwconfig eth0 enc off",
2755                  * we will arrive there with an index of -1. This is valid
2756                  * but need to be taken care off... Jean II */
2757                 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
2758                         if((index != -1) || (erq->flags == 0)) {
2759                                 err = -EINVAL;
2760                                 goto out;
2761                         }
2762                 } else {
2763                         /* Set the index : Check that the key is valid */
2764                         if(priv->keys[index].len == 0) {
2765                                 err = -EINVAL;
2766                                 goto out;
2767                         }
2768                         setindex = index;
2769                 }
2770         }
2771         
2772         if (erq->flags & IW_ENCODE_DISABLED)
2773                 enable = 0;
2774         /* Only for Prism2 & Symbol cards (so far) - Jean II */
2775         if (erq->flags & IW_ENCODE_OPEN)
2776                 restricted = 0;
2777         if (erq->flags & IW_ENCODE_RESTRICTED)
2778                 restricted = 1;
2779
2780         if (erq->pointer) {
2781                 priv->keys[index].len = cpu_to_le16(xlen);
2782                 memset(priv->keys[index].data, 0, sizeof(priv->keys[index].data));
2783                 memcpy(priv->keys[index].data, keybuf, erq->length);
2784         }
2785         priv->tx_key = setindex;
2786         priv->wep_on = enable;
2787         priv->wep_restrict = restricted;
2788
2789         
2790  out:
2791         orinoco_unlock(priv, &flags);
2792
2793         return err;
2794 }
2795
2796 static int orinoco_ioctl_getiwencode(struct net_device *dev, struct iw_point *erq)
2797 {
2798         struct orinoco_private *priv = netdev_priv(dev);
2799         int index = (erq->flags & IW_ENCODE_INDEX) - 1;
2800         u16 xlen = 0;
2801         char keybuf[ORINOCO_MAX_KEY_SIZE];
2802         int err;
2803         unsigned long flags;
2804         
2805         err = orinoco_lock(priv, &flags);
2806         if (err)
2807                 return err;
2808
2809         if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
2810                 index = priv->tx_key;
2811
2812         erq->flags = 0;
2813         if (! priv->wep_on)
2814                 erq->flags |= IW_ENCODE_DISABLED;
2815         erq->flags |= index + 1;
2816         
2817         /* Only for symbol cards - Jean II */
2818         if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
2819                 if(priv->wep_restrict)
2820                         erq->flags |= IW_ENCODE_RESTRICTED;
2821                 else
2822                         erq->flags |= IW_ENCODE_OPEN;
2823         }
2824
2825         xlen = le16_to_cpu(priv->keys[index].len);
2826
2827         erq->length = xlen;
2828
2829         if (erq->pointer) {
2830                 memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
2831         }
2832         
2833         orinoco_unlock(priv, &flags);
2834
2835         if (erq->pointer) {
2836                 if (copy_to_user(erq->pointer, keybuf, xlen))
2837                         return -EFAULT;
2838         }
2839
2840         return 0;
2841 }
2842
2843 static int orinoco_ioctl_setessid(struct net_device *dev, struct iw_point *erq)
2844 {
2845         struct orinoco_private *priv = netdev_priv(dev);
2846         char essidbuf[IW_ESSID_MAX_SIZE+1];
2847         int err;
2848         unsigned long flags;
2849
2850         /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
2851          * anyway... - Jean II */
2852
2853         memset(&essidbuf, 0, sizeof(essidbuf));
2854
2855         if (erq->flags) {
2856                 if (erq->length > IW_ESSID_MAX_SIZE)
2857                         return -E2BIG;
2858                 
2859                 if (copy_from_user(&essidbuf, erq->pointer, erq->length))
2860                         return -EFAULT;
2861
2862                 essidbuf[erq->length] = '\0';
2863         }
2864
2865         err = orinoco_lock(priv, &flags);
2866         if (err)
2867                 return err;
2868
2869         memcpy(priv->desired_essid, essidbuf, sizeof(priv->desired_essid));
2870
2871         orinoco_unlock(priv, &flags);
2872
2873         return 0;
2874 }
2875
2876 static int orinoco_ioctl_getessid(struct net_device *dev, struct iw_point *erq)
2877 {
2878         struct orinoco_private *priv = netdev_priv(dev);
2879         char essidbuf[IW_ESSID_MAX_SIZE+1];
2880         int active;
2881         int err = 0;
2882         unsigned long flags;
2883
2884         TRACE_ENTER(dev->name);
2885
2886         if (netif_running(dev)) {
2887                 err = orinoco_hw_get_essid(priv, &active, essidbuf);
2888                 if (err)
2889                         return err;
2890         } else {
2891                 err = orinoco_lock(priv, &flags);
2892                 if (err)
2893                         return err;
2894                 memcpy(essidbuf, priv->desired_essid, sizeof(essidbuf));
2895                 orinoco_unlock(priv, &flags);
2896         }
2897
2898         erq->flags = 1;
2899         erq->length = strlen(essidbuf) + 1;
2900         if (erq->pointer)
2901                 if (copy_to_user(erq->pointer, essidbuf, erq->length))
2902                         return -EFAULT;
2903
2904         TRACE_EXIT(dev->name);
2905         
2906         return 0;
2907 }
2908
2909 static int orinoco_ioctl_setnick(struct net_device *dev, struct iw_point *nrq)
2910 {
2911         struct orinoco_private *priv = netdev_priv(dev);
2912         char nickbuf[IW_ESSID_MAX_SIZE+1];
2913         int err;
2914         unsigned long flags;
2915
2916         if (nrq->length > IW_ESSID_MAX_SIZE)
2917                 return -E2BIG;
2918
2919         memset(nickbuf, 0, sizeof(nickbuf));
2920
2921         if (copy_from_user(nickbuf, nrq->pointer, nrq->length))
2922                 return -EFAULT;
2923
2924         nickbuf[nrq->length] = '\0';
2925         
2926         err = orinoco_lock(priv, &flags);
2927         if (err)
2928                 return err;
2929
2930         memcpy(priv->nick, nickbuf, sizeof(priv->nick));
2931
2932         orinoco_unlock(priv, &flags);
2933
2934         return 0;
2935 }
2936
2937 static int orinoco_ioctl_getnick(struct net_device *dev, struct iw_point *nrq)
2938 {
2939         struct orinoco_private *priv = netdev_priv(dev);
2940         char nickbuf[IW_ESSID_MAX_SIZE+1];
2941         int err;
2942         unsigned long flags;
2943
2944         err = orinoco_lock(priv, &flags);
2945         if (err)
2946                 return err;
2947
2948         memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
2949         orinoco_unlock(priv, &flags);
2950
2951         nrq->length = strlen(nickbuf)+1;
2952
2953         if (copy_to_user(nrq->pointer, nickbuf, sizeof(nickbuf)))
2954                 return -EFAULT;
2955
2956         return 0;
2957 }
2958
2959 static int orinoco_ioctl_setfreq(struct net_device *dev, struct iw_freq *frq)
2960 {
2961         struct orinoco_private *priv = netdev_priv(dev);
2962         int chan = -1;
2963         int err;
2964         unsigned long flags;
2965
2966         /* We can only use this in Ad-Hoc demo mode to set the operating
2967          * frequency, or in IBSS mode to set the frequency where the IBSS
2968          * will be created - Jean II */
2969         if (priv->iw_mode != IW_MODE_ADHOC)
2970                 return -EOPNOTSUPP;
2971
2972         if ( (frq->e == 0) && (frq->m <= 1000) ) {
2973                 /* Setting by channel number */
2974                 chan = frq->m;
2975         } else {
2976                 /* Setting by frequency - search the table */
2977                 int mult = 1;
2978                 int i;
2979
2980                 for (i = 0; i < (6 - frq->e); i++)
2981                         mult *= 10;
2982
2983                 for (i = 0; i < NUM_CHANNELS; i++)
2984                         if (frq->m == (channel_frequency[i] * mult))
2985                                 chan = i+1;
2986         }
2987
2988         if ( (chan < 1) || (chan > NUM_CHANNELS) ||
2989              ! (priv->channel_mask & (1 << (chan-1)) ) )
2990                 return -EINVAL;
2991
2992         err = orinoco_lock(priv, &flags);
2993         if (err)
2994                 return err;
2995         priv->channel = chan;
2996         orinoco_unlock(priv, &flags);
2997
2998         return 0;
2999 }
3000
3001 static int orinoco_ioctl_getsens(struct net_device *dev, struct iw_param *srq)
3002 {
3003         struct orinoco_private *priv = netdev_priv(dev);
3004         hermes_t *hw = &priv->hw;
3005         u16 val;
3006         int err;
3007         unsigned long flags;
3008
3009         if (!priv->has_sensitivity)
3010                 return -EOPNOTSUPP;
3011
3012         err = orinoco_lock(priv, &flags);
3013         if (err)
3014                 return err;
3015         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE, &val);
3016         orinoco_unlock(priv, &flags);
3017
3018         if (err)
3019                 return err;
3020
3021         srq->value = val;
3022         srq->fixed = 0; /* auto */
3023
3024         return 0;
3025 }
3026
3027 static int orinoco_ioctl_setsens(struct net_device *dev, struct iw_param *srq)
3028 {
3029         struct orinoco_private *priv = netdev_priv(dev);
3030         int val = srq->value;
3031         int err;
3032         unsigned long flags;
3033
3034         if (!priv->has_sensitivity)
3035                 return -EOPNOTSUPP;
3036
3037         if ((val < 1) || (val > 3))
3038                 return -EINVAL;
3039         
3040         err = orinoco_lock(priv, &flags);
3041         if (err)
3042                 return err;
3043         priv->ap_density = val;
3044         orinoco_unlock(priv, &flags);
3045
3046         return 0;
3047 }
3048
3049 static int orinoco_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
3050 {
3051         struct orinoco_private *priv = netdev_priv(dev);
3052         int val = rrq->value;
3053         int err;
3054         unsigned long flags;
3055
3056         if (rrq->disabled)
3057                 val = 2347;
3058
3059         if ( (val < 0) || (val > 2347) )
3060                 return -EINVAL;
3061
3062         err = orinoco_lock(priv, &flags);
3063         if (err)
3064                 return err;
3065
3066         priv->rts_thresh = val;
3067         orinoco_unlock(priv, &flags);
3068
3069         return 0;
3070 }
3071
3072 static int orinoco_ioctl_setfrag(struct net_device *dev, struct iw_param *frq)
3073 {
3074         struct orinoco_private *priv = netdev_priv(dev);
3075         int err = 0;
3076         unsigned long flags;
3077
3078         err = orinoco_lock(priv, &flags);
3079         if (err)
3080                 return err;
3081
3082         if (priv->has_mwo) {
3083                 if (frq->disabled)
3084                         priv->mwo_robust = 0;
3085                 else {
3086                         if (frq->fixed)
3087                                 printk(KERN_WARNING "%s: Fixed fragmentation not \
3088 supported on this firmware. Using MWO robust instead.\n", dev->name);
3089                         priv->mwo_robust = 1;
3090                 }
3091         } else {
3092                 if (frq->disabled)
3093                         priv->frag_thresh = 2346;
3094                 else {
3095                         if ( (frq->value < 256) || (frq->value > 2346) )
3096                                 err = -EINVAL;
3097                         else
3098                                 priv->frag_thresh = frq->value & ~0x1; /* must be even */
3099                 }
3100         }
3101
3102         orinoco_unlock(priv, &flags);
3103
3104         return err;
3105 }
3106
3107 static int orinoco_ioctl_getfrag(struct net_device *dev, struct iw_param *frq)
3108 {
3109         struct orinoco_private *priv = netdev_priv(dev);
3110         hermes_t *hw = &priv->hw;
3111         int err = 0;
3112         u16 val;
3113         unsigned long flags;
3114
3115         err = orinoco_lock(priv, &flags);
3116         if (err)
3117                 return err;
3118         
3119         if (priv->has_mwo) {
3120                 err = hermes_read_wordrec(hw, USER_BAP,
3121                                           HERMES_RID_CNFMWOROBUST_AGERE,
3122                                           &val);
3123                 if (err)
3124                         val = 0;
3125
3126                 frq->value = val ? 2347 : 0;
3127                 frq->disabled = ! val;
3128                 frq->fixed = 0;
3129         } else {
3130                 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
3131                                           &val);
3132                 if (err)
3133                         val = 0;
3134
3135                 frq->value = val;
3136                 frq->disabled = (val >= 2346);
3137                 frq->fixed = 1;
3138         }
3139
3140         orinoco_unlock(priv, &flags);
3141         
3142         return err;
3143 }
3144
3145 static int orinoco_ioctl_setrate(struct net_device *dev, struct iw_param *rrq)
3146 {
3147         struct orinoco_private *priv = netdev_priv(dev);
3148         int err = 0;
3149         int ratemode = -1;
3150         int bitrate; /* 100s of kilobits */
3151         int i;
3152         unsigned long flags;
3153         
3154         /* As the user space doesn't know our highest rate, it uses -1
3155          * to ask us to set the highest rate.  Test it using "iwconfig
3156          * ethX rate auto" - Jean II */
3157         if (rrq->value == -1)
3158                 bitrate = 110;
3159         else {
3160                 if (rrq->value % 100000)
3161                         return -EINVAL;
3162                 bitrate = rrq->value / 100000;
3163         }
3164
3165         if ( (bitrate != 10) && (bitrate != 20) &&
3166              (bitrate != 55) && (bitrate != 110) )
3167                 return -EINVAL;
3168
3169         for (i = 0; i < BITRATE_TABLE_SIZE; i++)
3170                 if ( (bitrate_table[i].bitrate == bitrate) &&
3171                      (bitrate_table[i].automatic == ! rrq->fixed) ) {
3172                         ratemode = i;
3173                         break;
3174                 }
3175         
3176         if (ratemode == -1)
3177                 return -EINVAL;
3178
3179         err = orinoco_lock(priv, &flags);
3180         if (err)
3181                 return err;
3182         priv->bitratemode = ratemode;
3183         orinoco_unlock(priv, &flags);
3184
3185         return err;
3186 }
3187
3188 static int orinoco_ioctl_getrate(struct net_device *dev, struct iw_param *rrq)
3189 {
3190         struct orinoco_private *priv = netdev_priv(dev);
3191         hermes_t *hw = &priv->hw;
3192         int err = 0;
3193         int ratemode;
3194         int i;
3195         u16 val;
3196         unsigned long flags;
3197
3198         err = orinoco_lock(priv, &flags);
3199         if (err)
3200                 return err;
3201
3202         ratemode = priv->bitratemode;
3203
3204         if ( (ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE) )
3205                 BUG();
3206
3207         rrq->value = bitrate_table[ratemode].bitrate * 100000;
3208         rrq->fixed = ! bitrate_table[ratemode].automatic;
3209         rrq->disabled = 0;
3210
3211         /* If the interface is running we try to find more about the
3212            current mode */
3213         if (netif_running(dev)) {
3214                 err = hermes_read_wordrec(hw, USER_BAP,
3215                                           HERMES_RID_CURRENTTXRATE, &val);
3216                 if (err)
3217                         goto out;
3218                 
3219                 switch (priv->firmware_type) {
3220                 case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
3221                         /* Note : in Lucent firmware, the return value of
3222                          * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
3223                          * and therefore is totally different from the
3224                          * encoding of HERMES_RID_CNFTXRATECONTROL.
3225                          * Don't forget that 6Mb/s is really 5.5Mb/s */
3226                         if (val == 6)
3227                                 rrq->value = 5500000;
3228                         else
3229                                 rrq->value = val * 1000000;
3230                         break;
3231                 case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
3232                 case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
3233                         for (i = 0; i < BITRATE_TABLE_SIZE; i++)
3234                                 if (bitrate_table[i].intersil_txratectrl == val) {
3235                                         ratemode = i;
3236                                         break;
3237                                 }
3238                         if (i >= BITRATE_TABLE_SIZE)
3239                                 printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
3240                                        dev->name, val);
3241
3242                         rrq->value = bitrate_table[ratemode].bitrate * 100000;
3243                         break;
3244                 default:
3245                         BUG();
3246                 }
3247         }
3248
3249  out:
3250         orinoco_unlock(priv, &flags);
3251
3252         return err;
3253 }
3254
3255 static int orinoco_ioctl_setpower(struct net_device *dev, struct iw_param *prq)
3256 {
3257         struct orinoco_private *priv = netdev_priv(dev);
3258         int err = 0;
3259         unsigned long flags;
3260
3261         err = orinoco_lock(priv, &flags);
3262         if (err)
3263                 return err;
3264
3265         if (prq->disabled) {
3266                 priv->pm_on = 0;
3267         } else {
3268                 switch (prq->flags & IW_POWER_MODE) {
3269                 case IW_POWER_UNICAST_R:
3270                         priv->pm_mcast = 0;
3271                         priv->pm_on = 1;
3272                         break;
3273                 case IW_POWER_ALL_R:
3274                         priv->pm_mcast = 1;
3275                         priv->pm_on = 1;
3276                         break;
3277                 case IW_POWER_ON:
3278                         /* No flags : but we may have a value - Jean II */
3279                         break;
3280                 default:
3281                         err = -EINVAL;
3282                 }
3283                 if (err)
3284                         goto out;
3285                 
3286                 if (prq->flags & IW_POWER_TIMEOUT) {
3287                         priv->pm_on = 1;
3288                         priv->pm_timeout = prq->value / 1000;
3289                 }
3290                 if (prq->flags & IW_POWER_PERIOD) {
3291                         priv->pm_on = 1;
3292                         priv->pm_period = prq->value / 1000;
3293                 }
3294                 /* It's valid to not have a value if we are just toggling
3295                  * the flags... Jean II */
3296                 if(!priv->pm_on) {
3297                         err = -EINVAL;
3298                         goto out;
3299                 }                       
3300         }
3301
3302  out:
3303         orinoco_unlock(priv, &flags);
3304
3305         return err;
3306 }
3307
3308 static int orinoco_ioctl_getpower(struct net_device *dev, struct iw_param *prq)
3309 {
3310         struct orinoco_private *priv = netdev_priv(dev);
3311         hermes_t *hw = &priv->hw;
3312         int err = 0;
3313         u16 enable, period, timeout, mcast;
3314         unsigned long flags;
3315
3316         err = orinoco_lock(priv, &flags);
3317         if (err)
3318                 return err;
3319         
3320         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
3321         if (err)
3322                 goto out;
3323
3324         err = hermes_read_wordrec(hw, USER_BAP,
3325                                   HERMES_RID_CNFMAXSLEEPDURATION, &period);
3326         if (err)
3327                 goto out;
3328
3329         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
3330         if (err)
3331                 goto out;
3332
3333         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
3334         if (err)
3335                 goto out;
3336
3337         prq->disabled = !enable;
3338         /* Note : by default, display the period */
3339         if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
3340                 prq->flags = IW_POWER_TIMEOUT;
3341                 prq->value = timeout * 1000;
3342         } else {
3343                 prq->flags = IW_POWER_PERIOD;
3344                 prq->value = period * 1000;
3345         }
3346         if (mcast)
3347                 prq->flags |= IW_POWER_ALL_R;
3348         else
3349                 prq->flags |= IW_POWER_UNICAST_R;
3350
3351  out:
3352         orinoco_unlock(priv, &flags);
3353
3354         return err;
3355 }
3356
3357 #if WIRELESS_EXT > 10
3358 static int orinoco_ioctl_getretry(struct net_device *dev, struct iw_param *rrq)
3359 {
3360         struct orinoco_private *priv = netdev_priv(dev);
3361         hermes_t *hw = &priv->hw;
3362         int err = 0;
3363         u16 short_limit, long_limit, lifetime;
3364         unsigned long flags;
3365
3366         err = orinoco_lock(priv, &flags);
3367         if (err)
3368                 return err;
3369         
3370         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
3371                                   &short_limit);
3372         if (err)
3373                 goto out;
3374
3375         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
3376                                   &long_limit);
3377         if (err)
3378                 goto out;
3379
3380         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
3381                                   &lifetime);
3382         if (err)
3383                 goto out;
3384
3385         rrq->disabled = 0;              /* Can't be disabled */
3386
3387         /* Note : by default, display the retry number */
3388         if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
3389                 rrq->flags = IW_RETRY_LIFETIME;
3390                 rrq->value = lifetime * 1000;   /* ??? */
3391         } else {
3392                 /* By default, display the min number */
3393                 if ((rrq->flags & IW_RETRY_MAX)) {
3394                         rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
3395                         rrq->value = long_limit;
3396                 } else {
3397                         rrq->flags = IW_RETRY_LIMIT;
3398                         rrq->value = short_limit;
3399                         if(short_limit != long_limit)
3400                                 rrq->flags |= IW_RETRY_MIN;
3401                 }
3402         }
3403
3404  out:
3405         orinoco_unlock(priv, &flags);
3406
3407         return err;
3408 }
3409 #endif /* WIRELESS_EXT > 10 */
3410
3411 static int orinoco_ioctl_setibssport(struct net_device *dev, struct iwreq *wrq)
3412 {
3413         struct orinoco_private *priv = netdev_priv(dev);
3414         int val = *( (int *) wrq->u.name );
3415         int err;
3416         unsigned long flags;
3417
3418         err = orinoco_lock(priv, &flags);
3419         if (err)
3420                 return err;
3421
3422         priv->ibss_port = val ;
3423
3424         /* Actually update the mode we are using */
3425         set_port_type(priv);
3426
3427         orinoco_unlock(priv, &flags);
3428         return 0;
3429 }
3430
3431 static int orinoco_ioctl_getibssport(struct net_device *dev, struct iwreq *wrq)
3432 {
3433         struct orinoco_private *priv = netdev_priv(dev);
3434         int *val = (int *)wrq->u.name;
3435         int err;
3436         unsigned long flags;
3437
3438         err = orinoco_lock(priv, &flags);
3439         if (err)
3440                 return err;
3441
3442         *val = priv->ibss_port;
3443         orinoco_unlock(priv, &flags);
3444
3445         return 0;
3446 }
3447
3448 static int orinoco_ioctl_setport3(struct net_device *dev, struct iwreq *wrq)
3449 {
3450         struct orinoco_private *priv = netdev_priv(dev);
3451         int val = *( (int *) wrq->u.name );
3452         int err = 0;
3453         unsigned long flags;
3454
3455         err = orinoco_lock(priv, &flags);
3456         if (err)
3457                 return err;
3458
3459         switch (val) {
3460         case 0: /* Try to do IEEE ad-hoc mode */
3461                 if (! priv->has_ibss) {
3462                         err = -EINVAL;
3463                         break;
3464                 }
3465                 priv->prefer_port3 = 0;
3466                         
3467                 break;
3468
3469         case 1: /* Try to do Lucent proprietary ad-hoc mode */
3470                 if (! priv->has_port3) {
3471                         err = -EINVAL;
3472                         break;
3473                 }
3474                 priv->prefer_port3 = 1;
3475                 break;
3476
3477         default:
3478                 err = -EINVAL;
3479         }
3480
3481         if (! err)
3482                 /* Actually update the mode we are using */
3483                 set_port_type(priv);
3484
3485         orinoco_unlock(priv, &flags);
3486
3487         return err;
3488 }
3489
3490 static int orinoco_ioctl_getport3(struct net_device *dev, struct iwreq *wrq)
3491 {
3492         struct orinoco_private *priv = netdev_priv(dev);
3493         int *val = (int *)wrq->u.name;
3494         int err;
3495         unsigned long flags;
3496
3497         err = orinoco_lock(priv, &flags);
3498         if (err)
3499                 return err;
3500
3501         *val = priv->prefer_port3;
3502         orinoco_unlock(priv, &flags);
3503
3504         return 0;
3505 }
3506
3507 /* Spy is used for link quality/strength measurements in Ad-Hoc mode
3508  * Jean II */
3509 static int orinoco_ioctl_setspy(struct net_device *dev, struct iw_point *srq)
3510 {
3511         struct orinoco_private *priv = netdev_priv(dev);
3512         struct sockaddr address[IW_MAX_SPY];
3513         int number = srq->length;
3514         int i;
3515         int err = 0;
3516         unsigned long flags;
3517
3518         /* Check the number of addresses */
3519         if (number > IW_MAX_SPY)
3520                 return -E2BIG;
3521
3522         /* Get the data in the driver */
3523         if (srq->pointer) {
3524                 if (copy_from_user(address, srq->pointer,
3525                                    sizeof(struct sockaddr) * number))
3526                         return -EFAULT;
3527         }
3528
3529         /* Make sure nobody mess with the structure while we do */
3530         err = orinoco_lock(priv, &flags);
3531         if (err)
3532                 return err;
3533
3534         /* orinoco_lock() doesn't disable interrupts, so make sure the
3535          * interrupt rx path don't get confused while we copy */
3536         priv->spy_number = 0;
3537
3538         if (number > 0) {
3539                 /* Extract the addresses */
3540                 for (i = 0; i < number; i++)
3541                         memcpy(priv->spy_address[i], address[i].sa_data,
3542                                ETH_ALEN);
3543                 /* Reset stats */
3544                 memset(priv->spy_stat, 0,
3545                        sizeof(struct iw_quality) * IW_MAX_SPY);
3546                 /* Set number of addresses */
3547                 priv->spy_number = number;
3548         }
3549
3550         /* Now, let the others play */
3551         orinoco_unlock(priv, &flags);
3552
3553         return err;
3554 }
3555
3556 static int orinoco_ioctl_getspy(struct net_device *dev, struct iw_point *srq)
3557 {
3558         struct orinoco_private *priv = netdev_priv(dev);
3559         struct sockaddr address[IW_MAX_SPY];
3560         struct iw_quality spy_stat[IW_MAX_SPY];
3561         int number;
3562         int i;
3563         int err;
3564         unsigned long flags;
3565
3566         err = orinoco_lock(priv, &flags);
3567         if (err)
3568                 return err;
3569
3570         number = priv->spy_number;
3571         if ((number > 0) && (srq->pointer)) {
3572                 /* Create address struct */
3573                 for (i = 0; i < number; i++) {
3574                         memcpy(address[i].sa_data, priv->spy_address[i],
3575                                ETH_ALEN);
3576                         address[i].sa_family = AF_UNIX;
3577                 }
3578                 /* Copy stats */
3579                 /* In theory, we should disable irqs while copying the stats
3580                  * because the rx path migh update it in the middle...
3581                  * Bah, who care ? - Jean II */
3582                 memcpy(&spy_stat, priv->spy_stat,
3583                        sizeof(struct iw_quality) * IW_MAX_SPY);
3584                 for (i=0; i < number; i++)
3585                         priv->spy_stat[i].updated = 0;
3586         }
3587
3588         orinoco_unlock(priv, &flags);
3589
3590         /* Push stuff to user space */
3591         srq->length = number;
3592         if(copy_to_user(srq->pointer, address,
3593                          sizeof(struct sockaddr) * number))
3594                 return -EFAULT;
3595         if(copy_to_user(srq->pointer + (sizeof(struct sockaddr)*number),
3596                         &spy_stat, sizeof(struct iw_quality) * number))
3597                 return -EFAULT;
3598
3599         return 0;
3600 }
3601
3602 static int
3603 orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3604 {
3605         struct orinoco_private *priv = netdev_priv(dev);
3606         struct iwreq *wrq = (struct iwreq *)rq;
3607         int err = 0;
3608         int tmp;
3609         int changed = 0;
3610         unsigned long flags;
3611
3612         TRACE_ENTER(dev->name);
3613
3614         /* In theory, we could allow most of the the SET stuff to be
3615          * done. In practice, the lapse of time at startup when the
3616          * card is not ready is very short, so why bother...  Note
3617          * that netif_device_present is different from up/down
3618          * (ifconfig), when the device is not yet up, it is usually
3619          * already ready...  Jean II */
3620         if (! netif_device_present(dev))
3621                 return -ENODEV;
3622
3623         switch (cmd) {
3624         case SIOCGIWNAME:
3625                 strcpy(wrq->u.name, "IEEE 802.11-DS");
3626                 break;
3627                 
3628         case SIOCGIWAP:
3629                 wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
3630                 err = orinoco_hw_get_bssid(priv, wrq->u.ap_addr.sa_data);
3631                 break;
3632
3633         case SIOCGIWRANGE:
3634                 err = orinoco_ioctl_getiwrange(dev, &wrq->u.data);
3635                 break;
3636
3637         case SIOCSIWMODE:
3638                 err = orinoco_lock(priv, &flags);
3639                 if (err)
3640                         return err;
3641                 switch (wrq->u.mode) {
3642                 case IW_MODE_ADHOC:
3643                         if (! (priv->has_ibss || priv->has_port3) )
3644                                 err = -EINVAL;
3645                         else {
3646                                 priv->iw_mode = IW_MODE_ADHOC;
3647                                 changed = 1;
3648                         }
3649                         break;
3650
3651                 case IW_MODE_INFRA:
3652                         priv->iw_mode = IW_MODE_INFRA;
3653                         changed = 1;
3654                         break;
3655
3656                 default:
3657                         err = -EINVAL;
3658                         break;
3659                 }
3660                 set_port_type(priv);
3661                 orinoco_unlock(priv, &flags);
3662                 break;
3663
3664         case SIOCGIWMODE:
3665                 err = orinoco_lock(priv, &flags);
3666                 if (err)
3667                         return err;
3668                 wrq->u.mode = priv->iw_mode;
3669                 orinoco_unlock(priv, &flags);
3670                 break;
3671
3672         case SIOCSIWENCODE:
3673                 if (! priv->has_wep) {
3674                         err = -EOPNOTSUPP;
3675                         break;
3676                 }
3677
3678                 err = orinoco_ioctl_setiwencode(dev, &wrq->u.encoding);
3679                 if (! err)
3680                         changed = 1;
3681                 break;
3682
3683         case SIOCGIWENCODE:
3684                 if (! priv->has_wep) {
3685                         err = -EOPNOTSUPP;
3686                         break;
3687                 }
3688
3689                 if (! capable(CAP_NET_ADMIN)) {
3690                         err = -EPERM;
3691                         break;
3692                 }
3693
3694                 err = orinoco_ioctl_getiwencode(dev, &wrq->u.encoding);
3695                 break;
3696
3697         case SIOCSIWESSID:
3698                 err = orinoco_ioctl_setessid(dev, &wrq->u.essid);
3699                 if (! err)
3700                         changed = 1;
3701                 break;
3702
3703         case SIOCGIWESSID:
3704                 err = orinoco_ioctl_getessid(dev, &wrq->u.essid);
3705                 break;
3706
3707         case SIOCSIWNICKN:
3708                 err = orinoco_ioctl_setnick(dev, &wrq->u.data);
3709                 if (! err)
3710                         changed = 1;
3711                 break;
3712
3713         case SIOCGIWNICKN:
3714                 err = orinoco_ioctl_getnick(dev, &wrq->u.data);
3715                 break;
3716
3717         case SIOCGIWFREQ:
3718                 tmp = orinoco_hw_get_freq(priv);
3719                 if (tmp < 0) {
3720                         err = tmp;
3721                 } else {
3722                         wrq->u.freq.m = tmp;
3723                         wrq->u.freq.e = 1;
3724                 }
3725                 break;
3726
3727         case SIOCSIWFREQ:
3728                 err = orinoco_ioctl_setfreq(dev, &wrq->u.freq);
3729                 if (! err)
3730                         changed = 1;
3731                 break;
3732
3733         case SIOCGIWSENS:
3734                 err = orinoco_ioctl_getsens(dev, &wrq->u.sens);
3735                 break;
3736
3737         case SIOCSIWSENS:
3738                 err = orinoco_ioctl_setsens(dev, &wrq->u.sens);
3739                 if (! err)
3740                         changed = 1;
3741                 break;
3742
3743         case SIOCGIWRTS:
3744                 wrq->u.rts.value = priv->rts_thresh;
3745                 wrq->u.rts.disabled = (wrq->u.rts.value == 2347);
3746                 wrq->u.rts.fixed = 1;
3747                 break;
3748
3749         case SIOCSIWRTS:
3750                 err = orinoco_ioctl_setrts(dev, &wrq->u.rts);
3751                 if (! err)
3752                         changed = 1;
3753                 break;
3754
3755         case SIOCSIWFRAG:
3756                 err = orinoco_ioctl_setfrag(dev, &wrq->u.frag);
3757                 if (! err)
3758                         changed = 1;
3759                 break;
3760
3761         case SIOCGIWFRAG:
3762                 err = orinoco_ioctl_getfrag(dev, &wrq->u.frag);
3763                 break;
3764
3765         case SIOCSIWRATE:
3766                 err = orinoco_ioctl_setrate(dev, &wrq->u.bitrate);
3767                 if (! err)
3768                         changed = 1;
3769                 break;
3770
3771         case SIOCGIWRATE:
3772                 err = orinoco_ioctl_getrate(dev, &wrq->u.bitrate);
3773                 break;
3774
3775         case SIOCSIWPOWER:
3776                 err = orinoco_ioctl_setpower(dev, &wrq->u.power);
3777                 if (! err)
3778                         changed = 1;
3779                 break;
3780
3781         case SIOCGIWPOWER:
3782                 err = orinoco_ioctl_getpower(dev, &wrq->u.power);
3783                 break;
3784
3785         case SIOCGIWTXPOW:
3786                 /* The card only supports one tx power, so this is easy */
3787                 wrq->u.txpower.value = 15; /* dBm */
3788                 wrq->u.txpower.fixed = 1;
3789                 wrq->u.txpower.disabled = 0;
3790                 wrq->u.txpower.flags = IW_TXPOW_DBM;
3791                 break;
3792
3793 #if WIRELESS_EXT > 10
3794         case SIOCSIWRETRY:
3795                 err = -EOPNOTSUPP;
3796                 break;
3797
3798         case SIOCGIWRETRY:
3799                 err = orinoco_ioctl_getretry(dev, &wrq->u.retry);
3800                 break;
3801 #endif /* WIRELESS_EXT > 10 */
3802
3803         case SIOCSIWSPY:
3804                 err = orinoco_ioctl_setspy(dev, &wrq->u.data);
3805                 break;
3806
3807         case SIOCGIWSPY:
3808                 err = orinoco_ioctl_getspy(dev, &wrq->u.data);
3809                 break;
3810
3811         case SIOCGIWPRIV:
3812                 if (wrq->u.data.pointer) {
3813                         struct iw_priv_args privtab[] = {
3814                                 { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
3815                                 { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
3816                                 { SIOCIWFIRSTPRIV + 0x2,
3817                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3818                                   0, "set_port3" },
3819                                 { SIOCIWFIRSTPRIV + 0x3, 0,
3820                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3821                                   "get_port3" },
3822                                 { SIOCIWFIRSTPRIV + 0x4,
3823                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3824                                   0, "set_preamble" },
3825                                 { SIOCIWFIRSTPRIV + 0x5, 0,
3826                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3827                                   "get_preamble" },
3828                                 { SIOCIWFIRSTPRIV + 0x6,
3829                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3830                                   0, "set_ibssport" },
3831                                 { SIOCIWFIRSTPRIV + 0x7, 0,
3832                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3833                                   "get_ibssport" },
3834                                 { SIOCIWLASTPRIV, 0, 0, "dump_recs" },
3835                         };
3836
3837                         wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
3838                         if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
3839                                 err = -EFAULT;
3840                 }
3841                 break;
3842                
3843         case SIOCIWFIRSTPRIV + 0x0: /* force_reset */
3844         case SIOCIWFIRSTPRIV + 0x1: /* card_reset */
3845                 if (! capable(CAP_NET_ADMIN)) {
3846                         err = -EPERM;
3847                         break;
3848                 }
3849                 
3850                 printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
3851
3852                 schedule_work(&priv->reset_work);
3853                 break;
3854
3855         case SIOCIWFIRSTPRIV + 0x2: /* set_port3 */
3856                 if (! capable(CAP_NET_ADMIN)) {
3857                         err = -EPERM;
3858                         break;
3859                 }
3860
3861                 err = orinoco_ioctl_setport3(dev, wrq);
3862                 if (! err)
3863                         changed = 1;
3864                 break;
3865
3866         case SIOCIWFIRSTPRIV + 0x3: /* get_port3 */
3867                 err = orinoco_ioctl_getport3(dev, wrq);
3868                 break;
3869
3870         case SIOCIWFIRSTPRIV + 0x4: /* set_preamble */
3871                 if (! capable(CAP_NET_ADMIN)) {
3872                         err = -EPERM;
3873                         break;
3874                 }
3875
3876                 /* 802.11b has recently defined some short preamble.
3877                  * Basically, the Phy header has been reduced in size.
3878                  * This increase performance, especially at high rates
3879                  * (the preamble is transmitted at 1Mb/s), unfortunately
3880                  * this give compatibility troubles... - Jean II */
3881                 if(priv->has_preamble) {
3882                         int val = *( (int *) wrq->u.name );
3883
3884                         err = orinoco_lock(priv, &flags);
3885                         if (err)
3886                                 return err;
3887                         if (val)
3888                                 priv->preamble = 1;
3889                         else
3890                                 priv->preamble = 0;
3891                         orinoco_unlock(priv, &flags);
3892                         changed = 1;
3893                 } else
3894                         err = -EOPNOTSUPP;
3895                 break;
3896
3897         case SIOCIWFIRSTPRIV + 0x5: /* get_preamble */
3898                 if(priv->has_preamble) {
3899                         int *val = (int *)wrq->u.name;
3900
3901                         err = orinoco_lock(priv, &flags);
3902                         if (err)
3903                                 return err;
3904                         *val = priv->preamble;
3905                         orinoco_unlock(priv, &flags);
3906                 } else
3907                         err = -EOPNOTSUPP;
3908                 break;
3909         case SIOCIWFIRSTPRIV + 0x6: /* set_ibssport */
3910                 if (! capable(CAP_NET_ADMIN)) {
3911                         err = -EPERM;
3912                         break;
3913                 }
3914
3915                 err = orinoco_ioctl_setibssport(dev, wrq);
3916                 if (! err)
3917                         changed = 1;
3918                 break;
3919
3920         case SIOCIWFIRSTPRIV + 0x7: /* get_ibssport */
3921                 err = orinoco_ioctl_getibssport(dev, wrq);
3922                 break;
3923
3924         case SIOCIWLASTPRIV:
3925                 err = orinoco_debug_dump_recs(dev);
3926                 if (err)
3927                         printk(KERN_ERR "%s: Unable to dump records (%d)\n",
3928                                dev->name, err);
3929                 break;
3930
3931
3932         default:
3933                 err = -EOPNOTSUPP;
3934         }
3935         
3936         if (! err && changed && netif_running(dev)) {
3937                 err = orinoco_reconfigure(dev);
3938         }               
3939
3940         TRACE_EXIT(dev->name);
3941
3942         return err;
3943 }
3944
3945 struct {
3946         u16 rid;
3947         char *name;
3948         int displaytype;
3949 #define DISPLAY_WORDS   0
3950 #define DISPLAY_BYTES   1
3951 #define DISPLAY_STRING  2
3952 #define DISPLAY_XSTRING 3
3953 } record_table[] = {
3954 #define DEBUG_REC(name,type) { HERMES_RID_##name, #name, DISPLAY_##type }
3955         DEBUG_REC(CNFPORTTYPE,WORDS),
3956         DEBUG_REC(CNFOWNMACADDR,BYTES),
3957         DEBUG_REC(CNFDESIREDSSID,STRING),
3958         DEBUG_REC(CNFOWNCHANNEL,WORDS),
3959         DEBUG_REC(CNFOWNSSID,STRING),
3960         DEBUG_REC(CNFOWNATIMWINDOW,WORDS),
3961         DEBUG_REC(CNFSYSTEMSCALE,WORDS),
3962         DEBUG_REC(CNFMAXDATALEN,WORDS),
3963         DEBUG_REC(CNFPMENABLED,WORDS),
3964         DEBUG_REC(CNFPMEPS,WORDS),
3965         DEBUG_REC(CNFMULTICASTRECEIVE,WORDS),
3966         DEBUG_REC(CNFMAXSLEEPDURATION,WORDS),
3967         DEBUG_REC(CNFPMHOLDOVERDURATION,WORDS),
3968         DEBUG_REC(CNFOWNNAME,STRING),
3969         DEBUG_REC(CNFOWNDTIMPERIOD,WORDS),
3970         DEBUG_REC(CNFMULTICASTPMBUFFERING,WORDS),
3971         DEBUG_REC(CNFWEPENABLED_AGERE,WORDS),
3972         DEBUG_REC(CNFMANDATORYBSSID_SYMBOL,WORDS),
3973         DEBUG_REC(CNFWEPDEFAULTKEYID,WORDS),
3974         DEBUG_REC(CNFDEFAULTKEY0,BYTES),
3975         DEBUG_REC(CNFDEFAULTKEY1,BYTES),
3976         DEBUG_REC(CNFMWOROBUST_AGERE,WORDS),
3977         DEBUG_REC(CNFDEFAULTKEY2,BYTES),
3978         DEBUG_REC(CNFDEFAULTKEY3,BYTES),
3979         DEBUG_REC(CNFWEPFLAGS_INTERSIL,WORDS),
3980         DEBUG_REC(CNFWEPKEYMAPPINGTABLE,WORDS),
3981         DEBUG_REC(CNFAUTHENTICATION,WORDS),
3982         DEBUG_REC(CNFMAXASSOCSTA,WORDS),
3983         DEBUG_REC(CNFKEYLENGTH_SYMBOL,WORDS),
3984         DEBUG_REC(CNFTXCONTROL,WORDS),
3985         DEBUG_REC(CNFROAMINGMODE,WORDS),
3986         DEBUG_REC(CNFHOSTAUTHENTICATION,WORDS),
3987         DEBUG_REC(CNFRCVCRCERROR,WORDS),
3988         DEBUG_REC(CNFMMLIFE,WORDS),
3989         DEBUG_REC(CNFALTRETRYCOUNT,WORDS),
3990         DEBUG_REC(CNFBEACONINT,WORDS),
3991         DEBUG_REC(CNFAPPCFINFO,WORDS),
3992         DEBUG_REC(CNFSTAPCFINFO,WORDS),
3993         DEBUG_REC(CNFPRIORITYQUSAGE,WORDS),
3994         DEBUG_REC(CNFTIMCTRL,WORDS),
3995         DEBUG_REC(CNFTHIRTY2TALLY,WORDS),
3996         DEBUG_REC(CNFENHSECURITY,WORDS),
3997         DEBUG_REC(CNFGROUPADDRESSES,BYTES),
3998         DEBUG_REC(CNFCREATEIBSS,WORDS),
3999         DEBUG_REC(CNFFRAGMENTATIONTHRESHOLD,WORDS),
4000         DEBUG_REC(CNFRTSTHRESHOLD,WORDS),
4001         DEBUG_REC(CNFTXRATECONTROL,WORDS),
4002         DEBUG_REC(CNFPROMISCUOUSMODE,WORDS),
4003         DEBUG_REC(CNFBASICRATES_SYMBOL,WORDS),
4004         DEBUG_REC(CNFPREAMBLE_SYMBOL,WORDS),
4005         DEBUG_REC(CNFSHORTPREAMBLE,WORDS),
4006         DEBUG_REC(CNFWEPKEYS_AGERE,BYTES),
4007         DEBUG_REC(CNFEXCLUDELONGPREAMBLE,WORDS),
4008         DEBUG_REC(CNFTXKEY_AGERE,WORDS),
4009         DEBUG_REC(CNFAUTHENTICATIONRSPTO,WORDS),
4010         DEBUG_REC(CNFBASICRATES,WORDS),
4011         DEBUG_REC(CNFSUPPORTEDRATES,WORDS),
4012         DEBUG_REC(CNFTICKTIME,WORDS),
4013         DEBUG_REC(CNFSCANREQUEST,WORDS),
4014         DEBUG_REC(CNFJOINREQUEST,WORDS),
4015         DEBUG_REC(CNFAUTHENTICATESTATION,WORDS),
4016         DEBUG_REC(CNFCHANNELINFOREQUEST,WORDS),
4017         DEBUG_REC(MAXLOADTIME,WORDS),
4018         DEBUG_REC(DOWNLOADBUFFER,WORDS),
4019         DEBUG_REC(PRIID,WORDS),
4020         DEBUG_REC(PRISUPRANGE,WORDS),
4021         DEBUG_REC(CFIACTRANGES,WORDS),
4022         DEBUG_REC(NICSERNUM,XSTRING),
4023         DEBUG_REC(NICID,WORDS),
4024         DEBUG_REC(MFISUPRANGE,WORDS),
4025         DEBUG_REC(CFISUPRANGE,WORDS),
4026         DEBUG_REC(CHANNELLIST,WORDS),
4027         DEBUG_REC(REGULATORYDOMAINS,WORDS),
4028         DEBUG_REC(TEMPTYPE,WORDS),
4029 /*      DEBUG_REC(CIS,BYTES), */
4030         DEBUG_REC(STAID,WORDS),
4031         DEBUG_REC(CURRENTSSID,STRING),
4032         DEBUG_REC(CURRENTBSSID,BYTES),
4033         DEBUG_REC(COMMSQUALITY,WORDS),
4034         DEBUG_REC(CURRENTTXRATE,WORDS),
4035         DEBUG_REC(CURRENTBEACONINTERVAL,WORDS),
4036         DEBUG_REC(CURRENTSCALETHRESHOLDS,WORDS),
4037         DEBUG_REC(PROTOCOLRSPTIME,WORDS),
4038         DEBUG_REC(SHORTRETRYLIMIT,WORDS),
4039         DEBUG_REC(LONGRETRYLIMIT,WORDS),
4040         DEBUG_REC(MAXTRANSMITLIFETIME,WORDS),
4041         DEBUG_REC(MAXRECEIVELIFETIME,WORDS),
4042         DEBUG_REC(CFPOLLABLE,WORDS),
4043         DEBUG_REC(AUTHENTICATIONALGORITHMS,WORDS),
4044         DEBUG_REC(PRIVACYOPTIONIMPLEMENTED,WORDS),
4045         DEBUG_REC(OWNMACADDR,BYTES),
4046         DEBUG_REC(SCANRESULTSTABLE,WORDS),
4047         DEBUG_REC(PHYTYPE,WORDS),
4048         DEBUG_REC(CURRENTCHANNEL,WORDS),
4049         DEBUG_REC(CURRENTPOWERSTATE,WORDS),
4050         DEBUG_REC(CCAMODE,WORDS),
4051         DEBUG_REC(SUPPORTEDDATARATES,WORDS),
4052         DEBUG_REC(BUILDSEQ,BYTES),
4053         DEBUG_REC(FWID,XSTRING)
4054 #undef DEBUG_REC
4055 };
4056
4057 #define DEBUG_LTV_SIZE          128
4058
4059 static int orinoco_debug_dump_recs(struct net_device *dev)
4060 {
4061         struct orinoco_private *priv = netdev_priv(dev);
4062         hermes_t *hw = &priv->hw;
4063         u8 *val8;
4064         u16 *val16;
4065         int i,j;
4066         u16 length;
4067         int err;
4068
4069         /* I'm not sure: we might have a lock here, so we'd better go
4070            atomic, just in case. */
4071         val8 = kmalloc(DEBUG_LTV_SIZE + 2, GFP_ATOMIC);
4072         if (! val8)
4073                 return -ENOMEM;
4074         val16 = (u16 *)val8;
4075
4076         for (i = 0; i < ARRAY_SIZE(record_table); i++) {
4077                 u16 rid = record_table[i].rid;
4078                 int len;
4079
4080                 memset(val8, 0, DEBUG_LTV_SIZE + 2);
4081
4082                 err = hermes_read_ltv(hw, USER_BAP, rid, DEBUG_LTV_SIZE,
4083                                       &length, val8);
4084                 if (err) {
4085                         DEBUG(0, "Error %d reading RID 0x%04x\n", err, rid);
4086                         continue;
4087                 }
4088                 val16 = (u16 *)val8;
4089                 if (length == 0)
4090                         continue;
4091
4092                 printk(KERN_DEBUG "%-15s (0x%04x): length=%d (%d bytes)\tvalue=",
4093                        record_table[i].name,
4094                        rid, length, (length-1)*2);
4095                 len = min(((int)length-1)*2, DEBUG_LTV_SIZE);
4096
4097                 switch (record_table[i].displaytype) {
4098                 case DISPLAY_WORDS:
4099                         for (j = 0; j < len / 2; j++)
4100                                 printk("%04X-", le16_to_cpu(val16[j]));
4101                         break;
4102
4103                 case DISPLAY_BYTES:
4104                 default:
4105                         for (j = 0; j < len; j++)
4106                                 printk("%02X:", val8[j]);
4107                         break;
4108
4109                 case DISPLAY_STRING:
4110                         len = min(len, le16_to_cpu(val16[0])+2);
4111                         val8[len] = '\0';
4112                         printk("\"%s\"", (char *)&val16[1]);
4113                         break;
4114
4115                 case DISPLAY_XSTRING:
4116                         printk("'%s'", (char *)val8);
4117                 }
4118
4119                 printk("\n");
4120         }
4121
4122         kfree(val8);
4123
4124         return 0;
4125 }
4126
4127 struct net_device *alloc_orinocodev(int sizeof_card, int (*hard_reset)(struct orinoco_private *))
4128 {
4129         struct net_device *dev;
4130         struct orinoco_private *priv;
4131
4132         dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
4133         if (!dev)
4134                 return NULL;
4135         priv = netdev_priv(dev);
4136         priv->ndev = dev;
4137         if (sizeof_card)
4138                 priv->card = (void *)((unsigned long)dev->priv + sizeof(struct orinoco_private));
4139         else
4140                 priv->card = NULL;
4141
4142         /* Setup / override net_device fields */
4143         dev->init = orinoco_init;
4144         dev->hard_start_xmit = orinoco_xmit;
4145         dev->tx_timeout = orinoco_tx_timeout;
4146         dev->watchdog_timeo = HZ; /* 1 second timeout */
4147         dev->get_stats = orinoco_get_stats;
4148         dev->get_wireless_stats = orinoco_get_wireless_stats;
4149         dev->do_ioctl = orinoco_ioctl;
4150         dev->change_mtu = orinoco_change_mtu;
4151         dev->set_multicast_list = orinoco_set_multicast_list;
4152         /* we use the default eth_mac_addr for setting the MAC addr */
4153
4154         /* Set up default callbacks */
4155         dev->open = orinoco_open;
4156         dev->stop = orinoco_stop;
4157         priv->hard_reset = hard_reset;
4158
4159         spin_lock_init(&priv->lock);
4160         priv->open = 0;
4161         priv->hw_unavailable = 1; /* orinoco_init() must clear this
4162                                    * before anything else touches the
4163                                    * hardware */
4164         INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev);
4165
4166         priv->last_linkstatus = 0xffff;
4167         priv->connected = 0;
4168
4169         return dev;
4170
4171 }
4172
4173 /********************************************************************/
4174 /* Module initialization                                            */
4175 /********************************************************************/
4176
4177 EXPORT_SYMBOL(alloc_orinocodev);
4178
4179 EXPORT_SYMBOL(__orinoco_up);
4180 EXPORT_SYMBOL(__orinoco_down);
4181 EXPORT_SYMBOL(orinoco_stop);
4182 EXPORT_SYMBOL(orinoco_reinit_firmware);
4183
4184 EXPORT_SYMBOL(orinoco_interrupt);
4185
4186 /* Can't be declared "const" or the whole __initdata section will
4187  * become const */
4188 static char version[] __initdata = "orinoco.c 0.13e (David Gibson <hermes@gibson.dropbear.id.au> and others)";
4189
4190 static int __init init_orinoco(void)
4191 {
4192         printk(KERN_DEBUG "%s\n", version);
4193         return 0;
4194 }
4195
4196 static void __exit exit_orinoco(void)
4197 {
4198 }
4199
4200 module_init(init_orinoco);
4201 module_exit(exit_orinoco);