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