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