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