]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/net/wireless/orinoco.c
orinoco: Split wevent work thread from wevent sending
[linux-2.6-omap-h63xx.git] / drivers / net / wireless / orinoco.c
1 /* orinoco.c - (formerly known as dldwd_cs.c and orinoco_cs.c)
2  *
3  * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
4  * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
5  *
6  * Current maintainers (as of 29 September 2003) are:
7  *      Pavel Roskin <proski AT gnu.org>
8  * and  David Gibson <hermes AT gibson.dropbear.id.au>
9  *
10  * (C) Copyright David Gibson, IBM Corporation 2001-2003.
11  * Copyright (C) 2000 David Gibson, Linuxcare Australia.
12  *      With some help from :
13  * Copyright (C) 2001 Jean Tourrilhes, HP Labs
14  * Copyright (C) 2001 Benjamin Herrenschmidt
15  *
16  * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
17  *
18  * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy
19  * AT fasta.fh-dortmund.de>
20  *      http://www.stud.fh-dortmund.de/~andy/wvlan/
21  *
22  * The contents of this file are subject to the Mozilla Public License
23  * Version 1.1 (the "License"); you may not use this file except in
24  * compliance with the License. You may obtain a copy of the License
25  * at http://www.mozilla.org/MPL/
26  *
27  * Software distributed under the License is distributed on an "AS IS"
28  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
29  * the License for the specific language governing rights and
30  * limitations under the License.
31  *
32  * The initial developer of the original code is David A. Hinds
33  * <dahinds AT users.sourceforge.net>.  Portions created by David
34  * A. Hinds are Copyright (C) 1999 David A. Hinds.  All Rights
35  * Reserved.
36  *
37  * Alternatively, the contents of this file may be used under the
38  * terms of the GNU General Public License version 2 (the "GPL"), in
39  * which case the provisions of the GPL are applicable instead of the
40  * above.  If you wish to allow the use of your version of this file
41  * only under the terms of the GPL and not to allow others to use your
42  * version of this file under the MPL, indicate your decision by
43  * deleting the provisions above and replace them with the notice and
44  * other provisions required by the GPL.  If you do not delete the
45  * provisions above, a recipient may use your version of this file
46  * under either the MPL or the GPL.  */
47
48 /*
49  * TODO
50  *      o Handle de-encapsulation within network layer, provide 802.11
51  *        headers (patch from Thomas 'Dent' Mirlacher)
52  *      o Fix possible races in SPY handling.
53  *      o Disconnect wireless extensions from fundamental configuration.
54  *      o (maybe) Software WEP support (patch from Stano Meduna).
55  *      o (maybe) Use multiple Tx buffers - driver handling queue
56  *        rather than firmware.
57  */
58
59 /* Locking and synchronization:
60  *
61  * The basic principle is that everything is serialized through a
62  * single spinlock, priv->lock.  The lock is used in user, bh and irq
63  * context, so when taken outside hardirq context it should always be
64  * taken with interrupts disabled.  The lock protects both the
65  * hardware and the struct orinoco_private.
66  *
67  * Another flag, priv->hw_unavailable indicates that the hardware is
68  * unavailable for an extended period of time (e.g. suspended, or in
69  * the middle of a hard reset).  This flag is protected by the
70  * spinlock.  All code which touches the hardware should check the
71  * flag after taking the lock, and if it is set, give up on whatever
72  * they are doing and drop the lock again.  The orinoco_lock()
73  * function handles this (it unlocks and returns -EBUSY if
74  * hw_unavailable is non-zero).
75  */
76
77 #define DRIVER_NAME "orinoco"
78
79 #include <linux/module.h>
80 #include <linux/kernel.h>
81 #include <linux/init.h>
82 #include <linux/netdevice.h>
83 #include <linux/etherdevice.h>
84 #include <linux/ethtool.h>
85 #include <linux/firmware.h>
86 #include <linux/if_arp.h>
87 #include <linux/wireless.h>
88 #include <net/iw_handler.h>
89 #include <net/ieee80211.h>
90
91 #include "hermes_rid.h"
92 #include "hermes_dld.h"
93 #include "orinoco.h"
94
95 /********************************************************************/
96 /* Module information                                               */
97 /********************************************************************/
98
99 MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
100 MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
101 MODULE_LICENSE("Dual MPL/GPL");
102
103 /* Level of debugging. Used in the macros in orinoco.h */
104 #ifdef ORINOCO_DEBUG
105 int orinoco_debug = ORINOCO_DEBUG;
106 module_param(orinoco_debug, int, 0644);
107 MODULE_PARM_DESC(orinoco_debug, "Debug level");
108 EXPORT_SYMBOL(orinoco_debug);
109 #endif
110
111 static int suppress_linkstatus; /* = 0 */
112 module_param(suppress_linkstatus, bool, 0644);
113 MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
114 static int ignore_disconnect; /* = 0 */
115 module_param(ignore_disconnect, int, 0644);
116 MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
117
118 static int force_monitor; /* = 0 */
119 module_param(force_monitor, int, 0644);
120 MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
121
122 /********************************************************************/
123 /* Compile time configuration and compatibility stuff               */
124 /********************************************************************/
125
126 /* We do this this way to avoid ifdefs in the actual code */
127 #ifdef WIRELESS_SPY
128 #define SPY_NUMBER(priv)        (priv->spy_data.spy_number)
129 #else
130 #define SPY_NUMBER(priv)        0
131 #endif /* WIRELESS_SPY */
132
133 /********************************************************************/
134 /* Internal constants                                               */
135 /********************************************************************/
136
137 /* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
138 static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
139 #define ENCAPS_OVERHEAD         (sizeof(encaps_hdr) + 2)
140
141 #define ORINOCO_MIN_MTU         256
142 #define ORINOCO_MAX_MTU         (IEEE80211_DATA_LEN - ENCAPS_OVERHEAD)
143
144 #define SYMBOL_MAX_VER_LEN      (14)
145 #define USER_BAP                0
146 #define IRQ_BAP                 1
147 #define MAX_IRQLOOPS_PER_IRQ    10
148 #define MAX_IRQLOOPS_PER_JIFFY  (20000/HZ) /* Based on a guestimate of
149                                             * how many events the
150                                             * device could
151                                             * legitimately generate */
152 #define SMALL_KEY_SIZE          5
153 #define LARGE_KEY_SIZE          13
154 #define TX_NICBUF_SIZE_BUG      1585            /* Bug in Symbol firmware */
155
156 #define DUMMY_FID               0xFFFF
157
158 /*#define MAX_MULTICAST(priv)   (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
159   HERMES_MAX_MULTICAST : 0)*/
160 #define MAX_MULTICAST(priv)     (HERMES_MAX_MULTICAST)
161
162 #define ORINOCO_INTEN           (HERMES_EV_RX | HERMES_EV_ALLOC \
163                                  | HERMES_EV_TX | HERMES_EV_TXEXC \
164                                  | HERMES_EV_WTERR | HERMES_EV_INFO \
165                                  | HERMES_EV_INFDROP )
166
167 #define MAX_RID_LEN 1024
168
169 static const struct iw_handler_def orinoco_handler_def;
170 static const struct ethtool_ops orinoco_ethtool_ops;
171
172 /********************************************************************/
173 /* Data tables                                                      */
174 /********************************************************************/
175
176 /* The frequency of each channel in MHz */
177 static const long channel_frequency[] = {
178         2412, 2417, 2422, 2427, 2432, 2437, 2442,
179         2447, 2452, 2457, 2462, 2467, 2472, 2484
180 };
181 #define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
182
183 /* This tables gives the actual meanings of the bitrate IDs returned
184  * by the firmware. */
185 static struct {
186         int bitrate; /* in 100s of kilobits */
187         int automatic;
188         u16 agere_txratectrl;
189         u16 intersil_txratectrl;
190 } bitrate_table[] = {
191         {110, 1,  3, 15}, /* Entry 0 is the default */
192         {10,  0,  1,  1},
193         {10,  1,  1,  1},
194         {20,  0,  2,  2},
195         {20,  1,  6,  3},
196         {55,  0,  4,  4},
197         {55,  1,  7,  7},
198         {110, 0,  5,  8},
199 };
200 #define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
201
202 /********************************************************************/
203 /* Data types                                                       */
204 /********************************************************************/
205
206 /* Beginning of the Tx descriptor, used in TxExc handling */
207 struct hermes_txexc_data {
208         struct hermes_tx_descriptor desc;
209         __le16 frame_ctl;
210         __le16 duration_id;
211         u8 addr1[ETH_ALEN];
212 } __attribute__ ((packed));
213
214 /* Rx frame header except compatibility 802.3 header */
215 struct hermes_rx_descriptor {
216         /* Control */
217         __le16 status;
218         __le32 time;
219         u8 silence;
220         u8 signal;
221         u8 rate;
222         u8 rxflow;
223         __le32 reserved;
224
225         /* 802.11 header */
226         __le16 frame_ctl;
227         __le16 duration_id;
228         u8 addr1[ETH_ALEN];
229         u8 addr2[ETH_ALEN];
230         u8 addr3[ETH_ALEN];
231         __le16 seq_ctl;
232         u8 addr4[ETH_ALEN];
233
234         /* Data length */
235         __le16 data_len;
236 } __attribute__ ((packed));
237
238 /********************************************************************/
239 /* Function prototypes                                              */
240 /********************************************************************/
241
242 static int __orinoco_program_rids(struct net_device *dev);
243 static void __orinoco_set_multicast_list(struct net_device *dev);
244
245 /********************************************************************/
246 /* Internal helper functions                                        */
247 /********************************************************************/
248
249 static inline void set_port_type(struct orinoco_private *priv)
250 {
251         switch (priv->iw_mode) {
252         case IW_MODE_INFRA:
253                 priv->port_type = 1;
254                 priv->createibss = 0;
255                 break;
256         case IW_MODE_ADHOC:
257                 if (priv->prefer_port3) {
258                         priv->port_type = 3;
259                         priv->createibss = 0;
260                 } else {
261                         priv->port_type = priv->ibss_port;
262                         priv->createibss = 1;
263                 }
264                 break;
265         case IW_MODE_MONITOR:
266                 priv->port_type = 3;
267                 priv->createibss = 0;
268                 break;
269         default:
270                 printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
271                        priv->ndev->name);
272         }
273 }
274
275 #define ORINOCO_MAX_BSS_COUNT   64
276 static int orinoco_bss_data_allocate(struct orinoco_private *priv)
277 {
278         if (priv->bss_xbss_data)
279                 return 0;
280
281         if (priv->has_ext_scan)
282                 priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
283                                               sizeof(struct xbss_element),
284                                               GFP_KERNEL);
285         else
286                 priv->bss_xbss_data = kzalloc(ORINOCO_MAX_BSS_COUNT *
287                                               sizeof(struct bss_element),
288                                               GFP_KERNEL);
289
290         if (!priv->bss_xbss_data) {
291                 printk(KERN_WARNING "Out of memory allocating beacons");
292                 return -ENOMEM;
293         }
294         return 0;
295 }
296
297 static void orinoco_bss_data_free(struct orinoco_private *priv)
298 {
299         kfree(priv->bss_xbss_data);
300         priv->bss_xbss_data = NULL;
301 }
302
303 #define PRIV_BSS        ((struct bss_element *)priv->bss_xbss_data)
304 #define PRIV_XBSS       ((struct xbss_element *)priv->bss_xbss_data)
305 static void orinoco_bss_data_init(struct orinoco_private *priv)
306 {
307         int i;
308
309         INIT_LIST_HEAD(&priv->bss_free_list);
310         INIT_LIST_HEAD(&priv->bss_list);
311         if (priv->has_ext_scan)
312                 for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
313                         list_add_tail(&(PRIV_XBSS[i].list),
314                                       &priv->bss_free_list);
315         else
316                 for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
317                         list_add_tail(&(PRIV_BSS[i].list),
318                                       &priv->bss_free_list);
319
320 }
321
322 static inline u8 *orinoco_get_ie(u8 *data, size_t len,
323                                  enum ieee80211_mfie eid)
324 {
325         u8 *p = data;
326         while ((p + 2) < (data + len)) {
327                 if (p[0] == eid)
328                         return p;
329                 p += p[1] + 2;
330         }
331         return NULL;
332 }
333
334 #define WPA_OUI_TYPE    "\x00\x50\xF2\x01"
335 #define WPA_SELECTOR_LEN 4
336 static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
337 {
338         u8 *p = data;
339         while ((p + 2 + WPA_SELECTOR_LEN) < (data + len)) {
340                 if ((p[0] == MFIE_TYPE_GENERIC) &&
341                     (memcmp(&p[2], WPA_OUI_TYPE, WPA_SELECTOR_LEN) == 0))
342                         return p;
343                 p += p[1] + 2;
344         }
345         return NULL;
346 }
347
348
349 /********************************************************************/
350 /* Download functionality                                           */
351 /********************************************************************/
352
353 struct fw_info {
354         char *pri_fw;
355         char *sta_fw;
356         char *ap_fw;
357         u32 pda_addr;
358         u16 pda_size;
359 };
360
361 const static struct fw_info orinoco_fw[] = {
362         { "", "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
363         { "", "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
364         { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", "", 0x00003100, 0x100 }
365 };
366
367 /* Structure used to access fields in FW
368  * Make sure LE decoding macros are used
369  */
370 struct orinoco_fw_header {
371         char hdr_vers[6];       /* ASCII string for header version */
372         __le16 headersize;      /* Total length of header */
373         __le32 entry_point;     /* NIC entry point */
374         __le32 blocks;          /* Number of blocks to program */
375         __le32 block_offset;    /* Offset of block data from eof header */
376         __le32 pdr_offset;      /* Offset to PDR data from eof header */
377         __le32 pri_offset;      /* Offset to primary plug data */
378         __le32 compat_offset;   /* Offset to compatibility data*/
379         char signature[0];      /* FW signature length headersize-20 */
380 } __attribute__ ((packed));
381
382 /* Download either STA or AP firmware into the card. */
383 static int
384 orinoco_dl_firmware(struct orinoco_private *priv,
385                     const struct fw_info *fw,
386                     int ap)
387 {
388         /* Plug Data Area (PDA) */
389         __le16 pda[512] = { 0 };
390
391         hermes_t *hw = &priv->hw;
392         const struct firmware *fw_entry;
393         const struct orinoco_fw_header *hdr;
394         const unsigned char *first_block;
395         const unsigned char *end;
396         const char *firmware;
397         struct net_device *dev = priv->ndev;
398         int err;
399
400         if (ap)
401                 firmware = fw->ap_fw;
402         else
403                 firmware = fw->sta_fw;
404
405         printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
406                dev->name, firmware);
407
408         /* Read current plug data */
409         err = hermes_read_pda(hw, pda, fw->pda_addr,
410                               min_t(u16, fw->pda_size, sizeof(pda)), 0);
411         printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
412         if (err)
413                 return err;
414
415         err = request_firmware(&fw_entry, firmware, priv->dev);
416         if (err) {
417                 printk(KERN_ERR "%s: Cannot find firmware %s\n",
418                        dev->name, firmware);
419                 return -ENOENT;
420         }
421
422         hdr = (const struct orinoco_fw_header *) fw_entry->data;
423
424         /* Enable aux port to allow programming */
425         err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
426         printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
427         if (err != 0)
428                 goto abort;
429
430         /* Program data */
431         first_block = (fw_entry->data +
432                        le16_to_cpu(hdr->headersize) +
433                        le32_to_cpu(hdr->block_offset));
434         end = fw_entry->data + fw_entry->size;
435
436         err = hermes_program(hw, first_block, end);
437         printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
438         if (err != 0)
439                 goto abort;
440
441         /* Update production data */
442         first_block = (fw_entry->data +
443                        le16_to_cpu(hdr->headersize) +
444                        le32_to_cpu(hdr->pdr_offset));
445
446         err = hermes_apply_pda_with_defaults(hw, first_block, pda);
447         printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
448         if (err)
449                 goto abort;
450
451         /* Tell card we've finished */
452         err = hermesi_program_end(hw);
453         printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
454         if (err != 0)
455                 goto abort;
456
457         /* Check if we're running */
458         printk(KERN_DEBUG "%s: hermes_present returned %d\n",
459                dev->name, hermes_present(hw));
460
461 abort:
462         release_firmware(fw_entry);
463         return err;
464 }
465
466 /* End markers */
467 #define TEXT_END        0x1A            /* End of text header */
468
469 /*
470  * Process a firmware image - stop the card, load the firmware, reset
471  * the card and make sure it responds.  For the secondary firmware take
472  * care of the PDA - read it and then write it on top of the firmware.
473  */
474 static int
475 symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
476                 const unsigned char *image, const unsigned char *end,
477                 int secondary)
478 {
479         hermes_t *hw = &priv->hw;
480         int ret;
481         const unsigned char *ptr;
482         const unsigned char *first_block;
483
484         /* Plug Data Area (PDA) */
485         __le16 pda[256];
486
487         /* Binary block begins after the 0x1A marker */
488         ptr = image;
489         while (*ptr++ != TEXT_END);
490         first_block = ptr;
491
492         /* Read the PDA from EEPROM */
493         if (secondary) {
494                 ret = hermes_read_pda(hw, pda, fw->pda_addr, sizeof(pda), 1);
495                 if (ret)
496                         return ret;
497         }
498
499         /* Stop the firmware, so that it can be safely rewritten */
500         if (priv->stop_fw) {
501                 ret = priv->stop_fw(priv, 1);
502                 if (ret)
503                         return ret;
504         }
505
506         /* Program the adapter with new firmware */
507         ret = hermes_program(hw, first_block, end);
508         if (ret)
509                 return ret;
510
511         /* Write the PDA to the adapter */
512         if (secondary) {
513                 size_t len = hermes_blocks_length(first_block);
514                 ptr = first_block + len;
515                 ret = hermes_apply_pda(hw, ptr, pda);
516                 if (ret)
517                         return ret;
518         }
519
520         /* Run the firmware */
521         if (priv->stop_fw) {
522                 ret = priv->stop_fw(priv, 0);
523                 if (ret)
524                         return ret;
525         }
526
527         /* Reset hermes chip and make sure it responds */
528         ret = hermes_init(hw);
529
530         /* hermes_reset() should return 0 with the secondary firmware */
531         if (secondary && ret != 0)
532                 return -ENODEV;
533
534         /* And this should work with any firmware */
535         if (!hermes_present(hw))
536                 return -ENODEV;
537
538         return 0;
539 }
540
541
542 /*
543  * Download the firmware into the card, this also does a PCMCIA soft
544  * reset on the card, to make sure it's in a sane state.
545  */
546 static int
547 symbol_dl_firmware(struct orinoco_private *priv,
548                    const struct fw_info *fw)
549 {
550         struct net_device *dev = priv->ndev;
551         int ret;
552         const struct firmware *fw_entry;
553
554         if (request_firmware(&fw_entry, fw->pri_fw,
555                              priv->dev) != 0) {
556                 printk(KERN_ERR "%s: Cannot find firmware: %s\n",
557                        dev->name, fw->pri_fw);
558                 return -ENOENT;
559         }
560
561         /* Load primary firmware */
562         ret = symbol_dl_image(priv, fw, fw_entry->data,
563                               fw_entry->data + fw_entry->size, 0);
564         release_firmware(fw_entry);
565         if (ret) {
566                 printk(KERN_ERR "%s: Primary firmware download failed\n",
567                        dev->name);
568                 return ret;
569         }
570
571         if (request_firmware(&fw_entry, fw->sta_fw,
572                              priv->dev) != 0) {
573                 printk(KERN_ERR "%s: Cannot find firmware: %s\n",
574                        dev->name, fw->sta_fw);
575                 return -ENOENT;
576         }
577
578         /* Load secondary firmware */
579         ret = symbol_dl_image(priv, fw, fw_entry->data,
580                               fw_entry->data + fw_entry->size, 1);
581         release_firmware(fw_entry);
582         if (ret) {
583                 printk(KERN_ERR "%s: Secondary firmware download failed\n",
584                        dev->name);
585         }
586
587         return ret;
588 }
589
590 static int orinoco_download(struct orinoco_private *priv)
591 {
592         int err = 0;
593         /* Reload firmware */
594         switch (priv->firmware_type) {
595         case FIRMWARE_TYPE_AGERE:
596                 /* case FIRMWARE_TYPE_INTERSIL: */
597                 err = orinoco_dl_firmware(priv,
598                                           &orinoco_fw[priv->firmware_type], 0);
599                 break;
600
601         case FIRMWARE_TYPE_SYMBOL:
602                 err = symbol_dl_firmware(priv,
603                                          &orinoco_fw[priv->firmware_type]);
604                 break;
605         case FIRMWARE_TYPE_INTERSIL:
606                 break;
607         }
608         /* TODO: if we fail we probably need to reinitialise
609          * the driver */
610
611         return err;
612 }
613
614 /********************************************************************/
615 /* Device methods                                                   */
616 /********************************************************************/
617
618 static int orinoco_open(struct net_device *dev)
619 {
620         struct orinoco_private *priv = netdev_priv(dev);
621         unsigned long flags;
622         int err;
623
624         if (orinoco_lock(priv, &flags) != 0)
625                 return -EBUSY;
626
627         err = __orinoco_up(dev);
628
629         if (! err)
630                 priv->open = 1;
631
632         orinoco_unlock(priv, &flags);
633
634         return err;
635 }
636
637 static int orinoco_stop(struct net_device *dev)
638 {
639         struct orinoco_private *priv = netdev_priv(dev);
640         int err = 0;
641
642         /* We mustn't use orinoco_lock() here, because we need to be
643            able to close the interface even if hw_unavailable is set
644            (e.g. as we're released after a PC Card removal) */
645         spin_lock_irq(&priv->lock);
646
647         priv->open = 0;
648
649         err = __orinoco_down(dev);
650
651         spin_unlock_irq(&priv->lock);
652
653         return err;
654 }
655
656 static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
657 {
658         struct orinoco_private *priv = netdev_priv(dev);
659         
660         return &priv->stats;
661 }
662
663 static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
664 {
665         struct orinoco_private *priv = netdev_priv(dev);
666         hermes_t *hw = &priv->hw;
667         struct iw_statistics *wstats = &priv->wstats;
668         int err;
669         unsigned long flags;
670
671         if (! netif_device_present(dev)) {
672                 printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
673                        dev->name);
674                 return NULL; /* FIXME: Can we do better than this? */
675         }
676
677         /* If busy, return the old stats.  Returning NULL may cause
678          * the interface to disappear from /proc/net/wireless */
679         if (orinoco_lock(priv, &flags) != 0)
680                 return wstats;
681
682         /* We can't really wait for the tallies inquiry command to
683          * complete, so we just use the previous results and trigger
684          * a new tallies inquiry command for next time - Jean II */
685         /* FIXME: Really we should wait for the inquiry to come back -
686          * as it is the stats we give don't make a whole lot of sense.
687          * Unfortunately, it's not clear how to do that within the
688          * wireless extensions framework: I think we're in user
689          * context, but a lock seems to be held by the time we get in
690          * here so we're not safe to sleep here. */
691         hermes_inquire(hw, HERMES_INQ_TALLIES);
692
693         if (priv->iw_mode == IW_MODE_ADHOC) {
694                 memset(&wstats->qual, 0, sizeof(wstats->qual));
695                 /* If a spy address is defined, we report stats of the
696                  * first spy address - Jean II */
697                 if (SPY_NUMBER(priv)) {
698                         wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
699                         wstats->qual.level = priv->spy_data.spy_stat[0].level;
700                         wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
701                         wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
702                 }
703         } else {
704                 struct {
705                         __le16 qual, signal, noise, unused;
706                 } __attribute__ ((packed)) cq;
707
708                 err = HERMES_READ_RECORD(hw, USER_BAP,
709                                          HERMES_RID_COMMSQUALITY, &cq);
710
711                 if (!err) {
712                         wstats->qual.qual = (int)le16_to_cpu(cq.qual);
713                         wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
714                         wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
715                         wstats->qual.updated = 7;
716                 }
717         }
718
719         orinoco_unlock(priv, &flags);
720         return wstats;
721 }
722
723 static void orinoco_set_multicast_list(struct net_device *dev)
724 {
725         struct orinoco_private *priv = netdev_priv(dev);
726         unsigned long flags;
727
728         if (orinoco_lock(priv, &flags) != 0) {
729                 printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
730                        "called when hw_unavailable\n", dev->name);
731                 return;
732         }
733
734         __orinoco_set_multicast_list(dev);
735         orinoco_unlock(priv, &flags);
736 }
737
738 static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
739 {
740         struct orinoco_private *priv = netdev_priv(dev);
741
742         if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
743                 return -EINVAL;
744
745         if ( (new_mtu + ENCAPS_OVERHEAD + IEEE80211_HLEN) >
746              (priv->nicbuf_size - ETH_HLEN) )
747                 return -EINVAL;
748
749         dev->mtu = new_mtu;
750
751         return 0;
752 }
753
754 /********************************************************************/
755 /* Tx path                                                          */
756 /********************************************************************/
757
758 static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
759 {
760         struct orinoco_private *priv = netdev_priv(dev);
761         struct net_device_stats *stats = &priv->stats;
762         hermes_t *hw = &priv->hw;
763         int err = 0;
764         u16 txfid = priv->txfid;
765         struct ethhdr *eh;
766         int data_off;
767         int tx_control;
768         unsigned long flags;
769
770         if (! netif_running(dev)) {
771                 printk(KERN_ERR "%s: Tx on stopped device!\n",
772                        dev->name);
773                 return NETDEV_TX_BUSY;
774         }
775         
776         if (netif_queue_stopped(dev)) {
777                 printk(KERN_DEBUG "%s: Tx while transmitter busy!\n", 
778                        dev->name);
779                 return NETDEV_TX_BUSY;
780         }
781         
782         if (orinoco_lock(priv, &flags) != 0) {
783                 printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
784                        dev->name);
785                 return NETDEV_TX_BUSY;
786         }
787
788         if (! netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
789                 /* Oops, the firmware hasn't established a connection,
790                    silently drop the packet (this seems to be the
791                    safest approach). */
792                 goto drop;
793         }
794
795         /* Check packet length */
796         if (skb->len < ETH_HLEN)
797                 goto drop;
798
799         eh = (struct ethhdr *)skb->data;
800
801         tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
802
803         if (priv->has_alt_txcntl) {
804                 /* WPA enabled firmwares have tx_cntl at the end of
805                  * the 802.11 header.  So write zeroed descriptor and
806                  * 802.11 header at the same time
807                  */
808                 char desc[HERMES_802_3_OFFSET];
809                 __le16 *txcntl = (__le16 *) &desc[HERMES_TXCNTL2_OFFSET];
810
811                 memset(&desc, 0, sizeof(desc));
812
813                 *txcntl = cpu_to_le16(tx_control);
814                 err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
815                                         txfid, 0);
816                 if (err) {
817                         if (net_ratelimit())
818                                 printk(KERN_ERR "%s: Error %d writing Tx "
819                                        "descriptor to BAP\n", dev->name, err);
820                         goto busy;
821                 }
822         } else {
823                 struct hermes_tx_descriptor desc;
824
825                 memset(&desc, 0, sizeof(desc));
826
827                 desc.tx_control = cpu_to_le16(tx_control);
828                 err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
829                                         txfid, 0);
830                 if (err) {
831                         if (net_ratelimit())
832                                 printk(KERN_ERR "%s: Error %d writing Tx "
833                                        "descriptor to BAP\n", dev->name, err);
834                         goto busy;
835                 }
836
837                 /* Clear the 802.11 header and data length fields - some
838                  * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
839                  * if this isn't done. */
840                 hermes_clear_words(hw, HERMES_DATA0,
841                                    HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
842         }
843
844         /* Encapsulate Ethernet-II frames */
845         if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
846                 struct header_struct {
847                         struct ethhdr eth;      /* 802.3 header */
848                         u8 encap[6];            /* 802.2 header */
849                 } __attribute__ ((packed)) hdr;
850
851                 /* Strip destination and source from the data */
852                 skb_pull(skb, 2 * ETH_ALEN);
853                 data_off = HERMES_802_2_OFFSET + sizeof(encaps_hdr);
854
855                 /* And move them to a separate header */
856                 memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
857                 hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
858                 memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
859
860                 err = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
861                                         txfid, HERMES_802_3_OFFSET);
862                 if (err) {
863                         if (net_ratelimit())
864                                 printk(KERN_ERR "%s: Error %d writing packet "
865                                        "header to BAP\n", dev->name, err);
866                         goto busy;
867                 }
868         } else { /* IEEE 802.3 frame */
869                 data_off = HERMES_802_3_OFFSET;
870         }
871
872         err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
873                                 txfid, data_off);
874         if (err) {
875                 printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
876                        dev->name, err);
877                 goto busy;
878         }
879
880         /* Finally, we actually initiate the send */
881         netif_stop_queue(dev);
882
883         err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
884                                 txfid, NULL);
885         if (err) {
886                 netif_start_queue(dev);
887                 if (net_ratelimit())
888                         printk(KERN_ERR "%s: Error %d transmitting packet\n",
889                                 dev->name, err);
890                 goto busy;
891         }
892
893         dev->trans_start = jiffies;
894         stats->tx_bytes += data_off + skb->len;
895         goto ok;
896
897  drop:
898         stats->tx_errors++;
899         stats->tx_dropped++;
900
901  ok:
902         orinoco_unlock(priv, &flags);
903         dev_kfree_skb(skb);
904         return NETDEV_TX_OK;
905
906  busy:
907         if (err == -EIO)
908                 schedule_work(&priv->reset_work);
909         orinoco_unlock(priv, &flags);
910         return NETDEV_TX_BUSY;
911 }
912
913 static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
914 {
915         struct orinoco_private *priv = netdev_priv(dev);
916         u16 fid = hermes_read_regn(hw, ALLOCFID);
917
918         if (fid != priv->txfid) {
919                 if (fid != DUMMY_FID)
920                         printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
921                                dev->name, fid);
922                 return;
923         }
924
925         hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
926 }
927
928 static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
929 {
930         struct orinoco_private *priv = netdev_priv(dev);
931         struct net_device_stats *stats = &priv->stats;
932
933         stats->tx_packets++;
934
935         netif_wake_queue(dev);
936
937         hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
938 }
939
940 static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
941 {
942         struct orinoco_private *priv = netdev_priv(dev);
943         struct net_device_stats *stats = &priv->stats;
944         u16 fid = hermes_read_regn(hw, TXCOMPLFID);
945         u16 status;
946         struct hermes_txexc_data hdr;
947         int err = 0;
948
949         if (fid == DUMMY_FID)
950                 return; /* Nothing's really happened */
951
952         /* Read part of the frame header - we need status and addr1 */
953         err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
954                                sizeof(struct hermes_txexc_data),
955                                fid, 0);
956
957         hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
958         stats->tx_errors++;
959
960         if (err) {
961                 printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
962                        "(FID=%04X error %d)\n",
963                        dev->name, fid, err);
964                 return;
965         }
966         
967         DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
968               err, fid);
969     
970         /* We produce a TXDROP event only for retry or lifetime
971          * exceeded, because that's the only status that really mean
972          * that this particular node went away.
973          * Other errors means that *we* screwed up. - Jean II */
974         status = le16_to_cpu(hdr.desc.status);
975         if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
976                 union iwreq_data        wrqu;
977
978                 /* Copy 802.11 dest address.
979                  * We use the 802.11 header because the frame may
980                  * not be 802.3 or may be mangled...
981                  * In Ad-Hoc mode, it will be the node address.
982                  * In managed mode, it will be most likely the AP addr
983                  * User space will figure out how to convert it to
984                  * whatever it needs (IP address or else).
985                  * - Jean II */
986                 memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
987                 wrqu.addr.sa_family = ARPHRD_ETHER;
988
989                 /* Send event to user space */
990                 wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
991         }
992
993         netif_wake_queue(dev);
994 }
995
996 static void orinoco_tx_timeout(struct net_device *dev)
997 {
998         struct orinoco_private *priv = netdev_priv(dev);
999         struct net_device_stats *stats = &priv->stats;
1000         struct hermes *hw = &priv->hw;
1001
1002         printk(KERN_WARNING "%s: Tx timeout! "
1003                "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
1004                dev->name, hermes_read_regn(hw, ALLOCFID),
1005                hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
1006
1007         stats->tx_errors++;
1008
1009         schedule_work(&priv->reset_work);
1010 }
1011
1012 /********************************************************************/
1013 /* Rx path (data frames)                                            */
1014 /********************************************************************/
1015
1016 /* Does the frame have a SNAP header indicating it should be
1017  * de-encapsulated to Ethernet-II? */
1018 static inline int is_ethersnap(void *_hdr)
1019 {
1020         u8 *hdr = _hdr;
1021
1022         /* We de-encapsulate all packets which, a) have SNAP headers
1023          * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
1024          * and where b) the OUI of the SNAP header is 00:00:00 or
1025          * 00:00:f8 - we need both because different APs appear to use
1026          * different OUIs for some reason */
1027         return (memcmp(hdr, &encaps_hdr, 5) == 0)
1028                 && ( (hdr[5] == 0x00) || (hdr[5] == 0xf8) );
1029 }
1030
1031 static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
1032                                       int level, int noise)
1033 {
1034         struct iw_quality wstats;
1035         wstats.level = level - 0x95;
1036         wstats.noise = noise - 0x95;
1037         wstats.qual = (level > noise) ? (level - noise) : 0;
1038         wstats.updated = 7;
1039         /* Update spy records */
1040         wireless_spy_update(dev, mac, &wstats);
1041 }
1042
1043 static void orinoco_stat_gather(struct net_device *dev,
1044                                 struct sk_buff *skb,
1045                                 struct hermes_rx_descriptor *desc)
1046 {
1047         struct orinoco_private *priv = netdev_priv(dev);
1048
1049         /* Using spy support with lots of Rx packets, like in an
1050          * infrastructure (AP), will really slow down everything, because
1051          * the MAC address must be compared to each entry of the spy list.
1052          * If the user really asks for it (set some address in the
1053          * spy list), we do it, but he will pay the price.
1054          * Note that to get here, you need both WIRELESS_SPY
1055          * compiled in AND some addresses in the list !!!
1056          */
1057         /* Note : gcc will optimise the whole section away if
1058          * WIRELESS_SPY is not defined... - Jean II */
1059         if (SPY_NUMBER(priv)) {
1060                 orinoco_spy_gather(dev, skb_mac_header(skb) + ETH_ALEN,
1061                                    desc->signal, desc->silence);
1062         }
1063 }
1064
1065 /*
1066  * orinoco_rx_monitor - handle received monitor frames.
1067  *
1068  * Arguments:
1069  *      dev             network device
1070  *      rxfid           received FID
1071  *      desc            rx descriptor of the frame
1072  *
1073  * Call context: interrupt
1074  */
1075 static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
1076                                struct hermes_rx_descriptor *desc)
1077 {
1078         u32 hdrlen = 30;        /* return full header by default */
1079         u32 datalen = 0;
1080         u16 fc;
1081         int err;
1082         int len;
1083         struct sk_buff *skb;
1084         struct orinoco_private *priv = netdev_priv(dev);
1085         struct net_device_stats *stats = &priv->stats;
1086         hermes_t *hw = &priv->hw;
1087
1088         len = le16_to_cpu(desc->data_len);
1089
1090         /* Determine the size of the header and the data */
1091         fc = le16_to_cpu(desc->frame_ctl);
1092         switch (fc & IEEE80211_FCTL_FTYPE) {
1093         case IEEE80211_FTYPE_DATA:
1094                 if ((fc & IEEE80211_FCTL_TODS)
1095                     && (fc & IEEE80211_FCTL_FROMDS))
1096                         hdrlen = 30;
1097                 else
1098                         hdrlen = 24;
1099                 datalen = len;
1100                 break;
1101         case IEEE80211_FTYPE_MGMT:
1102                 hdrlen = 24;
1103                 datalen = len;
1104                 break;
1105         case IEEE80211_FTYPE_CTL:
1106                 switch (fc & IEEE80211_FCTL_STYPE) {
1107                 case IEEE80211_STYPE_PSPOLL:
1108                 case IEEE80211_STYPE_RTS:
1109                 case IEEE80211_STYPE_CFEND:
1110                 case IEEE80211_STYPE_CFENDACK:
1111                         hdrlen = 16;
1112                         break;
1113                 case IEEE80211_STYPE_CTS:
1114                 case IEEE80211_STYPE_ACK:
1115                         hdrlen = 10;
1116                         break;
1117                 }
1118                 break;
1119         default:
1120                 /* Unknown frame type */
1121                 break;
1122         }
1123
1124         /* sanity check the length */
1125         if (datalen > IEEE80211_DATA_LEN + 12) {
1126                 printk(KERN_DEBUG "%s: oversized monitor frame, "
1127                        "data length = %d\n", dev->name, datalen);
1128                 stats->rx_length_errors++;
1129                 goto update_stats;
1130         }
1131
1132         skb = dev_alloc_skb(hdrlen + datalen);
1133         if (!skb) {
1134                 printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
1135                        dev->name);
1136                 goto update_stats;
1137         }
1138
1139         /* Copy the 802.11 header to the skb */
1140         memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
1141         skb_reset_mac_header(skb);
1142
1143         /* If any, copy the data from the card to the skb */
1144         if (datalen > 0) {
1145                 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
1146                                        ALIGN(datalen, 2), rxfid,
1147                                        HERMES_802_2_OFFSET);
1148                 if (err) {
1149                         printk(KERN_ERR "%s: error %d reading monitor frame\n",
1150                                dev->name, err);
1151                         goto drop;
1152                 }
1153         }
1154
1155         skb->dev = dev;
1156         skb->ip_summed = CHECKSUM_NONE;
1157         skb->pkt_type = PACKET_OTHERHOST;
1158         skb->protocol = __constant_htons(ETH_P_802_2);
1159         
1160         dev->last_rx = jiffies;
1161         stats->rx_packets++;
1162         stats->rx_bytes += skb->len;
1163
1164         netif_rx(skb);
1165         return;
1166
1167  drop:
1168         dev_kfree_skb_irq(skb);
1169  update_stats:
1170         stats->rx_errors++;
1171         stats->rx_dropped++;
1172 }
1173
1174 static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
1175 {
1176         struct orinoco_private *priv = netdev_priv(dev);
1177         struct net_device_stats *stats = &priv->stats;
1178         struct iw_statistics *wstats = &priv->wstats;
1179         struct sk_buff *skb = NULL;
1180         u16 rxfid, status, fc;
1181         int length;
1182         struct hermes_rx_descriptor desc;
1183         struct ethhdr *hdr;
1184         int err;
1185
1186         rxfid = hermes_read_regn(hw, RXFID);
1187
1188         err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc),
1189                                rxfid, 0);
1190         if (err) {
1191                 printk(KERN_ERR "%s: error %d reading Rx descriptor. "
1192                        "Frame dropped.\n", dev->name, err);
1193                 goto update_stats;
1194         }
1195
1196         status = le16_to_cpu(desc.status);
1197
1198         if (status & HERMES_RXSTAT_BADCRC) {
1199                 DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
1200                       dev->name);
1201                 stats->rx_crc_errors++;
1202                 goto update_stats;
1203         }
1204
1205         /* Handle frames in monitor mode */
1206         if (priv->iw_mode == IW_MODE_MONITOR) {
1207                 orinoco_rx_monitor(dev, rxfid, &desc);
1208                 return;
1209         }
1210
1211         if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
1212                 DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
1213                       dev->name);
1214                 wstats->discard.code++;
1215                 goto update_stats;
1216         }
1217
1218         length = le16_to_cpu(desc.data_len);
1219         fc = le16_to_cpu(desc.frame_ctl);
1220
1221         /* Sanity checks */
1222         if (length < 3) { /* No for even an 802.2 LLC header */
1223                 /* At least on Symbol firmware with PCF we get quite a
1224                    lot of these legitimately - Poll frames with no
1225                    data. */
1226                 return;
1227         }
1228         if (length > IEEE80211_DATA_LEN) {
1229                 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
1230                        dev->name, length);
1231                 stats->rx_length_errors++;
1232                 goto update_stats;
1233         }
1234
1235         /* We need space for the packet data itself, plus an ethernet
1236            header, plus 2 bytes so we can align the IP header on a
1237            32bit boundary, plus 1 byte so we can read in odd length
1238            packets from the card, which has an IO granularity of 16
1239            bits */  
1240         skb = dev_alloc_skb(length+ETH_HLEN+2+1);
1241         if (!skb) {
1242                 printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
1243                        dev->name);
1244                 goto update_stats;
1245         }
1246
1247         /* We'll prepend the header, so reserve space for it.  The worst
1248            case is no decapsulation, when 802.3 header is prepended and
1249            nothing is removed.  2 is for aligning the IP header.  */
1250         skb_reserve(skb, ETH_HLEN + 2);
1251
1252         err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
1253                                ALIGN(length, 2), rxfid,
1254                                HERMES_802_2_OFFSET);
1255         if (err) {
1256                 printk(KERN_ERR "%s: error %d reading frame. "
1257                        "Frame dropped.\n", dev->name, err);
1258                 goto drop;
1259         }
1260
1261         /* Handle decapsulation
1262          * In most cases, the firmware tell us about SNAP frames.
1263          * For some reason, the SNAP frames sent by LinkSys APs
1264          * are not properly recognised by most firmwares.
1265          * So, check ourselves */
1266         if (length >= ENCAPS_OVERHEAD &&
1267             (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
1268              ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
1269              is_ethersnap(skb->data))) {
1270                 /* These indicate a SNAP within 802.2 LLC within
1271                    802.11 frame which we'll need to de-encapsulate to
1272                    the original EthernetII frame. */
1273                 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN - ENCAPS_OVERHEAD);
1274         } else {
1275                 /* 802.3 frame - prepend 802.3 header as is */
1276                 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
1277                 hdr->h_proto = htons(length);
1278         }
1279         memcpy(hdr->h_dest, desc.addr1, ETH_ALEN);
1280         if (fc & IEEE80211_FCTL_FROMDS)
1281                 memcpy(hdr->h_source, desc.addr3, ETH_ALEN);
1282         else
1283                 memcpy(hdr->h_source, desc.addr2, ETH_ALEN);
1284
1285         dev->last_rx = jiffies;
1286         skb->protocol = eth_type_trans(skb, dev);
1287         skb->ip_summed = CHECKSUM_NONE;
1288         if (fc & IEEE80211_FCTL_TODS)
1289                 skb->pkt_type = PACKET_OTHERHOST;
1290         
1291         /* Process the wireless stats if needed */
1292         orinoco_stat_gather(dev, skb, &desc);
1293
1294         /* Pass the packet to the networking stack */
1295         netif_rx(skb);
1296         stats->rx_packets++;
1297         stats->rx_bytes += length;
1298
1299         return;
1300
1301  drop:  
1302         dev_kfree_skb_irq(skb);
1303  update_stats:
1304         stats->rx_errors++;
1305         stats->rx_dropped++;
1306 }
1307
1308 /********************************************************************/
1309 /* Rx path (info frames)                                            */
1310 /********************************************************************/
1311
1312 static void print_linkstatus(struct net_device *dev, u16 status)
1313 {
1314         char * s;
1315
1316         if (suppress_linkstatus)
1317                 return;
1318
1319         switch (status) {
1320         case HERMES_LINKSTATUS_NOT_CONNECTED:
1321                 s = "Not Connected";
1322                 break;
1323         case HERMES_LINKSTATUS_CONNECTED:
1324                 s = "Connected";
1325                 break;
1326         case HERMES_LINKSTATUS_DISCONNECTED:
1327                 s = "Disconnected";
1328                 break;
1329         case HERMES_LINKSTATUS_AP_CHANGE:
1330                 s = "AP Changed";
1331                 break;
1332         case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
1333                 s = "AP Out of Range";
1334                 break;
1335         case HERMES_LINKSTATUS_AP_IN_RANGE:
1336                 s = "AP In Range";
1337                 break;
1338         case HERMES_LINKSTATUS_ASSOC_FAILED:
1339                 s = "Association Failed";
1340                 break;
1341         default:
1342                 s = "UNKNOWN";
1343         }
1344         
1345         printk(KERN_INFO "%s: New link status: %s (%04x)\n",
1346                dev->name, s, status);
1347 }
1348
1349 /* Search scan results for requested BSSID, join it if found */
1350 static void orinoco_join_ap(struct work_struct *work)
1351 {
1352         struct orinoco_private *priv =
1353                 container_of(work, struct orinoco_private, join_work);
1354         struct net_device *dev = priv->ndev;
1355         struct hermes *hw = &priv->hw;
1356         int err;
1357         unsigned long flags;
1358         struct join_req {
1359                 u8 bssid[ETH_ALEN];
1360                 __le16 channel;
1361         } __attribute__ ((packed)) req;
1362         const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
1363         struct prism2_scan_apinfo *atom = NULL;
1364         int offset = 4;
1365         int found = 0;
1366         u8 *buf;
1367         u16 len;
1368
1369         /* Allocate buffer for scan results */
1370         buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
1371         if (! buf)
1372                 return;
1373
1374         if (orinoco_lock(priv, &flags) != 0)
1375                 goto fail_lock;
1376
1377         /* Sanity checks in case user changed something in the meantime */
1378         if (! priv->bssid_fixed)
1379                 goto out;
1380
1381         if (strlen(priv->desired_essid) == 0)
1382                 goto out;
1383
1384         /* Read scan results from the firmware */
1385         err = hermes_read_ltv(hw, USER_BAP,
1386                               HERMES_RID_SCANRESULTSTABLE,
1387                               MAX_SCAN_LEN, &len, buf);
1388         if (err) {
1389                 printk(KERN_ERR "%s: Cannot read scan results\n",
1390                        dev->name);
1391                 goto out;
1392         }
1393
1394         len = HERMES_RECLEN_TO_BYTES(len);
1395
1396         /* Go through the scan results looking for the channel of the AP
1397          * we were requested to join */
1398         for (; offset + atom_len <= len; offset += atom_len) {
1399                 atom = (struct prism2_scan_apinfo *) (buf + offset);
1400                 if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
1401                         found = 1;
1402                         break;
1403                 }
1404         }
1405
1406         if (! found) {
1407                 DEBUG(1, "%s: Requested AP not found in scan results\n",
1408                       dev->name);
1409                 goto out;
1410         }
1411
1412         memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
1413         req.channel = atom->channel;    /* both are little-endian */
1414         err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
1415                                   &req);
1416         if (err)
1417                 printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
1418
1419  out:
1420         orinoco_unlock(priv, &flags);
1421
1422  fail_lock:
1423         kfree(buf);
1424 }
1425
1426 /* Send new BSSID to userspace */
1427 static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
1428 {
1429         struct net_device *dev = priv->ndev;
1430         struct hermes *hw = &priv->hw;
1431         union iwreq_data wrqu;
1432         int err;
1433
1434         err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
1435                               ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
1436         if (err != 0)
1437                 return;
1438
1439         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1440
1441         /* Send event to user space */
1442         wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
1443 }
1444
1445 static void orinoco_send_wevents(struct work_struct *work)
1446 {
1447         struct orinoco_private *priv =
1448                 container_of(work, struct orinoco_private, wevent_work);
1449         unsigned long flags;
1450
1451         if (orinoco_lock(priv, &flags) != 0)
1452                 return;
1453
1454         orinoco_send_bssid_wevent(priv);
1455
1456         orinoco_unlock(priv, &flags);
1457 }
1458
1459 static inline void orinoco_clear_scan_results(struct orinoco_private *priv,
1460                                               unsigned long scan_age)
1461 {
1462         if (priv->has_ext_scan) {
1463                 struct xbss_element *bss;
1464                 struct xbss_element *tmp_bss;
1465
1466                 /* Blow away current list of scan results */
1467                 list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
1468                         if (!scan_age ||
1469                             time_after(jiffies, bss->last_scanned + scan_age)) {
1470                                 list_move_tail(&bss->list,
1471                                                &priv->bss_free_list);
1472                                 /* Don't blow away ->list, just BSS data */
1473                                 memset(&bss->bss, 0, sizeof(bss->bss));
1474                                 bss->last_scanned = 0;
1475                         }
1476                 }
1477         } else {
1478                 struct bss_element *bss;
1479                 struct bss_element *tmp_bss;
1480
1481                 /* Blow away current list of scan results */
1482                 list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
1483                         if (!scan_age ||
1484                             time_after(jiffies, bss->last_scanned + scan_age)) {
1485                                 list_move_tail(&bss->list,
1486                                                &priv->bss_free_list);
1487                                 /* Don't blow away ->list, just BSS data */
1488                                 memset(&bss->bss, 0, sizeof(bss->bss));
1489                                 bss->last_scanned = 0;
1490                         }
1491                 }
1492         }
1493 }
1494
1495 static void orinoco_add_ext_scan_result(struct orinoco_private *priv,
1496                                         struct agere_ext_scan_info *atom)
1497 {
1498         struct xbss_element *bss = NULL;
1499         int found = 0;
1500
1501         /* Try to update an existing bss first */
1502         list_for_each_entry(bss, &priv->bss_list, list) {
1503                 if (compare_ether_addr(bss->bss.bssid, atom->bssid))
1504                         continue;
1505                 /* ESSID lengths */
1506                 if (bss->bss.data[1] != atom->data[1])
1507                         continue;
1508                 if (memcmp(&bss->bss.data[2], &atom->data[2],
1509                            atom->data[1]))
1510                         continue;
1511                 found = 1;
1512                 break;
1513         }
1514
1515         /* Grab a bss off the free list */
1516         if (!found && !list_empty(&priv->bss_free_list)) {
1517                 bss = list_entry(priv->bss_free_list.next,
1518                                  struct xbss_element, list);
1519                 list_del(priv->bss_free_list.next);
1520
1521                 list_add_tail(&bss->list, &priv->bss_list);
1522         }
1523
1524         if (bss) {
1525                 /* Always update the BSS to get latest beacon info */
1526                 memcpy(&bss->bss, atom, sizeof(bss->bss));
1527                 bss->last_scanned = jiffies;
1528         }
1529 }
1530
1531 static int orinoco_process_scan_results(struct net_device *dev,
1532                                         unsigned char *buf,
1533                                         int len)
1534 {
1535         struct orinoco_private *priv = netdev_priv(dev);
1536         int                     offset;         /* In the scan data */
1537         union hermes_scan_info *atom;
1538         int                     atom_len;
1539
1540         switch (priv->firmware_type) {
1541         case FIRMWARE_TYPE_AGERE:
1542                 atom_len = sizeof(struct agere_scan_apinfo);
1543                 offset = 0;
1544                 break;
1545         case FIRMWARE_TYPE_SYMBOL:
1546                 /* Lack of documentation necessitates this hack.
1547                  * Different firmwares have 68 or 76 byte long atoms.
1548                  * We try modulo first.  If the length divides by both,
1549                  * we check what would be the channel in the second
1550                  * frame for a 68-byte atom.  76-byte atoms have 0 there.
1551                  * Valid channel cannot be 0.  */
1552                 if (len % 76)
1553                         atom_len = 68;
1554                 else if (len % 68)
1555                         atom_len = 76;
1556                 else if (len >= 1292 && buf[68] == 0)
1557                         atom_len = 76;
1558                 else
1559                         atom_len = 68;
1560                 offset = 0;
1561                 break;
1562         case FIRMWARE_TYPE_INTERSIL:
1563                 offset = 4;
1564                 if (priv->has_hostscan) {
1565                         atom_len = le16_to_cpup((__le16 *)buf);
1566                         /* Sanity check for atom_len */
1567                         if (atom_len < sizeof(struct prism2_scan_apinfo)) {
1568                                 printk(KERN_ERR "%s: Invalid atom_len in scan "
1569                                        "data: %d\n", dev->name, atom_len);
1570                                 return -EIO;
1571                         }
1572                 } else
1573                         atom_len = offsetof(struct prism2_scan_apinfo, atim);
1574                 break;
1575         default:
1576                 return -EOPNOTSUPP;
1577         }
1578
1579         /* Check that we got an whole number of atoms */
1580         if ((len - offset) % atom_len) {
1581                 printk(KERN_ERR "%s: Unexpected scan data length %d, "
1582                        "atom_len %d, offset %d\n", dev->name, len,
1583                        atom_len, offset);
1584                 return -EIO;
1585         }
1586
1587         orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
1588
1589         /* Read the entries one by one */
1590         for (; offset + atom_len <= len; offset += atom_len) {
1591                 int found = 0;
1592                 struct bss_element *bss = NULL;
1593
1594                 /* Get next atom */
1595                 atom = (union hermes_scan_info *) (buf + offset);
1596
1597                 /* Try to update an existing bss first */
1598                 list_for_each_entry(bss, &priv->bss_list, list) {
1599                         if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
1600                                 continue;
1601                         if (le16_to_cpu(bss->bss.a.essid_len) !=
1602                               le16_to_cpu(atom->a.essid_len))
1603                                 continue;
1604                         if (memcmp(bss->bss.a.essid, atom->a.essid,
1605                               le16_to_cpu(atom->a.essid_len)))
1606                                 continue;
1607                         found = 1;
1608                         break;
1609                 }
1610
1611                 /* Grab a bss off the free list */
1612                 if (!found && !list_empty(&priv->bss_free_list)) {
1613                         bss = list_entry(priv->bss_free_list.next,
1614                                          struct bss_element, list);
1615                         list_del(priv->bss_free_list.next);
1616
1617                         list_add_tail(&bss->list, &priv->bss_list);
1618                 }
1619
1620                 if (bss) {
1621                         /* Always update the BSS to get latest beacon info */
1622                         memcpy(&bss->bss, atom, sizeof(bss->bss));
1623                         bss->last_scanned = jiffies;
1624                 }
1625         }
1626
1627         return 0;
1628 }
1629
1630 static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1631 {
1632         struct orinoco_private *priv = netdev_priv(dev);
1633         u16 infofid;
1634         struct {
1635                 __le16 len;
1636                 __le16 type;
1637         } __attribute__ ((packed)) info;
1638         int len, type;
1639         int err;
1640
1641         /* This is an answer to an INQUIRE command that we did earlier,
1642          * or an information "event" generated by the card
1643          * The controller return to us a pseudo frame containing
1644          * the information in question - Jean II */
1645         infofid = hermes_read_regn(hw, INFOFID);
1646
1647         /* Read the info frame header - don't try too hard */
1648         err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
1649                                infofid, 0);
1650         if (err) {
1651                 printk(KERN_ERR "%s: error %d reading info frame. "
1652                        "Frame dropped.\n", dev->name, err);
1653                 return;
1654         }
1655         
1656         len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
1657         type = le16_to_cpu(info.type);
1658
1659         switch (type) {
1660         case HERMES_INQ_TALLIES: {
1661                 struct hermes_tallies_frame tallies;
1662                 struct iw_statistics *wstats = &priv->wstats;
1663                 
1664                 if (len > sizeof(tallies)) {
1665                         printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
1666                                dev->name, len);
1667                         len = sizeof(tallies);
1668                 }
1669                 
1670                 err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
1671                                        infofid, sizeof(info));
1672                 if (err)
1673                         break;
1674                 
1675                 /* Increment our various counters */
1676                 /* wstats->discard.nwid - no wrong BSSID stuff */
1677                 wstats->discard.code +=
1678                         le16_to_cpu(tallies.RxWEPUndecryptable);
1679                 if (len == sizeof(tallies))  
1680                         wstats->discard.code +=
1681                                 le16_to_cpu(tallies.RxDiscards_WEPICVError) +
1682                                 le16_to_cpu(tallies.RxDiscards_WEPExcluded);
1683                 wstats->discard.misc +=
1684                         le16_to_cpu(tallies.TxDiscardsWrongSA);
1685                 wstats->discard.fragment +=
1686                         le16_to_cpu(tallies.RxMsgInBadMsgFragments);
1687                 wstats->discard.retries +=
1688                         le16_to_cpu(tallies.TxRetryLimitExceeded);
1689                 /* wstats->miss.beacon - no match */
1690         }
1691         break;
1692         case HERMES_INQ_LINKSTATUS: {
1693                 struct hermes_linkstatus linkstatus;
1694                 u16 newstatus;
1695                 int connected;
1696
1697                 if (priv->iw_mode == IW_MODE_MONITOR)
1698                         break;
1699
1700                 if (len != sizeof(linkstatus)) {
1701                         printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
1702                                dev->name, len);
1703                         break;
1704                 }
1705
1706                 err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
1707                                        infofid, sizeof(info));
1708                 if (err)
1709                         break;
1710                 newstatus = le16_to_cpu(linkstatus.linkstatus);
1711
1712                 /* Symbol firmware uses "out of range" to signal that
1713                  * the hostscan frame can be requested.  */
1714                 if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
1715                     priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
1716                     priv->has_hostscan && priv->scan_inprogress) {
1717                         hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
1718                         break;
1719                 }
1720
1721                 connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
1722                         || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
1723                         || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
1724
1725                 if (connected)
1726                         netif_carrier_on(dev);
1727                 else if (!ignore_disconnect)
1728                         netif_carrier_off(dev);
1729
1730                 if (newstatus != priv->last_linkstatus) {
1731                         priv->last_linkstatus = newstatus;
1732                         print_linkstatus(dev, newstatus);
1733                         /* The info frame contains only one word which is the
1734                          * status (see hermes.h). The status is pretty boring
1735                          * in itself, that's why we export the new BSSID...
1736                          * Jean II */
1737                         schedule_work(&priv->wevent_work);
1738                 }
1739         }
1740         break;
1741         case HERMES_INQ_SCAN:
1742                 if (!priv->scan_inprogress && priv->bssid_fixed &&
1743                     priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
1744                         schedule_work(&priv->join_work);
1745                         break;
1746                 }
1747                 /* fall through */
1748         case HERMES_INQ_HOSTSCAN:
1749         case HERMES_INQ_HOSTSCAN_SYMBOL: {
1750                 /* Result of a scanning. Contains information about
1751                  * cells in the vicinity - Jean II */
1752                 union iwreq_data        wrqu;
1753                 unsigned char *buf;
1754
1755                 /* Scan is no longer in progress */
1756                 priv->scan_inprogress = 0;
1757
1758                 /* Sanity check */
1759                 if (len > 4096) {
1760                         printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
1761                                dev->name, len);
1762                         break;
1763                 }
1764
1765                 /* Allocate buffer for results */
1766                 buf = kmalloc(len, GFP_ATOMIC);
1767                 if (buf == NULL)
1768                         /* No memory, so can't printk()... */
1769                         break;
1770
1771                 /* Read scan data */
1772                 err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
1773                                        infofid, sizeof(info));
1774                 if (err) {
1775                         kfree(buf);
1776                         break;
1777                 }
1778
1779 #ifdef ORINOCO_DEBUG
1780                 {
1781                         int     i;
1782                         printk(KERN_DEBUG "Scan result [%02X", buf[0]);
1783                         for(i = 1; i < (len * 2); i++)
1784                                 printk(":%02X", buf[i]);
1785                         printk("]\n");
1786                 }
1787 #endif  /* ORINOCO_DEBUG */
1788
1789                 if (orinoco_process_scan_results(dev, buf, len) == 0) {
1790                         /* Send an empty event to user space.
1791                          * We don't send the received data on the event because
1792                          * it would require us to do complex transcoding, and
1793                          * we want to minimise the work done in the irq handler
1794                          * Use a request to extract the data - Jean II */
1795                         wrqu.data.length = 0;
1796                         wrqu.data.flags = 0;
1797                         wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
1798                 }
1799                 kfree(buf);
1800         }
1801         break;
1802         case HERMES_INQ_CHANNELINFO:
1803         {
1804                 struct agere_ext_scan_info *bss;
1805
1806                 if (!priv->scan_inprogress) {
1807                         printk(KERN_DEBUG "%s: Got chaninfo without scan, "
1808                                "len=%d\n", dev->name, len);
1809                         break;
1810                 }
1811
1812                 /* An empty result indicates that the scan is complete */
1813                 if (len == 0) {
1814                         union iwreq_data        wrqu;
1815
1816                         /* Scan is no longer in progress */
1817                         priv->scan_inprogress = 0;
1818
1819                         wrqu.data.length = 0;
1820                         wrqu.data.flags = 0;
1821                         wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
1822                         break;
1823                 }
1824
1825                 /* Sanity check */
1826                 else if (len > sizeof(*bss)) {
1827                         printk(KERN_WARNING
1828                                "%s: Ext scan results too large (%d bytes). "
1829                                "Truncating results to %zd bytes.\n",
1830                                dev->name, len, sizeof(*bss));
1831                         len = sizeof(*bss);
1832                 } else if (len < (offsetof(struct agere_ext_scan_info,
1833                                            data) + 2)) {
1834                         /* Drop this result now so we don't have to
1835                          * keep checking later */
1836                         printk(KERN_WARNING
1837                                "%s: Ext scan results too short (%d bytes)\n",
1838                                dev->name, len);
1839                         break;
1840                 }
1841
1842                 bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
1843                 if (bss == NULL)
1844                         break;
1845
1846                 /* Read scan data */
1847                 err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len,
1848                                        infofid, sizeof(info));
1849                 if (err) {
1850                         kfree(bss);
1851                         break;
1852                 }
1853
1854                 orinoco_add_ext_scan_result(priv, bss);
1855
1856                 kfree(bss);
1857                 break;
1858         }
1859         case HERMES_INQ_SEC_STAT_AGERE:
1860                 /* Security status (Agere specific) */
1861                 /* Ignore this frame for now */
1862                 if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
1863                         break;
1864                 /* fall through */
1865         default:
1866                 printk(KERN_DEBUG "%s: Unknown information frame received: "
1867                        "type 0x%04x, length %d\n", dev->name, type, len);
1868                 /* We don't actually do anything about it */
1869                 break;
1870         }
1871 }
1872
1873 static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
1874 {
1875         if (net_ratelimit())
1876                 printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
1877 }
1878
1879 /********************************************************************/
1880 /* Internal hardware control routines                               */
1881 /********************************************************************/
1882
1883 int __orinoco_up(struct net_device *dev)
1884 {
1885         struct orinoco_private *priv = netdev_priv(dev);
1886         struct hermes *hw = &priv->hw;
1887         int err;
1888
1889         netif_carrier_off(dev); /* just to make sure */
1890
1891         err = __orinoco_program_rids(dev);
1892         if (err) {
1893                 printk(KERN_ERR "%s: Error %d configuring card\n",
1894                        dev->name, err);
1895                 return err;
1896         }
1897
1898         /* Fire things up again */
1899         hermes_set_irqmask(hw, ORINOCO_INTEN);
1900         err = hermes_enable_port(hw, 0);
1901         if (err) {
1902                 printk(KERN_ERR "%s: Error %d enabling MAC port\n",
1903                        dev->name, err);
1904                 return err;
1905         }
1906
1907         netif_start_queue(dev);
1908
1909         return 0;
1910 }
1911
1912 int __orinoco_down(struct net_device *dev)
1913 {
1914         struct orinoco_private *priv = netdev_priv(dev);
1915         struct hermes *hw = &priv->hw;
1916         int err;
1917
1918         netif_stop_queue(dev);
1919
1920         if (! priv->hw_unavailable) {
1921                 if (! priv->broken_disableport) {
1922                         err = hermes_disable_port(hw, 0);
1923                         if (err) {
1924                                 /* Some firmwares (e.g. Intersil 1.3.x) seem
1925                                  * to have problems disabling the port, oh
1926                                  * well, too bad. */
1927                                 printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
1928                                        dev->name, err);
1929                                 priv->broken_disableport = 1;
1930                         }
1931                 }
1932                 hermes_set_irqmask(hw, 0);
1933                 hermes_write_regn(hw, EVACK, 0xffff);
1934         }
1935         
1936         /* firmware will have to reassociate */
1937         netif_carrier_off(dev);
1938         priv->last_linkstatus = 0xffff;
1939
1940         return 0;
1941 }
1942
1943 static int orinoco_allocate_fid(struct net_device *dev)
1944 {
1945         struct orinoco_private *priv = netdev_priv(dev);
1946         struct hermes *hw = &priv->hw;
1947         int err;
1948
1949         err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
1950         if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
1951                 /* Try workaround for old Symbol firmware bug */
1952                 printk(KERN_WARNING "%s: firmware ALLOC bug detected "
1953                        "(old Symbol firmware?). Trying to work around... ",
1954                        dev->name);
1955                 
1956                 priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
1957                 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
1958                 if (err)
1959                         printk("failed!\n");
1960                 else
1961                         printk("ok.\n");
1962         }
1963
1964         return err;
1965 }
1966
1967 int orinoco_reinit_firmware(struct net_device *dev)
1968 {
1969         struct orinoco_private *priv = netdev_priv(dev);
1970         struct hermes *hw = &priv->hw;
1971         int err;
1972
1973         err = hermes_init(hw);
1974         if (!err)
1975                 err = orinoco_allocate_fid(dev);
1976
1977         return err;
1978 }
1979
1980 static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
1981 {
1982         hermes_t *hw = &priv->hw;
1983         int err = 0;
1984
1985         if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
1986                 printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
1987                        priv->ndev->name, priv->bitratemode);
1988                 return -EINVAL;
1989         }
1990
1991         switch (priv->firmware_type) {
1992         case FIRMWARE_TYPE_AGERE:
1993                 err = hermes_write_wordrec(hw, USER_BAP,
1994                                            HERMES_RID_CNFTXRATECONTROL,
1995                                            bitrate_table[priv->bitratemode].agere_txratectrl);
1996                 break;
1997         case FIRMWARE_TYPE_INTERSIL:
1998         case FIRMWARE_TYPE_SYMBOL:
1999                 err = hermes_write_wordrec(hw, USER_BAP,
2000                                            HERMES_RID_CNFTXRATECONTROL,
2001                                            bitrate_table[priv->bitratemode].intersil_txratectrl);
2002                 break;
2003         default:
2004                 BUG();
2005         }
2006
2007         return err;
2008 }
2009
2010 /* Set fixed AP address */
2011 static int __orinoco_hw_set_wap(struct orinoco_private *priv)
2012 {
2013         int roaming_flag;
2014         int err = 0;
2015         hermes_t *hw = &priv->hw;
2016
2017         switch (priv->firmware_type) {
2018         case FIRMWARE_TYPE_AGERE:
2019                 /* not supported */
2020                 break;
2021         case FIRMWARE_TYPE_INTERSIL:
2022                 if (priv->bssid_fixed)
2023                         roaming_flag = 2;
2024                 else
2025                         roaming_flag = 1;
2026
2027                 err = hermes_write_wordrec(hw, USER_BAP,
2028                                            HERMES_RID_CNFROAMINGMODE,
2029                                            roaming_flag);
2030                 break;
2031         case FIRMWARE_TYPE_SYMBOL:
2032                 err = HERMES_WRITE_RECORD(hw, USER_BAP,
2033                                           HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
2034                                           &priv->desired_bssid);
2035                 break;
2036         }
2037         return err;
2038 }
2039
2040 /* Change the WEP keys and/or the current keys.  Can be called
2041  * either from __orinoco_hw_setup_wep() or directly from
2042  * orinoco_ioctl_setiwencode().  In the later case the association
2043  * with the AP is not broken (if the firmware can handle it),
2044  * which is needed for 802.1x implementations. */
2045 static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
2046 {
2047         hermes_t *hw = &priv->hw;
2048         int err = 0;
2049
2050         switch (priv->firmware_type) {
2051         case FIRMWARE_TYPE_AGERE:
2052                 err = HERMES_WRITE_RECORD(hw, USER_BAP,
2053                                           HERMES_RID_CNFWEPKEYS_AGERE,
2054                                           &priv->keys);
2055                 if (err)
2056                         return err;
2057                 err = hermes_write_wordrec(hw, USER_BAP,
2058                                            HERMES_RID_CNFTXKEY_AGERE,
2059                                            priv->tx_key);
2060                 if (err)
2061                         return err;
2062                 break;
2063         case FIRMWARE_TYPE_INTERSIL:
2064         case FIRMWARE_TYPE_SYMBOL:
2065                 {
2066                         int keylen;
2067                         int i;
2068
2069                         /* Force uniform key length to work around firmware bugs */
2070                         keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
2071                         
2072                         if (keylen > LARGE_KEY_SIZE) {
2073                                 printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
2074                                        priv->ndev->name, priv->tx_key, keylen);
2075                                 return -E2BIG;
2076                         }
2077
2078                         /* Write all 4 keys */
2079                         for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
2080                                 err = hermes_write_ltv(hw, USER_BAP,
2081                                                        HERMES_RID_CNFDEFAULTKEY0 + i,
2082                                                        HERMES_BYTES_TO_RECLEN(keylen),
2083                                                        priv->keys[i].data);
2084                                 if (err)
2085                                         return err;
2086                         }
2087
2088                         /* Write the index of the key used in transmission */
2089                         err = hermes_write_wordrec(hw, USER_BAP,
2090                                                    HERMES_RID_CNFWEPDEFAULTKEYID,
2091                                                    priv->tx_key);
2092                         if (err)
2093                                 return err;
2094                 }
2095                 break;
2096         }
2097
2098         return 0;
2099 }
2100
2101 static int __orinoco_hw_setup_wep(struct orinoco_private *priv)
2102 {
2103         hermes_t *hw = &priv->hw;
2104         int err = 0;
2105         int master_wep_flag;
2106         int auth_flag;
2107         int enc_flag;
2108
2109         if (priv->encode_alg == IW_ENCODE_ALG_WEP)
2110                 __orinoco_hw_setup_wepkeys(priv);
2111
2112         if (priv->wep_restrict)
2113                 auth_flag = HERMES_AUTH_SHARED_KEY;
2114         else
2115                 auth_flag = HERMES_AUTH_OPEN;
2116
2117         if (priv->encode_alg == IW_ENCODE_ALG_WEP)
2118                 enc_flag = 1;
2119         else
2120                 enc_flag = 0;
2121
2122         switch (priv->firmware_type) {
2123         case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
2124                 if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
2125                         /* Enable the shared-key authentication. */
2126                         err = hermes_write_wordrec(hw, USER_BAP,
2127                                                    HERMES_RID_CNFAUTHENTICATION_AGERE,
2128                                                    auth_flag);
2129                 }
2130                 err = hermes_write_wordrec(hw, USER_BAP,
2131                                            HERMES_RID_CNFWEPENABLED_AGERE,
2132                                            enc_flag);
2133                 if (err)
2134                         return err;
2135                 break;
2136
2137         case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
2138         case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
2139                 if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
2140                         if (priv->wep_restrict ||
2141                             (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
2142                                 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
2143                                                   HERMES_WEP_EXCL_UNENCRYPTED;
2144                         else
2145                                 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
2146
2147                         err = hermes_write_wordrec(hw, USER_BAP,
2148                                                    HERMES_RID_CNFAUTHENTICATION,
2149                                                    auth_flag);
2150                         if (err)
2151                                 return err;
2152                 } else
2153                         master_wep_flag = 0;
2154
2155                 if (priv->iw_mode == IW_MODE_MONITOR)
2156                         master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
2157
2158                 /* Master WEP setting : on/off */
2159                 err = hermes_write_wordrec(hw, USER_BAP,
2160                                            HERMES_RID_CNFWEPFLAGS_INTERSIL,
2161                                            master_wep_flag);
2162                 if (err)
2163                         return err;     
2164
2165                 break;
2166         }
2167
2168         return 0;
2169 }
2170
2171 static int __orinoco_program_rids(struct net_device *dev)
2172 {
2173         struct orinoco_private *priv = netdev_priv(dev);
2174         hermes_t *hw = &priv->hw;
2175         int err;
2176         struct hermes_idstring idbuf;
2177
2178         /* Set the MAC address */
2179         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
2180                                HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
2181         if (err) {
2182                 printk(KERN_ERR "%s: Error %d setting MAC address\n",
2183                        dev->name, err);
2184                 return err;
2185         }
2186
2187         /* Set up the link mode */
2188         err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
2189                                    priv->port_type);
2190         if (err) {
2191                 printk(KERN_ERR "%s: Error %d setting port type\n",
2192                        dev->name, err);
2193                 return err;
2194         }
2195         /* Set the channel/frequency */
2196         if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
2197                 err = hermes_write_wordrec(hw, USER_BAP,
2198                                            HERMES_RID_CNFOWNCHANNEL,
2199                                            priv->channel);
2200                 if (err) {
2201                         printk(KERN_ERR "%s: Error %d setting channel %d\n",
2202                                dev->name, err, priv->channel);
2203                         return err;
2204                 }
2205         }
2206
2207         if (priv->has_ibss) {
2208                 u16 createibss;
2209
2210                 if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
2211                         printk(KERN_WARNING "%s: This firmware requires an "
2212                                "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
2213                         /* With wvlan_cs, in this case, we would crash.
2214                          * hopefully, this driver will behave better...
2215                          * Jean II */
2216                         createibss = 0;
2217                 } else {
2218                         createibss = priv->createibss;
2219                 }
2220                 
2221                 err = hermes_write_wordrec(hw, USER_BAP,
2222                                            HERMES_RID_CNFCREATEIBSS,
2223                                            createibss);
2224                 if (err) {
2225                         printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
2226                                dev->name, err);
2227                         return err;
2228                 }
2229         }
2230
2231         /* Set the desired BSSID */
2232         err = __orinoco_hw_set_wap(priv);
2233         if (err) {
2234                 printk(KERN_ERR "%s: Error %d setting AP address\n",
2235                        dev->name, err);
2236                 return err;
2237         }
2238         /* Set the desired ESSID */
2239         idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
2240         memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
2241         /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
2242         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
2243                                HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
2244                                &idbuf);
2245         if (err) {
2246                 printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
2247                        dev->name, err);
2248                 return err;
2249         }
2250         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
2251                                HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
2252                                &idbuf);
2253         if (err) {
2254                 printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
2255                        dev->name, err);
2256                 return err;
2257         }
2258
2259         /* Set the station name */
2260         idbuf.len = cpu_to_le16(strlen(priv->nick));
2261         memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
2262         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
2263                                HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
2264                                &idbuf);
2265         if (err) {
2266                 printk(KERN_ERR "%s: Error %d setting nickname\n",
2267                        dev->name, err);
2268                 return err;
2269         }
2270
2271         /* Set AP density */
2272         if (priv->has_sensitivity) {
2273                 err = hermes_write_wordrec(hw, USER_BAP,
2274                                            HERMES_RID_CNFSYSTEMSCALE,
2275                                            priv->ap_density);
2276                 if (err) {
2277                         printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE.  "
2278                                "Disabling sensitivity control\n",
2279                                dev->name, err);
2280
2281                         priv->has_sensitivity = 0;
2282                 }
2283         }
2284
2285         /* Set RTS threshold */
2286         err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
2287                                    priv->rts_thresh);
2288         if (err) {
2289                 printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
2290                        dev->name, err);
2291                 return err;
2292         }
2293
2294         /* Set fragmentation threshold or MWO robustness */
2295         if (priv->has_mwo)
2296                 err = hermes_write_wordrec(hw, USER_BAP,
2297                                            HERMES_RID_CNFMWOROBUST_AGERE,
2298                                            priv->mwo_robust);
2299         else
2300                 err = hermes_write_wordrec(hw, USER_BAP,
2301                                            HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
2302                                            priv->frag_thresh);
2303         if (err) {
2304                 printk(KERN_ERR "%s: Error %d setting fragmentation\n",
2305                        dev->name, err);
2306                 return err;
2307         }
2308
2309         /* Set bitrate */
2310         err = __orinoco_hw_set_bitrate(priv);
2311         if (err) {
2312                 printk(KERN_ERR "%s: Error %d setting bitrate\n",
2313                        dev->name, err);
2314                 return err;
2315         }
2316
2317         /* Set power management */
2318         if (priv->has_pm) {
2319                 err = hermes_write_wordrec(hw, USER_BAP,
2320                                            HERMES_RID_CNFPMENABLED,
2321                                            priv->pm_on);
2322                 if (err) {
2323                         printk(KERN_ERR "%s: Error %d setting up PM\n",
2324                                dev->name, err);
2325                         return err;
2326                 }
2327
2328                 err = hermes_write_wordrec(hw, USER_BAP,
2329                                            HERMES_RID_CNFMULTICASTRECEIVE,
2330                                            priv->pm_mcast);
2331                 if (err) {
2332                         printk(KERN_ERR "%s: Error %d setting up PM\n",
2333                                dev->name, err);
2334                         return err;
2335                 }
2336                 err = hermes_write_wordrec(hw, USER_BAP,
2337                                            HERMES_RID_CNFMAXSLEEPDURATION,
2338                                            priv->pm_period);
2339                 if (err) {
2340                         printk(KERN_ERR "%s: Error %d setting up PM\n",
2341                                dev->name, err);
2342                         return err;
2343                 }
2344                 err = hermes_write_wordrec(hw, USER_BAP,
2345                                            HERMES_RID_CNFPMHOLDOVERDURATION,
2346                                            priv->pm_timeout);
2347                 if (err) {
2348                         printk(KERN_ERR "%s: Error %d setting up PM\n",
2349                                dev->name, err);
2350                         return err;
2351                 }
2352         }
2353
2354         /* Set preamble - only for Symbol so far... */
2355         if (priv->has_preamble) {
2356                 err = hermes_write_wordrec(hw, USER_BAP,
2357                                            HERMES_RID_CNFPREAMBLE_SYMBOL,
2358                                            priv->preamble);
2359                 if (err) {
2360                         printk(KERN_ERR "%s: Error %d setting preamble\n",
2361                                dev->name, err);
2362                         return err;
2363                 }
2364         }
2365
2366         /* Set up encryption */
2367         if (priv->has_wep) {
2368                 err = __orinoco_hw_setup_wep(priv);
2369                 if (err) {
2370                         printk(KERN_ERR "%s: Error %d activating WEP\n",
2371                                dev->name, err);
2372                         return err;
2373                 }
2374         }
2375
2376         if (priv->iw_mode == IW_MODE_MONITOR) {
2377                 /* Enable monitor mode */
2378                 dev->type = ARPHRD_IEEE80211;
2379                 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 
2380                                             HERMES_TEST_MONITOR, 0, NULL);
2381         } else {
2382                 /* Disable monitor mode */
2383                 dev->type = ARPHRD_ETHER;
2384                 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
2385                                             HERMES_TEST_STOP, 0, NULL);
2386         }
2387         if (err)
2388                 return err;
2389
2390         /* Set promiscuity / multicast*/
2391         priv->promiscuous = 0;
2392         priv->mc_count = 0;
2393
2394         /* FIXME: what about netif_tx_lock */
2395         __orinoco_set_multicast_list(dev);
2396
2397         return 0;
2398 }
2399
2400 /* FIXME: return int? */
2401 static void
2402 __orinoco_set_multicast_list(struct net_device *dev)
2403 {
2404         struct orinoco_private *priv = netdev_priv(dev);
2405         hermes_t *hw = &priv->hw;
2406         int err = 0;
2407         int promisc, mc_count;
2408
2409         /* The Hermes doesn't seem to have an allmulti mode, so we go
2410          * into promiscuous mode and let the upper levels deal. */
2411         if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
2412              (dev->mc_count > MAX_MULTICAST(priv)) ) {
2413                 promisc = 1;
2414                 mc_count = 0;
2415         } else {
2416                 promisc = 0;
2417                 mc_count = dev->mc_count;
2418         }
2419
2420         if (promisc != priv->promiscuous) {
2421                 err = hermes_write_wordrec(hw, USER_BAP,
2422                                            HERMES_RID_CNFPROMISCUOUSMODE,
2423                                            promisc);
2424                 if (err) {
2425                         printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
2426                                dev->name, err);
2427                 } else 
2428                         priv->promiscuous = promisc;
2429         }
2430
2431         if (! promisc && (mc_count || priv->mc_count) ) {
2432                 struct dev_mc_list *p = dev->mc_list;
2433                 struct hermes_multicast mclist;
2434                 int i;
2435
2436                 for (i = 0; i < mc_count; i++) {
2437                         /* paranoia: is list shorter than mc_count? */
2438                         BUG_ON(! p);
2439                         /* paranoia: bad address size in list? */
2440                         BUG_ON(p->dmi_addrlen != ETH_ALEN);
2441                         
2442                         memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
2443                         p = p->next;
2444                 }
2445                 
2446                 if (p)
2447                         printk(KERN_WARNING "%s: Multicast list is "
2448                                "longer than mc_count\n", dev->name);
2449
2450                 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES,
2451                                        HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
2452                                        &mclist);
2453                 if (err)
2454                         printk(KERN_ERR "%s: Error %d setting multicast list.\n",
2455                                dev->name, err);
2456                 else
2457                         priv->mc_count = mc_count;
2458         }
2459 }
2460
2461 /* This must be called from user context, without locks held - use
2462  * schedule_work() */
2463 static void orinoco_reset(struct work_struct *work)
2464 {
2465         struct orinoco_private *priv =
2466                 container_of(work, struct orinoco_private, reset_work);
2467         struct net_device *dev = priv->ndev;
2468         struct hermes *hw = &priv->hw;
2469         int err;
2470         unsigned long flags;
2471
2472         if (orinoco_lock(priv, &flags) != 0)
2473                 /* When the hardware becomes available again, whatever
2474                  * detects that is responsible for re-initializing
2475                  * it. So no need for anything further */
2476                 return;
2477
2478         netif_stop_queue(dev);
2479
2480         /* Shut off interrupts.  Depending on what state the hardware
2481          * is in, this might not work, but we'll try anyway */
2482         hermes_set_irqmask(hw, 0);
2483         hermes_write_regn(hw, EVACK, 0xffff);
2484
2485         priv->hw_unavailable++;
2486         priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
2487         netif_carrier_off(dev);
2488
2489         orinoco_unlock(priv, &flags);
2490
2491         /* Scanning support: Cleanup of driver struct */
2492         orinoco_clear_scan_results(priv, 0);
2493         priv->scan_inprogress = 0;
2494
2495         if (priv->hard_reset) {
2496                 err = (*priv->hard_reset)(priv);
2497                 if (err) {
2498                         printk(KERN_ERR "%s: orinoco_reset: Error %d "
2499                                "performing hard reset\n", dev->name, err);
2500                         goto disable;
2501                 }
2502         }
2503
2504         if (priv->do_fw_download) {
2505                 err = orinoco_download(priv);
2506                 if (err)
2507                         priv->do_fw_download = 0;
2508         }
2509
2510         err = orinoco_reinit_firmware(dev);
2511         if (err) {
2512                 printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
2513                        dev->name, err);
2514                 goto disable;
2515         }
2516
2517         spin_lock_irq(&priv->lock); /* This has to be called from user context */
2518
2519         priv->hw_unavailable--;
2520
2521         /* priv->open or priv->hw_unavailable might have changed while
2522          * we dropped the lock */
2523         if (priv->open && (! priv->hw_unavailable)) {
2524                 err = __orinoco_up(dev);
2525                 if (err) {
2526                         printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
2527                                dev->name, err);
2528                 } else
2529                         dev->trans_start = jiffies;
2530         }
2531
2532         spin_unlock_irq(&priv->lock);
2533
2534         return;
2535  disable:
2536         hermes_set_irqmask(hw, 0);
2537         netif_device_detach(dev);
2538         printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
2539 }
2540
2541 /********************************************************************/
2542 /* Interrupt handler                                                */
2543 /********************************************************************/
2544
2545 static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
2546 {
2547         printk(KERN_DEBUG "%s: TICK\n", dev->name);
2548 }
2549
2550 static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
2551 {
2552         /* This seems to happen a fair bit under load, but ignoring it
2553            seems to work fine...*/
2554         printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
2555                dev->name);
2556 }
2557
2558 irqreturn_t orinoco_interrupt(int irq, void *dev_id)
2559 {
2560         struct net_device *dev = dev_id;
2561         struct orinoco_private *priv = netdev_priv(dev);
2562         hermes_t *hw = &priv->hw;
2563         int count = MAX_IRQLOOPS_PER_IRQ;
2564         u16 evstat, events;
2565         /* These are used to detect a runaway interrupt situation */
2566         /* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
2567          * we panic and shut down the hardware */
2568         static int last_irq_jiffy = 0; /* jiffies value the last time
2569                                         * we were called */
2570         static int loops_this_jiffy = 0;
2571         unsigned long flags;
2572
2573         if (orinoco_lock(priv, &flags) != 0) {
2574                 /* If hw is unavailable - we don't know if the irq was
2575                  * for us or not */
2576                 return IRQ_HANDLED;
2577         }
2578
2579         evstat = hermes_read_regn(hw, EVSTAT);
2580         events = evstat & hw->inten;
2581         if (! events) {
2582                 orinoco_unlock(priv, &flags);
2583                 return IRQ_NONE;
2584         }
2585         
2586         if (jiffies != last_irq_jiffy)
2587                 loops_this_jiffy = 0;
2588         last_irq_jiffy = jiffies;
2589
2590         while (events && count--) {
2591                 if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
2592                         printk(KERN_WARNING "%s: IRQ handler is looping too "
2593                                "much! Resetting.\n", dev->name);
2594                         /* Disable interrupts for now */
2595                         hermes_set_irqmask(hw, 0);
2596                         schedule_work(&priv->reset_work);
2597                         break;
2598                 }
2599
2600                 /* Check the card hasn't been removed */
2601                 if (! hermes_present(hw)) {
2602                         DEBUG(0, "orinoco_interrupt(): card removed\n");
2603                         break;
2604                 }
2605
2606                 if (events & HERMES_EV_TICK)
2607                         __orinoco_ev_tick(dev, hw);
2608                 if (events & HERMES_EV_WTERR)
2609                         __orinoco_ev_wterr(dev, hw);
2610                 if (events & HERMES_EV_INFDROP)
2611                         __orinoco_ev_infdrop(dev, hw);
2612                 if (events & HERMES_EV_INFO)
2613                         __orinoco_ev_info(dev, hw);
2614                 if (events & HERMES_EV_RX)
2615                         __orinoco_ev_rx(dev, hw);
2616                 if (events & HERMES_EV_TXEXC)
2617                         __orinoco_ev_txexc(dev, hw);
2618                 if (events & HERMES_EV_TX)
2619                         __orinoco_ev_tx(dev, hw);
2620                 if (events & HERMES_EV_ALLOC)
2621                         __orinoco_ev_alloc(dev, hw);
2622                 
2623                 hermes_write_regn(hw, EVACK, evstat);
2624
2625                 evstat = hermes_read_regn(hw, EVSTAT);
2626                 events = evstat & hw->inten;
2627         };
2628
2629         orinoco_unlock(priv, &flags);
2630         return IRQ_HANDLED;
2631 }
2632
2633 /********************************************************************/
2634 /* Initialization                                                   */
2635 /********************************************************************/
2636
2637 struct comp_id {
2638         u16 id, variant, major, minor;
2639 } __attribute__ ((packed));
2640
2641 static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
2642 {
2643         if (nic_id->id < 0x8000)
2644                 return FIRMWARE_TYPE_AGERE;
2645         else if (nic_id->id == 0x8000 && nic_id->major == 0)
2646                 return FIRMWARE_TYPE_SYMBOL;
2647         else
2648                 return FIRMWARE_TYPE_INTERSIL;
2649 }
2650
2651 /* Set priv->firmware type, determine firmware properties */
2652 static int determine_firmware(struct net_device *dev)
2653 {
2654         struct orinoco_private *priv = netdev_priv(dev);
2655         hermes_t *hw = &priv->hw;
2656         int err;
2657         struct comp_id nic_id, sta_id;
2658         unsigned int firmver;
2659         char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
2660
2661         /* Get the hardware version */
2662         err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
2663         if (err) {
2664                 printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
2665                        dev->name, err);
2666                 return err;
2667         }
2668
2669         le16_to_cpus(&nic_id.id);
2670         le16_to_cpus(&nic_id.variant);
2671         le16_to_cpus(&nic_id.major);
2672         le16_to_cpus(&nic_id.minor);
2673         printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
2674                dev->name, nic_id.id, nic_id.variant,
2675                nic_id.major, nic_id.minor);
2676
2677         priv->firmware_type = determine_firmware_type(&nic_id);
2678
2679         /* Get the firmware version */
2680         err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
2681         if (err) {
2682                 printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
2683                        dev->name, err);
2684                 return err;
2685         }
2686
2687         le16_to_cpus(&sta_id.id);
2688         le16_to_cpus(&sta_id.variant);
2689         le16_to_cpus(&sta_id.major);
2690         le16_to_cpus(&sta_id.minor);
2691         printk(KERN_DEBUG "%s: Station identity  %04x:%04x:%04x:%04x\n",
2692                dev->name, sta_id.id, sta_id.variant,
2693                sta_id.major, sta_id.minor);
2694
2695         switch (sta_id.id) {
2696         case 0x15:
2697                 printk(KERN_ERR "%s: Primary firmware is active\n",
2698                        dev->name);
2699                 return -ENODEV;
2700         case 0x14b:
2701                 printk(KERN_ERR "%s: Tertiary firmware is active\n",
2702                        dev->name);
2703                 return -ENODEV;
2704         case 0x1f:      /* Intersil, Agere, Symbol Spectrum24 */
2705         case 0x21:      /* Symbol Spectrum24 Trilogy */
2706                 break;
2707         default:
2708                 printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
2709                        dev->name);
2710                 break;
2711         }
2712
2713         /* Default capabilities */
2714         priv->has_sensitivity = 1;
2715         priv->has_mwo = 0;
2716         priv->has_preamble = 0;
2717         priv->has_port3 = 1;
2718         priv->has_ibss = 1;
2719         priv->has_wep = 0;
2720         priv->has_big_wep = 0;
2721         priv->has_alt_txcntl = 0;
2722         priv->has_ext_scan = 0;
2723         priv->do_fw_download = 0;
2724
2725         /* Determine capabilities from the firmware version */
2726         switch (priv->firmware_type) {
2727         case FIRMWARE_TYPE_AGERE:
2728                 /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
2729                    ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
2730                 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2731                          "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
2732
2733                 firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
2734
2735                 priv->has_ibss = (firmver >= 0x60006);
2736                 priv->has_wep = (firmver >= 0x40020);
2737                 priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
2738                                           Gold cards from the others? */
2739                 priv->has_mwo = (firmver >= 0x60000);
2740                 priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
2741                 priv->ibss_port = 1;
2742                 priv->has_hostscan = (firmver >= 0x8000a);
2743                 priv->do_fw_download = 1;
2744                 priv->broken_monitor = (firmver >= 0x80000);
2745                 priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
2746                 priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
2747                 /* Tested with Agere firmware :
2748                  *      1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
2749                  * Tested CableTron firmware : 4.32 => Anton */
2750                 break;
2751         case FIRMWARE_TYPE_SYMBOL:
2752                 /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
2753                 /* Intel MAC : 00:02:B3:* */
2754                 /* 3Com MAC : 00:50:DA:* */
2755                 memset(tmp, 0, sizeof(tmp));
2756                 /* Get the Symbol firmware version */
2757                 err = hermes_read_ltv(hw, USER_BAP,
2758                                       HERMES_RID_SECONDARYVERSION_SYMBOL,
2759                                       SYMBOL_MAX_VER_LEN, NULL, &tmp);
2760                 if (err) {
2761                         printk(KERN_WARNING
2762                                "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",
2763                                dev->name, err);
2764                         firmver = 0;
2765                         tmp[0] = '\0';
2766                 } else {
2767                         /* The firmware revision is a string, the format is
2768                          * something like : "V2.20-01".
2769                          * Quick and dirty parsing... - Jean II
2770                          */
2771                         firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12)
2772                                 | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4)
2773                                 | (tmp[7] - '0');
2774
2775                         tmp[SYMBOL_MAX_VER_LEN] = '\0';
2776                 }
2777
2778                 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2779                          "Symbol %s", tmp);
2780
2781                 priv->has_ibss = (firmver >= 0x20000);
2782                 priv->has_wep = (firmver >= 0x15012);
2783                 priv->has_big_wep = (firmver >= 0x20000);
2784                 priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) || 
2785                                (firmver >= 0x29000 && firmver < 0x30000) ||
2786                                firmver >= 0x31000;
2787                 priv->has_preamble = (firmver >= 0x20000);
2788                 priv->ibss_port = 4;
2789
2790                 /* Symbol firmware is found on various cards, but
2791                  * there has been no attempt to check firmware
2792                  * download on non-spectrum_cs based cards.
2793                  *
2794                  * Given that the Agere firmware download works
2795                  * differently, we should avoid doing a firmware
2796                  * download with the Symbol algorithm on non-spectrum
2797                  * cards.
2798                  *
2799                  * For now we can identify a spectrum_cs based card
2800                  * because it has a firmware reset function.
2801                  */
2802                 priv->do_fw_download = (priv->stop_fw != NULL);
2803
2804                 priv->broken_disableport = (firmver == 0x25013) ||
2805                                            (firmver >= 0x30000 && firmver <= 0x31000);
2806                 priv->has_hostscan = (firmver >= 0x31001) ||
2807                                      (firmver >= 0x29057 && firmver < 0x30000);
2808                 /* Tested with Intel firmware : 0x20015 => Jean II */
2809                 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
2810                 break;
2811         case FIRMWARE_TYPE_INTERSIL:
2812                 /* D-Link, Linksys, Adtron, ZoomAir, and many others...
2813                  * Samsung, Compaq 100/200 and Proxim are slightly
2814                  * different and less well tested */
2815                 /* D-Link MAC : 00:40:05:* */
2816                 /* Addtron MAC : 00:90:D1:* */
2817                 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2818                          "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
2819                          sta_id.variant);
2820
2821                 firmver = ((unsigned long)sta_id.major << 16) |
2822                         ((unsigned long)sta_id.minor << 8) | sta_id.variant;
2823
2824                 priv->has_ibss = (firmver >= 0x000700); /* FIXME */
2825                 priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
2826                 priv->has_pm = (firmver >= 0x000700);
2827                 priv->has_hostscan = (firmver >= 0x010301);
2828
2829                 if (firmver >= 0x000800)
2830                         priv->ibss_port = 0;
2831                 else {
2832                         printk(KERN_NOTICE "%s: Intersil firmware earlier "
2833                                "than v0.8.x - several features not supported\n",
2834                                dev->name);
2835                         priv->ibss_port = 1;
2836                 }
2837                 break;
2838         }
2839         printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
2840                priv->fw_name);
2841
2842         return 0;
2843 }
2844
2845 static int orinoco_init(struct net_device *dev)
2846 {
2847         struct orinoco_private *priv = netdev_priv(dev);
2848         hermes_t *hw = &priv->hw;
2849         int err = 0;
2850         struct hermes_idstring nickbuf;
2851         u16 reclen;
2852         int len;
2853         DECLARE_MAC_BUF(mac);
2854
2855         /* No need to lock, the hw_unavailable flag is already set in
2856          * alloc_orinocodev() */
2857         priv->nicbuf_size = IEEE80211_FRAME_LEN + ETH_HLEN;
2858
2859         /* Initialize the firmware */
2860         err = hermes_init(hw);
2861         if (err != 0) {
2862                 printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
2863                        dev->name, err);
2864                 goto out;
2865         }
2866
2867         err = determine_firmware(dev);
2868         if (err != 0) {
2869                 printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
2870                        dev->name);
2871                 goto out;
2872         }
2873
2874         if (priv->do_fw_download) {
2875                 err = orinoco_download(priv);
2876                 if (err)
2877                         priv->do_fw_download = 0;
2878
2879                 /* Check firmware version again */
2880                 err = determine_firmware(dev);
2881                 if (err != 0) {
2882                         printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
2883                                dev->name);
2884                         goto out;
2885                 }
2886         }
2887
2888         if (priv->has_port3)
2889                 printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
2890         if (priv->has_ibss)
2891                 printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
2892                        dev->name);
2893         if (priv->has_wep) {
2894                 printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
2895                 if (priv->has_big_wep)
2896                         printk("104-bit key\n");
2897                 else
2898                         printk("40-bit key\n");
2899         }
2900
2901         /* Now we have the firmware capabilities, allocate appropiate
2902          * sized scan buffers */
2903         if (orinoco_bss_data_allocate(priv))
2904                 goto out;
2905         orinoco_bss_data_init(priv);
2906
2907         /* Get the MAC address */
2908         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
2909                               ETH_ALEN, NULL, dev->dev_addr);
2910         if (err) {
2911                 printk(KERN_WARNING "%s: failed to read MAC address!\n",
2912                        dev->name);
2913                 goto out;
2914         }
2915
2916         printk(KERN_DEBUG "%s: MAC address %s\n",
2917                dev->name, print_mac(mac, dev->dev_addr));
2918
2919         /* Get the station name */
2920         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
2921                               sizeof(nickbuf), &reclen, &nickbuf);
2922         if (err) {
2923                 printk(KERN_ERR "%s: failed to read station name\n",
2924                        dev->name);
2925                 goto out;
2926         }
2927         if (nickbuf.len)
2928                 len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
2929         else
2930                 len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
2931         memcpy(priv->nick, &nickbuf.val, len);
2932         priv->nick[len] = '\0';
2933
2934         printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
2935
2936         err = orinoco_allocate_fid(dev);
2937         if (err) {
2938                 printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
2939                        dev->name);
2940                 goto out;
2941         }
2942
2943         /* Get allowed channels */
2944         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
2945                                   &priv->channel_mask);
2946         if (err) {
2947                 printk(KERN_ERR "%s: failed to read channel list!\n",
2948                        dev->name);
2949                 goto out;
2950         }
2951
2952         /* Get initial AP density */
2953         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
2954                                   &priv->ap_density);
2955         if (err || priv->ap_density < 1 || priv->ap_density > 3) {
2956                 priv->has_sensitivity = 0;
2957         }
2958
2959         /* Get initial RTS threshold */
2960         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
2961                                   &priv->rts_thresh);
2962         if (err) {
2963                 printk(KERN_ERR "%s: failed to read RTS threshold!\n",
2964                        dev->name);
2965                 goto out;
2966         }
2967
2968         /* Get initial fragmentation settings */
2969         if (priv->has_mwo)
2970                 err = hermes_read_wordrec(hw, USER_BAP,
2971                                           HERMES_RID_CNFMWOROBUST_AGERE,
2972                                           &priv->mwo_robust);
2973         else
2974                 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
2975                                           &priv->frag_thresh);
2976         if (err) {
2977                 printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
2978                        dev->name);
2979                 goto out;
2980         }
2981
2982         /* Power management setup */
2983         if (priv->has_pm) {
2984                 priv->pm_on = 0;
2985                 priv->pm_mcast = 1;
2986                 err = hermes_read_wordrec(hw, USER_BAP,
2987                                           HERMES_RID_CNFMAXSLEEPDURATION,
2988                                           &priv->pm_period);
2989                 if (err) {
2990                         printk(KERN_ERR "%s: failed to read power management period!\n",
2991                                dev->name);
2992                         goto out;
2993                 }
2994                 err = hermes_read_wordrec(hw, USER_BAP,
2995                                           HERMES_RID_CNFPMHOLDOVERDURATION,
2996                                           &priv->pm_timeout);
2997                 if (err) {
2998                         printk(KERN_ERR "%s: failed to read power management timeout!\n",
2999                                dev->name);
3000                         goto out;
3001                 }
3002         }
3003
3004         /* Preamble setup */
3005         if (priv->has_preamble) {
3006                 err = hermes_read_wordrec(hw, USER_BAP,
3007                                           HERMES_RID_CNFPREAMBLE_SYMBOL,
3008                                           &priv->preamble);
3009                 if (err)
3010                         goto out;
3011         }
3012                 
3013         /* Set up the default configuration */
3014         priv->iw_mode = IW_MODE_INFRA;
3015         /* By default use IEEE/IBSS ad-hoc mode if we have it */
3016         priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
3017         set_port_type(priv);
3018         priv->channel = 0; /* use firmware default */
3019
3020         priv->promiscuous = 0;
3021         priv->encode_alg = IW_ENCODE_ALG_NONE;
3022         priv->tx_key = 0;
3023
3024         /* Make the hardware available, as long as it hasn't been
3025          * removed elsewhere (e.g. by PCMCIA hot unplug) */
3026         spin_lock_irq(&priv->lock);
3027         priv->hw_unavailable--;
3028         spin_unlock_irq(&priv->lock);
3029
3030         printk(KERN_DEBUG "%s: ready\n", dev->name);
3031
3032  out:
3033         return err;
3034 }
3035
3036 struct net_device
3037 *alloc_orinocodev(int sizeof_card,
3038                   struct device *device,
3039                   int (*hard_reset)(struct orinoco_private *),
3040                   int (*stop_fw)(struct orinoco_private *, int))
3041 {
3042         struct net_device *dev;
3043         struct orinoco_private *priv;
3044
3045         dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
3046         if (! dev)
3047                 return NULL;
3048         priv = netdev_priv(dev);
3049         priv->ndev = dev;
3050         if (sizeof_card)
3051                 priv->card = (void *)((unsigned long)priv
3052                                       + sizeof(struct orinoco_private));
3053         else
3054                 priv->card = NULL;
3055         priv->dev = device;
3056
3057         /* Setup / override net_device fields */
3058         dev->init = orinoco_init;
3059         dev->hard_start_xmit = orinoco_xmit;
3060         dev->tx_timeout = orinoco_tx_timeout;
3061         dev->watchdog_timeo = HZ; /* 1 second timeout */
3062         dev->get_stats = orinoco_get_stats;
3063         dev->ethtool_ops = &orinoco_ethtool_ops;
3064         dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
3065 #ifdef WIRELESS_SPY
3066         priv->wireless_data.spy_data = &priv->spy_data;
3067         dev->wireless_data = &priv->wireless_data;
3068 #endif
3069         dev->change_mtu = orinoco_change_mtu;
3070         dev->set_multicast_list = orinoco_set_multicast_list;
3071         /* we use the default eth_mac_addr for setting the MAC addr */
3072
3073         /* Set up default callbacks */
3074         dev->open = orinoco_open;
3075         dev->stop = orinoco_stop;
3076         priv->hard_reset = hard_reset;
3077         priv->stop_fw = stop_fw;
3078
3079         spin_lock_init(&priv->lock);
3080         priv->open = 0;
3081         priv->hw_unavailable = 1; /* orinoco_init() must clear this
3082                                    * before anything else touches the
3083                                    * hardware */
3084         INIT_WORK(&priv->reset_work, orinoco_reset);
3085         INIT_WORK(&priv->join_work, orinoco_join_ap);
3086         INIT_WORK(&priv->wevent_work, orinoco_send_wevents);
3087
3088         netif_carrier_off(dev);
3089         priv->last_linkstatus = 0xffff;
3090
3091         return dev;
3092 }
3093
3094 void free_orinocodev(struct net_device *dev)
3095 {
3096         struct orinoco_private *priv = netdev_priv(dev);
3097
3098         orinoco_bss_data_free(priv);
3099         free_netdev(dev);
3100 }
3101
3102 /********************************************************************/
3103 /* Wireless extensions                                              */
3104 /********************************************************************/
3105
3106 /* Return : < 0 -> error code ; >= 0 -> length */
3107 static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
3108                                 char buf[IW_ESSID_MAX_SIZE+1])
3109 {
3110         hermes_t *hw = &priv->hw;
3111         int err = 0;
3112         struct hermes_idstring essidbuf;
3113         char *p = (char *)(&essidbuf.val);
3114         int len;
3115         unsigned long flags;
3116
3117         if (orinoco_lock(priv, &flags) != 0)
3118                 return -EBUSY;
3119
3120         if (strlen(priv->desired_essid) > 0) {
3121                 /* We read the desired SSID from the hardware rather
3122                    than from priv->desired_essid, just in case the
3123                    firmware is allowed to change it on us. I'm not
3124                    sure about this */
3125                 /* My guess is that the OWNSSID should always be whatever
3126                  * we set to the card, whereas CURRENT_SSID is the one that
3127                  * may change... - Jean II */
3128                 u16 rid;
3129
3130                 *active = 1;
3131
3132                 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
3133                         HERMES_RID_CNFDESIREDSSID;
3134                 
3135                 err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
3136                                       NULL, &essidbuf);
3137                 if (err)
3138                         goto fail_unlock;
3139         } else {
3140                 *active = 0;
3141
3142                 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
3143                                       sizeof(essidbuf), NULL, &essidbuf);
3144                 if (err)
3145                         goto fail_unlock;
3146         }
3147
3148         len = le16_to_cpu(essidbuf.len);
3149         BUG_ON(len > IW_ESSID_MAX_SIZE);
3150
3151         memset(buf, 0, IW_ESSID_MAX_SIZE);
3152         memcpy(buf, p, len);
3153         err = len;
3154
3155  fail_unlock:
3156         orinoco_unlock(priv, &flags);
3157
3158         return err;       
3159 }
3160
3161 static long orinoco_hw_get_freq(struct orinoco_private *priv)
3162 {
3163         
3164         hermes_t *hw = &priv->hw;
3165         int err = 0;
3166         u16 channel;
3167         long freq = 0;
3168         unsigned long flags;
3169
3170         if (orinoco_lock(priv, &flags) != 0)
3171                 return -EBUSY;
3172         
3173         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
3174         if (err)
3175                 goto out;
3176
3177         /* Intersil firmware 1.3.5 returns 0 when the interface is down */
3178         if (channel == 0) {
3179                 err = -EBUSY;
3180                 goto out;
3181         }
3182
3183         if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
3184                 printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
3185                        priv->ndev->name, channel);
3186                 err = -EBUSY;
3187                 goto out;
3188
3189         }
3190         freq = channel_frequency[channel-1] * 100000;
3191
3192  out:
3193         orinoco_unlock(priv, &flags);
3194
3195         if (err > 0)
3196                 err = -EBUSY;
3197         return err ? err : freq;
3198 }
3199
3200 static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
3201                                       int *numrates, s32 *rates, int max)
3202 {
3203         hermes_t *hw = &priv->hw;
3204         struct hermes_idstring list;
3205         unsigned char *p = (unsigned char *)&list.val;
3206         int err = 0;
3207         int num;
3208         int i;
3209         unsigned long flags;
3210
3211         if (orinoco_lock(priv, &flags) != 0)
3212                 return -EBUSY;
3213
3214         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
3215                               sizeof(list), NULL, &list);
3216         orinoco_unlock(priv, &flags);
3217
3218         if (err)
3219                 return err;
3220         
3221         num = le16_to_cpu(list.len);
3222         *numrates = num;
3223         num = min(num, max);
3224
3225         for (i = 0; i < num; i++) {
3226                 rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
3227         }
3228
3229         return 0;
3230 }
3231
3232 static int orinoco_ioctl_getname(struct net_device *dev,
3233                                  struct iw_request_info *info,
3234                                  char *name,
3235                                  char *extra)
3236 {
3237         struct orinoco_private *priv = netdev_priv(dev);
3238         int numrates;
3239         int err;
3240
3241         err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
3242
3243         if (!err && (numrates > 2))
3244                 strcpy(name, "IEEE 802.11b");
3245         else
3246                 strcpy(name, "IEEE 802.11-DS");
3247
3248         return 0;
3249 }
3250
3251 static int orinoco_ioctl_setwap(struct net_device *dev,
3252                                 struct iw_request_info *info,
3253                                 struct sockaddr *ap_addr,
3254                                 char *extra)
3255 {
3256         struct orinoco_private *priv = netdev_priv(dev);
3257         int err = -EINPROGRESS;         /* Call commit handler */
3258         unsigned long flags;
3259         static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3260         static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
3261
3262         if (orinoco_lock(priv, &flags) != 0)
3263                 return -EBUSY;
3264
3265         /* Enable automatic roaming - no sanity checks are needed */
3266         if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
3267             memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
3268                 priv->bssid_fixed = 0;
3269                 memset(priv->desired_bssid, 0, ETH_ALEN);
3270
3271                 /* "off" means keep existing connection */
3272                 if (ap_addr->sa_data[0] == 0) {
3273                         __orinoco_hw_set_wap(priv);
3274                         err = 0;
3275                 }
3276                 goto out;
3277         }
3278
3279         if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
3280                 printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
3281                        "support manual roaming\n",
3282                        dev->name);
3283                 err = -EOPNOTSUPP;
3284                 goto out;
3285         }
3286
3287         if (priv->iw_mode != IW_MODE_INFRA) {
3288                 printk(KERN_WARNING "%s: Manual roaming supported only in "
3289                        "managed mode\n", dev->name);
3290                 err = -EOPNOTSUPP;
3291                 goto out;
3292         }
3293
3294         /* Intersil firmware hangs without Desired ESSID */
3295         if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
3296             strlen(priv->desired_essid) == 0) {
3297                 printk(KERN_WARNING "%s: Desired ESSID must be set for "
3298                        "manual roaming\n", dev->name);
3299                 err = -EOPNOTSUPP;
3300                 goto out;
3301         }
3302
3303         /* Finally, enable manual roaming */
3304         priv->bssid_fixed = 1;
3305         memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
3306
3307  out:
3308         orinoco_unlock(priv, &flags);
3309         return err;
3310 }
3311
3312 static int orinoco_ioctl_getwap(struct net_device *dev,
3313                                 struct iw_request_info *info,
3314                                 struct sockaddr *ap_addr,
3315                                 char *extra)
3316 {
3317         struct orinoco_private *priv = netdev_priv(dev);
3318
3319         hermes_t *hw = &priv->hw;
3320         int err = 0;
3321         unsigned long flags;
3322
3323         if (orinoco_lock(priv, &flags) != 0)
3324                 return -EBUSY;
3325
3326         ap_addr->sa_family = ARPHRD_ETHER;
3327         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
3328                               ETH_ALEN, NULL, ap_addr->sa_data);
3329
3330         orinoco_unlock(priv, &flags);
3331
3332         return err;
3333 }
3334
3335 static int orinoco_ioctl_setmode(struct net_device *dev,
3336                                  struct iw_request_info *info,
3337                                  u32 *mode,
3338                                  char *extra)
3339 {
3340         struct orinoco_private *priv = netdev_priv(dev);
3341         int err = -EINPROGRESS;         /* Call commit handler */
3342         unsigned long flags;
3343
3344         if (priv->iw_mode == *mode)
3345                 return 0;
3346
3347         if (orinoco_lock(priv, &flags) != 0)
3348                 return -EBUSY;
3349
3350         switch (*mode) {
3351         case IW_MODE_ADHOC:
3352                 if (!priv->has_ibss && !priv->has_port3)
3353                         err = -EOPNOTSUPP;
3354                 break;
3355
3356         case IW_MODE_INFRA:
3357                 break;
3358
3359         case IW_MODE_MONITOR:
3360                 if (priv->broken_monitor && !force_monitor) {
3361                         printk(KERN_WARNING "%s: Monitor mode support is "
3362                                "buggy in this firmware, not enabling\n",
3363                                dev->name);
3364                         err = -EOPNOTSUPP;
3365                 }
3366                 break;
3367
3368         default:
3369                 err = -EOPNOTSUPP;
3370                 break;
3371         }
3372
3373         if (err == -EINPROGRESS) {
3374                 priv->iw_mode = *mode;
3375                 set_port_type(priv);
3376         }
3377
3378         orinoco_unlock(priv, &flags);
3379
3380         return err;
3381 }
3382
3383 static int orinoco_ioctl_getmode(struct net_device *dev,
3384                                  struct iw_request_info *info,
3385                                  u32 *mode,
3386                                  char *extra)
3387 {
3388         struct orinoco_private *priv = netdev_priv(dev);
3389
3390         *mode = priv->iw_mode;
3391         return 0;
3392 }
3393
3394 static int orinoco_ioctl_getiwrange(struct net_device *dev,
3395                                     struct iw_request_info *info,
3396                                     struct iw_point *rrq,
3397                                     char *extra)
3398 {
3399         struct orinoco_private *priv = netdev_priv(dev);
3400         int err = 0;
3401         struct iw_range *range = (struct iw_range *) extra;
3402         int numrates;
3403         int i, k;
3404
3405         rrq->length = sizeof(struct iw_range);
3406         memset(range, 0, sizeof(struct iw_range));
3407
3408         range->we_version_compiled = WIRELESS_EXT;
3409         range->we_version_source = 14;
3410
3411         /* Set available channels/frequencies */
3412         range->num_channels = NUM_CHANNELS;
3413         k = 0;
3414         for (i = 0; i < NUM_CHANNELS; i++) {
3415                 if (priv->channel_mask & (1 << i)) {
3416                         range->freq[k].i = i + 1;
3417                         range->freq[k].m = channel_frequency[i] * 100000;
3418                         range->freq[k].e = 1;
3419                         k++;
3420                 }
3421                 
3422                 if (k >= IW_MAX_FREQUENCIES)
3423                         break;
3424         }
3425         range->num_frequency = k;
3426         range->sensitivity = 3;
3427
3428         if (priv->has_wep) {
3429                 range->max_encoding_tokens = ORINOCO_MAX_KEYS;
3430                 range->encoding_size[0] = SMALL_KEY_SIZE;
3431                 range->num_encoding_sizes = 1;
3432
3433                 if (priv->has_big_wep) {
3434                         range->encoding_size[1] = LARGE_KEY_SIZE;
3435                         range->num_encoding_sizes = 2;
3436                 }
3437         }
3438
3439         if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
3440                 /* Quality stats meaningless in ad-hoc mode */
3441         } else {
3442                 range->max_qual.qual = 0x8b - 0x2f;
3443                 range->max_qual.level = 0x2f - 0x95 - 1;
3444                 range->max_qual.noise = 0x2f - 0x95 - 1;
3445                 /* Need to get better values */
3446                 range->avg_qual.qual = 0x24;
3447                 range->avg_qual.level = 0xC2;
3448                 range->avg_qual.noise = 0x9E;
3449         }
3450
3451         err = orinoco_hw_get_bitratelist(priv, &numrates,
3452                                          range->bitrate, IW_MAX_BITRATES);
3453         if (err)
3454                 return err;
3455         range->num_bitrates = numrates;
3456
3457         /* Set an indication of the max TCP throughput in bit/s that we can
3458          * expect using this interface. May be use for QoS stuff...
3459          * Jean II */
3460         if (numrates > 2)
3461                 range->throughput = 5 * 1000 * 1000;    /* ~5 Mb/s */
3462         else
3463                 range->throughput = 1.5 * 1000 * 1000;  /* ~1.5 Mb/s */
3464
3465         range->min_rts = 0;
3466         range->max_rts = 2347;
3467         range->min_frag = 256;
3468         range->max_frag = 2346;
3469
3470         range->min_pmp = 0;
3471         range->max_pmp = 65535000;
3472         range->min_pmt = 0;
3473         range->max_pmt = 65535 * 1000;  /* ??? */
3474         range->pmp_flags = IW_POWER_PERIOD;
3475         range->pmt_flags = IW_POWER_TIMEOUT;
3476         range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
3477
3478         range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
3479         range->retry_flags = IW_RETRY_LIMIT;
3480         range->r_time_flags = IW_RETRY_LIFETIME;
3481         range->min_retry = 0;
3482         range->max_retry = 65535;       /* ??? */
3483         range->min_r_time = 0;
3484         range->max_r_time = 65535 * 1000;       /* ??? */
3485
3486         if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
3487                 range->scan_capa = IW_SCAN_CAPA_ESSID;
3488         else
3489                 range->scan_capa = IW_SCAN_CAPA_NONE;
3490
3491         /* Event capability (kernel) */
3492         IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
3493         /* Event capability (driver) */
3494         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
3495         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
3496         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
3497         IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
3498
3499         return 0;
3500 }
3501
3502 static int orinoco_ioctl_setiwencode(struct net_device *dev,
3503                                      struct iw_request_info *info,
3504                                      struct iw_point *erq,
3505                                      char *keybuf)
3506 {
3507         struct orinoco_private *priv = netdev_priv(dev);
3508         int index = (erq->flags & IW_ENCODE_INDEX) - 1;
3509         int setindex = priv->tx_key;
3510         int encode_alg = priv->encode_alg;
3511         int restricted = priv->wep_restrict;
3512         u16 xlen = 0;
3513         int err = -EINPROGRESS;         /* Call commit handler */
3514         unsigned long flags;
3515
3516         if (! priv->has_wep)
3517                 return -EOPNOTSUPP;
3518
3519         if (erq->pointer) {
3520                 /* We actually have a key to set - check its length */
3521                 if (erq->length > LARGE_KEY_SIZE)
3522                         return -E2BIG;
3523
3524                 if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
3525                         return -E2BIG;
3526         }
3527
3528         if (orinoco_lock(priv, &flags) != 0)
3529                 return -EBUSY;
3530
3531         if (erq->length > 0) {
3532                 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
3533                         index = priv->tx_key;
3534
3535                 /* Adjust key length to a supported value */
3536                 if (erq->length > SMALL_KEY_SIZE) {
3537                         xlen = LARGE_KEY_SIZE;
3538                 } else if (erq->length > 0) {
3539                         xlen = SMALL_KEY_SIZE;
3540                 } else
3541                         xlen = 0;
3542
3543                 /* Switch on WEP if off */
3544                 if ((encode_alg != IW_ENCODE_ALG_WEP) && (xlen > 0)) {
3545                         setindex = index;
3546                         encode_alg = IW_ENCODE_ALG_WEP;
3547                 }
3548         } else {
3549                 /* Important note : if the user do "iwconfig eth0 enc off",
3550                  * we will arrive there with an index of -1. This is valid
3551                  * but need to be taken care off... Jean II */
3552                 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
3553                         if((index != -1) || (erq->flags == 0)) {
3554                                 err = -EINVAL;
3555                                 goto out;
3556                         }
3557                 } else {
3558                         /* Set the index : Check that the key is valid */
3559                         if(priv->keys[index].len == 0) {
3560                                 err = -EINVAL;
3561                                 goto out;
3562                         }
3563                         setindex = index;
3564                 }
3565         }
3566
3567         if (erq->flags & IW_ENCODE_DISABLED)
3568                 encode_alg = IW_ENCODE_ALG_NONE;
3569         if (erq->flags & IW_ENCODE_OPEN)
3570                 restricted = 0;
3571         if (erq->flags & IW_ENCODE_RESTRICTED)
3572                 restricted = 1;
3573
3574         if (erq->pointer && erq->length > 0) {
3575                 priv->keys[index].len = cpu_to_le16(xlen);
3576                 memset(priv->keys[index].data, 0,
3577                        sizeof(priv->keys[index].data));
3578                 memcpy(priv->keys[index].data, keybuf, erq->length);
3579         }
3580         priv->tx_key = setindex;
3581
3582         /* Try fast key change if connected and only keys are changed */
3583         if ((priv->encode_alg == encode_alg) &&
3584             (priv->wep_restrict == restricted) &&
3585             netif_carrier_ok(dev)) {
3586                 err = __orinoco_hw_setup_wepkeys(priv);
3587                 /* No need to commit if successful */
3588                 goto out;
3589         }
3590
3591         priv->encode_alg = encode_alg;
3592         priv->wep_restrict = restricted;
3593
3594  out:
3595         orinoco_unlock(priv, &flags);
3596
3597         return err;
3598 }
3599
3600 static int orinoco_ioctl_getiwencode(struct net_device *dev,
3601                                      struct iw_request_info *info,
3602                                      struct iw_point *erq,
3603                                      char *keybuf)
3604 {
3605         struct orinoco_private *priv = netdev_priv(dev);
3606         int index = (erq->flags & IW_ENCODE_INDEX) - 1;
3607         u16 xlen = 0;
3608         unsigned long flags;
3609
3610         if (! priv->has_wep)
3611                 return -EOPNOTSUPP;
3612
3613         if (orinoco_lock(priv, &flags) != 0)
3614                 return -EBUSY;
3615
3616         if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
3617                 index = priv->tx_key;
3618
3619         erq->flags = 0;
3620         if (!priv->encode_alg)
3621                 erq->flags |= IW_ENCODE_DISABLED;
3622         erq->flags |= index + 1;
3623
3624         if (priv->wep_restrict)
3625                 erq->flags |= IW_ENCODE_RESTRICTED;
3626         else
3627                 erq->flags |= IW_ENCODE_OPEN;
3628
3629         xlen = le16_to_cpu(priv->keys[index].len);
3630
3631         erq->length = xlen;
3632
3633         memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
3634
3635         orinoco_unlock(priv, &flags);
3636         return 0;
3637 }
3638
3639 static int orinoco_ioctl_setessid(struct net_device *dev,
3640                                   struct iw_request_info *info,
3641                                   struct iw_point *erq,
3642                                   char *essidbuf)
3643 {
3644         struct orinoco_private *priv = netdev_priv(dev);
3645         unsigned long flags;
3646
3647         /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
3648          * anyway... - Jean II */
3649
3650         /* Hum... Should not use Wireless Extension constant (may change),
3651          * should use our own... - Jean II */
3652         if (erq->length > IW_ESSID_MAX_SIZE)
3653                 return -E2BIG;
3654
3655         if (orinoco_lock(priv, &flags) != 0)
3656                 return -EBUSY;
3657
3658         /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
3659         memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
3660
3661         /* If not ANY, get the new ESSID */
3662         if (erq->flags) {
3663                 memcpy(priv->desired_essid, essidbuf, erq->length);
3664         }
3665
3666         orinoco_unlock(priv, &flags);
3667
3668         return -EINPROGRESS;            /* Call commit handler */
3669 }
3670
3671 static int orinoco_ioctl_getessid(struct net_device *dev,
3672                                   struct iw_request_info *info,
3673                                   struct iw_point *erq,
3674                                   char *essidbuf)
3675 {
3676         struct orinoco_private *priv = netdev_priv(dev);
3677         int active;
3678         int err = 0;
3679         unsigned long flags;
3680
3681         if (netif_running(dev)) {
3682                 err = orinoco_hw_get_essid(priv, &active, essidbuf);
3683                 if (err < 0)
3684                         return err;
3685                 erq->length = err;
3686         } else {
3687                 if (orinoco_lock(priv, &flags) != 0)
3688                         return -EBUSY;
3689                 memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
3690                 erq->length = strlen(priv->desired_essid);
3691                 orinoco_unlock(priv, &flags);
3692         }
3693
3694         erq->flags = 1;
3695
3696         return 0;
3697 }
3698
3699 static int orinoco_ioctl_setnick(struct net_device *dev,
3700                                  struct iw_request_info *info,
3701                                  struct iw_point *nrq,
3702                                  char *nickbuf)
3703 {
3704         struct orinoco_private *priv = netdev_priv(dev);
3705         unsigned long flags;
3706
3707         if (nrq->length > IW_ESSID_MAX_SIZE)
3708                 return -E2BIG;
3709
3710         if (orinoco_lock(priv, &flags) != 0)
3711                 return -EBUSY;
3712
3713         memset(priv->nick, 0, sizeof(priv->nick));
3714         memcpy(priv->nick, nickbuf, nrq->length);
3715
3716         orinoco_unlock(priv, &flags);
3717
3718         return -EINPROGRESS;            /* Call commit handler */
3719 }
3720
3721 static int orinoco_ioctl_getnick(struct net_device *dev,
3722                                  struct iw_request_info *info,
3723                                  struct iw_point *nrq,
3724                                  char *nickbuf)
3725 {
3726         struct orinoco_private *priv = netdev_priv(dev);
3727         unsigned long flags;
3728
3729         if (orinoco_lock(priv, &flags) != 0)
3730                 return -EBUSY;
3731
3732         memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
3733         orinoco_unlock(priv, &flags);
3734
3735         nrq->length = strlen(priv->nick);
3736
3737         return 0;
3738 }
3739
3740 static int orinoco_ioctl_setfreq(struct net_device *dev,
3741                                  struct iw_request_info *info,
3742                                  struct iw_freq *frq,
3743                                  char *extra)
3744 {
3745         struct orinoco_private *priv = netdev_priv(dev);
3746         int chan = -1;
3747         unsigned long flags;
3748         int err = -EINPROGRESS;         /* Call commit handler */
3749
3750         /* In infrastructure mode the AP sets the channel */
3751         if (priv->iw_mode == IW_MODE_INFRA)
3752                 return -EBUSY;
3753
3754         if ( (frq->e == 0) && (frq->m <= 1000) ) {
3755                 /* Setting by channel number */
3756                 chan = frq->m;
3757         } else {
3758                 /* Setting by frequency - search the table */
3759                 int mult = 1;
3760                 int i;
3761
3762                 for (i = 0; i < (6 - frq->e); i++)
3763                         mult *= 10;
3764
3765                 for (i = 0; i < NUM_CHANNELS; i++)
3766                         if (frq->m == (channel_frequency[i] * mult))
3767                                 chan = i+1;
3768         }
3769
3770         if ( (chan < 1) || (chan > NUM_CHANNELS) ||
3771              ! (priv->channel_mask & (1 << (chan-1)) ) )
3772                 return -EINVAL;
3773
3774         if (orinoco_lock(priv, &flags) != 0)
3775                 return -EBUSY;
3776
3777         priv->channel = chan;
3778         if (priv->iw_mode == IW_MODE_MONITOR) {
3779                 /* Fast channel change - no commit if successful */
3780                 hermes_t *hw = &priv->hw;
3781                 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
3782                                             HERMES_TEST_SET_CHANNEL,
3783                                         chan, NULL);
3784         }
3785         orinoco_unlock(priv, &flags);
3786
3787         return err;
3788 }
3789
3790 static int orinoco_ioctl_getfreq(struct net_device *dev,
3791                                  struct iw_request_info *info,
3792                                  struct iw_freq *frq,
3793                                  char *extra)
3794 {
3795         struct orinoco_private *priv = netdev_priv(dev);
3796         int tmp;
3797
3798         /* Locking done in there */
3799         tmp = orinoco_hw_get_freq(priv);
3800         if (tmp < 0) {
3801                 return tmp;
3802         }
3803
3804         frq->m = tmp;
3805         frq->e = 1;
3806
3807         return 0;
3808 }
3809
3810 static int orinoco_ioctl_getsens(struct net_device *dev,
3811                                  struct iw_request_info *info,
3812                                  struct iw_param *srq,
3813                                  char *extra)
3814 {
3815         struct orinoco_private *priv = netdev_priv(dev);
3816         hermes_t *hw = &priv->hw;
3817         u16 val;
3818         int err;
3819         unsigned long flags;
3820
3821         if (!priv->has_sensitivity)
3822                 return -EOPNOTSUPP;
3823
3824         if (orinoco_lock(priv, &flags) != 0)
3825                 return -EBUSY;
3826         err = hermes_read_wordrec(hw, USER_BAP,
3827                                   HERMES_RID_CNFSYSTEMSCALE, &val);
3828         orinoco_unlock(priv, &flags);
3829
3830         if (err)
3831                 return err;
3832
3833         srq->value = val;
3834         srq->fixed = 0; /* auto */
3835
3836         return 0;
3837 }
3838
3839 static int orinoco_ioctl_setsens(struct net_device *dev,
3840                                  struct iw_request_info *info,
3841                                  struct iw_param *srq,
3842                                  char *extra)
3843 {
3844         struct orinoco_private *priv = netdev_priv(dev);
3845         int val = srq->value;
3846         unsigned long flags;
3847
3848         if (!priv->has_sensitivity)
3849                 return -EOPNOTSUPP;
3850
3851         if ((val < 1) || (val > 3))
3852                 return -EINVAL;
3853         
3854         if (orinoco_lock(priv, &flags) != 0)
3855                 return -EBUSY;
3856         priv->ap_density = val;
3857         orinoco_unlock(priv, &flags);
3858
3859         return -EINPROGRESS;            /* Call commit handler */
3860 }
3861
3862 static int orinoco_ioctl_setrts(struct net_device *dev,
3863                                 struct iw_request_info *info,
3864                                 struct iw_param *rrq,
3865                                 char *extra)
3866 {
3867         struct orinoco_private *priv = netdev_priv(dev);
3868         int val = rrq->value;
3869         unsigned long flags;
3870
3871         if (rrq->disabled)
3872                 val = 2347;
3873
3874         if ( (val < 0) || (val > 2347) )
3875                 return -EINVAL;
3876
3877         if (orinoco_lock(priv, &flags) != 0)
3878                 return -EBUSY;
3879
3880         priv->rts_thresh = val;
3881         orinoco_unlock(priv, &flags);
3882
3883         return -EINPROGRESS;            /* Call commit handler */
3884 }
3885
3886 static int orinoco_ioctl_getrts(struct net_device *dev,
3887                                 struct iw_request_info *info,
3888                                 struct iw_param *rrq,
3889                                 char *extra)
3890 {
3891         struct orinoco_private *priv = netdev_priv(dev);
3892
3893         rrq->value = priv->rts_thresh;
3894         rrq->disabled = (rrq->value == 2347);
3895         rrq->fixed = 1;
3896
3897         return 0;
3898 }
3899
3900 static int orinoco_ioctl_setfrag(struct net_device *dev,
3901                                  struct iw_request_info *info,
3902                                  struct iw_param *frq,
3903                                  char *extra)
3904 {
3905         struct orinoco_private *priv = netdev_priv(dev);
3906         int err = -EINPROGRESS;         /* Call commit handler */
3907         unsigned long flags;
3908
3909         if (orinoco_lock(priv, &flags) != 0)
3910                 return -EBUSY;
3911
3912         if (priv->has_mwo) {
3913                 if (frq->disabled)
3914                         priv->mwo_robust = 0;
3915                 else {
3916                         if (frq->fixed)
3917                                 printk(KERN_WARNING "%s: Fixed fragmentation is "
3918                                        "not supported on this firmware. "
3919                                        "Using MWO robust instead.\n", dev->name);
3920                         priv->mwo_robust = 1;
3921                 }
3922         } else {
3923                 if (frq->disabled)
3924                         priv->frag_thresh = 2346;
3925                 else {
3926                         if ( (frq->value < 256) || (frq->value > 2346) )
3927                                 err = -EINVAL;
3928                         else
3929                                 priv->frag_thresh = frq->value & ~0x1; /* must be even */
3930                 }
3931         }
3932
3933         orinoco_unlock(priv, &flags);
3934
3935         return err;
3936 }
3937
3938 static int orinoco_ioctl_getfrag(struct net_device *dev,
3939                                  struct iw_request_info *info,
3940                                  struct iw_param *frq,
3941                                  char *extra)
3942 {
3943         struct orinoco_private *priv = netdev_priv(dev);
3944         hermes_t *hw = &priv->hw;
3945         int err;
3946         u16 val;
3947         unsigned long flags;
3948
3949         if (orinoco_lock(priv, &flags) != 0)
3950                 return -EBUSY;
3951         
3952         if (priv->has_mwo) {
3953                 err = hermes_read_wordrec(hw, USER_BAP,
3954                                           HERMES_RID_CNFMWOROBUST_AGERE,
3955                                           &val);
3956                 if (err)
3957                         val = 0;
3958
3959                 frq->value = val ? 2347 : 0;
3960                 frq->disabled = ! val;
3961                 frq->fixed = 0;
3962         } else {
3963                 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
3964                                           &val);
3965                 if (err)
3966                         val = 0;
3967
3968                 frq->value = val;
3969                 frq->disabled = (val >= 2346);
3970                 frq->fixed = 1;
3971         }
3972
3973         orinoco_unlock(priv, &flags);
3974         
3975         return err;
3976 }
3977
3978 static int orinoco_ioctl_setrate(struct net_device *dev,
3979                                  struct iw_request_info *info,
3980                                  struct iw_param *rrq,
3981                                  char *extra)
3982 {
3983         struct orinoco_private *priv = netdev_priv(dev);
3984         int ratemode = -1;
3985         int bitrate; /* 100s of kilobits */
3986         int i;
3987         unsigned long flags;
3988         
3989         /* As the user space doesn't know our highest rate, it uses -1
3990          * to ask us to set the highest rate.  Test it using "iwconfig
3991          * ethX rate auto" - Jean II */
3992         if (rrq->value == -1)
3993                 bitrate = 110;
3994         else {
3995                 if (rrq->value % 100000)
3996                         return -EINVAL;
3997                 bitrate = rrq->value / 100000;
3998         }
3999
4000         if ( (bitrate != 10) && (bitrate != 20) &&
4001              (bitrate != 55) && (bitrate != 110) )
4002                 return -EINVAL;
4003
4004         for (i = 0; i < BITRATE_TABLE_SIZE; i++)
4005                 if ( (bitrate_table[i].bitrate == bitrate) &&
4006                      (bitrate_table[i].automatic == ! rrq->fixed) ) {
4007                         ratemode = i;
4008                         break;
4009                 }
4010         
4011         if (ratemode == -1)
4012                 return -EINVAL;
4013
4014         if (orinoco_lock(priv, &flags) != 0)
4015                 return -EBUSY;
4016         priv->bitratemode = ratemode;
4017         orinoco_unlock(priv, &flags);
4018
4019         return -EINPROGRESS;
4020 }
4021
4022 static int orinoco_ioctl_getrate(struct net_device *dev,
4023                                  struct iw_request_info *info,
4024                                  struct iw_param *rrq,
4025                                  char *extra)
4026 {
4027         struct orinoco_private *priv = netdev_priv(dev);
4028         hermes_t *hw = &priv->hw;
4029         int err = 0;
4030         int ratemode;
4031         int i;
4032         u16 val;
4033         unsigned long flags;
4034
4035         if (orinoco_lock(priv, &flags) != 0)
4036                 return -EBUSY;
4037
4038         ratemode = priv->bitratemode;
4039
4040         BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
4041
4042         rrq->value = bitrate_table[ratemode].bitrate * 100000;
4043         rrq->fixed = ! bitrate_table[ratemode].automatic;
4044         rrq->disabled = 0;
4045
4046         /* If the interface is running we try to find more about the
4047            current mode */
4048         if (netif_running(dev)) {
4049                 err = hermes_read_wordrec(hw, USER_BAP,
4050                                           HERMES_RID_CURRENTTXRATE, &val);
4051                 if (err)
4052                         goto out;
4053                 
4054                 switch (priv->firmware_type) {
4055                 case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
4056                         /* Note : in Lucent firmware, the return value of
4057                          * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
4058                          * and therefore is totally different from the
4059                          * encoding of HERMES_RID_CNFTXRATECONTROL.
4060                          * Don't forget that 6Mb/s is really 5.5Mb/s */
4061                         if (val == 6)
4062                                 rrq->value = 5500000;
4063                         else
4064                                 rrq->value = val * 1000000;
4065                         break;
4066                 case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
4067                 case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
4068                         for (i = 0; i < BITRATE_TABLE_SIZE; i++)
4069                                 if (bitrate_table[i].intersil_txratectrl == val) {
4070                                         ratemode = i;
4071                                         break;
4072                                 }
4073                         if (i >= BITRATE_TABLE_SIZE)
4074                                 printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
4075                                        dev->name, val);
4076
4077                         rrq->value = bitrate_table[ratemode].bitrate * 100000;
4078                         break;
4079                 default:
4080                         BUG();
4081                 }
4082         }
4083
4084  out:
4085         orinoco_unlock(priv, &flags);
4086
4087         return err;
4088 }
4089
4090 static int orinoco_ioctl_setpower(struct net_device *dev,
4091                                   struct iw_request_info *info,
4092                                   struct iw_param *prq,
4093                                   char *extra)
4094 {
4095         struct orinoco_private *priv = netdev_priv(dev);
4096         int err = -EINPROGRESS;         /* Call commit handler */
4097         unsigned long flags;
4098
4099         if (orinoco_lock(priv, &flags) != 0)
4100                 return -EBUSY;
4101
4102         if (prq->disabled) {
4103                 priv->pm_on = 0;
4104         } else {
4105                 switch (prq->flags & IW_POWER_MODE) {
4106                 case IW_POWER_UNICAST_R:
4107                         priv->pm_mcast = 0;
4108                         priv->pm_on = 1;
4109                         break;
4110                 case IW_POWER_ALL_R:
4111                         priv->pm_mcast = 1;
4112                         priv->pm_on = 1;
4113                         break;
4114                 case IW_POWER_ON:
4115                         /* No flags : but we may have a value - Jean II */
4116                         break;
4117                 default:
4118                         err = -EINVAL;
4119                         goto out;
4120                 }
4121                 
4122                 if (prq->flags & IW_POWER_TIMEOUT) {
4123                         priv->pm_on = 1;
4124                         priv->pm_timeout = prq->value / 1000;
4125                 }
4126                 if (prq->flags & IW_POWER_PERIOD) {
4127                         priv->pm_on = 1;
4128                         priv->pm_period = prq->value / 1000;
4129                 }
4130                 /* It's valid to not have a value if we are just toggling
4131                  * the flags... Jean II */
4132                 if(!priv->pm_on) {
4133                         err = -EINVAL;
4134                         goto out;
4135                 }                       
4136         }
4137
4138  out:
4139         orinoco_unlock(priv, &flags);
4140
4141         return err;
4142 }
4143
4144 static int orinoco_ioctl_getpower(struct net_device *dev,
4145                                   struct iw_request_info *info,
4146                                   struct iw_param *prq,
4147                                   char *extra)
4148 {
4149         struct orinoco_private *priv = netdev_priv(dev);
4150         hermes_t *hw = &priv->hw;
4151         int err = 0;
4152         u16 enable, period, timeout, mcast;
4153         unsigned long flags;
4154
4155         if (orinoco_lock(priv, &flags) != 0)
4156                 return -EBUSY;
4157         
4158         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
4159         if (err)
4160                 goto out;
4161
4162         err = hermes_read_wordrec(hw, USER_BAP,
4163                                   HERMES_RID_CNFMAXSLEEPDURATION, &period);
4164         if (err)
4165                 goto out;
4166
4167         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
4168         if (err)
4169                 goto out;
4170
4171         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
4172         if (err)
4173                 goto out;
4174
4175         prq->disabled = !enable;
4176         /* Note : by default, display the period */
4177         if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
4178                 prq->flags = IW_POWER_TIMEOUT;
4179                 prq->value = timeout * 1000;
4180         } else {
4181                 prq->flags = IW_POWER_PERIOD;
4182                 prq->value = period * 1000;
4183         }
4184         if (mcast)
4185                 prq->flags |= IW_POWER_ALL_R;
4186         else
4187                 prq->flags |= IW_POWER_UNICAST_R;
4188
4189  out:
4190         orinoco_unlock(priv, &flags);
4191
4192         return err;
4193 }
4194
4195 static int orinoco_ioctl_getretry(struct net_device *dev,
4196                                   struct iw_request_info *info,
4197                                   struct iw_param *rrq,
4198                                   char *extra)
4199 {
4200         struct orinoco_private *priv = netdev_priv(dev);
4201         hermes_t *hw = &priv->hw;
4202         int err = 0;
4203         u16 short_limit, long_limit, lifetime;
4204         unsigned long flags;
4205
4206         if (orinoco_lock(priv, &flags) != 0)
4207                 return -EBUSY;
4208         
4209         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
4210                                   &short_limit);
4211         if (err)
4212                 goto out;
4213
4214         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
4215                                   &long_limit);
4216         if (err)
4217                 goto out;
4218
4219         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
4220                                   &lifetime);
4221         if (err)
4222                 goto out;
4223
4224         rrq->disabled = 0;              /* Can't be disabled */
4225
4226         /* Note : by default, display the retry number */
4227         if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
4228                 rrq->flags = IW_RETRY_LIFETIME;
4229                 rrq->value = lifetime * 1000;   /* ??? */
4230         } else {
4231                 /* By default, display the min number */
4232                 if ((rrq->flags & IW_RETRY_LONG)) {
4233                         rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
4234                         rrq->value = long_limit;
4235                 } else {
4236                         rrq->flags = IW_RETRY_LIMIT;
4237                         rrq->value = short_limit;
4238                         if(short_limit != long_limit)
4239                                 rrq->flags |= IW_RETRY_SHORT;
4240                 }
4241         }
4242
4243  out:
4244         orinoco_unlock(priv, &flags);
4245
4246         return err;
4247 }
4248
4249 static int orinoco_ioctl_reset(struct net_device *dev,
4250                                struct iw_request_info *info,
4251                                void *wrqu,
4252                                char *extra)
4253 {
4254         struct orinoco_private *priv = netdev_priv(dev);
4255
4256         if (! capable(CAP_NET_ADMIN))
4257                 return -EPERM;
4258
4259         if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
4260                 printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
4261
4262                 /* Firmware reset */
4263                 orinoco_reset(&priv->reset_work);
4264         } else {
4265                 printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
4266
4267                 schedule_work(&priv->reset_work);
4268         }
4269
4270         return 0;
4271 }
4272
4273 static int orinoco_ioctl_setibssport(struct net_device *dev,
4274                                      struct iw_request_info *info,
4275                                      void *wrqu,
4276                                      char *extra)
4277
4278 {
4279         struct orinoco_private *priv = netdev_priv(dev);
4280         int val = *( (int *) extra );
4281         unsigned long flags;
4282
4283         if (orinoco_lock(priv, &flags) != 0)
4284                 return -EBUSY;
4285
4286         priv->ibss_port = val ;
4287
4288         /* Actually update the mode we are using */
4289         set_port_type(priv);
4290
4291         orinoco_unlock(priv, &flags);
4292         return -EINPROGRESS;            /* Call commit handler */
4293 }
4294
4295 static int orinoco_ioctl_getibssport(struct net_device *dev,
4296                                      struct iw_request_info *info,
4297                                      void *wrqu,
4298                                      char *extra)
4299 {
4300         struct orinoco_private *priv = netdev_priv(dev);
4301         int *val = (int *) extra;
4302
4303         *val = priv->ibss_port;
4304         return 0;
4305 }
4306
4307 static int orinoco_ioctl_setport3(struct net_device *dev,
4308                                   struct iw_request_info *info,
4309                                   void *wrqu,
4310                                   char *extra)
4311 {
4312         struct orinoco_private *priv = netdev_priv(dev);
4313         int val = *( (int *) extra );
4314         int err = 0;
4315         unsigned long flags;
4316
4317         if (orinoco_lock(priv, &flags) != 0)
4318                 return -EBUSY;
4319
4320         switch (val) {
4321         case 0: /* Try to do IEEE ad-hoc mode */
4322                 if (! priv->has_ibss) {
4323                         err = -EINVAL;
4324                         break;
4325                 }
4326                 priv->prefer_port3 = 0;
4327                         
4328                 break;
4329
4330         case 1: /* Try to do Lucent proprietary ad-hoc mode */
4331                 if (! priv->has_port3) {
4332                         err = -EINVAL;
4333                         break;
4334                 }
4335                 priv->prefer_port3 = 1;
4336                 break;
4337
4338         default:
4339                 err = -EINVAL;
4340         }
4341
4342         if (! err) {
4343                 /* Actually update the mode we are using */
4344                 set_port_type(priv);
4345                 err = -EINPROGRESS;
4346         }
4347
4348         orinoco_unlock(priv, &flags);
4349
4350         return err;
4351 }
4352
4353 static int orinoco_ioctl_getport3(struct net_device *dev,
4354                                   struct iw_request_info *info,
4355                                   void *wrqu,
4356                                   char *extra)
4357 {
4358         struct orinoco_private *priv = netdev_priv(dev);
4359         int *val = (int *) extra;
4360
4361         *val = priv->prefer_port3;
4362         return 0;
4363 }
4364
4365 static int orinoco_ioctl_setpreamble(struct net_device *dev,
4366                                      struct iw_request_info *info,
4367                                      void *wrqu,
4368                                      char *extra)
4369 {
4370         struct orinoco_private *priv = netdev_priv(dev);
4371         unsigned long flags;
4372         int val;
4373
4374         if (! priv->has_preamble)
4375                 return -EOPNOTSUPP;
4376
4377         /* 802.11b has recently defined some short preamble.
4378          * Basically, the Phy header has been reduced in size.
4379          * This increase performance, especially at high rates
4380          * (the preamble is transmitted at 1Mb/s), unfortunately
4381          * this give compatibility troubles... - Jean II */
4382         val = *( (int *) extra );
4383
4384         if (orinoco_lock(priv, &flags) != 0)
4385                 return -EBUSY;
4386
4387         if (val)
4388                 priv->preamble = 1;
4389         else
4390                 priv->preamble = 0;
4391
4392         orinoco_unlock(priv, &flags);
4393
4394         return -EINPROGRESS;            /* Call commit handler */
4395 }
4396
4397 static int orinoco_ioctl_getpreamble(struct net_device *dev,
4398                                      struct iw_request_info *info,
4399                                      void *wrqu,
4400                                      char *extra)
4401 {
4402         struct orinoco_private *priv = netdev_priv(dev);
4403         int *val = (int *) extra;
4404
4405         if (! priv->has_preamble)
4406                 return -EOPNOTSUPP;
4407
4408         *val = priv->preamble;
4409         return 0;
4410 }
4411
4412 /* ioctl interface to hermes_read_ltv()
4413  * To use with iwpriv, pass the RID as the token argument, e.g.
4414  * iwpriv get_rid [0xfc00]
4415  * At least Wireless Tools 25 is required to use iwpriv.
4416  * For Wireless Tools 25 and 26 append "dummy" are the end. */
4417 static int orinoco_ioctl_getrid(struct net_device *dev,
4418                                 struct iw_request_info *info,
4419                                 struct iw_point *data,
4420                                 char *extra)
4421 {
4422         struct orinoco_private *priv = netdev_priv(dev);
4423         hermes_t *hw = &priv->hw;
4424         int rid = data->flags;
4425         u16 length;
4426         int err;
4427         unsigned long flags;
4428
4429         /* It's a "get" function, but we don't want users to access the
4430          * WEP key and other raw firmware data */
4431         if (! capable(CAP_NET_ADMIN))
4432                 return -EPERM;
4433
4434         if (rid < 0xfc00 || rid > 0xffff)
4435                 return -EINVAL;
4436
4437         if (orinoco_lock(priv, &flags) != 0)
4438                 return -EBUSY;
4439
4440         err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
4441                               extra);
4442         if (err)
4443                 goto out;
4444
4445         data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
4446                              MAX_RID_LEN);
4447
4448  out:
4449         orinoco_unlock(priv, &flags);
4450         return err;
4451 }
4452
4453 /* Trigger a scan (look for other cells in the vicinity) */
4454 static int orinoco_ioctl_setscan(struct net_device *dev,
4455                                  struct iw_request_info *info,
4456                                  struct iw_param *srq,
4457                                  char *extra)
4458 {
4459         struct orinoco_private *priv = netdev_priv(dev);
4460         hermes_t *hw = &priv->hw;
4461         struct iw_scan_req *si = (struct iw_scan_req *) extra;
4462         int err = 0;
4463         unsigned long flags;
4464
4465         /* Note : you may have realised that, as this is a SET operation,
4466          * this is privileged and therefore a normal user can't
4467          * perform scanning.
4468          * This is not an error, while the device perform scanning,
4469          * traffic doesn't flow, so it's a perfect DoS...
4470          * Jean II */
4471
4472         if (orinoco_lock(priv, &flags) != 0)
4473                 return -EBUSY;
4474
4475         /* Scanning with port 0 disabled would fail */
4476         if (!netif_running(dev)) {
4477                 err = -ENETDOWN;
4478                 goto out;
4479         }
4480
4481         /* In monitor mode, the scan results are always empty.
4482          * Probe responses are passed to the driver as received
4483          * frames and could be processed in software. */
4484         if (priv->iw_mode == IW_MODE_MONITOR) {
4485                 err = -EOPNOTSUPP;
4486                 goto out;
4487         }
4488
4489         /* Note : because we don't lock out the irq handler, the way
4490          * we access scan variables in priv is critical.
4491          *      o scan_inprogress : not touched by irq handler
4492          *      o scan_mode : not touched by irq handler
4493          * Before modifying anything on those variables, please think hard !
4494          * Jean II */
4495
4496         /* Save flags */
4497         priv->scan_mode = srq->flags;
4498
4499         /* Always trigger scanning, even if it's in progress.
4500          * This way, if the info frame get lost, we will recover somewhat
4501          * gracefully  - Jean II */
4502
4503         if (priv->has_hostscan) {
4504                 switch (priv->firmware_type) {
4505                 case FIRMWARE_TYPE_SYMBOL:
4506                         err = hermes_write_wordrec(hw, USER_BAP,
4507                                                    HERMES_RID_CNFHOSTSCAN_SYMBOL,
4508                                                    HERMES_HOSTSCAN_SYMBOL_ONCE |
4509                                                    HERMES_HOSTSCAN_SYMBOL_BCAST);
4510                         break;
4511                 case FIRMWARE_TYPE_INTERSIL: {
4512                         __le16 req[3];
4513
4514                         req[0] = cpu_to_le16(0x3fff);   /* All channels */
4515                         req[1] = cpu_to_le16(0x0001);   /* rate 1 Mbps */
4516                         req[2] = 0;                     /* Any ESSID */
4517                         err = HERMES_WRITE_RECORD(hw, USER_BAP,
4518                                                   HERMES_RID_CNFHOSTSCAN, &req);
4519                 }
4520                 break;
4521                 case FIRMWARE_TYPE_AGERE:
4522                         if (priv->scan_mode & IW_SCAN_THIS_ESSID) {
4523                                 struct hermes_idstring idbuf;
4524                                 size_t len = min(sizeof(idbuf.val),
4525                                                  (size_t) si->essid_len);
4526                                 idbuf.len = cpu_to_le16(len);
4527                                 memcpy(idbuf.val, si->essid, len);
4528
4529                                 err = hermes_write_ltv(hw, USER_BAP,
4530                                                HERMES_RID_CNFSCANSSID_AGERE,
4531                                                HERMES_BYTES_TO_RECLEN(len + 2),
4532                                                &idbuf);
4533                         } else
4534                                 err = hermes_write_wordrec(hw, USER_BAP,
4535                                                    HERMES_RID_CNFSCANSSID_AGERE,
4536                                                    0);  /* Any ESSID */
4537                         if (err)
4538                                 break;
4539
4540                         if (priv->has_ext_scan) {
4541                                 /* Clear scan results at the start of
4542                                  * an extended scan */
4543                                 orinoco_clear_scan_results(priv,
4544                                                 msecs_to_jiffies(15000));
4545
4546                                 /* TODO: Is this available on older firmware?
4547                                  *   Can we use it to scan specific channels
4548                                  *   for IW_SCAN_THIS_FREQ? */
4549                                 err = hermes_write_wordrec(hw, USER_BAP,
4550                                                 HERMES_RID_CNFSCANCHANNELS2GHZ,
4551                                                 0x7FFF);
4552                                 if (err)
4553                                         goto out;
4554
4555                                 err = hermes_inquire(hw,
4556                                                      HERMES_INQ_CHANNELINFO);
4557                         } else
4558                                 err = hermes_inquire(hw, HERMES_INQ_SCAN);
4559                         break;
4560                 }
4561         } else
4562                 err = hermes_inquire(hw, HERMES_INQ_SCAN);
4563
4564         /* One more client */
4565         if (! err)
4566                 priv->scan_inprogress = 1;
4567
4568  out:
4569         orinoco_unlock(priv, &flags);
4570         return err;
4571 }
4572
4573 #define MAX_CUSTOM_LEN 64
4574
4575 /* Translate scan data returned from the card to a card independant
4576  * format that the Wireless Tools will understand - Jean II */
4577 static inline char *orinoco_translate_scan(struct net_device *dev,
4578                                            struct iw_request_info *info,
4579                                            char *current_ev,
4580                                            char *end_buf,
4581                                            union hermes_scan_info *bss,
4582                                            unsigned int last_scanned)
4583 {
4584         struct orinoco_private *priv = netdev_priv(dev);
4585         u16                     capabilities;
4586         u16                     channel;
4587         struct iw_event         iwe;            /* Temporary buffer */
4588         char custom[MAX_CUSTOM_LEN];
4589
4590         memset(&iwe, 0, sizeof(iwe));
4591
4592         /* First entry *MUST* be the AP MAC address */
4593         iwe.cmd = SIOCGIWAP;
4594         iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
4595         memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
4596         current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4597                                           &iwe, IW_EV_ADDR_LEN);
4598
4599         /* Other entries will be displayed in the order we give them */
4600
4601         /* Add the ESSID */
4602         iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
4603         if (iwe.u.data.length > 32)
4604                 iwe.u.data.length = 32;
4605         iwe.cmd = SIOCGIWESSID;
4606         iwe.u.data.flags = 1;
4607         current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4608                                           &iwe, bss->a.essid);
4609
4610         /* Add mode */
4611         iwe.cmd = SIOCGIWMODE;
4612         capabilities = le16_to_cpu(bss->a.capabilities);
4613         if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
4614                 if (capabilities & WLAN_CAPABILITY_ESS)
4615                         iwe.u.mode = IW_MODE_MASTER;
4616                 else
4617                         iwe.u.mode = IW_MODE_ADHOC;
4618                 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4619                                                   &iwe, IW_EV_UINT_LEN);
4620         }
4621
4622         channel = bss->s.channel;
4623         if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
4624                 /* Add channel and frequency */
4625                 iwe.cmd = SIOCGIWFREQ;
4626                 iwe.u.freq.m = channel;
4627                 iwe.u.freq.e = 0;
4628                 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4629                                                   &iwe, IW_EV_FREQ_LEN);
4630
4631                 iwe.u.freq.m = channel_frequency[channel-1] * 100000;
4632                 iwe.u.freq.e = 1;
4633                 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4634                                                   &iwe, IW_EV_FREQ_LEN);
4635         }
4636
4637         /* Add quality statistics. level and noise in dB. No link quality */
4638         iwe.cmd = IWEVQUAL;
4639         iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
4640         iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
4641         iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
4642         /* Wireless tools prior to 27.pre22 will show link quality
4643          * anyway, so we provide a reasonable value. */
4644         if (iwe.u.qual.level > iwe.u.qual.noise)
4645                 iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
4646         else
4647                 iwe.u.qual.qual = 0;
4648         current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4649                                           &iwe, IW_EV_QUAL_LEN);
4650
4651         /* Add encryption capability */
4652         iwe.cmd = SIOCGIWENCODE;
4653         if (capabilities & WLAN_CAPABILITY_PRIVACY)
4654                 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
4655         else
4656                 iwe.u.data.flags = IW_ENCODE_DISABLED;
4657         iwe.u.data.length = 0;
4658         current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4659                                           &iwe, NULL);
4660
4661         /* Bit rate is not available in Lucent/Agere firmwares */
4662         if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
4663                 char *current_val = current_ev + iwe_stream_lcp_len(info);
4664                 int i;
4665                 int step;
4666
4667                 if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
4668                         step = 2;
4669                 else
4670                         step = 1;
4671
4672                 iwe.cmd = SIOCGIWRATE;
4673                 /* Those two flags are ignored... */
4674                 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
4675                 /* Max 10 values */
4676                 for (i = 0; i < 10; i += step) {
4677                         /* NULL terminated */
4678                         if (bss->p.rates[i] == 0x0)
4679                                 break;
4680                         /* Bit rate given in 500 kb/s units (+ 0x80) */
4681                         iwe.u.bitrate.value =
4682                                 ((bss->p.rates[i] & 0x7f) * 500000);
4683                         current_val = iwe_stream_add_value(info, current_ev,
4684                                                            current_val,
4685                                                            end_buf, &iwe,
4686                                                            IW_EV_PARAM_LEN);
4687                 }
4688                 /* Check if we added any event */
4689                 if ((current_val - current_ev) > iwe_stream_lcp_len(info))
4690                         current_ev = current_val;
4691         }
4692
4693         /* Beacon interval */
4694         iwe.cmd = IWEVCUSTOM;
4695         iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
4696                                      "bcn_int=%d",
4697                                      le16_to_cpu(bss->a.beacon_interv));
4698         if (iwe.u.data.length)
4699                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4700                                                   &iwe, custom);
4701
4702         /* Capabilites */
4703         iwe.cmd = IWEVCUSTOM;
4704         iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
4705                                      "capab=0x%04x",
4706                                      capabilities);
4707         if (iwe.u.data.length)
4708                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4709                                                   &iwe, custom);
4710
4711         /* Add EXTRA: Age to display seconds since last beacon/probe response
4712          * for given network. */
4713         iwe.cmd = IWEVCUSTOM;
4714         iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
4715                                      " Last beacon: %dms ago",
4716                                      jiffies_to_msecs(jiffies - last_scanned));
4717         if (iwe.u.data.length)
4718                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4719                                                   &iwe, custom);
4720
4721         return current_ev;
4722 }
4723
4724 static inline char *orinoco_translate_ext_scan(struct net_device *dev,
4725                                                struct iw_request_info *info,
4726                                                char *current_ev,
4727                                                char *end_buf,
4728                                                struct agere_ext_scan_info *bss,
4729                                                unsigned int last_scanned)
4730 {
4731         u16                     capabilities;
4732         u16                     channel;
4733         struct iw_event         iwe;            /* Temporary buffer */
4734         char custom[MAX_CUSTOM_LEN];
4735         u8 *ie;
4736
4737         memset(&iwe, 0, sizeof(iwe));
4738
4739         /* First entry *MUST* be the AP MAC address */
4740         iwe.cmd = SIOCGIWAP;
4741         iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
4742         memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
4743         current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4744                                           &iwe, IW_EV_ADDR_LEN);
4745
4746         /* Other entries will be displayed in the order we give them */
4747
4748         /* Add the ESSID */
4749         ie = bss->data;
4750         iwe.u.data.length = ie[1];
4751         if (iwe.u.data.length) {
4752                 if (iwe.u.data.length > 32)
4753                         iwe.u.data.length = 32;
4754                 iwe.cmd = SIOCGIWESSID;
4755                 iwe.u.data.flags = 1;
4756                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4757                                                   &iwe, &ie[2]);
4758         }
4759
4760         /* Add mode */
4761         capabilities = le16_to_cpu(bss->capabilities);
4762         if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
4763                 iwe.cmd = SIOCGIWMODE;
4764                 if (capabilities & WLAN_CAPABILITY_ESS)
4765                         iwe.u.mode = IW_MODE_MASTER;
4766                 else
4767                         iwe.u.mode = IW_MODE_ADHOC;
4768                 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4769                                                   &iwe, IW_EV_UINT_LEN);
4770         }
4771
4772         ie = orinoco_get_ie(bss->data, sizeof(bss->data), MFIE_TYPE_DS_SET);
4773         channel = ie ? ie[2] : 0;
4774         if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
4775                 /* Add channel and frequency */
4776                 iwe.cmd = SIOCGIWFREQ;
4777                 iwe.u.freq.m = channel;
4778                 iwe.u.freq.e = 0;
4779                 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4780                                                   &iwe, IW_EV_FREQ_LEN);
4781
4782                 iwe.u.freq.m = channel_frequency[channel-1] * 100000;
4783                 iwe.u.freq.e = 1;
4784                 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4785                                                   &iwe, IW_EV_FREQ_LEN);
4786         }
4787
4788         /* Add quality statistics. level and noise in dB. No link quality */
4789         iwe.cmd = IWEVQUAL;
4790         iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
4791         iwe.u.qual.level = bss->level - 0x95;
4792         iwe.u.qual.noise = bss->noise - 0x95;
4793         /* Wireless tools prior to 27.pre22 will show link quality
4794          * anyway, so we provide a reasonable value. */
4795         if (iwe.u.qual.level > iwe.u.qual.noise)
4796                 iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
4797         else
4798                 iwe.u.qual.qual = 0;
4799         current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4800                                           &iwe, IW_EV_QUAL_LEN);
4801
4802         /* Add encryption capability */
4803         iwe.cmd = SIOCGIWENCODE;
4804         if (capabilities & WLAN_CAPABILITY_PRIVACY)
4805                 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
4806         else
4807                 iwe.u.data.flags = IW_ENCODE_DISABLED;
4808         iwe.u.data.length = 0;
4809         current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4810                                           &iwe, NULL);
4811
4812         /* WPA IE */
4813         ie = orinoco_get_wpa_ie(bss->data, sizeof(bss->data));
4814         if (ie) {
4815                 iwe.cmd = IWEVGENIE;
4816                 iwe.u.data.length = ie[1] + 2;
4817                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4818                                                   &iwe, ie);
4819         }
4820
4821         /* RSN IE */
4822         ie = orinoco_get_ie(bss->data, sizeof(bss->data), MFIE_TYPE_RSN);
4823         if (ie) {
4824                 iwe.cmd = IWEVGENIE;
4825                 iwe.u.data.length = ie[1] + 2;
4826                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4827                                                   &iwe, ie);
4828         }
4829
4830         ie = orinoco_get_ie(bss->data, sizeof(bss->data), MFIE_TYPE_RATES);
4831         if (ie) {
4832                 char *p = current_ev + iwe_stream_lcp_len(info);
4833                 int i;
4834
4835                 iwe.cmd = SIOCGIWRATE;
4836                 /* Those two flags are ignored... */
4837                 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
4838
4839                 for (i = 2; i < (ie[1] + 2); i++) {
4840                         iwe.u.bitrate.value = ((ie[i] & 0x7F) * 500000);
4841                         p = iwe_stream_add_value(info, current_ev, p, end_buf,
4842                                                  &iwe, IW_EV_PARAM_LEN);
4843                 }
4844                 /* Check if we added any event */
4845                 if (p > (current_ev + iwe_stream_lcp_len(info)))
4846                         current_ev = p;
4847         }
4848
4849         /* Timestamp */
4850         iwe.cmd = IWEVCUSTOM;
4851         iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
4852                                      "tsf=%016llx",
4853                                      le64_to_cpu(bss->timestamp));
4854         if (iwe.u.data.length)
4855                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4856                                                   &iwe, custom);
4857
4858         /* Beacon interval */
4859         iwe.cmd = IWEVCUSTOM;
4860         iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
4861                                      "bcn_int=%d",
4862                                      le16_to_cpu(bss->beacon_interval));
4863         if (iwe.u.data.length)
4864                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4865                                                   &iwe, custom);
4866
4867         /* Capabilites */
4868         iwe.cmd = IWEVCUSTOM;
4869         iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
4870                                      "capab=0x%04x",
4871                                      capabilities);
4872         if (iwe.u.data.length)
4873                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4874                                                   &iwe, custom);
4875
4876         /* Add EXTRA: Age to display seconds since last beacon/probe response
4877          * for given network. */
4878         iwe.cmd = IWEVCUSTOM;
4879         iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
4880                                      " Last beacon: %dms ago",
4881                                      jiffies_to_msecs(jiffies - last_scanned));
4882         if (iwe.u.data.length)
4883                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4884                                                   &iwe, custom);
4885
4886         return current_ev;
4887 }
4888
4889 /* Return results of a scan */
4890 static int orinoco_ioctl_getscan(struct net_device *dev,
4891                                  struct iw_request_info *info,
4892                                  struct iw_point *srq,
4893                                  char *extra)
4894 {
4895         struct orinoco_private *priv = netdev_priv(dev);
4896         int err = 0;
4897         unsigned long flags;
4898         char *current_ev = extra;
4899
4900         if (orinoco_lock(priv, &flags) != 0)
4901                 return -EBUSY;
4902
4903         if (priv->scan_inprogress) {
4904                 /* Important note : we don't want to block the caller
4905                  * until results are ready for various reasons.
4906                  * First, managing wait queues is complex and racy.
4907                  * Second, we grab some rtnetlink lock before comming
4908                  * here (in dev_ioctl()).
4909                  * Third, we generate an Wireless Event, so the
4910                  * caller can wait itself on that - Jean II */
4911                 err = -EAGAIN;
4912                 goto out;
4913         }
4914
4915         if (priv->has_ext_scan) {
4916                 struct xbss_element *bss;
4917
4918                 list_for_each_entry(bss, &priv->bss_list, list) {
4919                         /* Translate this entry to WE format */
4920                         current_ev =
4921                                 orinoco_translate_ext_scan(dev, info,
4922                                                            current_ev,
4923                                                            extra + srq->length,
4924                                                            &bss->bss,
4925                                                            bss->last_scanned);
4926
4927                         /* Check if there is space for one more entry */
4928                         if ((extra + srq->length - current_ev)
4929                             <= IW_EV_ADDR_LEN) {
4930                                 /* Ask user space to try again with a
4931                                  * bigger buffer */
4932                                 err = -E2BIG;
4933                                 goto out;
4934                         }
4935                 }
4936
4937         } else {
4938                 struct bss_element *bss;
4939
4940                 list_for_each_entry(bss, &priv->bss_list, list) {
4941                         /* Translate this entry to WE format */
4942                         current_ev = orinoco_translate_scan(dev, info,
4943                                                             current_ev,
4944                                                             extra + srq->length,
4945                                                             &bss->bss,
4946                                                             bss->last_scanned);
4947
4948                         /* Check if there is space for one more entry */
4949                         if ((extra + srq->length - current_ev)
4950                             <= IW_EV_ADDR_LEN) {
4951                                 /* Ask user space to try again with a
4952                                  * bigger buffer */
4953                                 err = -E2BIG;
4954                                 goto out;
4955                         }
4956                 }
4957         }
4958
4959         srq->length = (current_ev - extra);
4960         srq->flags = (__u16) priv->scan_mode;
4961
4962 out:
4963         orinoco_unlock(priv, &flags);
4964         return err;
4965 }
4966
4967 /* Commit handler, called after set operations */
4968 static int orinoco_ioctl_commit(struct net_device *dev,
4969                                 struct iw_request_info *info,
4970                                 void *wrqu,
4971                                 char *extra)
4972 {
4973         struct orinoco_private *priv = netdev_priv(dev);
4974         struct hermes *hw = &priv->hw;
4975         unsigned long flags;
4976         int err = 0;
4977
4978         if (!priv->open)
4979                 return 0;
4980
4981         if (priv->broken_disableport) {
4982                 orinoco_reset(&priv->reset_work);
4983                 return 0;
4984         }
4985
4986         if (orinoco_lock(priv, &flags) != 0)
4987                 return err;
4988
4989         err = hermes_disable_port(hw, 0);
4990         if (err) {
4991                 printk(KERN_WARNING "%s: Unable to disable port "
4992                        "while reconfiguring card\n", dev->name);
4993                 priv->broken_disableport = 1;
4994                 goto out;
4995         }
4996
4997         err = __orinoco_program_rids(dev);
4998         if (err) {
4999                 printk(KERN_WARNING "%s: Unable to reconfigure card\n",
5000                        dev->name);
5001                 goto out;
5002         }
5003
5004         err = hermes_enable_port(hw, 0);
5005         if (err) {
5006                 printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
5007                        dev->name);
5008                 goto out;
5009         }
5010
5011  out:
5012         if (err) {
5013                 printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
5014                 schedule_work(&priv->reset_work);
5015                 err = 0;
5016         }
5017
5018         orinoco_unlock(priv, &flags);
5019         return err;
5020 }
5021
5022 static const struct iw_priv_args orinoco_privtab[] = {
5023         { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
5024         { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
5025         { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5026           0, "set_port3" },
5027         { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5028           "get_port3" },
5029         { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5030           0, "set_preamble" },
5031         { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5032           "get_preamble" },
5033         { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5034           0, "set_ibssport" },
5035         { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5036           "get_ibssport" },
5037         { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
5038           "get_rid" },
5039 };
5040
5041
5042 /*
5043  * Structures to export the Wireless Handlers
5044  */
5045
5046 static const iw_handler orinoco_handler[] = {
5047         [SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_commit,
5048         [SIOCGIWNAME  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getname,
5049         [SIOCSIWFREQ  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setfreq,
5050         [SIOCGIWFREQ  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getfreq,
5051         [SIOCSIWMODE  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setmode,
5052         [SIOCGIWMODE  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getmode,
5053         [SIOCSIWSENS  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens,
5054         [SIOCGIWSENS  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens,
5055         [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange,
5056         [SIOCSIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
5057         [SIOCGIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
5058         [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
5059         [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
5060         [SIOCSIWAP    -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap,
5061         [SIOCGIWAP    -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap,
5062         [SIOCSIWSCAN  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan,
5063         [SIOCGIWSCAN  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getscan,
5064         [SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setessid,
5065         [SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getessid,
5066         [SIOCSIWNICKN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setnick,
5067         [SIOCGIWNICKN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getnick,
5068         [SIOCSIWRATE  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setrate,
5069         [SIOCGIWRATE  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getrate,
5070         [SIOCSIWRTS   -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setrts,
5071         [SIOCGIWRTS   -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getrts,
5072         [SIOCSIWFRAG  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setfrag,
5073         [SIOCGIWFRAG  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getfrag,
5074         [SIOCGIWRETRY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getretry,
5075         [SIOCSIWENCODE-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setiwencode,
5076         [SIOCGIWENCODE-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwencode,
5077         [SIOCSIWPOWER -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setpower,
5078         [SIOCGIWPOWER -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getpower,
5079 };
5080
5081
5082 /*
5083   Added typecasting since we no longer use iwreq_data -- Moustafa
5084  */
5085 static const iw_handler orinoco_private_handler[] = {
5086         [0] = (iw_handler) orinoco_ioctl_reset,
5087         [1] = (iw_handler) orinoco_ioctl_reset,
5088         [2] = (iw_handler) orinoco_ioctl_setport3,
5089         [3] = (iw_handler) orinoco_ioctl_getport3,
5090         [4] = (iw_handler) orinoco_ioctl_setpreamble,
5091         [5] = (iw_handler) orinoco_ioctl_getpreamble,
5092         [6] = (iw_handler) orinoco_ioctl_setibssport,
5093         [7] = (iw_handler) orinoco_ioctl_getibssport,
5094         [9] = (iw_handler) orinoco_ioctl_getrid,
5095 };
5096
5097 static const struct iw_handler_def orinoco_handler_def = {
5098         .num_standard = ARRAY_SIZE(orinoco_handler),
5099         .num_private = ARRAY_SIZE(orinoco_private_handler),
5100         .num_private_args = ARRAY_SIZE(orinoco_privtab),
5101         .standard = orinoco_handler,
5102         .private = orinoco_private_handler,
5103         .private_args = orinoco_privtab,
5104         .get_wireless_stats = orinoco_get_wireless_stats,
5105 };
5106
5107 static void orinoco_get_drvinfo(struct net_device *dev,
5108                                 struct ethtool_drvinfo *info)
5109 {
5110         struct orinoco_private *priv = netdev_priv(dev);
5111
5112         strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
5113         strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
5114         strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
5115         if (dev->dev.parent)
5116                 strncpy(info->bus_info, dev->dev.parent->bus_id,
5117                         sizeof(info->bus_info) - 1);
5118         else
5119                 snprintf(info->bus_info, sizeof(info->bus_info) - 1,
5120                          "PCMCIA %p", priv->hw.iobase);
5121 }
5122
5123 static const struct ethtool_ops orinoco_ethtool_ops = {
5124         .get_drvinfo = orinoco_get_drvinfo,
5125         .get_link = ethtool_op_get_link,
5126 };
5127
5128 /********************************************************************/
5129 /* Module initialization                                            */
5130 /********************************************************************/
5131
5132 EXPORT_SYMBOL(alloc_orinocodev);
5133 EXPORT_SYMBOL(free_orinocodev);
5134
5135 EXPORT_SYMBOL(__orinoco_up);
5136 EXPORT_SYMBOL(__orinoco_down);
5137 EXPORT_SYMBOL(orinoco_reinit_firmware);
5138
5139 EXPORT_SYMBOL(orinoco_interrupt);
5140
5141 /* Can't be declared "const" or the whole __initdata section will
5142  * become const */
5143 static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
5144         " (David Gibson <hermes@gibson.dropbear.id.au>, "
5145         "Pavel Roskin <proski@gnu.org>, et al)";
5146
5147 static int __init init_orinoco(void)
5148 {
5149         printk(KERN_DEBUG "%s\n", version);
5150         return 0;
5151 }
5152
5153 static void __exit exit_orinoco(void)
5154 {
5155 }
5156
5157 module_init(init_orinoco);
5158 module_exit(exit_orinoco);