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