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