]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/net/wireless/orinoco.c
orinoco: Don't use boolean parameter to record encoding type
[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_wevents(struct work_struct *work)
1428 {
1429         struct orinoco_private *priv =
1430                 container_of(work, struct orinoco_private, wevent_work);
1431         struct net_device *dev = priv->ndev;
1432         struct hermes *hw = &priv->hw;
1433         union iwreq_data wrqu;
1434         int err;
1435         unsigned long flags;
1436
1437         if (orinoco_lock(priv, &flags) != 0)
1438                 return;
1439
1440         err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
1441                               ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
1442         if (err != 0)
1443                 goto out;
1444
1445         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1446
1447         /* Send event to user space */
1448         wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
1449
1450  out:
1451         orinoco_unlock(priv, &flags);
1452 }
1453
1454
1455 static inline void orinoco_clear_scan_results(struct orinoco_private *priv,
1456                                               unsigned long scan_age)
1457 {
1458         if (priv->has_ext_scan) {
1459                 struct xbss_element *bss;
1460                 struct xbss_element *tmp_bss;
1461
1462                 /* Blow away current list of scan results */
1463                 list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
1464                         if (!scan_age ||
1465                             time_after(jiffies, bss->last_scanned + scan_age)) {
1466                                 list_move_tail(&bss->list,
1467                                                &priv->bss_free_list);
1468                                 /* Don't blow away ->list, just BSS data */
1469                                 memset(&bss->bss, 0, sizeof(bss->bss));
1470                                 bss->last_scanned = 0;
1471                         }
1472                 }
1473         } else {
1474                 struct bss_element *bss;
1475                 struct bss_element *tmp_bss;
1476
1477                 /* Blow away current list of scan results */
1478                 list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
1479                         if (!scan_age ||
1480                             time_after(jiffies, bss->last_scanned + scan_age)) {
1481                                 list_move_tail(&bss->list,
1482                                                &priv->bss_free_list);
1483                                 /* Don't blow away ->list, just BSS data */
1484                                 memset(&bss->bss, 0, sizeof(bss->bss));
1485                                 bss->last_scanned = 0;
1486                         }
1487                 }
1488         }
1489 }
1490
1491 static void orinoco_add_ext_scan_result(struct orinoco_private *priv,
1492                                         struct agere_ext_scan_info *atom)
1493 {
1494         struct xbss_element *bss = NULL;
1495         int found = 0;
1496
1497         /* Try to update an existing bss first */
1498         list_for_each_entry(bss, &priv->bss_list, list) {
1499                 if (compare_ether_addr(bss->bss.bssid, atom->bssid))
1500                         continue;
1501                 /* ESSID lengths */
1502                 if (bss->bss.data[1] != atom->data[1])
1503                         continue;
1504                 if (memcmp(&bss->bss.data[2], &atom->data[2],
1505                            atom->data[1]))
1506                         continue;
1507                 found = 1;
1508                 break;
1509         }
1510
1511         /* Grab a bss off the free list */
1512         if (!found && !list_empty(&priv->bss_free_list)) {
1513                 bss = list_entry(priv->bss_free_list.next,
1514                                  struct xbss_element, list);
1515                 list_del(priv->bss_free_list.next);
1516
1517                 list_add_tail(&bss->list, &priv->bss_list);
1518         }
1519
1520         if (bss) {
1521                 /* Always update the BSS to get latest beacon info */
1522                 memcpy(&bss->bss, atom, sizeof(bss->bss));
1523                 bss->last_scanned = jiffies;
1524         }
1525 }
1526
1527 static int orinoco_process_scan_results(struct net_device *dev,
1528                                         unsigned char *buf,
1529                                         int len)
1530 {
1531         struct orinoco_private *priv = netdev_priv(dev);
1532         int                     offset;         /* In the scan data */
1533         union hermes_scan_info *atom;
1534         int                     atom_len;
1535
1536         switch (priv->firmware_type) {
1537         case FIRMWARE_TYPE_AGERE:
1538                 atom_len = sizeof(struct agere_scan_apinfo);
1539                 offset = 0;
1540                 break;
1541         case FIRMWARE_TYPE_SYMBOL:
1542                 /* Lack of documentation necessitates this hack.
1543                  * Different firmwares have 68 or 76 byte long atoms.
1544                  * We try modulo first.  If the length divides by both,
1545                  * we check what would be the channel in the second
1546                  * frame for a 68-byte atom.  76-byte atoms have 0 there.
1547                  * Valid channel cannot be 0.  */
1548                 if (len % 76)
1549                         atom_len = 68;
1550                 else if (len % 68)
1551                         atom_len = 76;
1552                 else if (len >= 1292 && buf[68] == 0)
1553                         atom_len = 76;
1554                 else
1555                         atom_len = 68;
1556                 offset = 0;
1557                 break;
1558         case FIRMWARE_TYPE_INTERSIL:
1559                 offset = 4;
1560                 if (priv->has_hostscan) {
1561                         atom_len = le16_to_cpup((__le16 *)buf);
1562                         /* Sanity check for atom_len */
1563                         if (atom_len < sizeof(struct prism2_scan_apinfo)) {
1564                                 printk(KERN_ERR "%s: Invalid atom_len in scan "
1565                                        "data: %d\n", dev->name, atom_len);
1566                                 return -EIO;
1567                         }
1568                 } else
1569                         atom_len = offsetof(struct prism2_scan_apinfo, atim);
1570                 break;
1571         default:
1572                 return -EOPNOTSUPP;
1573         }
1574
1575         /* Check that we got an whole number of atoms */
1576         if ((len - offset) % atom_len) {
1577                 printk(KERN_ERR "%s: Unexpected scan data length %d, "
1578                        "atom_len %d, offset %d\n", dev->name, len,
1579                        atom_len, offset);
1580                 return -EIO;
1581         }
1582
1583         orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
1584
1585         /* Read the entries one by one */
1586         for (; offset + atom_len <= len; offset += atom_len) {
1587                 int found = 0;
1588                 struct bss_element *bss = NULL;
1589
1590                 /* Get next atom */
1591                 atom = (union hermes_scan_info *) (buf + offset);
1592
1593                 /* Try to update an existing bss first */
1594                 list_for_each_entry(bss, &priv->bss_list, list) {
1595                         if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
1596                                 continue;
1597                         if (le16_to_cpu(bss->bss.a.essid_len) !=
1598                               le16_to_cpu(atom->a.essid_len))
1599                                 continue;
1600                         if (memcmp(bss->bss.a.essid, atom->a.essid,
1601                               le16_to_cpu(atom->a.essid_len)))
1602                                 continue;
1603                         found = 1;
1604                         break;
1605                 }
1606
1607                 /* Grab a bss off the free list */
1608                 if (!found && !list_empty(&priv->bss_free_list)) {
1609                         bss = list_entry(priv->bss_free_list.next,
1610                                          struct bss_element, list);
1611                         list_del(priv->bss_free_list.next);
1612
1613                         list_add_tail(&bss->list, &priv->bss_list);
1614                 }
1615
1616                 if (bss) {
1617                         /* Always update the BSS to get latest beacon info */
1618                         memcpy(&bss->bss, atom, sizeof(bss->bss));
1619                         bss->last_scanned = jiffies;
1620                 }
1621         }
1622
1623         return 0;
1624 }
1625
1626 static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1627 {
1628         struct orinoco_private *priv = netdev_priv(dev);
1629         u16 infofid;
1630         struct {
1631                 __le16 len;
1632                 __le16 type;
1633         } __attribute__ ((packed)) info;
1634         int len, type;
1635         int err;
1636
1637         /* This is an answer to an INQUIRE command that we did earlier,
1638          * or an information "event" generated by the card
1639          * The controller return to us a pseudo frame containing
1640          * the information in question - Jean II */
1641         infofid = hermes_read_regn(hw, INFOFID);
1642
1643         /* Read the info frame header - don't try too hard */
1644         err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
1645                                infofid, 0);
1646         if (err) {
1647                 printk(KERN_ERR "%s: error %d reading info frame. "
1648                        "Frame dropped.\n", dev->name, err);
1649                 return;
1650         }
1651         
1652         len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
1653         type = le16_to_cpu(info.type);
1654
1655         switch (type) {
1656         case HERMES_INQ_TALLIES: {
1657                 struct hermes_tallies_frame tallies;
1658                 struct iw_statistics *wstats = &priv->wstats;
1659                 
1660                 if (len > sizeof(tallies)) {
1661                         printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
1662                                dev->name, len);
1663                         len = sizeof(tallies);
1664                 }
1665                 
1666                 err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
1667                                        infofid, sizeof(info));
1668                 if (err)
1669                         break;
1670                 
1671                 /* Increment our various counters */
1672                 /* wstats->discard.nwid - no wrong BSSID stuff */
1673                 wstats->discard.code +=
1674                         le16_to_cpu(tallies.RxWEPUndecryptable);
1675                 if (len == sizeof(tallies))  
1676                         wstats->discard.code +=
1677                                 le16_to_cpu(tallies.RxDiscards_WEPICVError) +
1678                                 le16_to_cpu(tallies.RxDiscards_WEPExcluded);
1679                 wstats->discard.misc +=
1680                         le16_to_cpu(tallies.TxDiscardsWrongSA);
1681                 wstats->discard.fragment +=
1682                         le16_to_cpu(tallies.RxMsgInBadMsgFragments);
1683                 wstats->discard.retries +=
1684                         le16_to_cpu(tallies.TxRetryLimitExceeded);
1685                 /* wstats->miss.beacon - no match */
1686         }
1687         break;
1688         case HERMES_INQ_LINKSTATUS: {
1689                 struct hermes_linkstatus linkstatus;
1690                 u16 newstatus;
1691                 int connected;
1692
1693                 if (priv->iw_mode == IW_MODE_MONITOR)
1694                         break;
1695
1696                 if (len != sizeof(linkstatus)) {
1697                         printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
1698                                dev->name, len);
1699                         break;
1700                 }
1701
1702                 err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
1703                                        infofid, sizeof(info));
1704                 if (err)
1705                         break;
1706                 newstatus = le16_to_cpu(linkstatus.linkstatus);
1707
1708                 /* Symbol firmware uses "out of range" to signal that
1709                  * the hostscan frame can be requested.  */
1710                 if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
1711                     priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
1712                     priv->has_hostscan && priv->scan_inprogress) {
1713                         hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
1714                         break;
1715                 }
1716
1717                 connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
1718                         || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
1719                         || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
1720
1721                 if (connected)
1722                         netif_carrier_on(dev);
1723                 else if (!ignore_disconnect)
1724                         netif_carrier_off(dev);
1725
1726                 if (newstatus != priv->last_linkstatus) {
1727                         priv->last_linkstatus = newstatus;
1728                         print_linkstatus(dev, newstatus);
1729                         /* The info frame contains only one word which is the
1730                          * status (see hermes.h). The status is pretty boring
1731                          * in itself, that's why we export the new BSSID...
1732                          * Jean II */
1733                         schedule_work(&priv->wevent_work);
1734                 }
1735         }
1736         break;
1737         case HERMES_INQ_SCAN:
1738                 if (!priv->scan_inprogress && priv->bssid_fixed &&
1739                     priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
1740                         schedule_work(&priv->join_work);
1741                         break;
1742                 }
1743                 /* fall through */
1744         case HERMES_INQ_HOSTSCAN:
1745         case HERMES_INQ_HOSTSCAN_SYMBOL: {
1746                 /* Result of a scanning. Contains information about
1747                  * cells in the vicinity - Jean II */
1748                 union iwreq_data        wrqu;
1749                 unsigned char *buf;
1750
1751                 /* Scan is no longer in progress */
1752                 priv->scan_inprogress = 0;
1753
1754                 /* Sanity check */
1755                 if (len > 4096) {
1756                         printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
1757                                dev->name, len);
1758                         break;
1759                 }
1760
1761                 /* Allocate buffer for results */
1762                 buf = kmalloc(len, GFP_ATOMIC);
1763                 if (buf == NULL)
1764                         /* No memory, so can't printk()... */
1765                         break;
1766
1767                 /* Read scan data */
1768                 err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
1769                                        infofid, sizeof(info));
1770                 if (err) {
1771                         kfree(buf);
1772                         break;
1773                 }
1774
1775 #ifdef ORINOCO_DEBUG
1776                 {
1777                         int     i;
1778                         printk(KERN_DEBUG "Scan result [%02X", buf[0]);
1779                         for(i = 1; i < (len * 2); i++)
1780                                 printk(":%02X", buf[i]);
1781                         printk("]\n");
1782                 }
1783 #endif  /* ORINOCO_DEBUG */
1784
1785                 if (orinoco_process_scan_results(dev, buf, len) == 0) {
1786                         /* Send an empty event to user space.
1787                          * We don't send the received data on the event because
1788                          * it would require us to do complex transcoding, and
1789                          * we want to minimise the work done in the irq handler
1790                          * Use a request to extract the data - Jean II */
1791                         wrqu.data.length = 0;
1792                         wrqu.data.flags = 0;
1793                         wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
1794                 }
1795                 kfree(buf);
1796         }
1797         break;
1798         case HERMES_INQ_CHANNELINFO:
1799         {
1800                 struct agere_ext_scan_info *bss;
1801
1802                 if (!priv->scan_inprogress) {
1803                         printk(KERN_DEBUG "%s: Got chaninfo without scan, "
1804                                "len=%d\n", dev->name, len);
1805                         break;
1806                 }
1807
1808                 /* An empty result indicates that the scan is complete */
1809                 if (len == 0) {
1810                         union iwreq_data        wrqu;
1811
1812                         /* Scan is no longer in progress */
1813                         priv->scan_inprogress = 0;
1814
1815                         wrqu.data.length = 0;
1816                         wrqu.data.flags = 0;
1817                         wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
1818                         break;
1819                 }
1820
1821                 /* Sanity check */
1822                 else if (len > sizeof(*bss)) {
1823                         printk(KERN_WARNING
1824                                "%s: Ext scan results too large (%d bytes). "
1825                                "Truncating results to %zd bytes.\n",
1826                                dev->name, len, sizeof(*bss));
1827                         len = sizeof(*bss);
1828                 } else if (len < (offsetof(struct agere_ext_scan_info,
1829                                            data) + 2)) {
1830                         /* Drop this result now so we don't have to
1831                          * keep checking later */
1832                         printk(KERN_WARNING
1833                                "%s: Ext scan results too short (%d bytes)\n",
1834                                dev->name, len);
1835                         break;
1836                 }
1837
1838                 bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
1839                 if (bss == NULL)
1840                         break;
1841
1842                 /* Read scan data */
1843                 err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len,
1844                                        infofid, sizeof(info));
1845                 if (err) {
1846                         kfree(bss);
1847                         break;
1848                 }
1849
1850                 orinoco_add_ext_scan_result(priv, bss);
1851
1852                 kfree(bss);
1853                 break;
1854         }
1855         case HERMES_INQ_SEC_STAT_AGERE:
1856                 /* Security status (Agere specific) */
1857                 /* Ignore this frame for now */
1858                 if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
1859                         break;
1860                 /* fall through */
1861         default:
1862                 printk(KERN_DEBUG "%s: Unknown information frame received: "
1863                        "type 0x%04x, length %d\n", dev->name, type, len);
1864                 /* We don't actually do anything about it */
1865                 break;
1866         }
1867 }
1868
1869 static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
1870 {
1871         if (net_ratelimit())
1872                 printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
1873 }
1874
1875 /********************************************************************/
1876 /* Internal hardware control routines                               */
1877 /********************************************************************/
1878
1879 int __orinoco_up(struct net_device *dev)
1880 {
1881         struct orinoco_private *priv = netdev_priv(dev);
1882         struct hermes *hw = &priv->hw;
1883         int err;
1884
1885         netif_carrier_off(dev); /* just to make sure */
1886
1887         err = __orinoco_program_rids(dev);
1888         if (err) {
1889                 printk(KERN_ERR "%s: Error %d configuring card\n",
1890                        dev->name, err);
1891                 return err;
1892         }
1893
1894         /* Fire things up again */
1895         hermes_set_irqmask(hw, ORINOCO_INTEN);
1896         err = hermes_enable_port(hw, 0);
1897         if (err) {
1898                 printk(KERN_ERR "%s: Error %d enabling MAC port\n",
1899                        dev->name, err);
1900                 return err;
1901         }
1902
1903         netif_start_queue(dev);
1904
1905         return 0;
1906 }
1907
1908 int __orinoco_down(struct net_device *dev)
1909 {
1910         struct orinoco_private *priv = netdev_priv(dev);
1911         struct hermes *hw = &priv->hw;
1912         int err;
1913
1914         netif_stop_queue(dev);
1915
1916         if (! priv->hw_unavailable) {
1917                 if (! priv->broken_disableport) {
1918                         err = hermes_disable_port(hw, 0);
1919                         if (err) {
1920                                 /* Some firmwares (e.g. Intersil 1.3.x) seem
1921                                  * to have problems disabling the port, oh
1922                                  * well, too bad. */
1923                                 printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
1924                                        dev->name, err);
1925                                 priv->broken_disableport = 1;
1926                         }
1927                 }
1928                 hermes_set_irqmask(hw, 0);
1929                 hermes_write_regn(hw, EVACK, 0xffff);
1930         }
1931         
1932         /* firmware will have to reassociate */
1933         netif_carrier_off(dev);
1934         priv->last_linkstatus = 0xffff;
1935
1936         return 0;
1937 }
1938
1939 static int orinoco_allocate_fid(struct net_device *dev)
1940 {
1941         struct orinoco_private *priv = netdev_priv(dev);
1942         struct hermes *hw = &priv->hw;
1943         int err;
1944
1945         err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
1946         if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
1947                 /* Try workaround for old Symbol firmware bug */
1948                 printk(KERN_WARNING "%s: firmware ALLOC bug detected "
1949                        "(old Symbol firmware?). Trying to work around... ",
1950                        dev->name);
1951                 
1952                 priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
1953                 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
1954                 if (err)
1955                         printk("failed!\n");
1956                 else
1957                         printk("ok.\n");
1958         }
1959
1960         return err;
1961 }
1962
1963 int orinoco_reinit_firmware(struct net_device *dev)
1964 {
1965         struct orinoco_private *priv = netdev_priv(dev);
1966         struct hermes *hw = &priv->hw;
1967         int err;
1968
1969         err = hermes_init(hw);
1970         if (!err)
1971                 err = orinoco_allocate_fid(dev);
1972
1973         return err;
1974 }
1975
1976 static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
1977 {
1978         hermes_t *hw = &priv->hw;
1979         int err = 0;
1980
1981         if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
1982                 printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
1983                        priv->ndev->name, priv->bitratemode);
1984                 return -EINVAL;
1985         }
1986
1987         switch (priv->firmware_type) {
1988         case FIRMWARE_TYPE_AGERE:
1989                 err = hermes_write_wordrec(hw, USER_BAP,
1990                                            HERMES_RID_CNFTXRATECONTROL,
1991                                            bitrate_table[priv->bitratemode].agere_txratectrl);
1992                 break;
1993         case FIRMWARE_TYPE_INTERSIL:
1994         case FIRMWARE_TYPE_SYMBOL:
1995                 err = hermes_write_wordrec(hw, USER_BAP,
1996                                            HERMES_RID_CNFTXRATECONTROL,
1997                                            bitrate_table[priv->bitratemode].intersil_txratectrl);
1998                 break;
1999         default:
2000                 BUG();
2001         }
2002
2003         return err;
2004 }
2005
2006 /* Set fixed AP address */
2007 static int __orinoco_hw_set_wap(struct orinoco_private *priv)
2008 {
2009         int roaming_flag;
2010         int err = 0;
2011         hermes_t *hw = &priv->hw;
2012
2013         switch (priv->firmware_type) {
2014         case FIRMWARE_TYPE_AGERE:
2015                 /* not supported */
2016                 break;
2017         case FIRMWARE_TYPE_INTERSIL:
2018                 if (priv->bssid_fixed)
2019                         roaming_flag = 2;
2020                 else
2021                         roaming_flag = 1;
2022
2023                 err = hermes_write_wordrec(hw, USER_BAP,
2024                                            HERMES_RID_CNFROAMINGMODE,
2025                                            roaming_flag);
2026                 break;
2027         case FIRMWARE_TYPE_SYMBOL:
2028                 err = HERMES_WRITE_RECORD(hw, USER_BAP,
2029                                           HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
2030                                           &priv->desired_bssid);
2031                 break;
2032         }
2033         return err;
2034 }
2035
2036 /* Change the WEP keys and/or the current keys.  Can be called
2037  * either from __orinoco_hw_setup_wep() or directly from
2038  * orinoco_ioctl_setiwencode().  In the later case the association
2039  * with the AP is not broken (if the firmware can handle it),
2040  * which is needed for 802.1x implementations. */
2041 static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
2042 {
2043         hermes_t *hw = &priv->hw;
2044         int err = 0;
2045
2046         switch (priv->firmware_type) {
2047         case FIRMWARE_TYPE_AGERE:
2048                 err = HERMES_WRITE_RECORD(hw, USER_BAP,
2049                                           HERMES_RID_CNFWEPKEYS_AGERE,
2050                                           &priv->keys);
2051                 if (err)
2052                         return err;
2053                 err = hermes_write_wordrec(hw, USER_BAP,
2054                                            HERMES_RID_CNFTXKEY_AGERE,
2055                                            priv->tx_key);
2056                 if (err)
2057                         return err;
2058                 break;
2059         case FIRMWARE_TYPE_INTERSIL:
2060         case FIRMWARE_TYPE_SYMBOL:
2061                 {
2062                         int keylen;
2063                         int i;
2064
2065                         /* Force uniform key length to work around firmware bugs */
2066                         keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
2067                         
2068                         if (keylen > LARGE_KEY_SIZE) {
2069                                 printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
2070                                        priv->ndev->name, priv->tx_key, keylen);
2071                                 return -E2BIG;
2072                         }
2073
2074                         /* Write all 4 keys */
2075                         for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
2076                                 err = hermes_write_ltv(hw, USER_BAP,
2077                                                        HERMES_RID_CNFDEFAULTKEY0 + i,
2078                                                        HERMES_BYTES_TO_RECLEN(keylen),
2079                                                        priv->keys[i].data);
2080                                 if (err)
2081                                         return err;
2082                         }
2083
2084                         /* Write the index of the key used in transmission */
2085                         err = hermes_write_wordrec(hw, USER_BAP,
2086                                                    HERMES_RID_CNFWEPDEFAULTKEYID,
2087                                                    priv->tx_key);
2088                         if (err)
2089                                 return err;
2090                 }
2091                 break;
2092         }
2093
2094         return 0;
2095 }
2096
2097 static int __orinoco_hw_setup_wep(struct orinoco_private *priv)
2098 {
2099         hermes_t *hw = &priv->hw;
2100         int err = 0;
2101         int master_wep_flag;
2102         int auth_flag;
2103         int enc_flag;
2104
2105         if (priv->encode_alg == IW_ENCODE_ALG_WEP)
2106                 __orinoco_hw_setup_wepkeys(priv);
2107
2108         if (priv->wep_restrict)
2109                 auth_flag = HERMES_AUTH_SHARED_KEY;
2110         else
2111                 auth_flag = HERMES_AUTH_OPEN;
2112
2113         if (priv->encode_alg == IW_ENCODE_ALG_WEP)
2114                 enc_flag = 1;
2115         else
2116                 enc_flag = 0;
2117
2118         switch (priv->firmware_type) {
2119         case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
2120                 if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
2121                         /* Enable the shared-key authentication. */
2122                         err = hermes_write_wordrec(hw, USER_BAP,
2123                                                    HERMES_RID_CNFAUTHENTICATION_AGERE,
2124                                                    auth_flag);
2125                 }
2126                 err = hermes_write_wordrec(hw, USER_BAP,
2127                                            HERMES_RID_CNFWEPENABLED_AGERE,
2128                                            enc_flag);
2129                 if (err)
2130                         return err;
2131                 break;
2132
2133         case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
2134         case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
2135                 if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
2136                         if (priv->wep_restrict ||
2137                             (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
2138                                 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
2139                                                   HERMES_WEP_EXCL_UNENCRYPTED;
2140                         else
2141                                 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
2142
2143                         err = hermes_write_wordrec(hw, USER_BAP,
2144                                                    HERMES_RID_CNFAUTHENTICATION,
2145                                                    auth_flag);
2146                         if (err)
2147                                 return err;
2148                 } else
2149                         master_wep_flag = 0;
2150
2151                 if (priv->iw_mode == IW_MODE_MONITOR)
2152                         master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
2153
2154                 /* Master WEP setting : on/off */
2155                 err = hermes_write_wordrec(hw, USER_BAP,
2156                                            HERMES_RID_CNFWEPFLAGS_INTERSIL,
2157                                            master_wep_flag);
2158                 if (err)
2159                         return err;     
2160
2161                 break;
2162         }
2163
2164         return 0;
2165 }
2166
2167 static int __orinoco_program_rids(struct net_device *dev)
2168 {
2169         struct orinoco_private *priv = netdev_priv(dev);
2170         hermes_t *hw = &priv->hw;
2171         int err;
2172         struct hermes_idstring idbuf;
2173
2174         /* Set the MAC address */
2175         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
2176                                HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
2177         if (err) {
2178                 printk(KERN_ERR "%s: Error %d setting MAC address\n",
2179                        dev->name, err);
2180                 return err;
2181         }
2182
2183         /* Set up the link mode */
2184         err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
2185                                    priv->port_type);
2186         if (err) {
2187                 printk(KERN_ERR "%s: Error %d setting port type\n",
2188                        dev->name, err);
2189                 return err;
2190         }
2191         /* Set the channel/frequency */
2192         if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
2193                 err = hermes_write_wordrec(hw, USER_BAP,
2194                                            HERMES_RID_CNFOWNCHANNEL,
2195                                            priv->channel);
2196                 if (err) {
2197                         printk(KERN_ERR "%s: Error %d setting channel %d\n",
2198                                dev->name, err, priv->channel);
2199                         return err;
2200                 }
2201         }
2202
2203         if (priv->has_ibss) {
2204                 u16 createibss;
2205
2206                 if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
2207                         printk(KERN_WARNING "%s: This firmware requires an "
2208                                "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
2209                         /* With wvlan_cs, in this case, we would crash.
2210                          * hopefully, this driver will behave better...
2211                          * Jean II */
2212                         createibss = 0;
2213                 } else {
2214                         createibss = priv->createibss;
2215                 }
2216                 
2217                 err = hermes_write_wordrec(hw, USER_BAP,
2218                                            HERMES_RID_CNFCREATEIBSS,
2219                                            createibss);
2220                 if (err) {
2221                         printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
2222                                dev->name, err);
2223                         return err;
2224                 }
2225         }
2226
2227         /* Set the desired BSSID */
2228         err = __orinoco_hw_set_wap(priv);
2229         if (err) {
2230                 printk(KERN_ERR "%s: Error %d setting AP address\n",
2231                        dev->name, err);
2232                 return err;
2233         }
2234         /* Set the desired ESSID */
2235         idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
2236         memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
2237         /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
2238         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
2239                                HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
2240                                &idbuf);
2241         if (err) {
2242                 printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
2243                        dev->name, err);
2244                 return err;
2245         }
2246         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
2247                                HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
2248                                &idbuf);
2249         if (err) {
2250                 printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
2251                        dev->name, err);
2252                 return err;
2253         }
2254
2255         /* Set the station name */
2256         idbuf.len = cpu_to_le16(strlen(priv->nick));
2257         memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
2258         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
2259                                HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
2260                                &idbuf);
2261         if (err) {
2262                 printk(KERN_ERR "%s: Error %d setting nickname\n",
2263                        dev->name, err);
2264                 return err;
2265         }
2266
2267         /* Set AP density */
2268         if (priv->has_sensitivity) {
2269                 err = hermes_write_wordrec(hw, USER_BAP,
2270                                            HERMES_RID_CNFSYSTEMSCALE,
2271                                            priv->ap_density);
2272                 if (err) {
2273                         printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE.  "
2274                                "Disabling sensitivity control\n",
2275                                dev->name, err);
2276
2277                         priv->has_sensitivity = 0;
2278                 }
2279         }
2280
2281         /* Set RTS threshold */
2282         err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
2283                                    priv->rts_thresh);
2284         if (err) {
2285                 printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
2286                        dev->name, err);
2287                 return err;
2288         }
2289
2290         /* Set fragmentation threshold or MWO robustness */
2291         if (priv->has_mwo)
2292                 err = hermes_write_wordrec(hw, USER_BAP,
2293                                            HERMES_RID_CNFMWOROBUST_AGERE,
2294                                            priv->mwo_robust);
2295         else
2296                 err = hermes_write_wordrec(hw, USER_BAP,
2297                                            HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
2298                                            priv->frag_thresh);
2299         if (err) {
2300                 printk(KERN_ERR "%s: Error %d setting fragmentation\n",
2301                        dev->name, err);
2302                 return err;
2303         }
2304
2305         /* Set bitrate */
2306         err = __orinoco_hw_set_bitrate(priv);
2307         if (err) {
2308                 printk(KERN_ERR "%s: Error %d setting bitrate\n",
2309                        dev->name, err);
2310                 return err;
2311         }
2312
2313         /* Set power management */
2314         if (priv->has_pm) {
2315                 err = hermes_write_wordrec(hw, USER_BAP,
2316                                            HERMES_RID_CNFPMENABLED,
2317                                            priv->pm_on);
2318                 if (err) {
2319                         printk(KERN_ERR "%s: Error %d setting up PM\n",
2320                                dev->name, err);
2321                         return err;
2322                 }
2323
2324                 err = hermes_write_wordrec(hw, USER_BAP,
2325                                            HERMES_RID_CNFMULTICASTRECEIVE,
2326                                            priv->pm_mcast);
2327                 if (err) {
2328                         printk(KERN_ERR "%s: Error %d setting up PM\n",
2329                                dev->name, err);
2330                         return err;
2331                 }
2332                 err = hermes_write_wordrec(hw, USER_BAP,
2333                                            HERMES_RID_CNFMAXSLEEPDURATION,
2334                                            priv->pm_period);
2335                 if (err) {
2336                         printk(KERN_ERR "%s: Error %d setting up PM\n",
2337                                dev->name, err);
2338                         return err;
2339                 }
2340                 err = hermes_write_wordrec(hw, USER_BAP,
2341                                            HERMES_RID_CNFPMHOLDOVERDURATION,
2342                                            priv->pm_timeout);
2343                 if (err) {
2344                         printk(KERN_ERR "%s: Error %d setting up PM\n",
2345                                dev->name, err);
2346                         return err;
2347                 }
2348         }
2349
2350         /* Set preamble - only for Symbol so far... */
2351         if (priv->has_preamble) {
2352                 err = hermes_write_wordrec(hw, USER_BAP,
2353                                            HERMES_RID_CNFPREAMBLE_SYMBOL,
2354                                            priv->preamble);
2355                 if (err) {
2356                         printk(KERN_ERR "%s: Error %d setting preamble\n",
2357                                dev->name, err);
2358                         return err;
2359                 }
2360         }
2361
2362         /* Set up encryption */
2363         if (priv->has_wep) {
2364                 err = __orinoco_hw_setup_wep(priv);
2365                 if (err) {
2366                         printk(KERN_ERR "%s: Error %d activating WEP\n",
2367                                dev->name, err);
2368                         return err;
2369                 }
2370         }
2371
2372         if (priv->iw_mode == IW_MODE_MONITOR) {
2373                 /* Enable monitor mode */
2374                 dev->type = ARPHRD_IEEE80211;
2375                 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 
2376                                             HERMES_TEST_MONITOR, 0, NULL);
2377         } else {
2378                 /* Disable monitor mode */
2379                 dev->type = ARPHRD_ETHER;
2380                 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
2381                                             HERMES_TEST_STOP, 0, NULL);
2382         }
2383         if (err)
2384                 return err;
2385
2386         /* Set promiscuity / multicast*/
2387         priv->promiscuous = 0;
2388         priv->mc_count = 0;
2389
2390         /* FIXME: what about netif_tx_lock */
2391         __orinoco_set_multicast_list(dev);
2392
2393         return 0;
2394 }
2395
2396 /* FIXME: return int? */
2397 static void
2398 __orinoco_set_multicast_list(struct net_device *dev)
2399 {
2400         struct orinoco_private *priv = netdev_priv(dev);
2401         hermes_t *hw = &priv->hw;
2402         int err = 0;
2403         int promisc, mc_count;
2404
2405         /* The Hermes doesn't seem to have an allmulti mode, so we go
2406          * into promiscuous mode and let the upper levels deal. */
2407         if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
2408              (dev->mc_count > MAX_MULTICAST(priv)) ) {
2409                 promisc = 1;
2410                 mc_count = 0;
2411         } else {
2412                 promisc = 0;
2413                 mc_count = dev->mc_count;
2414         }
2415
2416         if (promisc != priv->promiscuous) {
2417                 err = hermes_write_wordrec(hw, USER_BAP,
2418                                            HERMES_RID_CNFPROMISCUOUSMODE,
2419                                            promisc);
2420                 if (err) {
2421                         printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
2422                                dev->name, err);
2423                 } else 
2424                         priv->promiscuous = promisc;
2425         }
2426
2427         if (! promisc && (mc_count || priv->mc_count) ) {
2428                 struct dev_mc_list *p = dev->mc_list;
2429                 struct hermes_multicast mclist;
2430                 int i;
2431
2432                 for (i = 0; i < mc_count; i++) {
2433                         /* paranoia: is list shorter than mc_count? */
2434                         BUG_ON(! p);
2435                         /* paranoia: bad address size in list? */
2436                         BUG_ON(p->dmi_addrlen != ETH_ALEN);
2437                         
2438                         memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
2439                         p = p->next;
2440                 }
2441                 
2442                 if (p)
2443                         printk(KERN_WARNING "%s: Multicast list is "
2444                                "longer than mc_count\n", dev->name);
2445
2446                 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES,
2447                                        HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
2448                                        &mclist);
2449                 if (err)
2450                         printk(KERN_ERR "%s: Error %d setting multicast list.\n",
2451                                dev->name, err);
2452                 else
2453                         priv->mc_count = mc_count;
2454         }
2455 }
2456
2457 /* This must be called from user context, without locks held - use
2458  * schedule_work() */
2459 static void orinoco_reset(struct work_struct *work)
2460 {
2461         struct orinoco_private *priv =
2462                 container_of(work, struct orinoco_private, reset_work);
2463         struct net_device *dev = priv->ndev;
2464         struct hermes *hw = &priv->hw;
2465         int err;
2466         unsigned long flags;
2467
2468         if (orinoco_lock(priv, &flags) != 0)
2469                 /* When the hardware becomes available again, whatever
2470                  * detects that is responsible for re-initializing
2471                  * it. So no need for anything further */
2472                 return;
2473
2474         netif_stop_queue(dev);
2475
2476         /* Shut off interrupts.  Depending on what state the hardware
2477          * is in, this might not work, but we'll try anyway */
2478         hermes_set_irqmask(hw, 0);
2479         hermes_write_regn(hw, EVACK, 0xffff);
2480
2481         priv->hw_unavailable++;
2482         priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
2483         netif_carrier_off(dev);
2484
2485         orinoco_unlock(priv, &flags);
2486
2487         /* Scanning support: Cleanup of driver struct */
2488         orinoco_clear_scan_results(priv, 0);
2489         priv->scan_inprogress = 0;
2490
2491         if (priv->hard_reset) {
2492                 err = (*priv->hard_reset)(priv);
2493                 if (err) {
2494                         printk(KERN_ERR "%s: orinoco_reset: Error %d "
2495                                "performing hard reset\n", dev->name, err);
2496                         goto disable;
2497                 }
2498         }
2499
2500         if (priv->do_fw_download) {
2501                 err = orinoco_download(priv);
2502                 if (err)
2503                         priv->do_fw_download = 0;
2504         }
2505
2506         err = orinoco_reinit_firmware(dev);
2507         if (err) {
2508                 printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
2509                        dev->name, err);
2510                 goto disable;
2511         }
2512
2513         spin_lock_irq(&priv->lock); /* This has to be called from user context */
2514
2515         priv->hw_unavailable--;
2516
2517         /* priv->open or priv->hw_unavailable might have changed while
2518          * we dropped the lock */
2519         if (priv->open && (! priv->hw_unavailable)) {
2520                 err = __orinoco_up(dev);
2521                 if (err) {
2522                         printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
2523                                dev->name, err);
2524                 } else
2525                         dev->trans_start = jiffies;
2526         }
2527
2528         spin_unlock_irq(&priv->lock);
2529
2530         return;
2531  disable:
2532         hermes_set_irqmask(hw, 0);
2533         netif_device_detach(dev);
2534         printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
2535 }
2536
2537 /********************************************************************/
2538 /* Interrupt handler                                                */
2539 /********************************************************************/
2540
2541 static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
2542 {
2543         printk(KERN_DEBUG "%s: TICK\n", dev->name);
2544 }
2545
2546 static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
2547 {
2548         /* This seems to happen a fair bit under load, but ignoring it
2549            seems to work fine...*/
2550         printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
2551                dev->name);
2552 }
2553
2554 irqreturn_t orinoco_interrupt(int irq, void *dev_id)
2555 {
2556         struct net_device *dev = dev_id;
2557         struct orinoco_private *priv = netdev_priv(dev);
2558         hermes_t *hw = &priv->hw;
2559         int count = MAX_IRQLOOPS_PER_IRQ;
2560         u16 evstat, events;
2561         /* These are used to detect a runaway interrupt situation */
2562         /* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
2563          * we panic and shut down the hardware */
2564         static int last_irq_jiffy = 0; /* jiffies value the last time
2565                                         * we were called */
2566         static int loops_this_jiffy = 0;
2567         unsigned long flags;
2568
2569         if (orinoco_lock(priv, &flags) != 0) {
2570                 /* If hw is unavailable - we don't know if the irq was
2571                  * for us or not */
2572                 return IRQ_HANDLED;
2573         }
2574
2575         evstat = hermes_read_regn(hw, EVSTAT);
2576         events = evstat & hw->inten;
2577         if (! events) {
2578                 orinoco_unlock(priv, &flags);
2579                 return IRQ_NONE;
2580         }
2581         
2582         if (jiffies != last_irq_jiffy)
2583                 loops_this_jiffy = 0;
2584         last_irq_jiffy = jiffies;
2585
2586         while (events && count--) {
2587                 if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
2588                         printk(KERN_WARNING "%s: IRQ handler is looping too "
2589                                "much! Resetting.\n", dev->name);
2590                         /* Disable interrupts for now */
2591                         hermes_set_irqmask(hw, 0);
2592                         schedule_work(&priv->reset_work);
2593                         break;
2594                 }
2595
2596                 /* Check the card hasn't been removed */
2597                 if (! hermes_present(hw)) {
2598                         DEBUG(0, "orinoco_interrupt(): card removed\n");
2599                         break;
2600                 }
2601
2602                 if (events & HERMES_EV_TICK)
2603                         __orinoco_ev_tick(dev, hw);
2604                 if (events & HERMES_EV_WTERR)
2605                         __orinoco_ev_wterr(dev, hw);
2606                 if (events & HERMES_EV_INFDROP)
2607                         __orinoco_ev_infdrop(dev, hw);
2608                 if (events & HERMES_EV_INFO)
2609                         __orinoco_ev_info(dev, hw);
2610                 if (events & HERMES_EV_RX)
2611                         __orinoco_ev_rx(dev, hw);
2612                 if (events & HERMES_EV_TXEXC)
2613                         __orinoco_ev_txexc(dev, hw);
2614                 if (events & HERMES_EV_TX)
2615                         __orinoco_ev_tx(dev, hw);
2616                 if (events & HERMES_EV_ALLOC)
2617                         __orinoco_ev_alloc(dev, hw);
2618                 
2619                 hermes_write_regn(hw, EVACK, evstat);
2620
2621                 evstat = hermes_read_regn(hw, EVSTAT);
2622                 events = evstat & hw->inten;
2623         };
2624
2625         orinoco_unlock(priv, &flags);
2626         return IRQ_HANDLED;
2627 }
2628
2629 /********************************************************************/
2630 /* Initialization                                                   */
2631 /********************************************************************/
2632
2633 struct comp_id {
2634         u16 id, variant, major, minor;
2635 } __attribute__ ((packed));
2636
2637 static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
2638 {
2639         if (nic_id->id < 0x8000)
2640                 return FIRMWARE_TYPE_AGERE;
2641         else if (nic_id->id == 0x8000 && nic_id->major == 0)
2642                 return FIRMWARE_TYPE_SYMBOL;
2643         else
2644                 return FIRMWARE_TYPE_INTERSIL;
2645 }
2646
2647 /* Set priv->firmware type, determine firmware properties */
2648 static int determine_firmware(struct net_device *dev)
2649 {
2650         struct orinoco_private *priv = netdev_priv(dev);
2651         hermes_t *hw = &priv->hw;
2652         int err;
2653         struct comp_id nic_id, sta_id;
2654         unsigned int firmver;
2655         char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
2656
2657         /* Get the hardware version */
2658         err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
2659         if (err) {
2660                 printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
2661                        dev->name, err);
2662                 return err;
2663         }
2664
2665         le16_to_cpus(&nic_id.id);
2666         le16_to_cpus(&nic_id.variant);
2667         le16_to_cpus(&nic_id.major);
2668         le16_to_cpus(&nic_id.minor);
2669         printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
2670                dev->name, nic_id.id, nic_id.variant,
2671                nic_id.major, nic_id.minor);
2672
2673         priv->firmware_type = determine_firmware_type(&nic_id);
2674
2675         /* Get the firmware version */
2676         err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
2677         if (err) {
2678                 printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
2679                        dev->name, err);
2680                 return err;
2681         }
2682
2683         le16_to_cpus(&sta_id.id);
2684         le16_to_cpus(&sta_id.variant);
2685         le16_to_cpus(&sta_id.major);
2686         le16_to_cpus(&sta_id.minor);
2687         printk(KERN_DEBUG "%s: Station identity  %04x:%04x:%04x:%04x\n",
2688                dev->name, sta_id.id, sta_id.variant,
2689                sta_id.major, sta_id.minor);
2690
2691         switch (sta_id.id) {
2692         case 0x15:
2693                 printk(KERN_ERR "%s: Primary firmware is active\n",
2694                        dev->name);
2695                 return -ENODEV;
2696         case 0x14b:
2697                 printk(KERN_ERR "%s: Tertiary firmware is active\n",
2698                        dev->name);
2699                 return -ENODEV;
2700         case 0x1f:      /* Intersil, Agere, Symbol Spectrum24 */
2701         case 0x21:      /* Symbol Spectrum24 Trilogy */
2702                 break;
2703         default:
2704                 printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
2705                        dev->name);
2706                 break;
2707         }
2708
2709         /* Default capabilities */
2710         priv->has_sensitivity = 1;
2711         priv->has_mwo = 0;
2712         priv->has_preamble = 0;
2713         priv->has_port3 = 1;
2714         priv->has_ibss = 1;
2715         priv->has_wep = 0;
2716         priv->has_big_wep = 0;
2717         priv->has_alt_txcntl = 0;
2718         priv->has_ext_scan = 0;
2719         priv->do_fw_download = 0;
2720
2721         /* Determine capabilities from the firmware version */
2722         switch (priv->firmware_type) {
2723         case FIRMWARE_TYPE_AGERE:
2724                 /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
2725                    ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
2726                 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2727                          "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
2728
2729                 firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
2730
2731                 priv->has_ibss = (firmver >= 0x60006);
2732                 priv->has_wep = (firmver >= 0x40020);
2733                 priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
2734                                           Gold cards from the others? */
2735                 priv->has_mwo = (firmver >= 0x60000);
2736                 priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
2737                 priv->ibss_port = 1;
2738                 priv->has_hostscan = (firmver >= 0x8000a);
2739                 priv->do_fw_download = 1;
2740                 priv->broken_monitor = (firmver >= 0x80000);
2741                 priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */
2742                 priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */
2743                 /* Tested with Agere firmware :
2744                  *      1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
2745                  * Tested CableTron firmware : 4.32 => Anton */
2746                 break;
2747         case FIRMWARE_TYPE_SYMBOL:
2748                 /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
2749                 /* Intel MAC : 00:02:B3:* */
2750                 /* 3Com MAC : 00:50:DA:* */
2751                 memset(tmp, 0, sizeof(tmp));
2752                 /* Get the Symbol firmware version */
2753                 err = hermes_read_ltv(hw, USER_BAP,
2754                                       HERMES_RID_SECONDARYVERSION_SYMBOL,
2755                                       SYMBOL_MAX_VER_LEN, NULL, &tmp);
2756                 if (err) {
2757                         printk(KERN_WARNING
2758                                "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",
2759                                dev->name, err);
2760                         firmver = 0;
2761                         tmp[0] = '\0';
2762                 } else {
2763                         /* The firmware revision is a string, the format is
2764                          * something like : "V2.20-01".
2765                          * Quick and dirty parsing... - Jean II
2766                          */
2767                         firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12)
2768                                 | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4)
2769                                 | (tmp[7] - '0');
2770
2771                         tmp[SYMBOL_MAX_VER_LEN] = '\0';
2772                 }
2773
2774                 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2775                          "Symbol %s", tmp);
2776
2777                 priv->has_ibss = (firmver >= 0x20000);
2778                 priv->has_wep = (firmver >= 0x15012);
2779                 priv->has_big_wep = (firmver >= 0x20000);
2780                 priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) || 
2781                                (firmver >= 0x29000 && firmver < 0x30000) ||
2782                                firmver >= 0x31000;
2783                 priv->has_preamble = (firmver >= 0x20000);
2784                 priv->ibss_port = 4;
2785
2786                 /* Symbol firmware is found on various cards, but
2787                  * there has been no attempt to check firmware
2788                  * download on non-spectrum_cs based cards.
2789                  *
2790                  * Given that the Agere firmware download works
2791                  * differently, we should avoid doing a firmware
2792                  * download with the Symbol algorithm on non-spectrum
2793                  * cards.
2794                  *
2795                  * For now we can identify a spectrum_cs based card
2796                  * because it has a firmware reset function.
2797                  */
2798                 priv->do_fw_download = (priv->stop_fw != NULL);
2799
2800                 priv->broken_disableport = (firmver == 0x25013) ||
2801                                            (firmver >= 0x30000 && firmver <= 0x31000);
2802                 priv->has_hostscan = (firmver >= 0x31001) ||
2803                                      (firmver >= 0x29057 && firmver < 0x30000);
2804                 /* Tested with Intel firmware : 0x20015 => Jean II */
2805                 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
2806                 break;
2807         case FIRMWARE_TYPE_INTERSIL:
2808                 /* D-Link, Linksys, Adtron, ZoomAir, and many others...
2809                  * Samsung, Compaq 100/200 and Proxim are slightly
2810                  * different and less well tested */
2811                 /* D-Link MAC : 00:40:05:* */
2812                 /* Addtron MAC : 00:90:D1:* */
2813                 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2814                          "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
2815                          sta_id.variant);
2816
2817                 firmver = ((unsigned long)sta_id.major << 16) |
2818                         ((unsigned long)sta_id.minor << 8) | sta_id.variant;
2819
2820                 priv->has_ibss = (firmver >= 0x000700); /* FIXME */
2821                 priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
2822                 priv->has_pm = (firmver >= 0x000700);
2823                 priv->has_hostscan = (firmver >= 0x010301);
2824
2825                 if (firmver >= 0x000800)
2826                         priv->ibss_port = 0;
2827                 else {
2828                         printk(KERN_NOTICE "%s: Intersil firmware earlier "
2829                                "than v0.8.x - several features not supported\n",
2830                                dev->name);
2831                         priv->ibss_port = 1;
2832                 }
2833                 break;
2834         }
2835         printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
2836                priv->fw_name);
2837
2838         return 0;
2839 }
2840
2841 static int orinoco_init(struct net_device *dev)
2842 {
2843         struct orinoco_private *priv = netdev_priv(dev);
2844         hermes_t *hw = &priv->hw;
2845         int err = 0;
2846         struct hermes_idstring nickbuf;
2847         u16 reclen;
2848         int len;
2849         DECLARE_MAC_BUF(mac);
2850
2851         /* No need to lock, the hw_unavailable flag is already set in
2852          * alloc_orinocodev() */
2853         priv->nicbuf_size = IEEE80211_FRAME_LEN + ETH_HLEN;
2854
2855         /* Initialize the firmware */
2856         err = hermes_init(hw);
2857         if (err != 0) {
2858                 printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
2859                        dev->name, err);
2860                 goto out;
2861         }
2862
2863         err = determine_firmware(dev);
2864         if (err != 0) {
2865                 printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
2866                        dev->name);
2867                 goto out;
2868         }
2869
2870         if (priv->do_fw_download) {
2871                 err = orinoco_download(priv);
2872                 if (err)
2873                         priv->do_fw_download = 0;
2874
2875                 /* Check firmware version again */
2876                 err = determine_firmware(dev);
2877                 if (err != 0) {
2878                         printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
2879                                dev->name);
2880                         goto out;
2881                 }
2882         }
2883
2884         if (priv->has_port3)
2885                 printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
2886         if (priv->has_ibss)
2887                 printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
2888                        dev->name);
2889         if (priv->has_wep) {
2890                 printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
2891                 if (priv->has_big_wep)
2892                         printk("104-bit key\n");
2893                 else
2894                         printk("40-bit key\n");
2895         }
2896
2897         /* Now we have the firmware capabilities, allocate appropiate
2898          * sized scan buffers */
2899         if (orinoco_bss_data_allocate(priv))
2900                 goto out;
2901         orinoco_bss_data_init(priv);
2902
2903         /* Get the MAC address */
2904         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
2905                               ETH_ALEN, NULL, dev->dev_addr);
2906         if (err) {
2907                 printk(KERN_WARNING "%s: failed to read MAC address!\n",
2908                        dev->name);
2909                 goto out;
2910         }
2911
2912         printk(KERN_DEBUG "%s: MAC address %s\n",
2913                dev->name, print_mac(mac, dev->dev_addr));
2914
2915         /* Get the station name */
2916         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
2917                               sizeof(nickbuf), &reclen, &nickbuf);
2918         if (err) {
2919                 printk(KERN_ERR "%s: failed to read station name\n",
2920                        dev->name);
2921                 goto out;
2922         }
2923         if (nickbuf.len)
2924                 len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
2925         else
2926                 len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
2927         memcpy(priv->nick, &nickbuf.val, len);
2928         priv->nick[len] = '\0';
2929
2930         printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
2931
2932         err = orinoco_allocate_fid(dev);
2933         if (err) {
2934                 printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
2935                        dev->name);
2936                 goto out;
2937         }
2938
2939         /* Get allowed channels */
2940         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
2941                                   &priv->channel_mask);
2942         if (err) {
2943                 printk(KERN_ERR "%s: failed to read channel list!\n",
2944                        dev->name);
2945                 goto out;
2946         }
2947
2948         /* Get initial AP density */
2949         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
2950                                   &priv->ap_density);
2951         if (err || priv->ap_density < 1 || priv->ap_density > 3) {
2952                 priv->has_sensitivity = 0;
2953         }
2954
2955         /* Get initial RTS threshold */
2956         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
2957                                   &priv->rts_thresh);
2958         if (err) {
2959                 printk(KERN_ERR "%s: failed to read RTS threshold!\n",
2960                        dev->name);
2961                 goto out;
2962         }
2963
2964         /* Get initial fragmentation settings */
2965         if (priv->has_mwo)
2966                 err = hermes_read_wordrec(hw, USER_BAP,
2967                                           HERMES_RID_CNFMWOROBUST_AGERE,
2968                                           &priv->mwo_robust);
2969         else
2970                 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
2971                                           &priv->frag_thresh);
2972         if (err) {
2973                 printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
2974                        dev->name);
2975                 goto out;
2976         }
2977
2978         /* Power management setup */
2979         if (priv->has_pm) {
2980                 priv->pm_on = 0;
2981                 priv->pm_mcast = 1;
2982                 err = hermes_read_wordrec(hw, USER_BAP,
2983                                           HERMES_RID_CNFMAXSLEEPDURATION,
2984                                           &priv->pm_period);
2985                 if (err) {
2986                         printk(KERN_ERR "%s: failed to read power management period!\n",
2987                                dev->name);
2988                         goto out;
2989                 }
2990                 err = hermes_read_wordrec(hw, USER_BAP,
2991                                           HERMES_RID_CNFPMHOLDOVERDURATION,
2992                                           &priv->pm_timeout);
2993                 if (err) {
2994                         printk(KERN_ERR "%s: failed to read power management timeout!\n",
2995                                dev->name);
2996                         goto out;
2997                 }
2998         }
2999
3000         /* Preamble setup */
3001         if (priv->has_preamble) {
3002                 err = hermes_read_wordrec(hw, USER_BAP,
3003                                           HERMES_RID_CNFPREAMBLE_SYMBOL,
3004                                           &priv->preamble);
3005                 if (err)
3006                         goto out;
3007         }
3008                 
3009         /* Set up the default configuration */
3010         priv->iw_mode = IW_MODE_INFRA;
3011         /* By default use IEEE/IBSS ad-hoc mode if we have it */
3012         priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
3013         set_port_type(priv);
3014         priv->channel = 0; /* use firmware default */
3015
3016         priv->promiscuous = 0;
3017         priv->encode_alg = IW_ENCODE_ALG_NONE;
3018         priv->tx_key = 0;
3019
3020         /* Make the hardware available, as long as it hasn't been
3021          * removed elsewhere (e.g. by PCMCIA hot unplug) */
3022         spin_lock_irq(&priv->lock);
3023         priv->hw_unavailable--;
3024         spin_unlock_irq(&priv->lock);
3025
3026         printk(KERN_DEBUG "%s: ready\n", dev->name);
3027
3028  out:
3029         return err;
3030 }
3031
3032 struct net_device
3033 *alloc_orinocodev(int sizeof_card,
3034                   struct device *device,
3035                   int (*hard_reset)(struct orinoco_private *),
3036                   int (*stop_fw)(struct orinoco_private *, int))
3037 {
3038         struct net_device *dev;
3039         struct orinoco_private *priv;
3040
3041         dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
3042         if (! dev)
3043                 return NULL;
3044         priv = netdev_priv(dev);
3045         priv->ndev = dev;
3046         if (sizeof_card)
3047                 priv->card = (void *)((unsigned long)priv
3048                                       + sizeof(struct orinoco_private));
3049         else
3050                 priv->card = NULL;
3051         priv->dev = device;
3052
3053         /* Setup / override net_device fields */
3054         dev->init = orinoco_init;
3055         dev->hard_start_xmit = orinoco_xmit;
3056         dev->tx_timeout = orinoco_tx_timeout;
3057         dev->watchdog_timeo = HZ; /* 1 second timeout */
3058         dev->get_stats = orinoco_get_stats;
3059         dev->ethtool_ops = &orinoco_ethtool_ops;
3060         dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
3061 #ifdef WIRELESS_SPY
3062         priv->wireless_data.spy_data = &priv->spy_data;
3063         dev->wireless_data = &priv->wireless_data;
3064 #endif
3065         dev->change_mtu = orinoco_change_mtu;
3066         dev->set_multicast_list = orinoco_set_multicast_list;
3067         /* we use the default eth_mac_addr for setting the MAC addr */
3068
3069         /* Set up default callbacks */
3070         dev->open = orinoco_open;
3071         dev->stop = orinoco_stop;
3072         priv->hard_reset = hard_reset;
3073         priv->stop_fw = stop_fw;
3074
3075         spin_lock_init(&priv->lock);
3076         priv->open = 0;
3077         priv->hw_unavailable = 1; /* orinoco_init() must clear this
3078                                    * before anything else touches the
3079                                    * hardware */
3080         INIT_WORK(&priv->reset_work, orinoco_reset);
3081         INIT_WORK(&priv->join_work, orinoco_join_ap);
3082         INIT_WORK(&priv->wevent_work, orinoco_send_wevents);
3083
3084         netif_carrier_off(dev);
3085         priv->last_linkstatus = 0xffff;
3086
3087         return dev;
3088 }
3089
3090 void free_orinocodev(struct net_device *dev)
3091 {
3092         struct orinoco_private *priv = netdev_priv(dev);
3093
3094         orinoco_bss_data_free(priv);
3095         free_netdev(dev);
3096 }
3097
3098 /********************************************************************/
3099 /* Wireless extensions                                              */
3100 /********************************************************************/
3101
3102 /* Return : < 0 -> error code ; >= 0 -> length */
3103 static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
3104                                 char buf[IW_ESSID_MAX_SIZE+1])
3105 {
3106         hermes_t *hw = &priv->hw;
3107         int err = 0;
3108         struct hermes_idstring essidbuf;
3109         char *p = (char *)(&essidbuf.val);
3110         int len;
3111         unsigned long flags;
3112
3113         if (orinoco_lock(priv, &flags) != 0)
3114                 return -EBUSY;
3115
3116         if (strlen(priv->desired_essid) > 0) {
3117                 /* We read the desired SSID from the hardware rather
3118                    than from priv->desired_essid, just in case the
3119                    firmware is allowed to change it on us. I'm not
3120                    sure about this */
3121                 /* My guess is that the OWNSSID should always be whatever
3122                  * we set to the card, whereas CURRENT_SSID is the one that
3123                  * may change... - Jean II */
3124                 u16 rid;
3125
3126                 *active = 1;
3127
3128                 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
3129                         HERMES_RID_CNFDESIREDSSID;
3130                 
3131                 err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
3132                                       NULL, &essidbuf);
3133                 if (err)
3134                         goto fail_unlock;
3135         } else {
3136                 *active = 0;
3137
3138                 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
3139                                       sizeof(essidbuf), NULL, &essidbuf);
3140                 if (err)
3141                         goto fail_unlock;
3142         }
3143
3144         len = le16_to_cpu(essidbuf.len);
3145         BUG_ON(len > IW_ESSID_MAX_SIZE);
3146
3147         memset(buf, 0, IW_ESSID_MAX_SIZE);
3148         memcpy(buf, p, len);
3149         err = len;
3150
3151  fail_unlock:
3152         orinoco_unlock(priv, &flags);
3153
3154         return err;       
3155 }
3156
3157 static long orinoco_hw_get_freq(struct orinoco_private *priv)
3158 {
3159         
3160         hermes_t *hw = &priv->hw;
3161         int err = 0;
3162         u16 channel;
3163         long freq = 0;
3164         unsigned long flags;
3165
3166         if (orinoco_lock(priv, &flags) != 0)
3167                 return -EBUSY;
3168         
3169         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
3170         if (err)
3171                 goto out;
3172
3173         /* Intersil firmware 1.3.5 returns 0 when the interface is down */
3174         if (channel == 0) {
3175                 err = -EBUSY;
3176                 goto out;
3177         }
3178
3179         if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
3180                 printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
3181                        priv->ndev->name, channel);
3182                 err = -EBUSY;
3183                 goto out;
3184
3185         }
3186         freq = channel_frequency[channel-1] * 100000;
3187
3188  out:
3189         orinoco_unlock(priv, &flags);
3190
3191         if (err > 0)
3192                 err = -EBUSY;
3193         return err ? err : freq;
3194 }
3195
3196 static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
3197                                       int *numrates, s32 *rates, int max)
3198 {
3199         hermes_t *hw = &priv->hw;
3200         struct hermes_idstring list;
3201         unsigned char *p = (unsigned char *)&list.val;
3202         int err = 0;
3203         int num;
3204         int i;
3205         unsigned long flags;
3206
3207         if (orinoco_lock(priv, &flags) != 0)
3208                 return -EBUSY;
3209
3210         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
3211                               sizeof(list), NULL, &list);
3212         orinoco_unlock(priv, &flags);
3213
3214         if (err)
3215                 return err;
3216         
3217         num = le16_to_cpu(list.len);
3218         *numrates = num;
3219         num = min(num, max);
3220
3221         for (i = 0; i < num; i++) {
3222                 rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
3223         }
3224
3225         return 0;
3226 }
3227
3228 static int orinoco_ioctl_getname(struct net_device *dev,
3229                                  struct iw_request_info *info,
3230                                  char *name,
3231                                  char *extra)
3232 {
3233         struct orinoco_private *priv = netdev_priv(dev);
3234         int numrates;
3235         int err;
3236
3237         err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
3238
3239         if (!err && (numrates > 2))
3240                 strcpy(name, "IEEE 802.11b");
3241         else
3242                 strcpy(name, "IEEE 802.11-DS");
3243
3244         return 0;
3245 }
3246
3247 static int orinoco_ioctl_setwap(struct net_device *dev,
3248                                 struct iw_request_info *info,
3249                                 struct sockaddr *ap_addr,
3250                                 char *extra)
3251 {
3252         struct orinoco_private *priv = netdev_priv(dev);
3253         int err = -EINPROGRESS;         /* Call commit handler */
3254         unsigned long flags;
3255         static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
3256         static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
3257
3258         if (orinoco_lock(priv, &flags) != 0)
3259                 return -EBUSY;
3260
3261         /* Enable automatic roaming - no sanity checks are needed */
3262         if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
3263             memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
3264                 priv->bssid_fixed = 0;
3265                 memset(priv->desired_bssid, 0, ETH_ALEN);
3266
3267                 /* "off" means keep existing connection */
3268                 if (ap_addr->sa_data[0] == 0) {
3269                         __orinoco_hw_set_wap(priv);
3270                         err = 0;
3271                 }
3272                 goto out;
3273         }
3274
3275         if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
3276                 printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
3277                        "support manual roaming\n",
3278                        dev->name);
3279                 err = -EOPNOTSUPP;
3280                 goto out;
3281         }
3282
3283         if (priv->iw_mode != IW_MODE_INFRA) {
3284                 printk(KERN_WARNING "%s: Manual roaming supported only in "
3285                        "managed mode\n", dev->name);
3286                 err = -EOPNOTSUPP;
3287                 goto out;
3288         }
3289
3290         /* Intersil firmware hangs without Desired ESSID */
3291         if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
3292             strlen(priv->desired_essid) == 0) {
3293                 printk(KERN_WARNING "%s: Desired ESSID must be set for "
3294                        "manual roaming\n", dev->name);
3295                 err = -EOPNOTSUPP;
3296                 goto out;
3297         }
3298
3299         /* Finally, enable manual roaming */
3300         priv->bssid_fixed = 1;
3301         memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
3302
3303  out:
3304         orinoco_unlock(priv, &flags);
3305         return err;
3306 }
3307
3308 static int orinoco_ioctl_getwap(struct net_device *dev,
3309                                 struct iw_request_info *info,
3310                                 struct sockaddr *ap_addr,
3311                                 char *extra)
3312 {
3313         struct orinoco_private *priv = netdev_priv(dev);
3314
3315         hermes_t *hw = &priv->hw;
3316         int err = 0;
3317         unsigned long flags;
3318
3319         if (orinoco_lock(priv, &flags) != 0)
3320                 return -EBUSY;
3321
3322         ap_addr->sa_family = ARPHRD_ETHER;
3323         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
3324                               ETH_ALEN, NULL, ap_addr->sa_data);
3325
3326         orinoco_unlock(priv, &flags);
3327
3328         return err;
3329 }
3330
3331 static int orinoco_ioctl_setmode(struct net_device *dev,
3332                                  struct iw_request_info *info,
3333                                  u32 *mode,
3334                                  char *extra)
3335 {
3336         struct orinoco_private *priv = netdev_priv(dev);
3337         int err = -EINPROGRESS;         /* Call commit handler */
3338         unsigned long flags;
3339
3340         if (priv->iw_mode == *mode)
3341                 return 0;
3342
3343         if (orinoco_lock(priv, &flags) != 0)
3344                 return -EBUSY;
3345
3346         switch (*mode) {
3347         case IW_MODE_ADHOC:
3348                 if (!priv->has_ibss && !priv->has_port3)
3349                         err = -EOPNOTSUPP;
3350                 break;
3351
3352         case IW_MODE_INFRA:
3353                 break;
3354
3355         case IW_MODE_MONITOR:
3356                 if (priv->broken_monitor && !force_monitor) {
3357                         printk(KERN_WARNING "%s: Monitor mode support is "
3358                                "buggy in this firmware, not enabling\n",
3359                                dev->name);
3360                         err = -EOPNOTSUPP;
3361                 }
3362                 break;
3363
3364         default:
3365                 err = -EOPNOTSUPP;
3366                 break;
3367         }
3368
3369         if (err == -EINPROGRESS) {
3370                 priv->iw_mode = *mode;
3371                 set_port_type(priv);
3372         }
3373
3374         orinoco_unlock(priv, &flags);
3375
3376         return err;
3377 }
3378
3379 static int orinoco_ioctl_getmode(struct net_device *dev,
3380                                  struct iw_request_info *info,
3381                                  u32 *mode,
3382                                  char *extra)
3383 {
3384         struct orinoco_private *priv = netdev_priv(dev);
3385
3386         *mode = priv->iw_mode;
3387         return 0;
3388 }
3389
3390 static int orinoco_ioctl_getiwrange(struct net_device *dev,
3391                                     struct iw_request_info *info,
3392                                     struct iw_point *rrq,
3393                                     char *extra)
3394 {
3395         struct orinoco_private *priv = netdev_priv(dev);
3396         int err = 0;
3397         struct iw_range *range = (struct iw_range *) extra;
3398         int numrates;
3399         int i, k;
3400
3401         rrq->length = sizeof(struct iw_range);
3402         memset(range, 0, sizeof(struct iw_range));
3403
3404         range->we_version_compiled = WIRELESS_EXT;
3405         range->we_version_source = 14;
3406
3407         /* Set available channels/frequencies */
3408         range->num_channels = NUM_CHANNELS;
3409         k = 0;
3410         for (i = 0; i < NUM_CHANNELS; i++) {
3411                 if (priv->channel_mask & (1 << i)) {
3412                         range->freq[k].i = i + 1;
3413                         range->freq[k].m = channel_frequency[i] * 100000;
3414                         range->freq[k].e = 1;
3415                         k++;
3416                 }
3417                 
3418                 if (k >= IW_MAX_FREQUENCIES)
3419                         break;
3420         }
3421         range->num_frequency = k;
3422         range->sensitivity = 3;
3423
3424         if (priv->has_wep) {
3425                 range->max_encoding_tokens = ORINOCO_MAX_KEYS;
3426                 range->encoding_size[0] = SMALL_KEY_SIZE;
3427                 range->num_encoding_sizes = 1;
3428
3429                 if (priv->has_big_wep) {
3430                         range->encoding_size[1] = LARGE_KEY_SIZE;
3431                         range->num_encoding_sizes = 2;
3432                 }
3433         }
3434
3435         if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
3436                 /* Quality stats meaningless in ad-hoc mode */
3437         } else {
3438                 range->max_qual.qual = 0x8b - 0x2f;
3439                 range->max_qual.level = 0x2f - 0x95 - 1;
3440                 range->max_qual.noise = 0x2f - 0x95 - 1;
3441                 /* Need to get better values */
3442                 range->avg_qual.qual = 0x24;
3443                 range->avg_qual.level = 0xC2;
3444                 range->avg_qual.noise = 0x9E;
3445         }
3446
3447         err = orinoco_hw_get_bitratelist(priv, &numrates,
3448                                          range->bitrate, IW_MAX_BITRATES);
3449         if (err)
3450                 return err;
3451         range->num_bitrates = numrates;
3452
3453         /* Set an indication of the max TCP throughput in bit/s that we can
3454          * expect using this interface. May be use for QoS stuff...
3455          * Jean II */
3456         if (numrates > 2)
3457                 range->throughput = 5 * 1000 * 1000;    /* ~5 Mb/s */
3458         else
3459                 range->throughput = 1.5 * 1000 * 1000;  /* ~1.5 Mb/s */
3460
3461         range->min_rts = 0;
3462         range->max_rts = 2347;
3463         range->min_frag = 256;
3464         range->max_frag = 2346;
3465
3466         range->min_pmp = 0;
3467         range->max_pmp = 65535000;
3468         range->min_pmt = 0;
3469         range->max_pmt = 65535 * 1000;  /* ??? */
3470         range->pmp_flags = IW_POWER_PERIOD;
3471         range->pmt_flags = IW_POWER_TIMEOUT;
3472         range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
3473
3474         range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
3475         range->retry_flags = IW_RETRY_LIMIT;
3476         range->r_time_flags = IW_RETRY_LIFETIME;
3477         range->min_retry = 0;
3478         range->max_retry = 65535;       /* ??? */
3479         range->min_r_time = 0;
3480         range->max_r_time = 65535 * 1000;       /* ??? */
3481
3482         if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
3483                 range->scan_capa = IW_SCAN_CAPA_ESSID;
3484         else
3485                 range->scan_capa = IW_SCAN_CAPA_NONE;
3486
3487         /* Event capability (kernel) */
3488         IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
3489         /* Event capability (driver) */
3490         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
3491         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
3492         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
3493         IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
3494
3495         return 0;
3496 }
3497
3498 static int orinoco_ioctl_setiwencode(struct net_device *dev,
3499                                      struct iw_request_info *info,
3500                                      struct iw_point *erq,
3501                                      char *keybuf)
3502 {
3503         struct orinoco_private *priv = netdev_priv(dev);
3504         int index = (erq->flags & IW_ENCODE_INDEX) - 1;
3505         int setindex = priv->tx_key;
3506         int encode_alg = priv->encode_alg;
3507         int restricted = priv->wep_restrict;
3508         u16 xlen = 0;
3509         int err = -EINPROGRESS;         /* Call commit handler */
3510         unsigned long flags;
3511
3512         if (! priv->has_wep)
3513                 return -EOPNOTSUPP;
3514
3515         if (erq->pointer) {
3516                 /* We actually have a key to set - check its length */
3517                 if (erq->length > LARGE_KEY_SIZE)
3518                         return -E2BIG;
3519
3520                 if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
3521                         return -E2BIG;
3522         }
3523
3524         if (orinoco_lock(priv, &flags) != 0)
3525                 return -EBUSY;
3526
3527         if (erq->length > 0) {
3528                 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
3529                         index = priv->tx_key;
3530
3531                 /* Adjust key length to a supported value */
3532                 if (erq->length > SMALL_KEY_SIZE) {
3533                         xlen = LARGE_KEY_SIZE;
3534                 } else if (erq->length > 0) {
3535                         xlen = SMALL_KEY_SIZE;
3536                 } else
3537                         xlen = 0;
3538
3539                 /* Switch on WEP if off */
3540                 if ((encode_alg != IW_ENCODE_ALG_WEP) && (xlen > 0)) {
3541                         setindex = index;
3542                         encode_alg = IW_ENCODE_ALG_WEP;
3543                 }
3544         } else {
3545                 /* Important note : if the user do "iwconfig eth0 enc off",
3546                  * we will arrive there with an index of -1. This is valid
3547                  * but need to be taken care off... Jean II */
3548                 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
3549                         if((index != -1) || (erq->flags == 0)) {
3550                                 err = -EINVAL;
3551                                 goto out;
3552                         }
3553                 } else {
3554                         /* Set the index : Check that the key is valid */
3555                         if(priv->keys[index].len == 0) {
3556                                 err = -EINVAL;
3557                                 goto out;
3558                         }
3559                         setindex = index;
3560                 }
3561         }
3562
3563         if (erq->flags & IW_ENCODE_DISABLED)
3564                 encode_alg = IW_ENCODE_ALG_NONE;
3565         if (erq->flags & IW_ENCODE_OPEN)
3566                 restricted = 0;
3567         if (erq->flags & IW_ENCODE_RESTRICTED)
3568                 restricted = 1;
3569
3570         if (erq->pointer && erq->length > 0) {
3571                 priv->keys[index].len = cpu_to_le16(xlen);
3572                 memset(priv->keys[index].data, 0,
3573                        sizeof(priv->keys[index].data));
3574                 memcpy(priv->keys[index].data, keybuf, erq->length);
3575         }
3576         priv->tx_key = setindex;
3577
3578         /* Try fast key change if connected and only keys are changed */
3579         if ((priv->encode_alg == encode_alg) &&
3580             (priv->wep_restrict == restricted) &&
3581             netif_carrier_ok(dev)) {
3582                 err = __orinoco_hw_setup_wepkeys(priv);
3583                 /* No need to commit if successful */
3584                 goto out;
3585         }
3586
3587         priv->encode_alg = encode_alg;
3588         priv->wep_restrict = restricted;
3589
3590  out:
3591         orinoco_unlock(priv, &flags);
3592
3593         return err;
3594 }
3595
3596 static int orinoco_ioctl_getiwencode(struct net_device *dev,
3597                                      struct iw_request_info *info,
3598                                      struct iw_point *erq,
3599                                      char *keybuf)
3600 {
3601         struct orinoco_private *priv = netdev_priv(dev);
3602         int index = (erq->flags & IW_ENCODE_INDEX) - 1;
3603         u16 xlen = 0;
3604         unsigned long flags;
3605
3606         if (! priv->has_wep)
3607                 return -EOPNOTSUPP;
3608
3609         if (orinoco_lock(priv, &flags) != 0)
3610                 return -EBUSY;
3611
3612         if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
3613                 index = priv->tx_key;
3614
3615         erq->flags = 0;
3616         if (!priv->encode_alg)
3617                 erq->flags |= IW_ENCODE_DISABLED;
3618         erq->flags |= index + 1;
3619
3620         if (priv->wep_restrict)
3621                 erq->flags |= IW_ENCODE_RESTRICTED;
3622         else
3623                 erq->flags |= IW_ENCODE_OPEN;
3624
3625         xlen = le16_to_cpu(priv->keys[index].len);
3626
3627         erq->length = xlen;
3628
3629         memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
3630
3631         orinoco_unlock(priv, &flags);
3632         return 0;
3633 }
3634
3635 static int orinoco_ioctl_setessid(struct net_device *dev,
3636                                   struct iw_request_info *info,
3637                                   struct iw_point *erq,
3638                                   char *essidbuf)
3639 {
3640         struct orinoco_private *priv = netdev_priv(dev);
3641         unsigned long flags;
3642
3643         /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
3644          * anyway... - Jean II */
3645
3646         /* Hum... Should not use Wireless Extension constant (may change),
3647          * should use our own... - Jean II */
3648         if (erq->length > IW_ESSID_MAX_SIZE)
3649                 return -E2BIG;
3650
3651         if (orinoco_lock(priv, &flags) != 0)
3652                 return -EBUSY;
3653
3654         /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
3655         memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
3656
3657         /* If not ANY, get the new ESSID */
3658         if (erq->flags) {
3659                 memcpy(priv->desired_essid, essidbuf, erq->length);
3660         }
3661
3662         orinoco_unlock(priv, &flags);
3663
3664         return -EINPROGRESS;            /* Call commit handler */
3665 }
3666
3667 static int orinoco_ioctl_getessid(struct net_device *dev,
3668                                   struct iw_request_info *info,
3669                                   struct iw_point *erq,
3670                                   char *essidbuf)
3671 {
3672         struct orinoco_private *priv = netdev_priv(dev);
3673         int active;
3674         int err = 0;
3675         unsigned long flags;
3676
3677         if (netif_running(dev)) {
3678                 err = orinoco_hw_get_essid(priv, &active, essidbuf);
3679                 if (err < 0)
3680                         return err;
3681                 erq->length = err;
3682         } else {
3683                 if (orinoco_lock(priv, &flags) != 0)
3684                         return -EBUSY;
3685                 memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
3686                 erq->length = strlen(priv->desired_essid);
3687                 orinoco_unlock(priv, &flags);
3688         }
3689
3690         erq->flags = 1;
3691
3692         return 0;
3693 }
3694
3695 static int orinoco_ioctl_setnick(struct net_device *dev,
3696                                  struct iw_request_info *info,
3697                                  struct iw_point *nrq,
3698                                  char *nickbuf)
3699 {
3700         struct orinoco_private *priv = netdev_priv(dev);
3701         unsigned long flags;
3702
3703         if (nrq->length > IW_ESSID_MAX_SIZE)
3704                 return -E2BIG;
3705
3706         if (orinoco_lock(priv, &flags) != 0)
3707                 return -EBUSY;
3708
3709         memset(priv->nick, 0, sizeof(priv->nick));
3710         memcpy(priv->nick, nickbuf, nrq->length);
3711
3712         orinoco_unlock(priv, &flags);
3713
3714         return -EINPROGRESS;            /* Call commit handler */
3715 }
3716
3717 static int orinoco_ioctl_getnick(struct net_device *dev,
3718                                  struct iw_request_info *info,
3719                                  struct iw_point *nrq,
3720                                  char *nickbuf)
3721 {
3722         struct orinoco_private *priv = netdev_priv(dev);
3723         unsigned long flags;
3724
3725         if (orinoco_lock(priv, &flags) != 0)
3726                 return -EBUSY;
3727
3728         memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
3729         orinoco_unlock(priv, &flags);
3730
3731         nrq->length = strlen(priv->nick);
3732
3733         return 0;
3734 }
3735
3736 static int orinoco_ioctl_setfreq(struct net_device *dev,
3737                                  struct iw_request_info *info,
3738                                  struct iw_freq *frq,
3739                                  char *extra)
3740 {
3741         struct orinoco_private *priv = netdev_priv(dev);
3742         int chan = -1;
3743         unsigned long flags;
3744         int err = -EINPROGRESS;         /* Call commit handler */
3745
3746         /* In infrastructure mode the AP sets the channel */
3747         if (priv->iw_mode == IW_MODE_INFRA)
3748                 return -EBUSY;
3749
3750         if ( (frq->e == 0) && (frq->m <= 1000) ) {
3751                 /* Setting by channel number */
3752                 chan = frq->m;
3753         } else {
3754                 /* Setting by frequency - search the table */
3755                 int mult = 1;
3756                 int i;
3757
3758                 for (i = 0; i < (6 - frq->e); i++)
3759                         mult *= 10;
3760
3761                 for (i = 0; i < NUM_CHANNELS; i++)
3762                         if (frq->m == (channel_frequency[i] * mult))
3763                                 chan = i+1;
3764         }
3765
3766         if ( (chan < 1) || (chan > NUM_CHANNELS) ||
3767              ! (priv->channel_mask & (1 << (chan-1)) ) )
3768                 return -EINVAL;
3769
3770         if (orinoco_lock(priv, &flags) != 0)
3771                 return -EBUSY;
3772
3773         priv->channel = chan;
3774         if (priv->iw_mode == IW_MODE_MONITOR) {
3775                 /* Fast channel change - no commit if successful */
3776                 hermes_t *hw = &priv->hw;
3777                 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
3778                                             HERMES_TEST_SET_CHANNEL,
3779                                         chan, NULL);
3780         }
3781         orinoco_unlock(priv, &flags);
3782
3783         return err;
3784 }
3785
3786 static int orinoco_ioctl_getfreq(struct net_device *dev,
3787                                  struct iw_request_info *info,
3788                                  struct iw_freq *frq,
3789                                  char *extra)
3790 {
3791         struct orinoco_private *priv = netdev_priv(dev);
3792         int tmp;
3793
3794         /* Locking done in there */
3795         tmp = orinoco_hw_get_freq(priv);
3796         if (tmp < 0) {
3797                 return tmp;
3798         }
3799
3800         frq->m = tmp;
3801         frq->e = 1;
3802
3803         return 0;
3804 }
3805
3806 static int orinoco_ioctl_getsens(struct net_device *dev,
3807                                  struct iw_request_info *info,
3808                                  struct iw_param *srq,
3809                                  char *extra)
3810 {
3811         struct orinoco_private *priv = netdev_priv(dev);
3812         hermes_t *hw = &priv->hw;
3813         u16 val;
3814         int err;
3815         unsigned long flags;
3816
3817         if (!priv->has_sensitivity)
3818                 return -EOPNOTSUPP;
3819
3820         if (orinoco_lock(priv, &flags) != 0)
3821                 return -EBUSY;
3822         err = hermes_read_wordrec(hw, USER_BAP,
3823                                   HERMES_RID_CNFSYSTEMSCALE, &val);
3824         orinoco_unlock(priv, &flags);
3825
3826         if (err)
3827                 return err;
3828
3829         srq->value = val;
3830         srq->fixed = 0; /* auto */
3831
3832         return 0;
3833 }
3834
3835 static int orinoco_ioctl_setsens(struct net_device *dev,
3836                                  struct iw_request_info *info,
3837                                  struct iw_param *srq,
3838                                  char *extra)
3839 {
3840         struct orinoco_private *priv = netdev_priv(dev);
3841         int val = srq->value;
3842         unsigned long flags;
3843
3844         if (!priv->has_sensitivity)
3845                 return -EOPNOTSUPP;
3846
3847         if ((val < 1) || (val > 3))
3848                 return -EINVAL;
3849         
3850         if (orinoco_lock(priv, &flags) != 0)
3851                 return -EBUSY;
3852         priv->ap_density = val;
3853         orinoco_unlock(priv, &flags);
3854
3855         return -EINPROGRESS;            /* Call commit handler */
3856 }
3857
3858 static int orinoco_ioctl_setrts(struct net_device *dev,
3859                                 struct iw_request_info *info,
3860                                 struct iw_param *rrq,
3861                                 char *extra)
3862 {
3863         struct orinoco_private *priv = netdev_priv(dev);
3864         int val = rrq->value;
3865         unsigned long flags;
3866
3867         if (rrq->disabled)
3868                 val = 2347;
3869
3870         if ( (val < 0) || (val > 2347) )
3871                 return -EINVAL;
3872
3873         if (orinoco_lock(priv, &flags) != 0)
3874                 return -EBUSY;
3875
3876         priv->rts_thresh = val;
3877         orinoco_unlock(priv, &flags);
3878
3879         return -EINPROGRESS;            /* Call commit handler */
3880 }
3881
3882 static int orinoco_ioctl_getrts(struct net_device *dev,
3883                                 struct iw_request_info *info,
3884                                 struct iw_param *rrq,
3885                                 char *extra)
3886 {
3887         struct orinoco_private *priv = netdev_priv(dev);
3888
3889         rrq->value = priv->rts_thresh;
3890         rrq->disabled = (rrq->value == 2347);
3891         rrq->fixed = 1;
3892
3893         return 0;
3894 }
3895
3896 static int orinoco_ioctl_setfrag(struct net_device *dev,
3897                                  struct iw_request_info *info,
3898                                  struct iw_param *frq,
3899                                  char *extra)
3900 {
3901         struct orinoco_private *priv = netdev_priv(dev);
3902         int err = -EINPROGRESS;         /* Call commit handler */
3903         unsigned long flags;
3904
3905         if (orinoco_lock(priv, &flags) != 0)
3906                 return -EBUSY;
3907
3908         if (priv->has_mwo) {
3909                 if (frq->disabled)
3910                         priv->mwo_robust = 0;
3911                 else {
3912                         if (frq->fixed)
3913                                 printk(KERN_WARNING "%s: Fixed fragmentation is "
3914                                        "not supported on this firmware. "
3915                                        "Using MWO robust instead.\n", dev->name);
3916                         priv->mwo_robust = 1;
3917                 }
3918         } else {
3919                 if (frq->disabled)
3920                         priv->frag_thresh = 2346;
3921                 else {
3922                         if ( (frq->value < 256) || (frq->value > 2346) )
3923                                 err = -EINVAL;
3924                         else
3925                                 priv->frag_thresh = frq->value & ~0x1; /* must be even */
3926                 }
3927         }
3928
3929         orinoco_unlock(priv, &flags);
3930
3931         return err;
3932 }
3933
3934 static int orinoco_ioctl_getfrag(struct net_device *dev,
3935                                  struct iw_request_info *info,
3936                                  struct iw_param *frq,
3937                                  char *extra)
3938 {
3939         struct orinoco_private *priv = netdev_priv(dev);
3940         hermes_t *hw = &priv->hw;
3941         int err;
3942         u16 val;
3943         unsigned long flags;
3944
3945         if (orinoco_lock(priv, &flags) != 0)
3946                 return -EBUSY;
3947         
3948         if (priv->has_mwo) {
3949                 err = hermes_read_wordrec(hw, USER_BAP,
3950                                           HERMES_RID_CNFMWOROBUST_AGERE,
3951                                           &val);
3952                 if (err)
3953                         val = 0;
3954
3955                 frq->value = val ? 2347 : 0;
3956                 frq->disabled = ! val;
3957                 frq->fixed = 0;
3958         } else {
3959                 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
3960                                           &val);
3961                 if (err)
3962                         val = 0;
3963
3964                 frq->value = val;
3965                 frq->disabled = (val >= 2346);
3966                 frq->fixed = 1;
3967         }
3968
3969         orinoco_unlock(priv, &flags);
3970         
3971         return err;
3972 }
3973
3974 static int orinoco_ioctl_setrate(struct net_device *dev,
3975                                  struct iw_request_info *info,
3976                                  struct iw_param *rrq,
3977                                  char *extra)
3978 {
3979         struct orinoco_private *priv = netdev_priv(dev);
3980         int ratemode = -1;
3981         int bitrate; /* 100s of kilobits */
3982         int i;
3983         unsigned long flags;
3984         
3985         /* As the user space doesn't know our highest rate, it uses -1
3986          * to ask us to set the highest rate.  Test it using "iwconfig
3987          * ethX rate auto" - Jean II */
3988         if (rrq->value == -1)
3989                 bitrate = 110;
3990         else {
3991                 if (rrq->value % 100000)
3992                         return -EINVAL;
3993                 bitrate = rrq->value / 100000;
3994         }
3995
3996         if ( (bitrate != 10) && (bitrate != 20) &&
3997              (bitrate != 55) && (bitrate != 110) )
3998                 return -EINVAL;
3999
4000         for (i = 0; i < BITRATE_TABLE_SIZE; i++)
4001                 if ( (bitrate_table[i].bitrate == bitrate) &&
4002                      (bitrate_table[i].automatic == ! rrq->fixed) ) {
4003                         ratemode = i;
4004                         break;
4005                 }
4006         
4007         if (ratemode == -1)
4008                 return -EINVAL;
4009
4010         if (orinoco_lock(priv, &flags) != 0)
4011                 return -EBUSY;
4012         priv->bitratemode = ratemode;
4013         orinoco_unlock(priv, &flags);
4014
4015         return -EINPROGRESS;
4016 }
4017
4018 static int orinoco_ioctl_getrate(struct net_device *dev,
4019                                  struct iw_request_info *info,
4020                                  struct iw_param *rrq,
4021                                  char *extra)
4022 {
4023         struct orinoco_private *priv = netdev_priv(dev);
4024         hermes_t *hw = &priv->hw;
4025         int err = 0;
4026         int ratemode;
4027         int i;
4028         u16 val;
4029         unsigned long flags;
4030
4031         if (orinoco_lock(priv, &flags) != 0)
4032                 return -EBUSY;
4033
4034         ratemode = priv->bitratemode;
4035
4036         BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
4037
4038         rrq->value = bitrate_table[ratemode].bitrate * 100000;
4039         rrq->fixed = ! bitrate_table[ratemode].automatic;
4040         rrq->disabled = 0;
4041
4042         /* If the interface is running we try to find more about the
4043            current mode */
4044         if (netif_running(dev)) {
4045                 err = hermes_read_wordrec(hw, USER_BAP,
4046                                           HERMES_RID_CURRENTTXRATE, &val);
4047                 if (err)
4048                         goto out;
4049                 
4050                 switch (priv->firmware_type) {
4051                 case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
4052                         /* Note : in Lucent firmware, the return value of
4053                          * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
4054                          * and therefore is totally different from the
4055                          * encoding of HERMES_RID_CNFTXRATECONTROL.
4056                          * Don't forget that 6Mb/s is really 5.5Mb/s */
4057                         if (val == 6)
4058                                 rrq->value = 5500000;
4059                         else
4060                                 rrq->value = val * 1000000;
4061                         break;
4062                 case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
4063                 case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
4064                         for (i = 0; i < BITRATE_TABLE_SIZE; i++)
4065                                 if (bitrate_table[i].intersil_txratectrl == val) {
4066                                         ratemode = i;
4067                                         break;
4068                                 }
4069                         if (i >= BITRATE_TABLE_SIZE)
4070                                 printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
4071                                        dev->name, val);
4072
4073                         rrq->value = bitrate_table[ratemode].bitrate * 100000;
4074                         break;
4075                 default:
4076                         BUG();
4077                 }
4078         }
4079
4080  out:
4081         orinoco_unlock(priv, &flags);
4082
4083         return err;
4084 }
4085
4086 static int orinoco_ioctl_setpower(struct net_device *dev,
4087                                   struct iw_request_info *info,
4088                                   struct iw_param *prq,
4089                                   char *extra)
4090 {
4091         struct orinoco_private *priv = netdev_priv(dev);
4092         int err = -EINPROGRESS;         /* Call commit handler */
4093         unsigned long flags;
4094
4095         if (orinoco_lock(priv, &flags) != 0)
4096                 return -EBUSY;
4097
4098         if (prq->disabled) {
4099                 priv->pm_on = 0;
4100         } else {
4101                 switch (prq->flags & IW_POWER_MODE) {
4102                 case IW_POWER_UNICAST_R:
4103                         priv->pm_mcast = 0;
4104                         priv->pm_on = 1;
4105                         break;
4106                 case IW_POWER_ALL_R:
4107                         priv->pm_mcast = 1;
4108                         priv->pm_on = 1;
4109                         break;
4110                 case IW_POWER_ON:
4111                         /* No flags : but we may have a value - Jean II */
4112                         break;
4113                 default:
4114                         err = -EINVAL;
4115                         goto out;
4116                 }
4117                 
4118                 if (prq->flags & IW_POWER_TIMEOUT) {
4119                         priv->pm_on = 1;
4120                         priv->pm_timeout = prq->value / 1000;
4121                 }
4122                 if (prq->flags & IW_POWER_PERIOD) {
4123                         priv->pm_on = 1;
4124                         priv->pm_period = prq->value / 1000;
4125                 }
4126                 /* It's valid to not have a value if we are just toggling
4127                  * the flags... Jean II */
4128                 if(!priv->pm_on) {
4129                         err = -EINVAL;
4130                         goto out;
4131                 }                       
4132         }
4133
4134  out:
4135         orinoco_unlock(priv, &flags);
4136
4137         return err;
4138 }
4139
4140 static int orinoco_ioctl_getpower(struct net_device *dev,
4141                                   struct iw_request_info *info,
4142                                   struct iw_param *prq,
4143                                   char *extra)
4144 {
4145         struct orinoco_private *priv = netdev_priv(dev);
4146         hermes_t *hw = &priv->hw;
4147         int err = 0;
4148         u16 enable, period, timeout, mcast;
4149         unsigned long flags;
4150
4151         if (orinoco_lock(priv, &flags) != 0)
4152                 return -EBUSY;
4153         
4154         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
4155         if (err)
4156                 goto out;
4157
4158         err = hermes_read_wordrec(hw, USER_BAP,
4159                                   HERMES_RID_CNFMAXSLEEPDURATION, &period);
4160         if (err)
4161                 goto out;
4162
4163         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
4164         if (err)
4165                 goto out;
4166
4167         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
4168         if (err)
4169                 goto out;
4170
4171         prq->disabled = !enable;
4172         /* Note : by default, display the period */
4173         if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
4174                 prq->flags = IW_POWER_TIMEOUT;
4175                 prq->value = timeout * 1000;
4176         } else {
4177                 prq->flags = IW_POWER_PERIOD;
4178                 prq->value = period * 1000;
4179         }
4180         if (mcast)
4181                 prq->flags |= IW_POWER_ALL_R;
4182         else
4183                 prq->flags |= IW_POWER_UNICAST_R;
4184
4185  out:
4186         orinoco_unlock(priv, &flags);
4187
4188         return err;
4189 }
4190
4191 static int orinoco_ioctl_getretry(struct net_device *dev,
4192                                   struct iw_request_info *info,
4193                                   struct iw_param *rrq,
4194                                   char *extra)
4195 {
4196         struct orinoco_private *priv = netdev_priv(dev);
4197         hermes_t *hw = &priv->hw;
4198         int err = 0;
4199         u16 short_limit, long_limit, lifetime;
4200         unsigned long flags;
4201
4202         if (orinoco_lock(priv, &flags) != 0)
4203                 return -EBUSY;
4204         
4205         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
4206                                   &short_limit);
4207         if (err)
4208                 goto out;
4209
4210         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
4211                                   &long_limit);
4212         if (err)
4213                 goto out;
4214
4215         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
4216                                   &lifetime);
4217         if (err)
4218                 goto out;
4219
4220         rrq->disabled = 0;              /* Can't be disabled */
4221
4222         /* Note : by default, display the retry number */
4223         if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
4224                 rrq->flags = IW_RETRY_LIFETIME;
4225                 rrq->value = lifetime * 1000;   /* ??? */
4226         } else {
4227                 /* By default, display the min number */
4228                 if ((rrq->flags & IW_RETRY_LONG)) {
4229                         rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
4230                         rrq->value = long_limit;
4231                 } else {
4232                         rrq->flags = IW_RETRY_LIMIT;
4233                         rrq->value = short_limit;
4234                         if(short_limit != long_limit)
4235                                 rrq->flags |= IW_RETRY_SHORT;
4236                 }
4237         }
4238
4239  out:
4240         orinoco_unlock(priv, &flags);
4241
4242         return err;
4243 }
4244
4245 static int orinoco_ioctl_reset(struct net_device *dev,
4246                                struct iw_request_info *info,
4247                                void *wrqu,
4248                                char *extra)
4249 {
4250         struct orinoco_private *priv = netdev_priv(dev);
4251
4252         if (! capable(CAP_NET_ADMIN))
4253                 return -EPERM;
4254
4255         if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
4256                 printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
4257
4258                 /* Firmware reset */
4259                 orinoco_reset(&priv->reset_work);
4260         } else {
4261                 printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
4262
4263                 schedule_work(&priv->reset_work);
4264         }
4265
4266         return 0;
4267 }
4268
4269 static int orinoco_ioctl_setibssport(struct net_device *dev,
4270                                      struct iw_request_info *info,
4271                                      void *wrqu,
4272                                      char *extra)
4273
4274 {
4275         struct orinoco_private *priv = netdev_priv(dev);
4276         int val = *( (int *) extra );
4277         unsigned long flags;
4278
4279         if (orinoco_lock(priv, &flags) != 0)
4280                 return -EBUSY;
4281
4282         priv->ibss_port = val ;
4283
4284         /* Actually update the mode we are using */
4285         set_port_type(priv);
4286
4287         orinoco_unlock(priv, &flags);
4288         return -EINPROGRESS;            /* Call commit handler */
4289 }
4290
4291 static int orinoco_ioctl_getibssport(struct net_device *dev,
4292                                      struct iw_request_info *info,
4293                                      void *wrqu,
4294                                      char *extra)
4295 {
4296         struct orinoco_private *priv = netdev_priv(dev);
4297         int *val = (int *) extra;
4298
4299         *val = priv->ibss_port;
4300         return 0;
4301 }
4302
4303 static int orinoco_ioctl_setport3(struct net_device *dev,
4304                                   struct iw_request_info *info,
4305                                   void *wrqu,
4306                                   char *extra)
4307 {
4308         struct orinoco_private *priv = netdev_priv(dev);
4309         int val = *( (int *) extra );
4310         int err = 0;
4311         unsigned long flags;
4312
4313         if (orinoco_lock(priv, &flags) != 0)
4314                 return -EBUSY;
4315
4316         switch (val) {
4317         case 0: /* Try to do IEEE ad-hoc mode */
4318                 if (! priv->has_ibss) {
4319                         err = -EINVAL;
4320                         break;
4321                 }
4322                 priv->prefer_port3 = 0;
4323                         
4324                 break;
4325
4326         case 1: /* Try to do Lucent proprietary ad-hoc mode */
4327                 if (! priv->has_port3) {
4328                         err = -EINVAL;
4329                         break;
4330                 }
4331                 priv->prefer_port3 = 1;
4332                 break;
4333
4334         default:
4335                 err = -EINVAL;
4336         }
4337
4338         if (! err) {
4339                 /* Actually update the mode we are using */
4340                 set_port_type(priv);
4341                 err = -EINPROGRESS;
4342         }
4343
4344         orinoco_unlock(priv, &flags);
4345
4346         return err;
4347 }
4348
4349 static int orinoco_ioctl_getport3(struct net_device *dev,
4350                                   struct iw_request_info *info,
4351                                   void *wrqu,
4352                                   char *extra)
4353 {
4354         struct orinoco_private *priv = netdev_priv(dev);
4355         int *val = (int *) extra;
4356
4357         *val = priv->prefer_port3;
4358         return 0;
4359 }
4360
4361 static int orinoco_ioctl_setpreamble(struct net_device *dev,
4362                                      struct iw_request_info *info,
4363                                      void *wrqu,
4364                                      char *extra)
4365 {
4366         struct orinoco_private *priv = netdev_priv(dev);
4367         unsigned long flags;
4368         int val;
4369
4370         if (! priv->has_preamble)
4371                 return -EOPNOTSUPP;
4372
4373         /* 802.11b has recently defined some short preamble.
4374          * Basically, the Phy header has been reduced in size.
4375          * This increase performance, especially at high rates
4376          * (the preamble is transmitted at 1Mb/s), unfortunately
4377          * this give compatibility troubles... - Jean II */
4378         val = *( (int *) extra );
4379
4380         if (orinoco_lock(priv, &flags) != 0)
4381                 return -EBUSY;
4382
4383         if (val)
4384                 priv->preamble = 1;
4385         else
4386                 priv->preamble = 0;
4387
4388         orinoco_unlock(priv, &flags);
4389
4390         return -EINPROGRESS;            /* Call commit handler */
4391 }
4392
4393 static int orinoco_ioctl_getpreamble(struct net_device *dev,
4394                                      struct iw_request_info *info,
4395                                      void *wrqu,
4396                                      char *extra)
4397 {
4398         struct orinoco_private *priv = netdev_priv(dev);
4399         int *val = (int *) extra;
4400
4401         if (! priv->has_preamble)
4402                 return -EOPNOTSUPP;
4403
4404         *val = priv->preamble;
4405         return 0;
4406 }
4407
4408 /* ioctl interface to hermes_read_ltv()
4409  * To use with iwpriv, pass the RID as the token argument, e.g.
4410  * iwpriv get_rid [0xfc00]
4411  * At least Wireless Tools 25 is required to use iwpriv.
4412  * For Wireless Tools 25 and 26 append "dummy" are the end. */
4413 static int orinoco_ioctl_getrid(struct net_device *dev,
4414                                 struct iw_request_info *info,
4415                                 struct iw_point *data,
4416                                 char *extra)
4417 {
4418         struct orinoco_private *priv = netdev_priv(dev);
4419         hermes_t *hw = &priv->hw;
4420         int rid = data->flags;
4421         u16 length;
4422         int err;
4423         unsigned long flags;
4424
4425         /* It's a "get" function, but we don't want users to access the
4426          * WEP key and other raw firmware data */
4427         if (! capable(CAP_NET_ADMIN))
4428                 return -EPERM;
4429
4430         if (rid < 0xfc00 || rid > 0xffff)
4431                 return -EINVAL;
4432
4433         if (orinoco_lock(priv, &flags) != 0)
4434                 return -EBUSY;
4435
4436         err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
4437                               extra);
4438         if (err)
4439                 goto out;
4440
4441         data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
4442                              MAX_RID_LEN);
4443
4444  out:
4445         orinoco_unlock(priv, &flags);
4446         return err;
4447 }
4448
4449 /* Trigger a scan (look for other cells in the vicinity) */
4450 static int orinoco_ioctl_setscan(struct net_device *dev,
4451                                  struct iw_request_info *info,
4452                                  struct iw_param *srq,
4453                                  char *extra)
4454 {
4455         struct orinoco_private *priv = netdev_priv(dev);
4456         hermes_t *hw = &priv->hw;
4457         struct iw_scan_req *si = (struct iw_scan_req *) extra;
4458         int err = 0;
4459         unsigned long flags;
4460
4461         /* Note : you may have realised that, as this is a SET operation,
4462          * this is privileged and therefore a normal user can't
4463          * perform scanning.
4464          * This is not an error, while the device perform scanning,
4465          * traffic doesn't flow, so it's a perfect DoS...
4466          * Jean II */
4467
4468         if (orinoco_lock(priv, &flags) != 0)
4469                 return -EBUSY;
4470
4471         /* Scanning with port 0 disabled would fail */
4472         if (!netif_running(dev)) {
4473                 err = -ENETDOWN;
4474                 goto out;
4475         }
4476
4477         /* In monitor mode, the scan results are always empty.
4478          * Probe responses are passed to the driver as received
4479          * frames and could be processed in software. */
4480         if (priv->iw_mode == IW_MODE_MONITOR) {
4481                 err = -EOPNOTSUPP;
4482                 goto out;
4483         }
4484
4485         /* Note : because we don't lock out the irq handler, the way
4486          * we access scan variables in priv is critical.
4487          *      o scan_inprogress : not touched by irq handler
4488          *      o scan_mode : not touched by irq handler
4489          * Before modifying anything on those variables, please think hard !
4490          * Jean II */
4491
4492         /* Save flags */
4493         priv->scan_mode = srq->flags;
4494
4495         /* Always trigger scanning, even if it's in progress.
4496          * This way, if the info frame get lost, we will recover somewhat
4497          * gracefully  - Jean II */
4498
4499         if (priv->has_hostscan) {
4500                 switch (priv->firmware_type) {
4501                 case FIRMWARE_TYPE_SYMBOL:
4502                         err = hermes_write_wordrec(hw, USER_BAP,
4503                                                    HERMES_RID_CNFHOSTSCAN_SYMBOL,
4504                                                    HERMES_HOSTSCAN_SYMBOL_ONCE |
4505                                                    HERMES_HOSTSCAN_SYMBOL_BCAST);
4506                         break;
4507                 case FIRMWARE_TYPE_INTERSIL: {
4508                         __le16 req[3];
4509
4510                         req[0] = cpu_to_le16(0x3fff);   /* All channels */
4511                         req[1] = cpu_to_le16(0x0001);   /* rate 1 Mbps */
4512                         req[2] = 0;                     /* Any ESSID */
4513                         err = HERMES_WRITE_RECORD(hw, USER_BAP,
4514                                                   HERMES_RID_CNFHOSTSCAN, &req);
4515                 }
4516                 break;
4517                 case FIRMWARE_TYPE_AGERE:
4518                         if (priv->scan_mode & IW_SCAN_THIS_ESSID) {
4519                                 struct hermes_idstring idbuf;
4520                                 size_t len = min(sizeof(idbuf.val),
4521                                                  (size_t) si->essid_len);
4522                                 idbuf.len = cpu_to_le16(len);
4523                                 memcpy(idbuf.val, si->essid, len);
4524
4525                                 err = hermes_write_ltv(hw, USER_BAP,
4526                                                HERMES_RID_CNFSCANSSID_AGERE,
4527                                                HERMES_BYTES_TO_RECLEN(len + 2),
4528                                                &idbuf);
4529                         } else
4530                                 err = hermes_write_wordrec(hw, USER_BAP,
4531                                                    HERMES_RID_CNFSCANSSID_AGERE,
4532                                                    0);  /* Any ESSID */
4533                         if (err)
4534                                 break;
4535
4536                         if (priv->has_ext_scan) {
4537                                 /* Clear scan results at the start of
4538                                  * an extended scan */
4539                                 orinoco_clear_scan_results(priv,
4540                                                 msecs_to_jiffies(15000));
4541
4542                                 /* TODO: Is this available on older firmware?
4543                                  *   Can we use it to scan specific channels
4544                                  *   for IW_SCAN_THIS_FREQ? */
4545                                 err = hermes_write_wordrec(hw, USER_BAP,
4546                                                 HERMES_RID_CNFSCANCHANNELS2GHZ,
4547                                                 0x7FFF);
4548                                 if (err)
4549                                         goto out;
4550
4551                                 err = hermes_inquire(hw,
4552                                                      HERMES_INQ_CHANNELINFO);
4553                         } else
4554                                 err = hermes_inquire(hw, HERMES_INQ_SCAN);
4555                         break;
4556                 }
4557         } else
4558                 err = hermes_inquire(hw, HERMES_INQ_SCAN);
4559
4560         /* One more client */
4561         if (! err)
4562                 priv->scan_inprogress = 1;
4563
4564  out:
4565         orinoco_unlock(priv, &flags);
4566         return err;
4567 }
4568
4569 #define MAX_CUSTOM_LEN 64
4570
4571 /* Translate scan data returned from the card to a card independant
4572  * format that the Wireless Tools will understand - Jean II */
4573 static inline char *orinoco_translate_scan(struct net_device *dev,
4574                                            struct iw_request_info *info,
4575                                            char *current_ev,
4576                                            char *end_buf,
4577                                            union hermes_scan_info *bss,
4578                                            unsigned int last_scanned)
4579 {
4580         struct orinoco_private *priv = netdev_priv(dev);
4581         u16                     capabilities;
4582         u16                     channel;
4583         struct iw_event         iwe;            /* Temporary buffer */
4584         char custom[MAX_CUSTOM_LEN];
4585
4586         memset(&iwe, 0, sizeof(iwe));
4587
4588         /* First entry *MUST* be the AP MAC address */
4589         iwe.cmd = SIOCGIWAP;
4590         iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
4591         memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
4592         current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4593                                           &iwe, IW_EV_ADDR_LEN);
4594
4595         /* Other entries will be displayed in the order we give them */
4596
4597         /* Add the ESSID */
4598         iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
4599         if (iwe.u.data.length > 32)
4600                 iwe.u.data.length = 32;
4601         iwe.cmd = SIOCGIWESSID;
4602         iwe.u.data.flags = 1;
4603         current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4604                                           &iwe, bss->a.essid);
4605
4606         /* Add mode */
4607         iwe.cmd = SIOCGIWMODE;
4608         capabilities = le16_to_cpu(bss->a.capabilities);
4609         if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
4610                 if (capabilities & WLAN_CAPABILITY_ESS)
4611                         iwe.u.mode = IW_MODE_MASTER;
4612                 else
4613                         iwe.u.mode = IW_MODE_ADHOC;
4614                 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4615                                                   &iwe, IW_EV_UINT_LEN);
4616         }
4617
4618         channel = bss->s.channel;
4619         if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
4620                 /* Add channel and frequency */
4621                 iwe.cmd = SIOCGIWFREQ;
4622                 iwe.u.freq.m = channel;
4623                 iwe.u.freq.e = 0;
4624                 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4625                                                   &iwe, IW_EV_FREQ_LEN);
4626
4627                 iwe.u.freq.m = channel_frequency[channel-1] * 100000;
4628                 iwe.u.freq.e = 1;
4629                 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4630                                                   &iwe, IW_EV_FREQ_LEN);
4631         }
4632
4633         /* Add quality statistics. level and noise in dB. No link quality */
4634         iwe.cmd = IWEVQUAL;
4635         iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
4636         iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
4637         iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
4638         /* Wireless tools prior to 27.pre22 will show link quality
4639          * anyway, so we provide a reasonable value. */
4640         if (iwe.u.qual.level > iwe.u.qual.noise)
4641                 iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
4642         else
4643                 iwe.u.qual.qual = 0;
4644         current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4645                                           &iwe, IW_EV_QUAL_LEN);
4646
4647         /* Add encryption capability */
4648         iwe.cmd = SIOCGIWENCODE;
4649         if (capabilities & WLAN_CAPABILITY_PRIVACY)
4650                 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
4651         else
4652                 iwe.u.data.flags = IW_ENCODE_DISABLED;
4653         iwe.u.data.length = 0;
4654         current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4655                                           &iwe, NULL);
4656
4657         /* Bit rate is not available in Lucent/Agere firmwares */
4658         if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
4659                 char *current_val = current_ev + iwe_stream_lcp_len(info);
4660                 int i;
4661                 int step;
4662
4663                 if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
4664                         step = 2;
4665                 else
4666                         step = 1;
4667
4668                 iwe.cmd = SIOCGIWRATE;
4669                 /* Those two flags are ignored... */
4670                 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
4671                 /* Max 10 values */
4672                 for (i = 0; i < 10; i += step) {
4673                         /* NULL terminated */
4674                         if (bss->p.rates[i] == 0x0)
4675                                 break;
4676                         /* Bit rate given in 500 kb/s units (+ 0x80) */
4677                         iwe.u.bitrate.value =
4678                                 ((bss->p.rates[i] & 0x7f) * 500000);
4679                         current_val = iwe_stream_add_value(info, current_ev,
4680                                                            current_val,
4681                                                            end_buf, &iwe,
4682                                                            IW_EV_PARAM_LEN);
4683                 }
4684                 /* Check if we added any event */
4685                 if ((current_val - current_ev) > iwe_stream_lcp_len(info))
4686                         current_ev = current_val;
4687         }
4688
4689         /* Beacon interval */
4690         iwe.cmd = IWEVCUSTOM;
4691         iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
4692                                      "bcn_int=%d",
4693                                      le16_to_cpu(bss->a.beacon_interv));
4694         if (iwe.u.data.length)
4695                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4696                                                   &iwe, custom);
4697
4698         /* Capabilites */
4699         iwe.cmd = IWEVCUSTOM;
4700         iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
4701                                      "capab=0x%04x",
4702                                      capabilities);
4703         if (iwe.u.data.length)
4704                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4705                                                   &iwe, custom);
4706
4707         /* Add EXTRA: Age to display seconds since last beacon/probe response
4708          * for given network. */
4709         iwe.cmd = IWEVCUSTOM;
4710         iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
4711                                      " Last beacon: %dms ago",
4712                                      jiffies_to_msecs(jiffies - last_scanned));
4713         if (iwe.u.data.length)
4714                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4715                                                   &iwe, custom);
4716
4717         return current_ev;
4718 }
4719
4720 static inline char *orinoco_translate_ext_scan(struct net_device *dev,
4721                                                struct iw_request_info *info,
4722                                                char *current_ev,
4723                                                char *end_buf,
4724                                                struct agere_ext_scan_info *bss,
4725                                                unsigned int last_scanned)
4726 {
4727         u16                     capabilities;
4728         u16                     channel;
4729         struct iw_event         iwe;            /* Temporary buffer */
4730         char custom[MAX_CUSTOM_LEN];
4731         u8 *ie;
4732
4733         memset(&iwe, 0, sizeof(iwe));
4734
4735         /* First entry *MUST* be the AP MAC address */
4736         iwe.cmd = SIOCGIWAP;
4737         iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
4738         memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
4739         current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4740                                           &iwe, IW_EV_ADDR_LEN);
4741
4742         /* Other entries will be displayed in the order we give them */
4743
4744         /* Add the ESSID */
4745         ie = bss->data;
4746         iwe.u.data.length = ie[1];
4747         if (iwe.u.data.length) {
4748                 if (iwe.u.data.length > 32)
4749                         iwe.u.data.length = 32;
4750                 iwe.cmd = SIOCGIWESSID;
4751                 iwe.u.data.flags = 1;
4752                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4753                                                   &iwe, &ie[2]);
4754         }
4755
4756         /* Add mode */
4757         capabilities = le16_to_cpu(bss->capabilities);
4758         if (capabilities & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
4759                 iwe.cmd = SIOCGIWMODE;
4760                 if (capabilities & WLAN_CAPABILITY_ESS)
4761                         iwe.u.mode = IW_MODE_MASTER;
4762                 else
4763                         iwe.u.mode = IW_MODE_ADHOC;
4764                 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4765                                                   &iwe, IW_EV_UINT_LEN);
4766         }
4767
4768         ie = orinoco_get_ie(bss->data, sizeof(bss->data), MFIE_TYPE_DS_SET);
4769         channel = ie ? ie[2] : 0;
4770         if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
4771                 /* Add channel and frequency */
4772                 iwe.cmd = SIOCGIWFREQ;
4773                 iwe.u.freq.m = channel;
4774                 iwe.u.freq.e = 0;
4775                 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4776                                                   &iwe, IW_EV_FREQ_LEN);
4777
4778                 iwe.u.freq.m = channel_frequency[channel-1] * 100000;
4779                 iwe.u.freq.e = 1;
4780                 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4781                                                   &iwe, IW_EV_FREQ_LEN);
4782         }
4783
4784         /* Add quality statistics. level and noise in dB. No link quality */
4785         iwe.cmd = IWEVQUAL;
4786         iwe.u.qual.updated = IW_QUAL_DBM | IW_QUAL_QUAL_INVALID;
4787         iwe.u.qual.level = bss->level - 0x95;
4788         iwe.u.qual.noise = bss->noise - 0x95;
4789         /* Wireless tools prior to 27.pre22 will show link quality
4790          * anyway, so we provide a reasonable value. */
4791         if (iwe.u.qual.level > iwe.u.qual.noise)
4792                 iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
4793         else
4794                 iwe.u.qual.qual = 0;
4795         current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4796                                           &iwe, IW_EV_QUAL_LEN);
4797
4798         /* Add encryption capability */
4799         iwe.cmd = SIOCGIWENCODE;
4800         if (capabilities & WLAN_CAPABILITY_PRIVACY)
4801                 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
4802         else
4803                 iwe.u.data.flags = IW_ENCODE_DISABLED;
4804         iwe.u.data.length = 0;
4805         current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4806                                           &iwe, NULL);
4807
4808         /* WPA IE */
4809         ie = orinoco_get_wpa_ie(bss->data, sizeof(bss->data));
4810         if (ie) {
4811                 iwe.cmd = IWEVGENIE;
4812                 iwe.u.data.length = ie[1] + 2;
4813                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4814                                                   &iwe, ie);
4815         }
4816
4817         /* RSN IE */
4818         ie = orinoco_get_ie(bss->data, sizeof(bss->data), MFIE_TYPE_RSN);
4819         if (ie) {
4820                 iwe.cmd = IWEVGENIE;
4821                 iwe.u.data.length = ie[1] + 2;
4822                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4823                                                   &iwe, ie);
4824         }
4825
4826         ie = orinoco_get_ie(bss->data, sizeof(bss->data), MFIE_TYPE_RATES);
4827         if (ie) {
4828                 char *p = current_ev + iwe_stream_lcp_len(info);
4829                 int i;
4830
4831                 iwe.cmd = SIOCGIWRATE;
4832                 /* Those two flags are ignored... */
4833                 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
4834
4835                 for (i = 2; i < (ie[1] + 2); i++) {
4836                         iwe.u.bitrate.value = ((ie[i] & 0x7F) * 500000);
4837                         p = iwe_stream_add_value(info, current_ev, p, end_buf,
4838                                                  &iwe, IW_EV_PARAM_LEN);
4839                 }
4840                 /* Check if we added any event */
4841                 if (p > (current_ev + iwe_stream_lcp_len(info)))
4842                         current_ev = p;
4843         }
4844
4845         /* Timestamp */
4846         iwe.cmd = IWEVCUSTOM;
4847         iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
4848                                      "tsf=%016llx",
4849                                      le64_to_cpu(bss->timestamp));
4850         if (iwe.u.data.length)
4851                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4852                                                   &iwe, custom);
4853
4854         /* Beacon interval */
4855         iwe.cmd = IWEVCUSTOM;
4856         iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
4857                                      "bcn_int=%d",
4858                                      le16_to_cpu(bss->beacon_interval));
4859         if (iwe.u.data.length)
4860                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4861                                                   &iwe, custom);
4862
4863         /* Capabilites */
4864         iwe.cmd = IWEVCUSTOM;
4865         iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
4866                                      "capab=0x%04x",
4867                                      capabilities);
4868         if (iwe.u.data.length)
4869                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4870                                                   &iwe, custom);
4871
4872         /* Add EXTRA: Age to display seconds since last beacon/probe response
4873          * for given network. */
4874         iwe.cmd = IWEVCUSTOM;
4875         iwe.u.data.length = snprintf(custom, MAX_CUSTOM_LEN,
4876                                      " Last beacon: %dms ago",
4877                                      jiffies_to_msecs(jiffies - last_scanned));
4878         if (iwe.u.data.length)
4879                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4880                                                   &iwe, custom);
4881
4882         return current_ev;
4883 }
4884
4885 /* Return results of a scan */
4886 static int orinoco_ioctl_getscan(struct net_device *dev,
4887                                  struct iw_request_info *info,
4888                                  struct iw_point *srq,
4889                                  char *extra)
4890 {
4891         struct orinoco_private *priv = netdev_priv(dev);
4892         int err = 0;
4893         unsigned long flags;
4894         char *current_ev = extra;
4895
4896         if (orinoco_lock(priv, &flags) != 0)
4897                 return -EBUSY;
4898
4899         if (priv->scan_inprogress) {
4900                 /* Important note : we don't want to block the caller
4901                  * until results are ready for various reasons.
4902                  * First, managing wait queues is complex and racy.
4903                  * Second, we grab some rtnetlink lock before comming
4904                  * here (in dev_ioctl()).
4905                  * Third, we generate an Wireless Event, so the
4906                  * caller can wait itself on that - Jean II */
4907                 err = -EAGAIN;
4908                 goto out;
4909         }
4910
4911         if (priv->has_ext_scan) {
4912                 struct xbss_element *bss;
4913
4914                 list_for_each_entry(bss, &priv->bss_list, list) {
4915                         /* Translate this entry to WE format */
4916                         current_ev =
4917                                 orinoco_translate_ext_scan(dev, info,
4918                                                            current_ev,
4919                                                            extra + srq->length,
4920                                                            &bss->bss,
4921                                                            bss->last_scanned);
4922
4923                         /* Check if there is space for one more entry */
4924                         if ((extra + srq->length - current_ev)
4925                             <= IW_EV_ADDR_LEN) {
4926                                 /* Ask user space to try again with a
4927                                  * bigger buffer */
4928                                 err = -E2BIG;
4929                                 goto out;
4930                         }
4931                 }
4932
4933         } else {
4934                 struct bss_element *bss;
4935
4936                 list_for_each_entry(bss, &priv->bss_list, list) {
4937                         /* Translate this entry to WE format */
4938                         current_ev = orinoco_translate_scan(dev, info,
4939                                                             current_ev,
4940                                                             extra + srq->length,
4941                                                             &bss->bss,
4942                                                             bss->last_scanned);
4943
4944                         /* Check if there is space for one more entry */
4945                         if ((extra + srq->length - current_ev)
4946                             <= IW_EV_ADDR_LEN) {
4947                                 /* Ask user space to try again with a
4948                                  * bigger buffer */
4949                                 err = -E2BIG;
4950                                 goto out;
4951                         }
4952                 }
4953         }
4954
4955         srq->length = (current_ev - extra);
4956         srq->flags = (__u16) priv->scan_mode;
4957
4958 out:
4959         orinoco_unlock(priv, &flags);
4960         return err;
4961 }
4962
4963 /* Commit handler, called after set operations */
4964 static int orinoco_ioctl_commit(struct net_device *dev,
4965                                 struct iw_request_info *info,
4966                                 void *wrqu,
4967                                 char *extra)
4968 {
4969         struct orinoco_private *priv = netdev_priv(dev);
4970         struct hermes *hw = &priv->hw;
4971         unsigned long flags;
4972         int err = 0;
4973
4974         if (!priv->open)
4975                 return 0;
4976
4977         if (priv->broken_disableport) {
4978                 orinoco_reset(&priv->reset_work);
4979                 return 0;
4980         }
4981
4982         if (orinoco_lock(priv, &flags) != 0)
4983                 return err;
4984
4985         err = hermes_disable_port(hw, 0);
4986         if (err) {
4987                 printk(KERN_WARNING "%s: Unable to disable port "
4988                        "while reconfiguring card\n", dev->name);
4989                 priv->broken_disableport = 1;
4990                 goto out;
4991         }
4992
4993         err = __orinoco_program_rids(dev);
4994         if (err) {
4995                 printk(KERN_WARNING "%s: Unable to reconfigure card\n",
4996                        dev->name);
4997                 goto out;
4998         }
4999
5000         err = hermes_enable_port(hw, 0);
5001         if (err) {
5002                 printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
5003                        dev->name);
5004                 goto out;
5005         }
5006
5007  out:
5008         if (err) {
5009                 printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
5010                 schedule_work(&priv->reset_work);
5011                 err = 0;
5012         }
5013
5014         orinoco_unlock(priv, &flags);
5015         return err;
5016 }
5017
5018 static const struct iw_priv_args orinoco_privtab[] = {
5019         { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
5020         { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
5021         { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5022           0, "set_port3" },
5023         { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5024           "get_port3" },
5025         { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5026           0, "set_preamble" },
5027         { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5028           "get_preamble" },
5029         { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5030           0, "set_ibssport" },
5031         { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5032           "get_ibssport" },
5033         { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
5034           "get_rid" },
5035 };
5036
5037
5038 /*
5039  * Structures to export the Wireless Handlers
5040  */
5041
5042 static const iw_handler orinoco_handler[] = {
5043         [SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_commit,
5044         [SIOCGIWNAME  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getname,
5045         [SIOCSIWFREQ  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setfreq,
5046         [SIOCGIWFREQ  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getfreq,
5047         [SIOCSIWMODE  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setmode,
5048         [SIOCGIWMODE  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getmode,
5049         [SIOCSIWSENS  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens,
5050         [SIOCGIWSENS  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens,
5051         [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange,
5052         [SIOCSIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
5053         [SIOCGIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
5054         [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
5055         [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
5056         [SIOCSIWAP    -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap,
5057         [SIOCGIWAP    -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap,
5058         [SIOCSIWSCAN  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan,
5059         [SIOCGIWSCAN  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getscan,
5060         [SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setessid,
5061         [SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getessid,
5062         [SIOCSIWNICKN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setnick,
5063         [SIOCGIWNICKN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getnick,
5064         [SIOCSIWRATE  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setrate,
5065         [SIOCGIWRATE  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getrate,
5066         [SIOCSIWRTS   -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setrts,
5067         [SIOCGIWRTS   -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getrts,
5068         [SIOCSIWFRAG  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setfrag,
5069         [SIOCGIWFRAG  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getfrag,
5070         [SIOCGIWRETRY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getretry,
5071         [SIOCSIWENCODE-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setiwencode,
5072         [SIOCGIWENCODE-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwencode,
5073         [SIOCSIWPOWER -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setpower,
5074         [SIOCGIWPOWER -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getpower,
5075 };
5076
5077
5078 /*
5079   Added typecasting since we no longer use iwreq_data -- Moustafa
5080  */
5081 static const iw_handler orinoco_private_handler[] = {
5082         [0] = (iw_handler) orinoco_ioctl_reset,
5083         [1] = (iw_handler) orinoco_ioctl_reset,
5084         [2] = (iw_handler) orinoco_ioctl_setport3,
5085         [3] = (iw_handler) orinoco_ioctl_getport3,
5086         [4] = (iw_handler) orinoco_ioctl_setpreamble,
5087         [5] = (iw_handler) orinoco_ioctl_getpreamble,
5088         [6] = (iw_handler) orinoco_ioctl_setibssport,
5089         [7] = (iw_handler) orinoco_ioctl_getibssport,
5090         [9] = (iw_handler) orinoco_ioctl_getrid,
5091 };
5092
5093 static const struct iw_handler_def orinoco_handler_def = {
5094         .num_standard = ARRAY_SIZE(orinoco_handler),
5095         .num_private = ARRAY_SIZE(orinoco_private_handler),
5096         .num_private_args = ARRAY_SIZE(orinoco_privtab),
5097         .standard = orinoco_handler,
5098         .private = orinoco_private_handler,
5099         .private_args = orinoco_privtab,
5100         .get_wireless_stats = orinoco_get_wireless_stats,
5101 };
5102
5103 static void orinoco_get_drvinfo(struct net_device *dev,
5104                                 struct ethtool_drvinfo *info)
5105 {
5106         struct orinoco_private *priv = netdev_priv(dev);
5107
5108         strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
5109         strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
5110         strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
5111         if (dev->dev.parent)
5112                 strncpy(info->bus_info, dev->dev.parent->bus_id,
5113                         sizeof(info->bus_info) - 1);
5114         else
5115                 snprintf(info->bus_info, sizeof(info->bus_info) - 1,
5116                          "PCMCIA %p", priv->hw.iobase);
5117 }
5118
5119 static const struct ethtool_ops orinoco_ethtool_ops = {
5120         .get_drvinfo = orinoco_get_drvinfo,
5121         .get_link = ethtool_op_get_link,
5122 };
5123
5124 /********************************************************************/
5125 /* Module initialization                                            */
5126 /********************************************************************/
5127
5128 EXPORT_SYMBOL(alloc_orinocodev);
5129 EXPORT_SYMBOL(free_orinocodev);
5130
5131 EXPORT_SYMBOL(__orinoco_up);
5132 EXPORT_SYMBOL(__orinoco_down);
5133 EXPORT_SYMBOL(orinoco_reinit_firmware);
5134
5135 EXPORT_SYMBOL(orinoco_interrupt);
5136
5137 /* Can't be declared "const" or the whole __initdata section will
5138  * become const */
5139 static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
5140         " (David Gibson <hermes@gibson.dropbear.id.au>, "
5141         "Pavel Roskin <proski@gnu.org>, et al)";
5142
5143 static int __init init_orinoco(void)
5144 {
5145         printk(KERN_DEBUG "%s\n", version);
5146         return 0;
5147 }
5148
5149 static void __exit exit_orinoco(void)
5150 {
5151 }
5152
5153 module_init(init_orinoco);
5154 module_exit(exit_orinoco);