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