Annotation of Gnu-Mach/linux/pcmcia-cs/wireless/orinoco.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.