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