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