Merge ../linux-2.6
[linux-2.6] / drivers / net / wireless / orinoco.c
1 /* orinoco.c - (formerly known as dldwd_cs.c and orinoco_cs.c)
2  *
3  * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
4  * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
5  *
6  * Current maintainers (as of 29 September 2003) are:
7  *      Pavel Roskin <proski AT gnu.org>
8  * and  David Gibson <hermes AT gibson.dropbear.id.au>
9  *
10  * (C) Copyright David Gibson, IBM Corporation 2001-2003.
11  * Copyright (C) 2000 David Gibson, Linuxcare Australia.
12  *      With some help from :
13  * Copyright (C) 2001 Jean Tourrilhes, HP Labs
14  * Copyright (C) 2001 Benjamin Herrenschmidt
15  *
16  * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
17  *
18  * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy
19  * AT fasta.fh-dortmund.de>
20  *      http://www.stud.fh-dortmund.de/~andy/wvlan/
21  *
22  * The contents of this file are subject to the Mozilla Public License
23  * Version 1.1 (the "License"); you may not use this file except in
24  * compliance with the License. You may obtain a copy of the License
25  * at http://www.mozilla.org/MPL/
26  *
27  * Software distributed under the License is distributed on an "AS IS"
28  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
29  * the License for the specific language governing rights and
30  * limitations under the License.
31  *
32  * The initial developer of the original code is David A. Hinds
33  * <dahinds AT users.sourceforge.net>.  Portions created by David
34  * A. Hinds are Copyright (C) 1999 David A. Hinds.  All Rights
35  * Reserved.
36  *
37  * Alternatively, the contents of this file may be used under the
38  * terms of the GNU General Public License version 2 (the "GPL"), in
39  * which case the provisions of the GPL are applicable instead of the
40  * above.  If you wish to allow the use of your version of this file
41  * only under the terms of the GPL and not to allow others to use your
42  * version of this file under the MPL, indicate your decision by
43  * deleting the provisions above and replace them with the notice and
44  * other provisions required by the GPL.  If you do not delete the
45  * provisions above, a recipient may use your version of this file
46  * under either the MPL or the GPL.  */
47
48 /*
49  * TODO
50  *      o Handle de-encapsulation within network layer, provide 802.11
51  *        headers (patch from Thomas 'Dent' Mirlacher)
52  *      o Fix possible races in SPY handling.
53  *      o Disconnect wireless extensions from fundamental configuration.
54  *      o (maybe) Software WEP support (patch from Stano Meduna).
55  *      o (maybe) Use multiple Tx buffers - driver handling queue
56  *        rather than firmware.
57  */
58
59 /* Locking and synchronization:
60  *
61  * The basic principle is that everything is serialized through a
62  * single spinlock, priv->lock.  The lock is used in user, bh and irq
63  * context, so when taken outside hardirq context it should always be
64  * taken with interrupts disabled.  The lock protects both the
65  * hardware and the struct orinoco_private.
66  *
67  * Another flag, priv->hw_unavailable indicates that the hardware is
68  * unavailable for an extended period of time (e.g. suspended, or in
69  * the middle of a hard reset).  This flag is protected by the
70  * spinlock.  All code which touches the hardware should check the
71  * flag after taking the lock, and if it is set, give up on whatever
72  * they are doing and drop the lock again.  The orinoco_lock()
73  * function handles this (it unlocks and returns -EBUSY if
74  * hw_unavailable is non-zero).
75  */
76
77 #define DRIVER_NAME "orinoco"
78
79 #include <linux/module.h>
80 #include <linux/kernel.h>
81 #include <linux/init.h>
82 #include <linux/netdevice.h>
83 #include <linux/etherdevice.h>
84 #include <linux/ethtool.h>
85 #include <linux/wireless.h>
86 #include <net/iw_handler.h>
87 #include <net/ieee80211.h>
88
89 #include "hermes_rid.h"
90 #include "orinoco.h"
91
92 /********************************************************************/
93 /* Module information                                               */
94 /********************************************************************/
95
96 MODULE_AUTHOR("Pavel Roskin <proski@gnu.org> & David Gibson <hermes@gibson.dropbear.id.au>");
97 MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
98 MODULE_LICENSE("Dual MPL/GPL");
99
100 /* Level of debugging. Used in the macros in orinoco.h */
101 #ifdef ORINOCO_DEBUG
102 int orinoco_debug = ORINOCO_DEBUG;
103 module_param(orinoco_debug, int, 0644);
104 MODULE_PARM_DESC(orinoco_debug, "Debug level");
105 EXPORT_SYMBOL(orinoco_debug);
106 #endif
107
108 static int suppress_linkstatus; /* = 0 */
109 module_param(suppress_linkstatus, bool, 0644);
110 MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
111 static int ignore_disconnect; /* = 0 */
112 module_param(ignore_disconnect, int, 0644);
113 MODULE_PARM_DESC(ignore_disconnect, "Don't report lost link to the network layer");
114
115 static int force_monitor; /* = 0 */
116 module_param(force_monitor, int, 0644);
117 MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
118
119 /********************************************************************/
120 /* Compile time configuration and compatibility stuff               */
121 /********************************************************************/
122
123 /* We do this this way to avoid ifdefs in the actual code */
124 #ifdef WIRELESS_SPY
125 #define SPY_NUMBER(priv)        (priv->spy_data.spy_number)
126 #else
127 #define SPY_NUMBER(priv)        0
128 #endif /* WIRELESS_SPY */
129
130 /********************************************************************/
131 /* Internal constants                                               */
132 /********************************************************************/
133
134 /* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
135 static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
136 #define ENCAPS_OVERHEAD         (sizeof(encaps_hdr) + 2)
137
138 #define ORINOCO_MIN_MTU         256
139 #define ORINOCO_MAX_MTU         (IEEE80211_DATA_LEN - ENCAPS_OVERHEAD)
140
141 #define SYMBOL_MAX_VER_LEN      (14)
142 #define USER_BAP                0
143 #define IRQ_BAP                 1
144 #define MAX_IRQLOOPS_PER_IRQ    10
145 #define MAX_IRQLOOPS_PER_JIFFY  (20000/HZ) /* Based on a guestimate of
146                                             * how many events the
147                                             * device could
148                                             * legitimately generate */
149 #define SMALL_KEY_SIZE          5
150 #define LARGE_KEY_SIZE          13
151 #define TX_NICBUF_SIZE_BUG      1585            /* Bug in Symbol firmware */
152
153 #define DUMMY_FID               0xFFFF
154
155 /*#define MAX_MULTICAST(priv)   (priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
156   HERMES_MAX_MULTICAST : 0)*/
157 #define MAX_MULTICAST(priv)     (HERMES_MAX_MULTICAST)
158
159 #define ORINOCO_INTEN           (HERMES_EV_RX | HERMES_EV_ALLOC \
160                                  | HERMES_EV_TX | HERMES_EV_TXEXC \
161                                  | HERMES_EV_WTERR | HERMES_EV_INFO \
162                                  | HERMES_EV_INFDROP )
163
164 #define MAX_RID_LEN 1024
165
166 static const struct iw_handler_def orinoco_handler_def;
167 static struct ethtool_ops orinoco_ethtool_ops;
168
169 /********************************************************************/
170 /* Data tables                                                      */
171 /********************************************************************/
172
173 /* The frequency of each channel in MHz */
174 static const long channel_frequency[] = {
175         2412, 2417, 2422, 2427, 2432, 2437, 2442,
176         2447, 2452, 2457, 2462, 2467, 2472, 2484
177 };
178 #define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
179
180 /* This tables gives the actual meanings of the bitrate IDs returned
181  * by the firmware. */
182 static struct {
183         int bitrate; /* in 100s of kilobits */
184         int automatic;
185         u16 agere_txratectrl;
186         u16 intersil_txratectrl;
187 } bitrate_table[] = {
188         {110, 1,  3, 15}, /* Entry 0 is the default */
189         {10,  0,  1,  1},
190         {10,  1,  1,  1},
191         {20,  0,  2,  2},
192         {20,  1,  6,  3},
193         {55,  0,  4,  4},
194         {55,  1,  7,  7},
195         {110, 0,  5,  8},
196 };
197 #define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
198
199 /********************************************************************/
200 /* Data types                                                       */
201 /********************************************************************/
202
203 /* Beginning of the Tx descriptor, used in TxExc handling */
204 struct hermes_txexc_data {
205         struct hermes_tx_descriptor desc;
206         __le16 frame_ctl;
207         __le16 duration_id;
208         u8 addr1[ETH_ALEN];
209 } __attribute__ ((packed));
210
211 /* Rx frame header except compatibility 802.3 header */
212 struct hermes_rx_descriptor {
213         /* Control */
214         __le16 status;
215         __le32 time;
216         u8 silence;
217         u8 signal;
218         u8 rate;
219         u8 rxflow;
220         __le32 reserved;
221
222         /* 802.11 header */
223         __le16 frame_ctl;
224         __le16 duration_id;
225         u8 addr1[ETH_ALEN];
226         u8 addr2[ETH_ALEN];
227         u8 addr3[ETH_ALEN];
228         __le16 seq_ctl;
229         u8 addr4[ETH_ALEN];
230
231         /* Data length */
232         __le16 data_len;
233 } __attribute__ ((packed));
234
235 /********************************************************************/
236 /* Function prototypes                                              */
237 /********************************************************************/
238
239 static int __orinoco_program_rids(struct net_device *dev);
240 static void __orinoco_set_multicast_list(struct net_device *dev);
241
242 /********************************************************************/
243 /* Internal helper functions                                        */
244 /********************************************************************/
245
246 static inline void set_port_type(struct orinoco_private *priv)
247 {
248         switch (priv->iw_mode) {
249         case IW_MODE_INFRA:
250                 priv->port_type = 1;
251                 priv->createibss = 0;
252                 break;
253         case IW_MODE_ADHOC:
254                 if (priv->prefer_port3) {
255                         priv->port_type = 3;
256                         priv->createibss = 0;
257                 } else {
258                         priv->port_type = priv->ibss_port;
259                         priv->createibss = 1;
260                 }
261                 break;
262         case IW_MODE_MONITOR:
263                 priv->port_type = 3;
264                 priv->createibss = 0;
265                 break;
266         default:
267                 printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
268                        priv->ndev->name);
269         }
270 }
271
272 /********************************************************************/
273 /* Device methods                                                   */
274 /********************************************************************/
275
276 static int orinoco_open(struct net_device *dev)
277 {
278         struct orinoco_private *priv = netdev_priv(dev);
279         unsigned long flags;
280         int err;
281
282         if (orinoco_lock(priv, &flags) != 0)
283                 return -EBUSY;
284
285         err = __orinoco_up(dev);
286
287         if (! err)
288                 priv->open = 1;
289
290         orinoco_unlock(priv, &flags);
291
292         return err;
293 }
294
295 static int orinoco_stop(struct net_device *dev)
296 {
297         struct orinoco_private *priv = netdev_priv(dev);
298         int err = 0;
299
300         /* We mustn't use orinoco_lock() here, because we need to be
301            able to close the interface even if hw_unavailable is set
302            (e.g. as we're released after a PC Card removal) */
303         spin_lock_irq(&priv->lock);
304
305         priv->open = 0;
306
307         err = __orinoco_down(dev);
308
309         spin_unlock_irq(&priv->lock);
310
311         return err;
312 }
313
314 static struct net_device_stats *orinoco_get_stats(struct net_device *dev)
315 {
316         struct orinoco_private *priv = netdev_priv(dev);
317         
318         return &priv->stats;
319 }
320
321 static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
322 {
323         struct orinoco_private *priv = netdev_priv(dev);
324         hermes_t *hw = &priv->hw;
325         struct iw_statistics *wstats = &priv->wstats;
326         int err;
327         unsigned long flags;
328
329         if (! netif_device_present(dev)) {
330                 printk(KERN_WARNING "%s: get_wireless_stats() called while device not present\n",
331                        dev->name);
332                 return NULL; /* FIXME: Can we do better than this? */
333         }
334
335         /* If busy, return the old stats.  Returning NULL may cause
336          * the interface to disappear from /proc/net/wireless */
337         if (orinoco_lock(priv, &flags) != 0)
338                 return wstats;
339
340         /* We can't really wait for the tallies inquiry command to
341          * complete, so we just use the previous results and trigger
342          * a new tallies inquiry command for next time - Jean II */
343         /* FIXME: Really we should wait for the inquiry to come back -
344          * as it is the stats we give don't make a whole lot of sense.
345          * Unfortunately, it's not clear how to do that within the
346          * wireless extensions framework: I think we're in user
347          * context, but a lock seems to be held by the time we get in
348          * here so we're not safe to sleep here. */
349         hermes_inquire(hw, HERMES_INQ_TALLIES);
350
351         if (priv->iw_mode == IW_MODE_ADHOC) {
352                 memset(&wstats->qual, 0, sizeof(wstats->qual));
353                 /* If a spy address is defined, we report stats of the
354                  * first spy address - Jean II */
355                 if (SPY_NUMBER(priv)) {
356                         wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
357                         wstats->qual.level = priv->spy_data.spy_stat[0].level;
358                         wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
359                         wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
360                 }
361         } else {
362                 struct {
363                         __le16 qual, signal, noise, unused;
364                 } __attribute__ ((packed)) cq;
365
366                 err = HERMES_READ_RECORD(hw, USER_BAP,
367                                          HERMES_RID_COMMSQUALITY, &cq);
368
369                 if (!err) {
370                         wstats->qual.qual = (int)le16_to_cpu(cq.qual);
371                         wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95;
372                         wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95;
373                         wstats->qual.updated = 7;
374                 }
375         }
376
377         orinoco_unlock(priv, &flags);
378         return wstats;
379 }
380
381 static void orinoco_set_multicast_list(struct net_device *dev)
382 {
383         struct orinoco_private *priv = netdev_priv(dev);
384         unsigned long flags;
385
386         if (orinoco_lock(priv, &flags) != 0) {
387                 printk(KERN_DEBUG "%s: orinoco_set_multicast_list() "
388                        "called when hw_unavailable\n", dev->name);
389                 return;
390         }
391
392         __orinoco_set_multicast_list(dev);
393         orinoco_unlock(priv, &flags);
394 }
395
396 static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
397 {
398         struct orinoco_private *priv = netdev_priv(dev);
399
400         if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
401                 return -EINVAL;
402
403         if ( (new_mtu + ENCAPS_OVERHEAD + IEEE80211_HLEN) >
404              (priv->nicbuf_size - ETH_HLEN) )
405                 return -EINVAL;
406
407         dev->mtu = new_mtu;
408
409         return 0;
410 }
411
412 /********************************************************************/
413 /* Tx path                                                          */
414 /********************************************************************/
415
416 static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
417 {
418         struct orinoco_private *priv = netdev_priv(dev);
419         struct net_device_stats *stats = &priv->stats;
420         hermes_t *hw = &priv->hw;
421         int err = 0;
422         u16 txfid = priv->txfid;
423         struct ethhdr *eh;
424         int data_off;
425         struct hermes_tx_descriptor desc;
426         unsigned long flags;
427
428         if (! netif_running(dev)) {
429                 printk(KERN_ERR "%s: Tx on stopped device!\n",
430                        dev->name);
431                 return NETDEV_TX_BUSY;
432         }
433         
434         if (netif_queue_stopped(dev)) {
435                 printk(KERN_DEBUG "%s: Tx while transmitter busy!\n", 
436                        dev->name);
437                 return NETDEV_TX_BUSY;
438         }
439         
440         if (orinoco_lock(priv, &flags) != 0) {
441                 printk(KERN_ERR "%s: orinoco_xmit() called while hw_unavailable\n",
442                        dev->name);
443                 return NETDEV_TX_BUSY;
444         }
445
446         if (! netif_carrier_ok(dev) || (priv->iw_mode == IW_MODE_MONITOR)) {
447                 /* Oops, the firmware hasn't established a connection,
448                    silently drop the packet (this seems to be the
449                    safest approach). */
450                 goto drop;
451         }
452
453         /* Check packet length */
454         if (skb->len < ETH_HLEN)
455                 goto drop;
456
457         eh = (struct ethhdr *)skb->data;
458
459         memset(&desc, 0, sizeof(desc));
460         desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX);
461         err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), txfid, 0);
462         if (err) {
463                 if (net_ratelimit())
464                         printk(KERN_ERR "%s: Error %d writing Tx descriptor "
465                                "to BAP\n", dev->name, err);
466                 goto busy;
467         }
468
469         /* Clear the 802.11 header and data length fields - some
470          * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
471          * if this isn't done. */
472         hermes_clear_words(hw, HERMES_DATA0,
473                            HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
474
475         /* Encapsulate Ethernet-II frames */
476         if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
477                 struct header_struct {
478                         struct ethhdr eth;      /* 802.3 header */
479                         u8 encap[6];            /* 802.2 header */
480                 } __attribute__ ((packed)) hdr;
481
482                 /* Strip destination and source from the data */
483                 skb_pull(skb, 2 * ETH_ALEN);
484                 data_off = HERMES_802_2_OFFSET + sizeof(encaps_hdr);
485
486                 /* And move them to a separate header */
487                 memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
488                 hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
489                 memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
490
491                 err = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
492                                         txfid, HERMES_802_3_OFFSET);
493                 if (err) {
494                         if (net_ratelimit())
495                                 printk(KERN_ERR "%s: Error %d writing packet "
496                                        "header to BAP\n", dev->name, err);
497                         goto busy;
498                 }
499         } else { /* IEEE 802.3 frame */
500                 data_off = HERMES_802_3_OFFSET;
501         }
502
503         err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
504                                 txfid, data_off);
505         if (err) {
506                 printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
507                        dev->name, err);
508                 goto busy;
509         }
510
511         /* Finally, we actually initiate the send */
512         netif_stop_queue(dev);
513
514         err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
515                                 txfid, NULL);
516         if (err) {
517                 netif_start_queue(dev);
518                 if (net_ratelimit())
519                         printk(KERN_ERR "%s: Error %d transmitting packet\n",
520                                 dev->name, err);
521                 goto busy;
522         }
523
524         dev->trans_start = jiffies;
525         stats->tx_bytes += data_off + skb->len;
526         goto ok;
527
528  drop:
529         stats->tx_errors++;
530         stats->tx_dropped++;
531
532  ok:
533         orinoco_unlock(priv, &flags);
534         dev_kfree_skb(skb);
535         return NETDEV_TX_OK;
536
537  busy:
538         if (err == -EIO)
539                 schedule_work(&priv->reset_work);
540         orinoco_unlock(priv, &flags);
541         return NETDEV_TX_BUSY;
542 }
543
544 static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
545 {
546         struct orinoco_private *priv = netdev_priv(dev);
547         u16 fid = hermes_read_regn(hw, ALLOCFID);
548
549         if (fid != priv->txfid) {
550                 if (fid != DUMMY_FID)
551                         printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
552                                dev->name, fid);
553                 return;
554         }
555
556         hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
557 }
558
559 static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
560 {
561         struct orinoco_private *priv = netdev_priv(dev);
562         struct net_device_stats *stats = &priv->stats;
563
564         stats->tx_packets++;
565
566         netif_wake_queue(dev);
567
568         hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
569 }
570
571 static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
572 {
573         struct orinoco_private *priv = netdev_priv(dev);
574         struct net_device_stats *stats = &priv->stats;
575         u16 fid = hermes_read_regn(hw, TXCOMPLFID);
576         u16 status;
577         struct hermes_txexc_data hdr;
578         int err = 0;
579
580         if (fid == DUMMY_FID)
581                 return; /* Nothing's really happened */
582
583         /* Read part of the frame header - we need status and addr1 */
584         err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
585                                sizeof(struct hermes_txexc_data),
586                                fid, 0);
587
588         hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
589         stats->tx_errors++;
590
591         if (err) {
592                 printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
593                        "(FID=%04X error %d)\n",
594                        dev->name, fid, err);
595                 return;
596         }
597         
598         DEBUG(1, "%s: Tx error, err %d (FID=%04X)\n", dev->name,
599               err, fid);
600     
601         /* We produce a TXDROP event only for retry or lifetime
602          * exceeded, because that's the only status that really mean
603          * that this particular node went away.
604          * Other errors means that *we* screwed up. - Jean II */
605         status = le16_to_cpu(hdr.desc.status);
606         if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
607                 union iwreq_data        wrqu;
608
609                 /* Copy 802.11 dest address.
610                  * We use the 802.11 header because the frame may
611                  * not be 802.3 or may be mangled...
612                  * In Ad-Hoc mode, it will be the node address.
613                  * In managed mode, it will be most likely the AP addr
614                  * User space will figure out how to convert it to
615                  * whatever it needs (IP address or else).
616                  * - Jean II */
617                 memcpy(wrqu.addr.sa_data, hdr.addr1, ETH_ALEN);
618                 wrqu.addr.sa_family = ARPHRD_ETHER;
619
620                 /* Send event to user space */
621                 wireless_send_event(dev, IWEVTXDROP, &wrqu, NULL);
622         }
623
624         netif_wake_queue(dev);
625 }
626
627 static void orinoco_tx_timeout(struct net_device *dev)
628 {
629         struct orinoco_private *priv = netdev_priv(dev);
630         struct net_device_stats *stats = &priv->stats;
631         struct hermes *hw = &priv->hw;
632
633         printk(KERN_WARNING "%s: Tx timeout! "
634                "ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n",
635                dev->name, hermes_read_regn(hw, ALLOCFID),
636                hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
637
638         stats->tx_errors++;
639
640         schedule_work(&priv->reset_work);
641 }
642
643 /********************************************************************/
644 /* Rx path (data frames)                                            */
645 /********************************************************************/
646
647 /* Does the frame have a SNAP header indicating it should be
648  * de-encapsulated to Ethernet-II? */
649 static inline int is_ethersnap(void *_hdr)
650 {
651         u8 *hdr = _hdr;
652
653         /* We de-encapsulate all packets which, a) have SNAP headers
654          * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
655          * and where b) the OUI of the SNAP header is 00:00:00 or
656          * 00:00:f8 - we need both because different APs appear to use
657          * different OUIs for some reason */
658         return (memcmp(hdr, &encaps_hdr, 5) == 0)
659                 && ( (hdr[5] == 0x00) || (hdr[5] == 0xf8) );
660 }
661
662 static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
663                                       int level, int noise)
664 {
665         struct iw_quality wstats;
666         wstats.level = level - 0x95;
667         wstats.noise = noise - 0x95;
668         wstats.qual = (level > noise) ? (level - noise) : 0;
669         wstats.updated = 7;
670         /* Update spy records */
671         wireless_spy_update(dev, mac, &wstats);
672 }
673
674 static void orinoco_stat_gather(struct net_device *dev,
675                                 struct sk_buff *skb,
676                                 struct hermes_rx_descriptor *desc)
677 {
678         struct orinoco_private *priv = netdev_priv(dev);
679
680         /* Using spy support with lots of Rx packets, like in an
681          * infrastructure (AP), will really slow down everything, because
682          * the MAC address must be compared to each entry of the spy list.
683          * If the user really asks for it (set some address in the
684          * spy list), we do it, but he will pay the price.
685          * Note that to get here, you need both WIRELESS_SPY
686          * compiled in AND some addresses in the list !!!
687          */
688         /* Note : gcc will optimise the whole section away if
689          * WIRELESS_SPY is not defined... - Jean II */
690         if (SPY_NUMBER(priv)) {
691                 orinoco_spy_gather(dev, skb->mac.raw + ETH_ALEN,
692                                    desc->signal, desc->silence);
693         }
694 }
695
696 /*
697  * orinoco_rx_monitor - handle received monitor frames.
698  *
699  * Arguments:
700  *      dev             network device
701  *      rxfid           received FID
702  *      desc            rx descriptor of the frame
703  *
704  * Call context: interrupt
705  */
706 static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
707                                struct hermes_rx_descriptor *desc)
708 {
709         u32 hdrlen = 30;        /* return full header by default */
710         u32 datalen = 0;
711         u16 fc;
712         int err;
713         int len;
714         struct sk_buff *skb;
715         struct orinoco_private *priv = netdev_priv(dev);
716         struct net_device_stats *stats = &priv->stats;
717         hermes_t *hw = &priv->hw;
718
719         len = le16_to_cpu(desc->data_len);
720
721         /* Determine the size of the header and the data */
722         fc = le16_to_cpu(desc->frame_ctl);
723         switch (fc & IEEE80211_FCTL_FTYPE) {
724         case IEEE80211_FTYPE_DATA:
725                 if ((fc & IEEE80211_FCTL_TODS)
726                     && (fc & IEEE80211_FCTL_FROMDS))
727                         hdrlen = 30;
728                 else
729                         hdrlen = 24;
730                 datalen = len;
731                 break;
732         case IEEE80211_FTYPE_MGMT:
733                 hdrlen = 24;
734                 datalen = len;
735                 break;
736         case IEEE80211_FTYPE_CTL:
737                 switch (fc & IEEE80211_FCTL_STYPE) {
738                 case IEEE80211_STYPE_PSPOLL:
739                 case IEEE80211_STYPE_RTS:
740                 case IEEE80211_STYPE_CFEND:
741                 case IEEE80211_STYPE_CFENDACK:
742                         hdrlen = 16;
743                         break;
744                 case IEEE80211_STYPE_CTS:
745                 case IEEE80211_STYPE_ACK:
746                         hdrlen = 10;
747                         break;
748                 }
749                 break;
750         default:
751                 /* Unknown frame type */
752                 break;
753         }
754
755         /* sanity check the length */
756         if (datalen > IEEE80211_DATA_LEN + 12) {
757                 printk(KERN_DEBUG "%s: oversized monitor frame, "
758                        "data length = %d\n", dev->name, datalen);
759                 stats->rx_length_errors++;
760                 goto update_stats;
761         }
762
763         skb = dev_alloc_skb(hdrlen + datalen);
764         if (!skb) {
765                 printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
766                        dev->name);
767                 goto update_stats;
768         }
769
770         /* Copy the 802.11 header to the skb */
771         memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
772         skb->mac.raw = skb->data;
773
774         /* If any, copy the data from the card to the skb */
775         if (datalen > 0) {
776                 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
777                                        ALIGN(datalen, 2), rxfid,
778                                        HERMES_802_2_OFFSET);
779                 if (err) {
780                         printk(KERN_ERR "%s: error %d reading monitor frame\n",
781                                dev->name, err);
782                         goto drop;
783                 }
784         }
785
786         skb->dev = dev;
787         skb->ip_summed = CHECKSUM_NONE;
788         skb->pkt_type = PACKET_OTHERHOST;
789         skb->protocol = __constant_htons(ETH_P_802_2);
790         
791         dev->last_rx = jiffies;
792         stats->rx_packets++;
793         stats->rx_bytes += skb->len;
794
795         netif_rx(skb);
796         return;
797
798  drop:
799         dev_kfree_skb_irq(skb);
800  update_stats:
801         stats->rx_errors++;
802         stats->rx_dropped++;
803 }
804
805 static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
806 {
807         struct orinoco_private *priv = netdev_priv(dev);
808         struct net_device_stats *stats = &priv->stats;
809         struct iw_statistics *wstats = &priv->wstats;
810         struct sk_buff *skb = NULL;
811         u16 rxfid, status, fc;
812         int length;
813         struct hermes_rx_descriptor desc;
814         struct ethhdr *hdr;
815         int err;
816
817         rxfid = hermes_read_regn(hw, RXFID);
818
819         err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc),
820                                rxfid, 0);
821         if (err) {
822                 printk(KERN_ERR "%s: error %d reading Rx descriptor. "
823                        "Frame dropped.\n", dev->name, err);
824                 goto update_stats;
825         }
826
827         status = le16_to_cpu(desc.status);
828
829         if (status & HERMES_RXSTAT_BADCRC) {
830                 DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n",
831                       dev->name);
832                 stats->rx_crc_errors++;
833                 goto update_stats;
834         }
835
836         /* Handle frames in monitor mode */
837         if (priv->iw_mode == IW_MODE_MONITOR) {
838                 orinoco_rx_monitor(dev, rxfid, &desc);
839                 return;
840         }
841
842         if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
843                 DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
844                       dev->name);
845                 wstats->discard.code++;
846                 goto update_stats;
847         }
848
849         length = le16_to_cpu(desc.data_len);
850         fc = le16_to_cpu(desc.frame_ctl);
851
852         /* Sanity checks */
853         if (length < 3) { /* No for even an 802.2 LLC header */
854                 /* At least on Symbol firmware with PCF we get quite a
855                    lot of these legitimately - Poll frames with no
856                    data. */
857                 return;
858         }
859         if (length > IEEE80211_DATA_LEN) {
860                 printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
861                        dev->name, length);
862                 stats->rx_length_errors++;
863                 goto update_stats;
864         }
865
866         /* We need space for the packet data itself, plus an ethernet
867            header, plus 2 bytes so we can align the IP header on a
868            32bit boundary, plus 1 byte so we can read in odd length
869            packets from the card, which has an IO granularity of 16
870            bits */  
871         skb = dev_alloc_skb(length+ETH_HLEN+2+1);
872         if (!skb) {
873                 printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
874                        dev->name);
875                 goto update_stats;
876         }
877
878         /* We'll prepend the header, so reserve space for it.  The worst
879            case is no decapsulation, when 802.3 header is prepended and
880            nothing is removed.  2 is for aligning the IP header.  */
881         skb_reserve(skb, ETH_HLEN + 2);
882
883         err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length),
884                                ALIGN(length, 2), rxfid,
885                                HERMES_802_2_OFFSET);
886         if (err) {
887                 printk(KERN_ERR "%s: error %d reading frame. "
888                        "Frame dropped.\n", dev->name, err);
889                 goto drop;
890         }
891
892         /* Handle decapsulation
893          * In most cases, the firmware tell us about SNAP frames.
894          * For some reason, the SNAP frames sent by LinkSys APs
895          * are not properly recognised by most firmwares.
896          * So, check ourselves */
897         if (length >= ENCAPS_OVERHEAD &&
898             (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
899              ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
900              is_ethersnap(skb->data))) {
901                 /* These indicate a SNAP within 802.2 LLC within
902                    802.11 frame which we'll need to de-encapsulate to
903                    the original EthernetII frame. */
904                 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN - ENCAPS_OVERHEAD);
905         } else {
906                 /* 802.3 frame - prepend 802.3 header as is */
907                 hdr = (struct ethhdr *)skb_push(skb, ETH_HLEN);
908                 hdr->h_proto = htons(length);
909         }
910         memcpy(hdr->h_dest, desc.addr1, ETH_ALEN);
911         if (fc & IEEE80211_FCTL_FROMDS)
912                 memcpy(hdr->h_source, desc.addr3, ETH_ALEN);
913         else
914                 memcpy(hdr->h_source, desc.addr2, ETH_ALEN);
915
916         dev->last_rx = jiffies;
917         skb->dev = dev;
918         skb->protocol = eth_type_trans(skb, dev);
919         skb->ip_summed = CHECKSUM_NONE;
920         if (fc & IEEE80211_FCTL_TODS)
921                 skb->pkt_type = PACKET_OTHERHOST;
922         
923         /* Process the wireless stats if needed */
924         orinoco_stat_gather(dev, skb, &desc);
925
926         /* Pass the packet to the networking stack */
927         netif_rx(skb);
928         stats->rx_packets++;
929         stats->rx_bytes += length;
930
931         return;
932
933  drop:  
934         dev_kfree_skb_irq(skb);
935  update_stats:
936         stats->rx_errors++;
937         stats->rx_dropped++;
938 }
939
940 /********************************************************************/
941 /* Rx path (info frames)                                            */
942 /********************************************************************/
943
944 static void print_linkstatus(struct net_device *dev, u16 status)
945 {
946         char * s;
947
948         if (suppress_linkstatus)
949                 return;
950
951         switch (status) {
952         case HERMES_LINKSTATUS_NOT_CONNECTED:
953                 s = "Not Connected";
954                 break;
955         case HERMES_LINKSTATUS_CONNECTED:
956                 s = "Connected";
957                 break;
958         case HERMES_LINKSTATUS_DISCONNECTED:
959                 s = "Disconnected";
960                 break;
961         case HERMES_LINKSTATUS_AP_CHANGE:
962                 s = "AP Changed";
963                 break;
964         case HERMES_LINKSTATUS_AP_OUT_OF_RANGE:
965                 s = "AP Out of Range";
966                 break;
967         case HERMES_LINKSTATUS_AP_IN_RANGE:
968                 s = "AP In Range";
969                 break;
970         case HERMES_LINKSTATUS_ASSOC_FAILED:
971                 s = "Association Failed";
972                 break;
973         default:
974                 s = "UNKNOWN";
975         }
976         
977         printk(KERN_INFO "%s: New link status: %s (%04x)\n",
978                dev->name, s, status);
979 }
980
981 /* Search scan results for requested BSSID, join it if found */
982 static void orinoco_join_ap(struct net_device *dev)
983 {
984         struct orinoco_private *priv = netdev_priv(dev);
985         struct hermes *hw = &priv->hw;
986         int err;
987         unsigned long flags;
988         struct join_req {
989                 u8 bssid[ETH_ALEN];
990                 __le16 channel;
991         } __attribute__ ((packed)) req;
992         const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
993         struct prism2_scan_apinfo *atom = NULL;
994         int offset = 4;
995         int found = 0;
996         u8 *buf;
997         u16 len;
998
999         /* Allocate buffer for scan results */
1000         buf = kmalloc(MAX_SCAN_LEN, GFP_KERNEL);
1001         if (! buf)
1002                 return;
1003
1004         if (orinoco_lock(priv, &flags) != 0)
1005                 goto fail_lock;
1006
1007         /* Sanity checks in case user changed something in the meantime */
1008         if (! priv->bssid_fixed)
1009                 goto out;
1010
1011         if (strlen(priv->desired_essid) == 0)
1012                 goto out;
1013
1014         /* Read scan results from the firmware */
1015         err = hermes_read_ltv(hw, USER_BAP,
1016                               HERMES_RID_SCANRESULTSTABLE,
1017                               MAX_SCAN_LEN, &len, buf);
1018         if (err) {
1019                 printk(KERN_ERR "%s: Cannot read scan results\n",
1020                        dev->name);
1021                 goto out;
1022         }
1023
1024         len = HERMES_RECLEN_TO_BYTES(len);
1025
1026         /* Go through the scan results looking for the channel of the AP
1027          * we were requested to join */
1028         for (; offset + atom_len <= len; offset += atom_len) {
1029                 atom = (struct prism2_scan_apinfo *) (buf + offset);
1030                 if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
1031                         found = 1;
1032                         break;
1033                 }
1034         }
1035
1036         if (! found) {
1037                 DEBUG(1, "%s: Requested AP not found in scan results\n",
1038                       dev->name);
1039                 goto out;
1040         }
1041
1042         memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
1043         req.channel = atom->channel;    /* both are little-endian */
1044         err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
1045                                   &req);
1046         if (err)
1047                 printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
1048
1049  out:
1050         orinoco_unlock(priv, &flags);
1051
1052  fail_lock:
1053         kfree(buf);
1054 }
1055
1056 /* Send new BSSID to userspace */
1057 static void orinoco_send_wevents(struct net_device *dev)
1058 {
1059         struct orinoco_private *priv = netdev_priv(dev);
1060         struct hermes *hw = &priv->hw;
1061         union iwreq_data wrqu;
1062         int err;
1063         unsigned long flags;
1064
1065         if (orinoco_lock(priv, &flags) != 0)
1066                 return;
1067
1068         err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
1069                               ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
1070         if (err != 0)
1071                 goto out;
1072
1073         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1074
1075         /* Send event to user space */
1076         wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
1077
1078  out:
1079         orinoco_unlock(priv, &flags);
1080 }
1081
1082 static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1083 {
1084         struct orinoco_private *priv = netdev_priv(dev);
1085         u16 infofid;
1086         struct {
1087                 __le16 len;
1088                 __le16 type;
1089         } __attribute__ ((packed)) info;
1090         int len, type;
1091         int err;
1092
1093         /* This is an answer to an INQUIRE command that we did earlier,
1094          * or an information "event" generated by the card
1095          * The controller return to us a pseudo frame containing
1096          * the information in question - Jean II */
1097         infofid = hermes_read_regn(hw, INFOFID);
1098
1099         /* Read the info frame header - don't try too hard */
1100         err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info),
1101                                infofid, 0);
1102         if (err) {
1103                 printk(KERN_ERR "%s: error %d reading info frame. "
1104                        "Frame dropped.\n", dev->name, err);
1105                 return;
1106         }
1107         
1108         len = HERMES_RECLEN_TO_BYTES(le16_to_cpu(info.len));
1109         type = le16_to_cpu(info.type);
1110
1111         switch (type) {
1112         case HERMES_INQ_TALLIES: {
1113                 struct hermes_tallies_frame tallies;
1114                 struct iw_statistics *wstats = &priv->wstats;
1115                 
1116                 if (len > sizeof(tallies)) {
1117                         printk(KERN_WARNING "%s: Tallies frame too long (%d bytes)\n",
1118                                dev->name, len);
1119                         len = sizeof(tallies);
1120                 }
1121                 
1122                 err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len,
1123                                        infofid, sizeof(info));
1124                 if (err)
1125                         break;
1126                 
1127                 /* Increment our various counters */
1128                 /* wstats->discard.nwid - no wrong BSSID stuff */
1129                 wstats->discard.code +=
1130                         le16_to_cpu(tallies.RxWEPUndecryptable);
1131                 if (len == sizeof(tallies))  
1132                         wstats->discard.code +=
1133                                 le16_to_cpu(tallies.RxDiscards_WEPICVError) +
1134                                 le16_to_cpu(tallies.RxDiscards_WEPExcluded);
1135                 wstats->discard.misc +=
1136                         le16_to_cpu(tallies.TxDiscardsWrongSA);
1137                 wstats->discard.fragment +=
1138                         le16_to_cpu(tallies.RxMsgInBadMsgFragments);
1139                 wstats->discard.retries +=
1140                         le16_to_cpu(tallies.TxRetryLimitExceeded);
1141                 /* wstats->miss.beacon - no match */
1142         }
1143         break;
1144         case HERMES_INQ_LINKSTATUS: {
1145                 struct hermes_linkstatus linkstatus;
1146                 u16 newstatus;
1147                 int connected;
1148
1149                 if (priv->iw_mode == IW_MODE_MONITOR)
1150                         break;
1151
1152                 if (len != sizeof(linkstatus)) {
1153                         printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
1154                                dev->name, len);
1155                         break;
1156                 }
1157
1158                 err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len,
1159                                        infofid, sizeof(info));
1160                 if (err)
1161                         break;
1162                 newstatus = le16_to_cpu(linkstatus.linkstatus);
1163
1164                 /* Symbol firmware uses "out of range" to signal that
1165                  * the hostscan frame can be requested.  */
1166                 if (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE &&
1167                     priv->firmware_type == FIRMWARE_TYPE_SYMBOL &&
1168                     priv->has_hostscan && priv->scan_inprogress) {
1169                         hermes_inquire(hw, HERMES_INQ_HOSTSCAN_SYMBOL);
1170                         break;
1171                 }
1172
1173                 connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
1174                         || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
1175                         || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
1176
1177                 if (connected)
1178                         netif_carrier_on(dev);
1179                 else if (!ignore_disconnect)
1180                         netif_carrier_off(dev);
1181
1182                 if (newstatus != priv->last_linkstatus) {
1183                         priv->last_linkstatus = newstatus;
1184                         print_linkstatus(dev, newstatus);
1185                         /* The info frame contains only one word which is the
1186                          * status (see hermes.h). The status is pretty boring
1187                          * in itself, that's why we export the new BSSID...
1188                          * Jean II */
1189                         schedule_work(&priv->wevent_work);
1190                 }
1191         }
1192         break;
1193         case HERMES_INQ_SCAN:
1194                 if (!priv->scan_inprogress && priv->bssid_fixed &&
1195                     priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
1196                         schedule_work(&priv->join_work);
1197                         break;
1198                 }
1199                 /* fall through */
1200         case HERMES_INQ_HOSTSCAN:
1201         case HERMES_INQ_HOSTSCAN_SYMBOL: {
1202                 /* Result of a scanning. Contains information about
1203                  * cells in the vicinity - Jean II */
1204                 union iwreq_data        wrqu;
1205                 unsigned char *buf;
1206
1207                 /* Sanity check */
1208                 if (len > 4096) {
1209                         printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
1210                                dev->name, len);
1211                         break;
1212                 }
1213
1214                 /* We are a strict producer. If the previous scan results
1215                  * have not been consumed, we just have to drop this
1216                  * frame. We can't remove the previous results ourselves,
1217                  * that would be *very* racy... Jean II */
1218                 if (priv->scan_result != NULL) {
1219                         printk(KERN_WARNING "%s: Previous scan results not consumed, dropping info frame.\n", dev->name);
1220                         break;
1221                 }
1222
1223                 /* Allocate buffer for results */
1224                 buf = kmalloc(len, GFP_ATOMIC);
1225                 if (buf == NULL)
1226                         /* No memory, so can't printk()... */
1227                         break;
1228
1229                 /* Read scan data */
1230                 err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
1231                                        infofid, sizeof(info));
1232                 if (err) {
1233                         kfree(buf);
1234                         break;
1235                 }
1236
1237 #ifdef ORINOCO_DEBUG
1238                 {
1239                         int     i;
1240                         printk(KERN_DEBUG "Scan result [%02X", buf[0]);
1241                         for(i = 1; i < (len * 2); i++)
1242                                 printk(":%02X", buf[i]);
1243                         printk("]\n");
1244                 }
1245 #endif  /* ORINOCO_DEBUG */
1246
1247                 /* Allow the clients to access the results */
1248                 priv->scan_len = len;
1249                 priv->scan_result = buf;
1250
1251                 /* Send an empty event to user space.
1252                  * We don't send the received data on the event because
1253                  * it would require us to do complex transcoding, and
1254                  * we want to minimise the work done in the irq handler
1255                  * Use a request to extract the data - Jean II */
1256                 wrqu.data.length = 0;
1257                 wrqu.data.flags = 0;
1258                 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
1259         }
1260         break;
1261         case HERMES_INQ_SEC_STAT_AGERE:
1262                 /* Security status (Agere specific) */
1263                 /* Ignore this frame for now */
1264                 if (priv->firmware_type == FIRMWARE_TYPE_AGERE)
1265                         break;
1266                 /* fall through */
1267         default:
1268                 printk(KERN_DEBUG "%s: Unknown information frame received: "
1269                        "type 0x%04x, length %d\n", dev->name, type, len);
1270                 /* We don't actually do anything about it */
1271                 break;
1272         }
1273 }
1274
1275 static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
1276 {
1277         if (net_ratelimit())
1278                 printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
1279 }
1280
1281 /********************************************************************/
1282 /* Internal hardware control routines                               */
1283 /********************************************************************/
1284
1285 int __orinoco_up(struct net_device *dev)
1286 {
1287         struct orinoco_private *priv = netdev_priv(dev);
1288         struct hermes *hw = &priv->hw;
1289         int err;
1290
1291         netif_carrier_off(dev); /* just to make sure */
1292
1293         err = __orinoco_program_rids(dev);
1294         if (err) {
1295                 printk(KERN_ERR "%s: Error %d configuring card\n",
1296                        dev->name, err);
1297                 return err;
1298         }
1299
1300         /* Fire things up again */
1301         hermes_set_irqmask(hw, ORINOCO_INTEN);
1302         err = hermes_enable_port(hw, 0);
1303         if (err) {
1304                 printk(KERN_ERR "%s: Error %d enabling MAC port\n",
1305                        dev->name, err);
1306                 return err;
1307         }
1308
1309         netif_start_queue(dev);
1310
1311         return 0;
1312 }
1313
1314 int __orinoco_down(struct net_device *dev)
1315 {
1316         struct orinoco_private *priv = netdev_priv(dev);
1317         struct hermes *hw = &priv->hw;
1318         int err;
1319
1320         netif_stop_queue(dev);
1321
1322         if (! priv->hw_unavailable) {
1323                 if (! priv->broken_disableport) {
1324                         err = hermes_disable_port(hw, 0);
1325                         if (err) {
1326                                 /* Some firmwares (e.g. Intersil 1.3.x) seem
1327                                  * to have problems disabling the port, oh
1328                                  * well, too bad. */
1329                                 printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
1330                                        dev->name, err);
1331                                 priv->broken_disableport = 1;
1332                         }
1333                 }
1334                 hermes_set_irqmask(hw, 0);
1335                 hermes_write_regn(hw, EVACK, 0xffff);
1336         }
1337         
1338         /* firmware will have to reassociate */
1339         netif_carrier_off(dev);
1340         priv->last_linkstatus = 0xffff;
1341
1342         return 0;
1343 }
1344
1345 static int orinoco_allocate_fid(struct net_device *dev)
1346 {
1347         struct orinoco_private *priv = netdev_priv(dev);
1348         struct hermes *hw = &priv->hw;
1349         int err;
1350
1351         err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
1352         if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
1353                 /* Try workaround for old Symbol firmware bug */
1354                 printk(KERN_WARNING "%s: firmware ALLOC bug detected "
1355                        "(old Symbol firmware?). Trying to work around... ",
1356                        dev->name);
1357                 
1358                 priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
1359                 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
1360                 if (err)
1361                         printk("failed!\n");
1362                 else
1363                         printk("ok.\n");
1364         }
1365
1366         return err;
1367 }
1368
1369 int orinoco_reinit_firmware(struct net_device *dev)
1370 {
1371         struct orinoco_private *priv = netdev_priv(dev);
1372         struct hermes *hw = &priv->hw;
1373         int err;
1374
1375         err = hermes_init(hw);
1376         if (!err)
1377                 err = orinoco_allocate_fid(dev);
1378
1379         return err;
1380 }
1381
1382 static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
1383 {
1384         hermes_t *hw = &priv->hw;
1385         int err = 0;
1386
1387         if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
1388                 printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
1389                        priv->ndev->name, priv->bitratemode);
1390                 return -EINVAL;
1391         }
1392
1393         switch (priv->firmware_type) {
1394         case FIRMWARE_TYPE_AGERE:
1395                 err = hermes_write_wordrec(hw, USER_BAP,
1396                                            HERMES_RID_CNFTXRATECONTROL,
1397                                            bitrate_table[priv->bitratemode].agere_txratectrl);
1398                 break;
1399         case FIRMWARE_TYPE_INTERSIL:
1400         case FIRMWARE_TYPE_SYMBOL:
1401                 err = hermes_write_wordrec(hw, USER_BAP,
1402                                            HERMES_RID_CNFTXRATECONTROL,
1403                                            bitrate_table[priv->bitratemode].intersil_txratectrl);
1404                 break;
1405         default:
1406                 BUG();
1407         }
1408
1409         return err;
1410 }
1411
1412 /* Set fixed AP address */
1413 static int __orinoco_hw_set_wap(struct orinoco_private *priv)
1414 {
1415         int roaming_flag;
1416         int err = 0;
1417         hermes_t *hw = &priv->hw;
1418
1419         switch (priv->firmware_type) {
1420         case FIRMWARE_TYPE_AGERE:
1421                 /* not supported */
1422                 break;
1423         case FIRMWARE_TYPE_INTERSIL:
1424                 if (priv->bssid_fixed)
1425                         roaming_flag = 2;
1426                 else
1427                         roaming_flag = 1;
1428
1429                 err = hermes_write_wordrec(hw, USER_BAP,
1430                                            HERMES_RID_CNFROAMINGMODE,
1431                                            roaming_flag);
1432                 break;
1433         case FIRMWARE_TYPE_SYMBOL:
1434                 err = HERMES_WRITE_RECORD(hw, USER_BAP,
1435                                           HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
1436                                           &priv->desired_bssid);
1437                 break;
1438         }
1439         return err;
1440 }
1441
1442 /* Change the WEP keys and/or the current keys.  Can be called
1443  * either from __orinoco_hw_setup_wep() or directly from
1444  * orinoco_ioctl_setiwencode().  In the later case the association
1445  * with the AP is not broken (if the firmware can handle it),
1446  * which is needed for 802.1x implementations. */
1447 static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
1448 {
1449         hermes_t *hw = &priv->hw;
1450         int err = 0;
1451
1452         switch (priv->firmware_type) {
1453         case FIRMWARE_TYPE_AGERE:
1454                 err = HERMES_WRITE_RECORD(hw, USER_BAP,
1455                                           HERMES_RID_CNFWEPKEYS_AGERE,
1456                                           &priv->keys);
1457                 if (err)
1458                         return err;
1459                 err = hermes_write_wordrec(hw, USER_BAP,
1460                                            HERMES_RID_CNFTXKEY_AGERE,
1461                                            priv->tx_key);
1462                 if (err)
1463                         return err;
1464                 break;
1465         case FIRMWARE_TYPE_INTERSIL:
1466         case FIRMWARE_TYPE_SYMBOL:
1467                 {
1468                         int keylen;
1469                         int i;
1470
1471                         /* Force uniform key length to work around firmware bugs */
1472                         keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
1473                         
1474                         if (keylen > LARGE_KEY_SIZE) {
1475                                 printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
1476                                        priv->ndev->name, priv->tx_key, keylen);
1477                                 return -E2BIG;
1478                         }
1479
1480                         /* Write all 4 keys */
1481                         for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
1482                                 err = hermes_write_ltv(hw, USER_BAP,
1483                                                        HERMES_RID_CNFDEFAULTKEY0 + i,
1484                                                        HERMES_BYTES_TO_RECLEN(keylen),
1485                                                        priv->keys[i].data);
1486                                 if (err)
1487                                         return err;
1488                         }
1489
1490                         /* Write the index of the key used in transmission */
1491                         err = hermes_write_wordrec(hw, USER_BAP,
1492                                                    HERMES_RID_CNFWEPDEFAULTKEYID,
1493                                                    priv->tx_key);
1494                         if (err)
1495                                 return err;
1496                 }
1497                 break;
1498         }
1499
1500         return 0;
1501 }
1502
1503 static int __orinoco_hw_setup_wep(struct orinoco_private *priv)
1504 {
1505         hermes_t *hw = &priv->hw;
1506         int err = 0;
1507         int master_wep_flag;
1508         int auth_flag;
1509
1510         if (priv->wep_on)
1511                 __orinoco_hw_setup_wepkeys(priv);
1512
1513         if (priv->wep_restrict)
1514                 auth_flag = HERMES_AUTH_SHARED_KEY;
1515         else
1516                 auth_flag = HERMES_AUTH_OPEN;
1517
1518         switch (priv->firmware_type) {
1519         case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
1520                 if (priv->wep_on) {
1521                         /* Enable the shared-key authentication. */
1522                         err = hermes_write_wordrec(hw, USER_BAP,
1523                                                    HERMES_RID_CNFAUTHENTICATION_AGERE,
1524                                                    auth_flag);
1525                 }
1526                 err = hermes_write_wordrec(hw, USER_BAP,
1527                                            HERMES_RID_CNFWEPENABLED_AGERE,
1528                                            priv->wep_on);
1529                 if (err)
1530                         return err;
1531                 break;
1532
1533         case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
1534         case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
1535                 if (priv->wep_on) {
1536                         if (priv->wep_restrict ||
1537                             (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
1538                                 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
1539                                                   HERMES_WEP_EXCL_UNENCRYPTED;
1540                         else
1541                                 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
1542
1543                         err = hermes_write_wordrec(hw, USER_BAP,
1544                                                    HERMES_RID_CNFAUTHENTICATION,
1545                                                    auth_flag);
1546                         if (err)
1547                                 return err;
1548                 } else
1549                         master_wep_flag = 0;
1550
1551                 if (priv->iw_mode == IW_MODE_MONITOR)
1552                         master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
1553
1554                 /* Master WEP setting : on/off */
1555                 err = hermes_write_wordrec(hw, USER_BAP,
1556                                            HERMES_RID_CNFWEPFLAGS_INTERSIL,
1557                                            master_wep_flag);
1558                 if (err)
1559                         return err;     
1560
1561                 break;
1562         }
1563
1564         return 0;
1565 }
1566
1567 static int __orinoco_program_rids(struct net_device *dev)
1568 {
1569         struct orinoco_private *priv = netdev_priv(dev);
1570         hermes_t *hw = &priv->hw;
1571         int err;
1572         struct hermes_idstring idbuf;
1573
1574         /* Set the MAC address */
1575         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
1576                                HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr);
1577         if (err) {
1578                 printk(KERN_ERR "%s: Error %d setting MAC address\n",
1579                        dev->name, err);
1580                 return err;
1581         }
1582
1583         /* Set up the link mode */
1584         err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFPORTTYPE,
1585                                    priv->port_type);
1586         if (err) {
1587                 printk(KERN_ERR "%s: Error %d setting port type\n",
1588                        dev->name, err);
1589                 return err;
1590         }
1591         /* Set the channel/frequency */
1592         if (priv->channel != 0 && priv->iw_mode != IW_MODE_INFRA) {
1593                 err = hermes_write_wordrec(hw, USER_BAP,
1594                                            HERMES_RID_CNFOWNCHANNEL,
1595                                            priv->channel);
1596                 if (err) {
1597                         printk(KERN_ERR "%s: Error %d setting channel %d\n",
1598                                dev->name, err, priv->channel);
1599                         return err;
1600                 }
1601         }
1602
1603         if (priv->has_ibss) {
1604                 u16 createibss;
1605
1606                 if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
1607                         printk(KERN_WARNING "%s: This firmware requires an "
1608                                "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
1609                         /* With wvlan_cs, in this case, we would crash.
1610                          * hopefully, this driver will behave better...
1611                          * Jean II */
1612                         createibss = 0;
1613                 } else {
1614                         createibss = priv->createibss;
1615                 }
1616                 
1617                 err = hermes_write_wordrec(hw, USER_BAP,
1618                                            HERMES_RID_CNFCREATEIBSS,
1619                                            createibss);
1620                 if (err) {
1621                         printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
1622                                dev->name, err);
1623                         return err;
1624                 }
1625         }
1626
1627         /* Set the desired BSSID */
1628         err = __orinoco_hw_set_wap(priv);
1629         if (err) {
1630                 printk(KERN_ERR "%s: Error %d setting AP address\n",
1631                        dev->name, err);
1632                 return err;
1633         }
1634         /* Set the desired ESSID */
1635         idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
1636         memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
1637         /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
1638         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
1639                                HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
1640                                &idbuf);
1641         if (err) {
1642                 printk(KERN_ERR "%s: Error %d setting OWNSSID\n",
1643                        dev->name, err);
1644                 return err;
1645         }
1646         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
1647                                HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
1648                                &idbuf);
1649         if (err) {
1650                 printk(KERN_ERR "%s: Error %d setting DESIREDSSID\n",
1651                        dev->name, err);
1652                 return err;
1653         }
1654
1655         /* Set the station name */
1656         idbuf.len = cpu_to_le16(strlen(priv->nick));
1657         memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
1658         err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
1659                                HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
1660                                &idbuf);
1661         if (err) {
1662                 printk(KERN_ERR "%s: Error %d setting nickname\n",
1663                        dev->name, err);
1664                 return err;
1665         }
1666
1667         /* Set AP density */
1668         if (priv->has_sensitivity) {
1669                 err = hermes_write_wordrec(hw, USER_BAP,
1670                                            HERMES_RID_CNFSYSTEMSCALE,
1671                                            priv->ap_density);
1672                 if (err) {
1673                         printk(KERN_WARNING "%s: Error %d setting SYSTEMSCALE.  "
1674                                "Disabling sensitivity control\n",
1675                                dev->name, err);
1676
1677                         priv->has_sensitivity = 0;
1678                 }
1679         }
1680
1681         /* Set RTS threshold */
1682         err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
1683                                    priv->rts_thresh);
1684         if (err) {
1685                 printk(KERN_ERR "%s: Error %d setting RTS threshold\n",
1686                        dev->name, err);
1687                 return err;
1688         }
1689
1690         /* Set fragmentation threshold or MWO robustness */
1691         if (priv->has_mwo)
1692                 err = hermes_write_wordrec(hw, USER_BAP,
1693                                            HERMES_RID_CNFMWOROBUST_AGERE,
1694                                            priv->mwo_robust);
1695         else
1696                 err = hermes_write_wordrec(hw, USER_BAP,
1697                                            HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
1698                                            priv->frag_thresh);
1699         if (err) {
1700                 printk(KERN_ERR "%s: Error %d setting fragmentation\n",
1701                        dev->name, err);
1702                 return err;
1703         }
1704
1705         /* Set bitrate */
1706         err = __orinoco_hw_set_bitrate(priv);
1707         if (err) {
1708                 printk(KERN_ERR "%s: Error %d setting bitrate\n",
1709                        dev->name, err);
1710                 return err;
1711         }
1712
1713         /* Set power management */
1714         if (priv->has_pm) {
1715                 err = hermes_write_wordrec(hw, USER_BAP,
1716                                            HERMES_RID_CNFPMENABLED,
1717                                            priv->pm_on);
1718                 if (err) {
1719                         printk(KERN_ERR "%s: Error %d setting up PM\n",
1720                                dev->name, err);
1721                         return err;
1722                 }
1723
1724                 err = hermes_write_wordrec(hw, USER_BAP,
1725                                            HERMES_RID_CNFMULTICASTRECEIVE,
1726                                            priv->pm_mcast);
1727                 if (err) {
1728                         printk(KERN_ERR "%s: Error %d setting up PM\n",
1729                                dev->name, err);
1730                         return err;
1731                 }
1732                 err = hermes_write_wordrec(hw, USER_BAP,
1733                                            HERMES_RID_CNFMAXSLEEPDURATION,
1734                                            priv->pm_period);
1735                 if (err) {
1736                         printk(KERN_ERR "%s: Error %d setting up PM\n",
1737                                dev->name, err);
1738                         return err;
1739                 }
1740                 err = hermes_write_wordrec(hw, USER_BAP,
1741                                            HERMES_RID_CNFPMHOLDOVERDURATION,
1742                                            priv->pm_timeout);
1743                 if (err) {
1744                         printk(KERN_ERR "%s: Error %d setting up PM\n",
1745                                dev->name, err);
1746                         return err;
1747                 }
1748         }
1749
1750         /* Set preamble - only for Symbol so far... */
1751         if (priv->has_preamble) {
1752                 err = hermes_write_wordrec(hw, USER_BAP,
1753                                            HERMES_RID_CNFPREAMBLE_SYMBOL,
1754                                            priv->preamble);
1755                 if (err) {
1756                         printk(KERN_ERR "%s: Error %d setting preamble\n",
1757                                dev->name, err);
1758                         return err;
1759                 }
1760         }
1761
1762         /* Set up encryption */
1763         if (priv->has_wep) {
1764                 err = __orinoco_hw_setup_wep(priv);
1765                 if (err) {
1766                         printk(KERN_ERR "%s: Error %d activating WEP\n",
1767                                dev->name, err);
1768                         return err;
1769                 }
1770         }
1771
1772         if (priv->iw_mode == IW_MODE_MONITOR) {
1773                 /* Enable monitor mode */
1774                 dev->type = ARPHRD_IEEE80211;
1775                 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 
1776                                             HERMES_TEST_MONITOR, 0, NULL);
1777         } else {
1778                 /* Disable monitor mode */
1779                 dev->type = ARPHRD_ETHER;
1780                 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
1781                                             HERMES_TEST_STOP, 0, NULL);
1782         }
1783         if (err)
1784                 return err;
1785
1786         /* Set promiscuity / multicast*/
1787         priv->promiscuous = 0;
1788         priv->mc_count = 0;
1789
1790         /* FIXME: what about netif_tx_lock */
1791         __orinoco_set_multicast_list(dev);
1792
1793         return 0;
1794 }
1795
1796 /* FIXME: return int? */
1797 static void
1798 __orinoco_set_multicast_list(struct net_device *dev)
1799 {
1800         struct orinoco_private *priv = netdev_priv(dev);
1801         hermes_t *hw = &priv->hw;
1802         int err = 0;
1803         int promisc, mc_count;
1804
1805         /* The Hermes doesn't seem to have an allmulti mode, so we go
1806          * into promiscuous mode and let the upper levels deal. */
1807         if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
1808              (dev->mc_count > MAX_MULTICAST(priv)) ) {
1809                 promisc = 1;
1810                 mc_count = 0;
1811         } else {
1812                 promisc = 0;
1813                 mc_count = dev->mc_count;
1814         }
1815
1816         if (promisc != priv->promiscuous) {
1817                 err = hermes_write_wordrec(hw, USER_BAP,
1818                                            HERMES_RID_CNFPROMISCUOUSMODE,
1819                                            promisc);
1820                 if (err) {
1821                         printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
1822                                dev->name, err);
1823                 } else 
1824                         priv->promiscuous = promisc;
1825         }
1826
1827         if (! promisc && (mc_count || priv->mc_count) ) {
1828                 struct dev_mc_list *p = dev->mc_list;
1829                 struct hermes_multicast mclist;
1830                 int i;
1831
1832                 for (i = 0; i < mc_count; i++) {
1833                         /* paranoia: is list shorter than mc_count? */
1834                         BUG_ON(! p);
1835                         /* paranoia: bad address size in list? */
1836                         BUG_ON(p->dmi_addrlen != ETH_ALEN);
1837                         
1838                         memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
1839                         p = p->next;
1840                 }
1841                 
1842                 if (p)
1843                         printk(KERN_WARNING "%s: Multicast list is "
1844                                "longer than mc_count\n", dev->name);
1845
1846                 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES,
1847                                        HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
1848                                        &mclist);
1849                 if (err)
1850                         printk(KERN_ERR "%s: Error %d setting multicast list.\n",
1851                                dev->name, err);
1852                 else
1853                         priv->mc_count = mc_count;
1854         }
1855
1856         /* Since we can set the promiscuous flag when it wasn't asked
1857            for, make sure the net_device knows about it. */
1858         if (priv->promiscuous)
1859                 dev->flags |= IFF_PROMISC;
1860         else
1861                 dev->flags &= ~IFF_PROMISC;
1862 }
1863
1864 /* This must be called from user context, without locks held - use
1865  * schedule_work() */
1866 static void orinoco_reset(struct net_device *dev)
1867 {
1868         struct orinoco_private *priv = netdev_priv(dev);
1869         struct hermes *hw = &priv->hw;
1870         int err;
1871         unsigned long flags;
1872
1873         if (orinoco_lock(priv, &flags) != 0)
1874                 /* When the hardware becomes available again, whatever
1875                  * detects that is responsible for re-initializing
1876                  * it. So no need for anything further */
1877                 return;
1878
1879         netif_stop_queue(dev);
1880
1881         /* Shut off interrupts.  Depending on what state the hardware
1882          * is in, this might not work, but we'll try anyway */
1883         hermes_set_irqmask(hw, 0);
1884         hermes_write_regn(hw, EVACK, 0xffff);
1885
1886         priv->hw_unavailable++;
1887         priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
1888         netif_carrier_off(dev);
1889
1890         orinoco_unlock(priv, &flags);
1891
1892         /* Scanning support: Cleanup of driver struct */
1893         kfree(priv->scan_result);
1894         priv->scan_result = NULL;
1895         priv->scan_inprogress = 0;
1896
1897         if (priv->hard_reset) {
1898                 err = (*priv->hard_reset)(priv);
1899                 if (err) {
1900                         printk(KERN_ERR "%s: orinoco_reset: Error %d "
1901                                "performing hard reset\n", dev->name, err);
1902                         goto disable;
1903                 }
1904         }
1905
1906         err = orinoco_reinit_firmware(dev);
1907         if (err) {
1908                 printk(KERN_ERR "%s: orinoco_reset: Error %d re-initializing firmware\n",
1909                        dev->name, err);
1910                 goto disable;
1911         }
1912
1913         spin_lock_irq(&priv->lock); /* This has to be called from user context */
1914
1915         priv->hw_unavailable--;
1916
1917         /* priv->open or priv->hw_unavailable might have changed while
1918          * we dropped the lock */
1919         if (priv->open && (! priv->hw_unavailable)) {
1920                 err = __orinoco_up(dev);
1921                 if (err) {
1922                         printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
1923                                dev->name, err);
1924                 } else
1925                         dev->trans_start = jiffies;
1926         }
1927
1928         spin_unlock_irq(&priv->lock);
1929
1930         return;
1931  disable:
1932         hermes_set_irqmask(hw, 0);
1933         netif_device_detach(dev);
1934         printk(KERN_ERR "%s: Device has been disabled!\n", dev->name);
1935 }
1936
1937 /********************************************************************/
1938 /* Interrupt handler                                                */
1939 /********************************************************************/
1940
1941 static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
1942 {
1943         printk(KERN_DEBUG "%s: TICK\n", dev->name);
1944 }
1945
1946 static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
1947 {
1948         /* This seems to happen a fair bit under load, but ignoring it
1949            seems to work fine...*/
1950         printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
1951                dev->name);
1952 }
1953
1954 irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1955 {
1956         struct net_device *dev = (struct net_device *)dev_id;
1957         struct orinoco_private *priv = netdev_priv(dev);
1958         hermes_t *hw = &priv->hw;
1959         int count = MAX_IRQLOOPS_PER_IRQ;
1960         u16 evstat, events;
1961         /* These are used to detect a runaway interrupt situation */
1962         /* If we get more than MAX_IRQLOOPS_PER_JIFFY iterations in a jiffy,
1963          * we panic and shut down the hardware */
1964         static int last_irq_jiffy = 0; /* jiffies value the last time
1965                                         * we were called */
1966         static int loops_this_jiffy = 0;
1967         unsigned long flags;
1968
1969         if (orinoco_lock(priv, &flags) != 0) {
1970                 /* If hw is unavailable - we don't know if the irq was
1971                  * for us or not */
1972                 return IRQ_HANDLED;
1973         }
1974
1975         evstat = hermes_read_regn(hw, EVSTAT);
1976         events = evstat & hw->inten;
1977         if (! events) {
1978                 orinoco_unlock(priv, &flags);
1979                 return IRQ_NONE;
1980         }
1981         
1982         if (jiffies != last_irq_jiffy)
1983                 loops_this_jiffy = 0;
1984         last_irq_jiffy = jiffies;
1985
1986         while (events && count--) {
1987                 if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
1988                         printk(KERN_WARNING "%s: IRQ handler is looping too "
1989                                "much! Resetting.\n", dev->name);
1990                         /* Disable interrupts for now */
1991                         hermes_set_irqmask(hw, 0);
1992                         schedule_work(&priv->reset_work);
1993                         break;
1994                 }
1995
1996                 /* Check the card hasn't been removed */
1997                 if (! hermes_present(hw)) {
1998                         DEBUG(0, "orinoco_interrupt(): card removed\n");
1999                         break;
2000                 }
2001
2002                 if (events & HERMES_EV_TICK)
2003                         __orinoco_ev_tick(dev, hw);
2004                 if (events & HERMES_EV_WTERR)
2005                         __orinoco_ev_wterr(dev, hw);
2006                 if (events & HERMES_EV_INFDROP)
2007                         __orinoco_ev_infdrop(dev, hw);
2008                 if (events & HERMES_EV_INFO)
2009                         __orinoco_ev_info(dev, hw);
2010                 if (events & HERMES_EV_RX)
2011                         __orinoco_ev_rx(dev, hw);
2012                 if (events & HERMES_EV_TXEXC)
2013                         __orinoco_ev_txexc(dev, hw);
2014                 if (events & HERMES_EV_TX)
2015                         __orinoco_ev_tx(dev, hw);
2016                 if (events & HERMES_EV_ALLOC)
2017                         __orinoco_ev_alloc(dev, hw);
2018                 
2019                 hermes_write_regn(hw, EVACK, evstat);
2020
2021                 evstat = hermes_read_regn(hw, EVSTAT);
2022                 events = evstat & hw->inten;
2023         };
2024
2025         orinoco_unlock(priv, &flags);
2026         return IRQ_HANDLED;
2027 }
2028
2029 /********************************************************************/
2030 /* Initialization                                                   */
2031 /********************************************************************/
2032
2033 struct comp_id {
2034         u16 id, variant, major, minor;
2035 } __attribute__ ((packed));
2036
2037 static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
2038 {
2039         if (nic_id->id < 0x8000)
2040                 return FIRMWARE_TYPE_AGERE;
2041         else if (nic_id->id == 0x8000 && nic_id->major == 0)
2042                 return FIRMWARE_TYPE_SYMBOL;
2043         else
2044                 return FIRMWARE_TYPE_INTERSIL;
2045 }
2046
2047 /* Set priv->firmware type, determine firmware properties */
2048 static int determine_firmware(struct net_device *dev)
2049 {
2050         struct orinoco_private *priv = netdev_priv(dev);
2051         hermes_t *hw = &priv->hw;
2052         int err;
2053         struct comp_id nic_id, sta_id;
2054         unsigned int firmver;
2055         char tmp[SYMBOL_MAX_VER_LEN+1];
2056
2057         /* Get the hardware version */
2058         err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
2059         if (err) {
2060                 printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
2061                        dev->name, err);
2062                 return err;
2063         }
2064
2065         le16_to_cpus(&nic_id.id);
2066         le16_to_cpus(&nic_id.variant);
2067         le16_to_cpus(&nic_id.major);
2068         le16_to_cpus(&nic_id.minor);
2069         printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
2070                dev->name, nic_id.id, nic_id.variant,
2071                nic_id.major, nic_id.minor);
2072
2073         priv->firmware_type = determine_firmware_type(&nic_id);
2074
2075         /* Get the firmware version */
2076         err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
2077         if (err) {
2078                 printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
2079                        dev->name, err);
2080                 return err;
2081         }
2082
2083         le16_to_cpus(&sta_id.id);
2084         le16_to_cpus(&sta_id.variant);
2085         le16_to_cpus(&sta_id.major);
2086         le16_to_cpus(&sta_id.minor);
2087         printk(KERN_DEBUG "%s: Station identity  %04x:%04x:%04x:%04x\n",
2088                dev->name, sta_id.id, sta_id.variant,
2089                sta_id.major, sta_id.minor);
2090
2091         switch (sta_id.id) {
2092         case 0x15:
2093                 printk(KERN_ERR "%s: Primary firmware is active\n",
2094                        dev->name);
2095                 return -ENODEV;
2096         case 0x14b:
2097                 printk(KERN_ERR "%s: Tertiary firmware is active\n",
2098                        dev->name);
2099                 return -ENODEV;
2100         case 0x1f:      /* Intersil, Agere, Symbol Spectrum24 */
2101         case 0x21:      /* Symbol Spectrum24 Trilogy */
2102                 break;
2103         default:
2104                 printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
2105                        dev->name);
2106                 break;
2107         }
2108
2109         /* Default capabilities */
2110         priv->has_sensitivity = 1;
2111         priv->has_mwo = 0;
2112         priv->has_preamble = 0;
2113         priv->has_port3 = 1;
2114         priv->has_ibss = 1;
2115         priv->has_wep = 0;
2116         priv->has_big_wep = 0;
2117
2118         /* Determine capabilities from the firmware version */
2119         switch (priv->firmware_type) {
2120         case FIRMWARE_TYPE_AGERE:
2121                 /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
2122                    ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
2123                 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2124                          "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
2125
2126                 firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
2127
2128                 priv->has_ibss = (firmver >= 0x60006);
2129                 priv->has_wep = (firmver >= 0x40020);
2130                 priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
2131                                           Gold cards from the others? */
2132                 priv->has_mwo = (firmver >= 0x60000);
2133                 priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
2134                 priv->ibss_port = 1;
2135                 priv->has_hostscan = (firmver >= 0x8000a);
2136                 priv->broken_monitor = (firmver >= 0x80000);
2137
2138                 /* Tested with Agere firmware :
2139                  *      1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
2140                  * Tested CableTron firmware : 4.32 => Anton */
2141                 break;
2142         case FIRMWARE_TYPE_SYMBOL:
2143                 /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
2144                 /* Intel MAC : 00:02:B3:* */
2145                 /* 3Com MAC : 00:50:DA:* */
2146                 memset(tmp, 0, sizeof(tmp));
2147                 /* Get the Symbol firmware version */
2148                 err = hermes_read_ltv(hw, USER_BAP,
2149                                       HERMES_RID_SECONDARYVERSION_SYMBOL,
2150                                       SYMBOL_MAX_VER_LEN, NULL, &tmp);
2151                 if (err) {
2152                         printk(KERN_WARNING
2153                                "%s: Error %d reading Symbol firmware info. Wildly guessing capabilities...\n",
2154                                dev->name, err);
2155                         firmver = 0;
2156                         tmp[0] = '\0';
2157                 } else {
2158                         /* The firmware revision is a string, the format is
2159                          * something like : "V2.20-01".
2160                          * Quick and dirty parsing... - Jean II
2161                          */
2162                         firmver = ((tmp[1] - '0') << 16) | ((tmp[3] - '0') << 12)
2163                                 | ((tmp[4] - '0') << 8) | ((tmp[6] - '0') << 4)
2164                                 | (tmp[7] - '0');
2165
2166                         tmp[SYMBOL_MAX_VER_LEN] = '\0';
2167                 }
2168
2169                 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2170                          "Symbol %s", tmp);
2171
2172                 priv->has_ibss = (firmver >= 0x20000);
2173                 priv->has_wep = (firmver >= 0x15012);
2174                 priv->has_big_wep = (firmver >= 0x20000);
2175                 priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) || 
2176                                (firmver >= 0x29000 && firmver < 0x30000) ||
2177                                firmver >= 0x31000;
2178                 priv->has_preamble = (firmver >= 0x20000);
2179                 priv->ibss_port = 4;
2180                 priv->broken_disableport = (firmver == 0x25013) ||
2181                                            (firmver >= 0x30000 && firmver <= 0x31000);
2182                 priv->has_hostscan = (firmver >= 0x31001) ||
2183                                      (firmver >= 0x29057 && firmver < 0x30000);
2184                 /* Tested with Intel firmware : 0x20015 => Jean II */
2185                 /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
2186                 break;
2187         case FIRMWARE_TYPE_INTERSIL:
2188                 /* D-Link, Linksys, Adtron, ZoomAir, and many others...
2189                  * Samsung, Compaq 100/200 and Proxim are slightly
2190                  * different and less well tested */
2191                 /* D-Link MAC : 00:40:05:* */
2192                 /* Addtron MAC : 00:90:D1:* */
2193                 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
2194                          "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
2195                          sta_id.variant);
2196
2197                 firmver = ((unsigned long)sta_id.major << 16) |
2198                         ((unsigned long)sta_id.minor << 8) | sta_id.variant;
2199
2200                 priv->has_ibss = (firmver >= 0x000700); /* FIXME */
2201                 priv->has_big_wep = priv->has_wep = (firmver >= 0x000800);
2202                 priv->has_pm = (firmver >= 0x000700);
2203                 priv->has_hostscan = (firmver >= 0x010301);
2204
2205                 if (firmver >= 0x000800)
2206                         priv->ibss_port = 0;
2207                 else {
2208                         printk(KERN_NOTICE "%s: Intersil firmware earlier "
2209                                "than v0.8.x - several features not supported\n",
2210                                dev->name);
2211                         priv->ibss_port = 1;
2212                 }
2213                 break;
2214         }
2215         printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
2216                priv->fw_name);
2217
2218         return 0;
2219 }
2220
2221 static int orinoco_init(struct net_device *dev)
2222 {
2223         struct orinoco_private *priv = netdev_priv(dev);
2224         hermes_t *hw = &priv->hw;
2225         int err = 0;
2226         struct hermes_idstring nickbuf;
2227         u16 reclen;
2228         int len;
2229
2230         /* No need to lock, the hw_unavailable flag is already set in
2231          * alloc_orinocodev() */
2232         priv->nicbuf_size = IEEE80211_FRAME_LEN + ETH_HLEN;
2233
2234         /* Initialize the firmware */
2235         err = hermes_init(hw);
2236         if (err != 0) {
2237                 printk(KERN_ERR "%s: failed to initialize firmware (err = %d)\n",
2238                        dev->name, err);
2239                 goto out;
2240         }
2241
2242         err = determine_firmware(dev);
2243         if (err != 0) {
2244                 printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
2245                        dev->name);
2246                 goto out;
2247         }
2248
2249         if (priv->has_port3)
2250                 printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
2251         if (priv->has_ibss)
2252                 printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported\n",
2253                        dev->name);
2254         if (priv->has_wep) {
2255                 printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
2256                 if (priv->has_big_wep)
2257                         printk("104-bit key\n");
2258                 else
2259                         printk("40-bit key\n");
2260         }
2261
2262         /* Get the MAC address */
2263         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
2264                               ETH_ALEN, NULL, dev->dev_addr);
2265         if (err) {
2266                 printk(KERN_WARNING "%s: failed to read MAC address!\n",
2267                        dev->name);
2268                 goto out;
2269         }
2270
2271         printk(KERN_DEBUG "%s: MAC address %02X:%02X:%02X:%02X:%02X:%02X\n",
2272                dev->name, dev->dev_addr[0], dev->dev_addr[1],
2273                dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4],
2274                dev->dev_addr[5]);
2275
2276         /* Get the station name */
2277         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
2278                               sizeof(nickbuf), &reclen, &nickbuf);
2279         if (err) {
2280                 printk(KERN_ERR "%s: failed to read station name\n",
2281                        dev->name);
2282                 goto out;
2283         }
2284         if (nickbuf.len)
2285                 len = min(IW_ESSID_MAX_SIZE, (int)le16_to_cpu(nickbuf.len));
2286         else
2287                 len = min(IW_ESSID_MAX_SIZE, 2 * reclen);
2288         memcpy(priv->nick, &nickbuf.val, len);
2289         priv->nick[len] = '\0';
2290
2291         printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
2292
2293         err = orinoco_allocate_fid(dev);
2294         if (err) {
2295                 printk(KERN_ERR "%s: failed to allocate NIC buffer!\n",
2296                        dev->name);
2297                 goto out;
2298         }
2299
2300         /* Get allowed channels */
2301         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNELLIST,
2302                                   &priv->channel_mask);
2303         if (err) {
2304                 printk(KERN_ERR "%s: failed to read channel list!\n",
2305                        dev->name);
2306                 goto out;
2307         }
2308
2309         /* Get initial AP density */
2310         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
2311                                   &priv->ap_density);
2312         if (err || priv->ap_density < 1 || priv->ap_density > 3) {
2313                 priv->has_sensitivity = 0;
2314         }
2315
2316         /* Get initial RTS threshold */
2317         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD,
2318                                   &priv->rts_thresh);
2319         if (err) {
2320                 printk(KERN_ERR "%s: failed to read RTS threshold!\n",
2321                        dev->name);
2322                 goto out;
2323         }
2324
2325         /* Get initial fragmentation settings */
2326         if (priv->has_mwo)
2327                 err = hermes_read_wordrec(hw, USER_BAP,
2328                                           HERMES_RID_CNFMWOROBUST_AGERE,
2329                                           &priv->mwo_robust);
2330         else
2331                 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
2332                                           &priv->frag_thresh);
2333         if (err) {
2334                 printk(KERN_ERR "%s: failed to read fragmentation settings!\n",
2335                        dev->name);
2336                 goto out;
2337         }
2338
2339         /* Power management setup */
2340         if (priv->has_pm) {
2341                 priv->pm_on = 0;
2342                 priv->pm_mcast = 1;
2343                 err = hermes_read_wordrec(hw, USER_BAP,
2344                                           HERMES_RID_CNFMAXSLEEPDURATION,
2345                                           &priv->pm_period);
2346                 if (err) {
2347                         printk(KERN_ERR "%s: failed to read power management period!\n",
2348                                dev->name);
2349                         goto out;
2350                 }
2351                 err = hermes_read_wordrec(hw, USER_BAP,
2352                                           HERMES_RID_CNFPMHOLDOVERDURATION,
2353                                           &priv->pm_timeout);
2354                 if (err) {
2355                         printk(KERN_ERR "%s: failed to read power management timeout!\n",
2356                                dev->name);
2357                         goto out;
2358                 }
2359         }
2360
2361         /* Preamble setup */
2362         if (priv->has_preamble) {
2363                 err = hermes_read_wordrec(hw, USER_BAP,
2364                                           HERMES_RID_CNFPREAMBLE_SYMBOL,
2365                                           &priv->preamble);
2366                 if (err)
2367                         goto out;
2368         }
2369                 
2370         /* Set up the default configuration */
2371         priv->iw_mode = IW_MODE_INFRA;
2372         /* By default use IEEE/IBSS ad-hoc mode if we have it */
2373         priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
2374         set_port_type(priv);
2375         priv->channel = 0; /* use firmware default */
2376
2377         priv->promiscuous = 0;
2378         priv->wep_on = 0;
2379         priv->tx_key = 0;
2380
2381         /* Make the hardware available, as long as it hasn't been
2382          * removed elsewhere (e.g. by PCMCIA hot unplug) */
2383         spin_lock_irq(&priv->lock);
2384         priv->hw_unavailable--;
2385         spin_unlock_irq(&priv->lock);
2386
2387         printk(KERN_DEBUG "%s: ready\n", dev->name);
2388
2389  out:
2390         return err;
2391 }
2392
2393 struct net_device *alloc_orinocodev(int sizeof_card,
2394                                     int (*hard_reset)(struct orinoco_private *))
2395 {
2396         struct net_device *dev;
2397         struct orinoco_private *priv;
2398
2399         dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
2400         if (! dev)
2401                 return NULL;
2402         priv = netdev_priv(dev);
2403         priv->ndev = dev;
2404         if (sizeof_card)
2405                 priv->card = (void *)((unsigned long)priv
2406                                       + sizeof(struct orinoco_private));
2407         else
2408                 priv->card = NULL;
2409
2410         /* Setup / override net_device fields */
2411         dev->init = orinoco_init;
2412         dev->hard_start_xmit = orinoco_xmit;
2413         dev->tx_timeout = orinoco_tx_timeout;
2414         dev->watchdog_timeo = HZ; /* 1 second timeout */
2415         dev->get_stats = orinoco_get_stats;
2416         dev->ethtool_ops = &orinoco_ethtool_ops;
2417         dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
2418 #ifdef WIRELESS_SPY
2419         priv->wireless_data.spy_data = &priv->spy_data;
2420         dev->wireless_data = &priv->wireless_data;
2421 #endif
2422         dev->change_mtu = orinoco_change_mtu;
2423         dev->set_multicast_list = orinoco_set_multicast_list;
2424         /* we use the default eth_mac_addr for setting the MAC addr */
2425
2426         /* Set up default callbacks */
2427         dev->open = orinoco_open;
2428         dev->stop = orinoco_stop;
2429         priv->hard_reset = hard_reset;
2430
2431         spin_lock_init(&priv->lock);
2432         priv->open = 0;
2433         priv->hw_unavailable = 1; /* orinoco_init() must clear this
2434                                    * before anything else touches the
2435                                    * hardware */
2436         INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev);
2437         INIT_WORK(&priv->join_work, (void (*)(void *))orinoco_join_ap, dev);
2438         INIT_WORK(&priv->wevent_work, (void (*)(void *))orinoco_send_wevents, dev);
2439
2440         netif_carrier_off(dev);
2441         priv->last_linkstatus = 0xffff;
2442
2443         return dev;
2444
2445 }
2446
2447 void free_orinocodev(struct net_device *dev)
2448 {
2449         struct orinoco_private *priv = netdev_priv(dev);
2450
2451         kfree(priv->scan_result);
2452         free_netdev(dev);
2453 }
2454
2455 /********************************************************************/
2456 /* Wireless extensions                                              */
2457 /********************************************************************/
2458
2459 static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
2460                                 char buf[IW_ESSID_MAX_SIZE+1])
2461 {
2462         hermes_t *hw = &priv->hw;
2463         int err = 0;
2464         struct hermes_idstring essidbuf;
2465         char *p = (char *)(&essidbuf.val);
2466         int len;
2467         unsigned long flags;
2468
2469         if (orinoco_lock(priv, &flags) != 0)
2470                 return -EBUSY;
2471
2472         if (strlen(priv->desired_essid) > 0) {
2473                 /* We read the desired SSID from the hardware rather
2474                    than from priv->desired_essid, just in case the
2475                    firmware is allowed to change it on us. I'm not
2476                    sure about this */
2477                 /* My guess is that the OWNSSID should always be whatever
2478                  * we set to the card, whereas CURRENT_SSID is the one that
2479                  * may change... - Jean II */
2480                 u16 rid;
2481
2482                 *active = 1;
2483
2484                 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
2485                         HERMES_RID_CNFDESIREDSSID;
2486                 
2487                 err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
2488                                       NULL, &essidbuf);
2489                 if (err)
2490                         goto fail_unlock;
2491         } else {
2492                 *active = 0;
2493
2494                 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
2495                                       sizeof(essidbuf), NULL, &essidbuf);
2496                 if (err)
2497                         goto fail_unlock;
2498         }
2499
2500         len = le16_to_cpu(essidbuf.len);
2501         BUG_ON(len > IW_ESSID_MAX_SIZE);
2502
2503         memset(buf, 0, IW_ESSID_MAX_SIZE+1);
2504         memcpy(buf, p, len);
2505         buf[len] = '\0';
2506
2507  fail_unlock:
2508         orinoco_unlock(priv, &flags);
2509
2510         return err;       
2511 }
2512
2513 static long orinoco_hw_get_freq(struct orinoco_private *priv)
2514 {
2515         
2516         hermes_t *hw = &priv->hw;
2517         int err = 0;
2518         u16 channel;
2519         long freq = 0;
2520         unsigned long flags;
2521
2522         if (orinoco_lock(priv, &flags) != 0)
2523                 return -EBUSY;
2524         
2525         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
2526         if (err)
2527                 goto out;
2528
2529         /* Intersil firmware 1.3.5 returns 0 when the interface is down */
2530         if (channel == 0) {
2531                 err = -EBUSY;
2532                 goto out;
2533         }
2534
2535         if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
2536                 printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
2537                        priv->ndev->name, channel);
2538                 err = -EBUSY;
2539                 goto out;
2540
2541         }
2542         freq = channel_frequency[channel-1] * 100000;
2543
2544  out:
2545         orinoco_unlock(priv, &flags);
2546
2547         if (err > 0)
2548                 err = -EBUSY;
2549         return err ? err : freq;
2550 }
2551
2552 static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
2553                                       int *numrates, s32 *rates, int max)
2554 {
2555         hermes_t *hw = &priv->hw;
2556         struct hermes_idstring list;
2557         unsigned char *p = (unsigned char *)&list.val;
2558         int err = 0;
2559         int num;
2560         int i;
2561         unsigned long flags;
2562
2563         if (orinoco_lock(priv, &flags) != 0)
2564                 return -EBUSY;
2565
2566         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
2567                               sizeof(list), NULL, &list);
2568         orinoco_unlock(priv, &flags);
2569
2570         if (err)
2571                 return err;
2572         
2573         num = le16_to_cpu(list.len);
2574         *numrates = num;
2575         num = min(num, max);
2576
2577         for (i = 0; i < num; i++) {
2578                 rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
2579         }
2580
2581         return 0;
2582 }
2583
2584 static int orinoco_ioctl_getname(struct net_device *dev,
2585                                  struct iw_request_info *info,
2586                                  char *name,
2587                                  char *extra)
2588 {
2589         struct orinoco_private *priv = netdev_priv(dev);
2590         int numrates;
2591         int err;
2592
2593         err = orinoco_hw_get_bitratelist(priv, &numrates, NULL, 0);
2594
2595         if (!err && (numrates > 2))
2596                 strcpy(name, "IEEE 802.11b");
2597         else
2598                 strcpy(name, "IEEE 802.11-DS");
2599
2600         return 0;
2601 }
2602
2603 static int orinoco_ioctl_setwap(struct net_device *dev,
2604                                 struct iw_request_info *info,
2605                                 struct sockaddr *ap_addr,
2606                                 char *extra)
2607 {
2608         struct orinoco_private *priv = netdev_priv(dev);
2609         int err = -EINPROGRESS;         /* Call commit handler */
2610         unsigned long flags;
2611         static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2612         static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2613
2614         if (orinoco_lock(priv, &flags) != 0)
2615                 return -EBUSY;
2616
2617         /* Enable automatic roaming - no sanity checks are needed */
2618         if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
2619             memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
2620                 priv->bssid_fixed = 0;
2621                 memset(priv->desired_bssid, 0, ETH_ALEN);
2622
2623                 /* "off" means keep existing connection */
2624                 if (ap_addr->sa_data[0] == 0) {
2625                         __orinoco_hw_set_wap(priv);
2626                         err = 0;
2627                 }
2628                 goto out;
2629         }
2630
2631         if (priv->firmware_type == FIRMWARE_TYPE_AGERE) {
2632                 printk(KERN_WARNING "%s: Lucent/Agere firmware doesn't "
2633                        "support manual roaming\n",
2634                        dev->name);
2635                 err = -EOPNOTSUPP;
2636                 goto out;
2637         }
2638
2639         if (priv->iw_mode != IW_MODE_INFRA) {
2640                 printk(KERN_WARNING "%s: Manual roaming supported only in "
2641                        "managed mode\n", dev->name);
2642                 err = -EOPNOTSUPP;
2643                 goto out;
2644         }
2645
2646         /* Intersil firmware hangs without Desired ESSID */
2647         if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL &&
2648             strlen(priv->desired_essid) == 0) {
2649                 printk(KERN_WARNING "%s: Desired ESSID must be set for "
2650                        "manual roaming\n", dev->name);
2651                 err = -EOPNOTSUPP;
2652                 goto out;
2653         }
2654
2655         /* Finally, enable manual roaming */
2656         priv->bssid_fixed = 1;
2657         memcpy(priv->desired_bssid, &ap_addr->sa_data, ETH_ALEN);
2658
2659  out:
2660         orinoco_unlock(priv, &flags);
2661         return err;
2662 }
2663
2664 static int orinoco_ioctl_getwap(struct net_device *dev,
2665                                 struct iw_request_info *info,
2666                                 struct sockaddr *ap_addr,
2667                                 char *extra)
2668 {
2669         struct orinoco_private *priv = netdev_priv(dev);
2670
2671         hermes_t *hw = &priv->hw;
2672         int err = 0;
2673         unsigned long flags;
2674
2675         if (orinoco_lock(priv, &flags) != 0)
2676                 return -EBUSY;
2677
2678         ap_addr->sa_family = ARPHRD_ETHER;
2679         err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
2680                               ETH_ALEN, NULL, ap_addr->sa_data);
2681
2682         orinoco_unlock(priv, &flags);
2683
2684         return err;
2685 }
2686
2687 static int orinoco_ioctl_setmode(struct net_device *dev,
2688                                  struct iw_request_info *info,
2689                                  u32 *mode,
2690                                  char *extra)
2691 {
2692         struct orinoco_private *priv = netdev_priv(dev);
2693         int err = -EINPROGRESS;         /* Call commit handler */
2694         unsigned long flags;
2695
2696         if (priv->iw_mode == *mode)
2697                 return 0;
2698
2699         if (orinoco_lock(priv, &flags) != 0)
2700                 return -EBUSY;
2701
2702         switch (*mode) {
2703         case IW_MODE_ADHOC:
2704                 if (!priv->has_ibss && !priv->has_port3)
2705                         err = -EOPNOTSUPP;
2706                 break;
2707
2708         case IW_MODE_INFRA:
2709                 break;
2710
2711         case IW_MODE_MONITOR:
2712                 if (priv->broken_monitor && !force_monitor) {
2713                         printk(KERN_WARNING "%s: Monitor mode support is "
2714                                "buggy in this firmware, not enabling\n",
2715                                dev->name);
2716                         err = -EOPNOTSUPP;
2717                 }
2718                 break;
2719
2720         default:
2721                 err = -EOPNOTSUPP;
2722                 break;
2723         }
2724
2725         if (err == -EINPROGRESS) {
2726                 priv->iw_mode = *mode;
2727                 set_port_type(priv);
2728         }
2729
2730         orinoco_unlock(priv, &flags);
2731
2732         return err;
2733 }
2734
2735 static int orinoco_ioctl_getmode(struct net_device *dev,
2736                                  struct iw_request_info *info,
2737                                  u32 *mode,
2738                                  char *extra)
2739 {
2740         struct orinoco_private *priv = netdev_priv(dev);
2741
2742         *mode = priv->iw_mode;
2743         return 0;
2744 }
2745
2746 static int orinoco_ioctl_getiwrange(struct net_device *dev,
2747                                     struct iw_request_info *info,
2748                                     struct iw_point *rrq,
2749                                     char *extra)
2750 {
2751         struct orinoco_private *priv = netdev_priv(dev);
2752         int err = 0;
2753         struct iw_range *range = (struct iw_range *) extra;
2754         int numrates;
2755         int i, k;
2756
2757         rrq->length = sizeof(struct iw_range);
2758         memset(range, 0, sizeof(struct iw_range));
2759
2760         range->we_version_compiled = WIRELESS_EXT;
2761         range->we_version_source = 14;
2762
2763         /* Set available channels/frequencies */
2764         range->num_channels = NUM_CHANNELS;
2765         k = 0;
2766         for (i = 0; i < NUM_CHANNELS; i++) {
2767                 if (priv->channel_mask & (1 << i)) {
2768                         range->freq[k].i = i + 1;
2769                         range->freq[k].m = channel_frequency[i] * 100000;
2770                         range->freq[k].e = 1;
2771                         k++;
2772                 }
2773                 
2774                 if (k >= IW_MAX_FREQUENCIES)
2775                         break;
2776         }
2777         range->num_frequency = k;
2778         range->sensitivity = 3;
2779
2780         if (priv->has_wep) {
2781                 range->max_encoding_tokens = ORINOCO_MAX_KEYS;
2782                 range->encoding_size[0] = SMALL_KEY_SIZE;
2783                 range->num_encoding_sizes = 1;
2784
2785                 if (priv->has_big_wep) {
2786                         range->encoding_size[1] = LARGE_KEY_SIZE;
2787                         range->num_encoding_sizes = 2;
2788                 }
2789         }
2790
2791         if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
2792                 /* Quality stats meaningless in ad-hoc mode */
2793         } else {
2794                 range->max_qual.qual = 0x8b - 0x2f;
2795                 range->max_qual.level = 0x2f - 0x95 - 1;
2796                 range->max_qual.noise = 0x2f - 0x95 - 1;
2797                 /* Need to get better values */
2798                 range->avg_qual.qual = 0x24;
2799                 range->avg_qual.level = 0xC2;
2800                 range->avg_qual.noise = 0x9E;
2801         }
2802
2803         err = orinoco_hw_get_bitratelist(priv, &numrates,
2804                                          range->bitrate, IW_MAX_BITRATES);
2805         if (err)
2806                 return err;
2807         range->num_bitrates = numrates;
2808
2809         /* Set an indication of the max TCP throughput in bit/s that we can
2810          * expect using this interface. May be use for QoS stuff...
2811          * Jean II */
2812         if (numrates > 2)
2813                 range->throughput = 5 * 1000 * 1000;    /* ~5 Mb/s */
2814         else
2815                 range->throughput = 1.5 * 1000 * 1000;  /* ~1.5 Mb/s */
2816
2817         range->min_rts = 0;
2818         range->max_rts = 2347;
2819         range->min_frag = 256;
2820         range->max_frag = 2346;
2821
2822         range->min_pmp = 0;
2823         range->max_pmp = 65535000;
2824         range->min_pmt = 0;
2825         range->max_pmt = 65535 * 1000;  /* ??? */
2826         range->pmp_flags = IW_POWER_PERIOD;
2827         range->pmt_flags = IW_POWER_TIMEOUT;
2828         range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
2829
2830         range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
2831         range->retry_flags = IW_RETRY_LIMIT;
2832         range->r_time_flags = IW_RETRY_LIFETIME;
2833         range->min_retry = 0;
2834         range->max_retry = 65535;       /* ??? */
2835         range->min_r_time = 0;
2836         range->max_r_time = 65535 * 1000;       /* ??? */
2837
2838         /* Event capability (kernel) */
2839         IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
2840         /* Event capability (driver) */
2841         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
2842         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
2843         IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
2844         IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
2845
2846         return 0;
2847 }
2848
2849 static int orinoco_ioctl_setiwencode(struct net_device *dev,
2850                                      struct iw_request_info *info,
2851                                      struct iw_point *erq,
2852                                      char *keybuf)
2853 {
2854         struct orinoco_private *priv = netdev_priv(dev);
2855         int index = (erq->flags & IW_ENCODE_INDEX) - 1;
2856         int setindex = priv->tx_key;
2857         int enable = priv->wep_on;
2858         int restricted = priv->wep_restrict;
2859         u16 xlen = 0;
2860         int err = -EINPROGRESS;         /* Call commit handler */
2861         unsigned long flags;
2862
2863         if (! priv->has_wep)
2864                 return -EOPNOTSUPP;
2865
2866         if (erq->pointer) {
2867                 /* We actually have a key to set - check its length */
2868                 if (erq->length > LARGE_KEY_SIZE)
2869                         return -E2BIG;
2870
2871                 if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
2872                         return -E2BIG;
2873         }
2874
2875         if (orinoco_lock(priv, &flags) != 0)
2876                 return -EBUSY;
2877
2878         if (erq->length > 0) {
2879                 if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
2880                         index = priv->tx_key;
2881
2882                 /* Adjust key length to a supported value */
2883                 if (erq->length > SMALL_KEY_SIZE) {
2884                         xlen = LARGE_KEY_SIZE;
2885                 } else if (erq->length > 0) {
2886                         xlen = SMALL_KEY_SIZE;
2887                 } else
2888                         xlen = 0;
2889
2890                 /* Switch on WEP if off */
2891                 if ((!enable) && (xlen > 0)) {
2892                         setindex = index;
2893                         enable = 1;
2894                 }
2895         } else {
2896                 /* Important note : if the user do "iwconfig eth0 enc off",
2897                  * we will arrive there with an index of -1. This is valid
2898                  * but need to be taken care off... Jean II */
2899                 if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) {
2900                         if((index != -1) || (erq->flags == 0)) {
2901                                 err = -EINVAL;
2902                                 goto out;
2903                         }
2904                 } else {
2905                         /* Set the index : Check that the key is valid */
2906                         if(priv->keys[index].len == 0) {
2907                                 err = -EINVAL;
2908                                 goto out;
2909                         }
2910                         setindex = index;
2911                 }
2912         }
2913
2914         if (erq->flags & IW_ENCODE_DISABLED)
2915                 enable = 0;
2916         if (erq->flags & IW_ENCODE_OPEN)
2917                 restricted = 0;
2918         if (erq->flags & IW_ENCODE_RESTRICTED)
2919                 restricted = 1;
2920
2921         if (erq->pointer && erq->length > 0) {
2922                 priv->keys[index].len = cpu_to_le16(xlen);
2923                 memset(priv->keys[index].data, 0,
2924                        sizeof(priv->keys[index].data));
2925                 memcpy(priv->keys[index].data, keybuf, erq->length);
2926         }
2927         priv->tx_key = setindex;
2928
2929         /* Try fast key change if connected and only keys are changed */
2930         if (priv->wep_on && enable && (priv->wep_restrict == restricted) &&
2931             netif_carrier_ok(dev)) {
2932                 err = __orinoco_hw_setup_wepkeys(priv);
2933                 /* No need to commit if successful */
2934                 goto out;
2935         }
2936
2937         priv->wep_on = enable;
2938         priv->wep_restrict = restricted;
2939
2940  out:
2941         orinoco_unlock(priv, &flags);
2942
2943         return err;
2944 }
2945
2946 static int orinoco_ioctl_getiwencode(struct net_device *dev,
2947                                      struct iw_request_info *info,
2948                                      struct iw_point *erq,
2949                                      char *keybuf)
2950 {
2951         struct orinoco_private *priv = netdev_priv(dev);
2952         int index = (erq->flags & IW_ENCODE_INDEX) - 1;
2953         u16 xlen = 0;
2954         unsigned long flags;
2955
2956         if (! priv->has_wep)
2957                 return -EOPNOTSUPP;
2958
2959         if (orinoco_lock(priv, &flags) != 0)
2960                 return -EBUSY;
2961
2962         if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
2963                 index = priv->tx_key;
2964
2965         erq->flags = 0;
2966         if (! priv->wep_on)
2967                 erq->flags |= IW_ENCODE_DISABLED;
2968         erq->flags |= index + 1;
2969
2970         if (priv->wep_restrict)
2971                 erq->flags |= IW_ENCODE_RESTRICTED;
2972         else
2973                 erq->flags |= IW_ENCODE_OPEN;
2974
2975         xlen = le16_to_cpu(priv->keys[index].len);
2976
2977         erq->length = xlen;
2978
2979         memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
2980
2981         orinoco_unlock(priv, &flags);
2982         return 0;
2983 }
2984
2985 static int orinoco_ioctl_setessid(struct net_device *dev,
2986                                   struct iw_request_info *info,
2987                                   struct iw_point *erq,
2988                                   char *essidbuf)
2989 {
2990         struct orinoco_private *priv = netdev_priv(dev);
2991         unsigned long flags;
2992
2993         /* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
2994          * anyway... - Jean II */
2995
2996         /* Hum... Should not use Wireless Extension constant (may change),
2997          * should use our own... - Jean II */
2998         if (erq->length > IW_ESSID_MAX_SIZE)
2999                 return -E2BIG;
3000
3001         if (orinoco_lock(priv, &flags) != 0)
3002                 return -EBUSY;
3003
3004         /* NULL the string (for NULL termination & ESSID = ANY) - Jean II */
3005         memset(priv->desired_essid, 0, sizeof(priv->desired_essid));
3006
3007         /* If not ANY, get the new ESSID */
3008         if (erq->flags) {
3009                 memcpy(priv->desired_essid, essidbuf, erq->length);
3010         }
3011
3012         orinoco_unlock(priv, &flags);
3013
3014         return -EINPROGRESS;            /* Call commit handler */
3015 }
3016
3017 static int orinoco_ioctl_getessid(struct net_device *dev,
3018                                   struct iw_request_info *info,
3019                                   struct iw_point *erq,
3020                                   char *essidbuf)
3021 {
3022         struct orinoco_private *priv = netdev_priv(dev);
3023         int active;
3024         int err = 0;
3025         unsigned long flags;
3026
3027         if (netif_running(dev)) {
3028                 err = orinoco_hw_get_essid(priv, &active, essidbuf);
3029                 if (err)
3030                         return err;
3031         } else {
3032                 if (orinoco_lock(priv, &flags) != 0)
3033                         return -EBUSY;
3034                 memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE + 1);
3035                 orinoco_unlock(priv, &flags);
3036         }
3037
3038         erq->flags = 1;
3039         erq->length = strlen(essidbuf) + 1;
3040
3041         return 0;
3042 }
3043
3044 static int orinoco_ioctl_setnick(struct net_device *dev,
3045                                  struct iw_request_info *info,
3046                                  struct iw_point *nrq,
3047                                  char *nickbuf)
3048 {
3049         struct orinoco_private *priv = netdev_priv(dev);
3050         unsigned long flags;
3051
3052         if (nrq->length > IW_ESSID_MAX_SIZE)
3053                 return -E2BIG;
3054
3055         if (orinoco_lock(priv, &flags) != 0)
3056                 return -EBUSY;
3057
3058         memset(priv->nick, 0, sizeof(priv->nick));
3059         memcpy(priv->nick, nickbuf, nrq->length);
3060
3061         orinoco_unlock(priv, &flags);
3062
3063         return -EINPROGRESS;            /* Call commit handler */
3064 }
3065
3066 static int orinoco_ioctl_getnick(struct net_device *dev,
3067                                  struct iw_request_info *info,
3068                                  struct iw_point *nrq,
3069                                  char *nickbuf)
3070 {
3071         struct orinoco_private *priv = netdev_priv(dev);
3072         unsigned long flags;
3073
3074         if (orinoco_lock(priv, &flags) != 0)
3075                 return -EBUSY;
3076
3077         memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
3078         orinoco_unlock(priv, &flags);
3079
3080         nrq->length = strlen(nickbuf)+1;
3081
3082         return 0;
3083 }
3084
3085 static int orinoco_ioctl_setfreq(struct net_device *dev,
3086                                  struct iw_request_info *info,
3087                                  struct iw_freq *frq,
3088                                  char *extra)
3089 {
3090         struct orinoco_private *priv = netdev_priv(dev);
3091         int chan = -1;
3092         unsigned long flags;
3093         int err = -EINPROGRESS;         /* Call commit handler */
3094
3095         /* In infrastructure mode the AP sets the channel */
3096         if (priv->iw_mode == IW_MODE_INFRA)
3097                 return -EBUSY;
3098
3099         if ( (frq->e == 0) && (frq->m <= 1000) ) {
3100                 /* Setting by channel number */
3101                 chan = frq->m;
3102         } else {
3103                 /* Setting by frequency - search the table */
3104                 int mult = 1;
3105                 int i;
3106
3107                 for (i = 0; i < (6 - frq->e); i++)
3108                         mult *= 10;
3109
3110                 for (i = 0; i < NUM_CHANNELS; i++)
3111                         if (frq->m == (channel_frequency[i] * mult))
3112                                 chan = i+1;
3113         }
3114
3115         if ( (chan < 1) || (chan > NUM_CHANNELS) ||
3116              ! (priv->channel_mask & (1 << (chan-1)) ) )
3117                 return -EINVAL;
3118
3119         if (orinoco_lock(priv, &flags) != 0)
3120                 return -EBUSY;
3121
3122         priv->channel = chan;
3123         if (priv->iw_mode == IW_MODE_MONITOR) {
3124                 /* Fast channel change - no commit if successful */
3125                 hermes_t *hw = &priv->hw;
3126                 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
3127                                             HERMES_TEST_SET_CHANNEL,
3128                                         chan, NULL);
3129         }
3130         orinoco_unlock(priv, &flags);
3131
3132         return err;
3133 }
3134
3135 static int orinoco_ioctl_getfreq(struct net_device *dev,
3136                                  struct iw_request_info *info,
3137                                  struct iw_freq *frq,
3138                                  char *extra)
3139 {
3140         struct orinoco_private *priv = netdev_priv(dev);
3141         int tmp;
3142
3143         /* Locking done in there */
3144         tmp = orinoco_hw_get_freq(priv);
3145         if (tmp < 0) {
3146                 return tmp;
3147         }
3148
3149         frq->m = tmp;
3150         frq->e = 1;
3151
3152         return 0;
3153 }
3154
3155 static int orinoco_ioctl_getsens(struct net_device *dev,
3156                                  struct iw_request_info *info,
3157                                  struct iw_param *srq,
3158                                  char *extra)
3159 {
3160         struct orinoco_private *priv = netdev_priv(dev);
3161         hermes_t *hw = &priv->hw;
3162         u16 val;
3163         int err;
3164         unsigned long flags;
3165
3166         if (!priv->has_sensitivity)
3167                 return -EOPNOTSUPP;
3168
3169         if (orinoco_lock(priv, &flags) != 0)
3170                 return -EBUSY;
3171         err = hermes_read_wordrec(hw, USER_BAP,
3172                                   HERMES_RID_CNFSYSTEMSCALE, &val);
3173         orinoco_unlock(priv, &flags);
3174
3175         if (err)
3176                 return err;
3177
3178         srq->value = val;
3179         srq->fixed = 0; /* auto */
3180
3181         return 0;
3182 }
3183
3184 static int orinoco_ioctl_setsens(struct net_device *dev,
3185                                  struct iw_request_info *info,
3186                                  struct iw_param *srq,
3187                                  char *extra)
3188 {
3189         struct orinoco_private *priv = netdev_priv(dev);
3190         int val = srq->value;
3191         unsigned long flags;
3192
3193         if (!priv->has_sensitivity)
3194                 return -EOPNOTSUPP;
3195
3196         if ((val < 1) || (val > 3))
3197                 return -EINVAL;
3198         
3199         if (orinoco_lock(priv, &flags) != 0)
3200                 return -EBUSY;
3201         priv->ap_density = val;
3202         orinoco_unlock(priv, &flags);
3203
3204         return -EINPROGRESS;            /* Call commit handler */
3205 }
3206
3207 static int orinoco_ioctl_setrts(struct net_device *dev,
3208                                 struct iw_request_info *info,
3209                                 struct iw_param *rrq,
3210                                 char *extra)
3211 {
3212         struct orinoco_private *priv = netdev_priv(dev);
3213         int val = rrq->value;
3214         unsigned long flags;
3215
3216         if (rrq->disabled)
3217                 val = 2347;
3218
3219         if ( (val < 0) || (val > 2347) )
3220                 return -EINVAL;
3221
3222         if (orinoco_lock(priv, &flags) != 0)
3223                 return -EBUSY;
3224
3225         priv->rts_thresh = val;
3226         orinoco_unlock(priv, &flags);
3227
3228         return -EINPROGRESS;            /* Call commit handler */
3229 }
3230
3231 static int orinoco_ioctl_getrts(struct net_device *dev,
3232                                 struct iw_request_info *info,
3233                                 struct iw_param *rrq,
3234                                 char *extra)
3235 {
3236         struct orinoco_private *priv = netdev_priv(dev);
3237
3238         rrq->value = priv->rts_thresh;
3239         rrq->disabled = (rrq->value == 2347);
3240         rrq->fixed = 1;
3241
3242         return 0;
3243 }
3244
3245 static int orinoco_ioctl_setfrag(struct net_device *dev,
3246                                  struct iw_request_info *info,
3247                                  struct iw_param *frq,
3248                                  char *extra)
3249 {
3250         struct orinoco_private *priv = netdev_priv(dev);
3251         int err = -EINPROGRESS;         /* Call commit handler */
3252         unsigned long flags;
3253
3254         if (orinoco_lock(priv, &flags) != 0)
3255                 return -EBUSY;
3256
3257         if (priv->has_mwo) {
3258                 if (frq->disabled)
3259                         priv->mwo_robust = 0;
3260                 else {
3261                         if (frq->fixed)
3262                                 printk(KERN_WARNING "%s: Fixed fragmentation is "
3263                                        "not supported on this firmware. "
3264                                        "Using MWO robust instead.\n", dev->name);
3265                         priv->mwo_robust = 1;
3266                 }
3267         } else {
3268                 if (frq->disabled)
3269                         priv->frag_thresh = 2346;
3270                 else {
3271                         if ( (frq->value < 256) || (frq->value > 2346) )
3272                                 err = -EINVAL;
3273                         else
3274                                 priv->frag_thresh = frq->value & ~0x1; /* must be even */
3275                 }
3276         }
3277
3278         orinoco_unlock(priv, &flags);
3279
3280         return err;
3281 }
3282
3283 static int orinoco_ioctl_getfrag(struct net_device *dev,
3284                                  struct iw_request_info *info,
3285                                  struct iw_param *frq,
3286                                  char *extra)
3287 {
3288         struct orinoco_private *priv = netdev_priv(dev);
3289         hermes_t *hw = &priv->hw;
3290         int err;
3291         u16 val;
3292         unsigned long flags;
3293
3294         if (orinoco_lock(priv, &flags) != 0)
3295                 return -EBUSY;
3296         
3297         if (priv->has_mwo) {
3298                 err = hermes_read_wordrec(hw, USER_BAP,
3299                                           HERMES_RID_CNFMWOROBUST_AGERE,
3300                                           &val);
3301                 if (err)
3302                         val = 0;
3303
3304                 frq->value = val ? 2347 : 0;
3305                 frq->disabled = ! val;
3306                 frq->fixed = 0;
3307         } else {
3308                 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
3309                                           &val);
3310                 if (err)
3311                         val = 0;
3312
3313                 frq->value = val;
3314                 frq->disabled = (val >= 2346);
3315                 frq->fixed = 1;
3316         }
3317
3318         orinoco_unlock(priv, &flags);
3319         
3320         return err;
3321 }
3322
3323 static int orinoco_ioctl_setrate(struct net_device *dev,
3324                                  struct iw_request_info *info,
3325                                  struct iw_param *rrq,
3326                                  char *extra)
3327 {
3328         struct orinoco_private *priv = netdev_priv(dev);
3329         int ratemode = -1;
3330         int bitrate; /* 100s of kilobits */
3331         int i;
3332         unsigned long flags;
3333         
3334         /* As the user space doesn't know our highest rate, it uses -1
3335          * to ask us to set the highest rate.  Test it using "iwconfig
3336          * ethX rate auto" - Jean II */
3337         if (rrq->value == -1)
3338                 bitrate = 110;
3339         else {
3340                 if (rrq->value % 100000)
3341                         return -EINVAL;
3342                 bitrate = rrq->value / 100000;
3343         }
3344
3345         if ( (bitrate != 10) && (bitrate != 20) &&
3346              (bitrate != 55) && (bitrate != 110) )
3347                 return -EINVAL;
3348
3349         for (i = 0; i < BITRATE_TABLE_SIZE; i++)
3350                 if ( (bitrate_table[i].bitrate == bitrate) &&
3351                      (bitrate_table[i].automatic == ! rrq->fixed) ) {
3352                         ratemode = i;
3353                         break;
3354                 }
3355         
3356         if (ratemode == -1)
3357                 return -EINVAL;
3358
3359         if (orinoco_lock(priv, &flags) != 0)
3360                 return -EBUSY;
3361         priv->bitratemode = ratemode;
3362         orinoco_unlock(priv, &flags);
3363
3364         return -EINPROGRESS;
3365 }
3366
3367 static int orinoco_ioctl_getrate(struct net_device *dev,
3368                                  struct iw_request_info *info,
3369                                  struct iw_param *rrq,
3370                                  char *extra)
3371 {
3372         struct orinoco_private *priv = netdev_priv(dev);
3373         hermes_t *hw = &priv->hw;
3374         int err = 0;
3375         int ratemode;
3376         int i;
3377         u16 val;
3378         unsigned long flags;
3379
3380         if (orinoco_lock(priv, &flags) != 0)
3381                 return -EBUSY;
3382
3383         ratemode = priv->bitratemode;
3384
3385         BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
3386
3387         rrq->value = bitrate_table[ratemode].bitrate * 100000;
3388         rrq->fixed = ! bitrate_table[ratemode].automatic;
3389         rrq->disabled = 0;
3390
3391         /* If the interface is running we try to find more about the
3392            current mode */
3393         if (netif_running(dev)) {
3394                 err = hermes_read_wordrec(hw, USER_BAP,
3395                                           HERMES_RID_CURRENTTXRATE, &val);
3396                 if (err)
3397                         goto out;
3398                 
3399                 switch (priv->firmware_type) {
3400                 case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
3401                         /* Note : in Lucent firmware, the return value of
3402                          * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
3403                          * and therefore is totally different from the
3404                          * encoding of HERMES_RID_CNFTXRATECONTROL.
3405                          * Don't forget that 6Mb/s is really 5.5Mb/s */
3406                         if (val == 6)
3407                                 rrq->value = 5500000;
3408                         else
3409                                 rrq->value = val * 1000000;
3410                         break;
3411                 case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
3412                 case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
3413                         for (i = 0; i < BITRATE_TABLE_SIZE; i++)
3414                                 if (bitrate_table[i].intersil_txratectrl == val) {
3415                                         ratemode = i;
3416                                         break;
3417                                 }
3418                         if (i >= BITRATE_TABLE_SIZE)
3419                                 printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
3420                                        dev->name, val);
3421
3422                         rrq->value = bitrate_table[ratemode].bitrate * 100000;
3423                         break;
3424                 default:
3425                         BUG();
3426                 }
3427         }
3428
3429  out:
3430         orinoco_unlock(priv, &flags);
3431
3432         return err;
3433 }
3434
3435 static int orinoco_ioctl_setpower(struct net_device *dev,
3436                                   struct iw_request_info *info,
3437                                   struct iw_param *prq,
3438                                   char *extra)
3439 {
3440         struct orinoco_private *priv = netdev_priv(dev);
3441         int err = -EINPROGRESS;         /* Call commit handler */
3442         unsigned long flags;
3443
3444         if (orinoco_lock(priv, &flags) != 0)
3445                 return -EBUSY;
3446
3447         if (prq->disabled) {
3448                 priv->pm_on = 0;
3449         } else {
3450                 switch (prq->flags & IW_POWER_MODE) {
3451                 case IW_POWER_UNICAST_R:
3452                         priv->pm_mcast = 0;
3453                         priv->pm_on = 1;
3454                         break;
3455                 case IW_POWER_ALL_R:
3456                         priv->pm_mcast = 1;
3457                         priv->pm_on = 1;
3458                         break;
3459                 case IW_POWER_ON:
3460                         /* No flags : but we may have a value - Jean II */
3461                         break;
3462                 default:
3463                         err = -EINVAL;
3464                         goto out;
3465                 }
3466                 
3467                 if (prq->flags & IW_POWER_TIMEOUT) {
3468                         priv->pm_on = 1;
3469                         priv->pm_timeout = prq->value / 1000;
3470                 }
3471                 if (prq->flags & IW_POWER_PERIOD) {
3472                         priv->pm_on = 1;
3473                         priv->pm_period = prq->value / 1000;
3474                 }
3475                 /* It's valid to not have a value if we are just toggling
3476                  * the flags... Jean II */
3477                 if(!priv->pm_on) {
3478                         err = -EINVAL;
3479                         goto out;
3480                 }                       
3481         }
3482
3483  out:
3484         orinoco_unlock(priv, &flags);
3485
3486         return err;
3487 }
3488
3489 static int orinoco_ioctl_getpower(struct net_device *dev,
3490                                   struct iw_request_info *info,
3491                                   struct iw_param *prq,
3492                                   char *extra)
3493 {
3494         struct orinoco_private *priv = netdev_priv(dev);
3495         hermes_t *hw = &priv->hw;
3496         int err = 0;
3497         u16 enable, period, timeout, mcast;
3498         unsigned long flags;
3499
3500         if (orinoco_lock(priv, &flags) != 0)
3501                 return -EBUSY;
3502         
3503         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
3504         if (err)
3505                 goto out;
3506
3507         err = hermes_read_wordrec(hw, USER_BAP,
3508                                   HERMES_RID_CNFMAXSLEEPDURATION, &period);
3509         if (err)
3510                 goto out;
3511
3512         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMHOLDOVERDURATION, &timeout);
3513         if (err)
3514                 goto out;
3515
3516         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFMULTICASTRECEIVE, &mcast);
3517         if (err)
3518                 goto out;
3519
3520         prq->disabled = !enable;
3521         /* Note : by default, display the period */
3522         if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
3523                 prq->flags = IW_POWER_TIMEOUT;
3524                 prq->value = timeout * 1000;
3525         } else {
3526                 prq->flags = IW_POWER_PERIOD;
3527                 prq->value = period * 1000;
3528         }
3529         if (mcast)
3530                 prq->flags |= IW_POWER_ALL_R;
3531         else
3532                 prq->flags |= IW_POWER_UNICAST_R;
3533
3534  out:
3535         orinoco_unlock(priv, &flags);
3536
3537         return err;
3538 }
3539
3540 static int orinoco_ioctl_getretry(struct net_device *dev,
3541                                   struct iw_request_info *info,
3542                                   struct iw_param *rrq,
3543                                   char *extra)
3544 {
3545         struct orinoco_private *priv = netdev_priv(dev);
3546         hermes_t *hw = &priv->hw;
3547         int err = 0;
3548         u16 short_limit, long_limit, lifetime;
3549         unsigned long flags;
3550
3551         if (orinoco_lock(priv, &flags) != 0)
3552                 return -EBUSY;
3553         
3554         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
3555                                   &short_limit);
3556         if (err)
3557                 goto out;
3558
3559         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
3560                                   &long_limit);
3561         if (err)
3562                 goto out;
3563
3564         err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
3565                                   &lifetime);
3566         if (err)
3567                 goto out;
3568
3569         rrq->disabled = 0;              /* Can't be disabled */
3570
3571         /* Note : by default, display the retry number */
3572         if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
3573                 rrq->flags = IW_RETRY_LIFETIME;
3574                 rrq->value = lifetime * 1000;   /* ??? */
3575         } else {
3576                 /* By default, display the min number */
3577                 if ((rrq->flags & IW_RETRY_MAX)) {
3578                         rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
3579                         rrq->value = long_limit;
3580                 } else {
3581                         rrq->flags = IW_RETRY_LIMIT;
3582                         rrq->value = short_limit;
3583                         if(short_limit != long_limit)
3584                                 rrq->flags |= IW_RETRY_MIN;
3585                 }
3586         }
3587
3588  out:
3589         orinoco_unlock(priv, &flags);
3590
3591         return err;
3592 }
3593
3594 static int orinoco_ioctl_reset(struct net_device *dev,
3595                                struct iw_request_info *info,
3596                                void *wrqu,
3597                                char *extra)
3598 {
3599         struct orinoco_private *priv = netdev_priv(dev);
3600
3601         if (! capable(CAP_NET_ADMIN))
3602                 return -EPERM;
3603
3604         if (info->cmd == (SIOCIWFIRSTPRIV + 0x1)) {
3605                 printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
3606
3607                 /* Firmware reset */
3608                 orinoco_reset(dev);
3609         } else {
3610                 printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
3611
3612                 schedule_work(&priv->reset_work);
3613         }
3614
3615         return 0;
3616 }
3617
3618 static int orinoco_ioctl_setibssport(struct net_device *dev,
3619                                      struct iw_request_info *info,
3620                                      void *wrqu,
3621                                      char *extra)
3622
3623 {
3624         struct orinoco_private *priv = netdev_priv(dev);
3625         int val = *( (int *) extra );
3626         unsigned long flags;
3627
3628         if (orinoco_lock(priv, &flags) != 0)
3629                 return -EBUSY;
3630
3631         priv->ibss_port = val ;
3632
3633         /* Actually update the mode we are using */
3634         set_port_type(priv);
3635
3636         orinoco_unlock(priv, &flags);
3637         return -EINPROGRESS;            /* Call commit handler */
3638 }
3639
3640 static int orinoco_ioctl_getibssport(struct net_device *dev,
3641                                      struct iw_request_info *info,
3642                                      void *wrqu,
3643                                      char *extra)
3644 {
3645         struct orinoco_private *priv = netdev_priv(dev);
3646         int *val = (int *) extra;
3647
3648         *val = priv->ibss_port;
3649         return 0;
3650 }
3651
3652 static int orinoco_ioctl_setport3(struct net_device *dev,
3653                                   struct iw_request_info *info,
3654                                   void *wrqu,
3655                                   char *extra)
3656 {
3657         struct orinoco_private *priv = netdev_priv(dev);
3658         int val = *( (int *) extra );
3659         int err = 0;
3660         unsigned long flags;
3661
3662         if (orinoco_lock(priv, &flags) != 0)
3663                 return -EBUSY;
3664
3665         switch (val) {
3666         case 0: /* Try to do IEEE ad-hoc mode */
3667                 if (! priv->has_ibss) {
3668                         err = -EINVAL;
3669                         break;
3670                 }
3671                 priv->prefer_port3 = 0;
3672                         
3673                 break;
3674
3675         case 1: /* Try to do Lucent proprietary ad-hoc mode */
3676                 if (! priv->has_port3) {
3677                         err = -EINVAL;
3678                         break;
3679                 }
3680                 priv->prefer_port3 = 1;
3681                 break;
3682
3683         default:
3684                 err = -EINVAL;
3685         }
3686
3687         if (! err) {
3688                 /* Actually update the mode we are using */
3689                 set_port_type(priv);
3690                 err = -EINPROGRESS;
3691         }
3692
3693         orinoco_unlock(priv, &flags);
3694
3695         return err;
3696 }
3697
3698 static int orinoco_ioctl_getport3(struct net_device *dev,
3699                                   struct iw_request_info *info,
3700                                   void *wrqu,
3701                                   char *extra)
3702 {
3703         struct orinoco_private *priv = netdev_priv(dev);
3704         int *val = (int *) extra;
3705
3706         *val = priv->prefer_port3;
3707         return 0;
3708 }
3709
3710 static int orinoco_ioctl_setpreamble(struct net_device *dev,
3711                                      struct iw_request_info *info,
3712                                      void *wrqu,
3713                                      char *extra)
3714 {
3715         struct orinoco_private *priv = netdev_priv(dev);
3716         unsigned long flags;
3717         int val;
3718
3719         if (! priv->has_preamble)
3720                 return -EOPNOTSUPP;
3721
3722         /* 802.11b has recently defined some short preamble.
3723          * Basically, the Phy header has been reduced in size.
3724          * This increase performance, especially at high rates
3725          * (the preamble is transmitted at 1Mb/s), unfortunately
3726          * this give compatibility troubles... - Jean II */
3727         val = *( (int *) extra );
3728
3729         if (orinoco_lock(priv, &flags) != 0)
3730                 return -EBUSY;
3731
3732         if (val)
3733                 priv->preamble = 1;
3734         else
3735                 priv->preamble = 0;
3736
3737         orinoco_unlock(priv, &flags);
3738
3739         return -EINPROGRESS;            /* Call commit handler */
3740 }
3741
3742 static int orinoco_ioctl_getpreamble(struct net_device *dev,
3743                                      struct iw_request_info *info,
3744                                      void *wrqu,
3745                                      char *extra)
3746 {
3747         struct orinoco_private *priv = netdev_priv(dev);
3748         int *val = (int *) extra;
3749
3750         if (! priv->has_preamble)
3751                 return -EOPNOTSUPP;
3752
3753         *val = priv->preamble;
3754         return 0;
3755 }
3756
3757 /* ioctl interface to hermes_read_ltv()
3758  * To use with iwpriv, pass the RID as the token argument, e.g.
3759  * iwpriv get_rid [0xfc00]
3760  * At least Wireless Tools 25 is required to use iwpriv.
3761  * For Wireless Tools 25 and 26 append "dummy" are the end. */
3762 static int orinoco_ioctl_getrid(struct net_device *dev,
3763                                 struct iw_request_info *info,
3764                                 struct iw_point *data,
3765                                 char *extra)
3766 {
3767         struct orinoco_private *priv = netdev_priv(dev);
3768         hermes_t *hw = &priv->hw;
3769         int rid = data->flags;
3770         u16 length;
3771         int err;
3772         unsigned long flags;
3773
3774         /* It's a "get" function, but we don't want users to access the
3775          * WEP key and other raw firmware data */
3776         if (! capable(CAP_NET_ADMIN))
3777                 return -EPERM;
3778
3779         if (rid < 0xfc00 || rid > 0xffff)
3780                 return -EINVAL;
3781
3782         if (orinoco_lock(priv, &flags) != 0)
3783                 return -EBUSY;
3784
3785         err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
3786                               extra);
3787         if (err)
3788                 goto out;
3789
3790         data->length = min_t(u16, HERMES_RECLEN_TO_BYTES(length),
3791                              MAX_RID_LEN);
3792
3793  out:
3794         orinoco_unlock(priv, &flags);
3795         return err;
3796 }
3797
3798 /* Trigger a scan (look for other cells in the vicinity */
3799 static int orinoco_ioctl_setscan(struct net_device *dev,
3800                                  struct iw_request_info *info,
3801                                  struct iw_param *srq,
3802                                  char *extra)
3803 {
3804         struct orinoco_private *priv = netdev_priv(dev);
3805         hermes_t *hw = &priv->hw;
3806         int err = 0;
3807         unsigned long flags;
3808
3809         /* Note : you may have realised that, as this is a SET operation,
3810          * this is privileged and therefore a normal user can't
3811          * perform scanning.
3812          * This is not an error, while the device perform scanning,
3813          * traffic doesn't flow, so it's a perfect DoS...
3814          * Jean II */
3815
3816         if (orinoco_lock(priv, &flags) != 0)
3817                 return -EBUSY;
3818
3819         /* Scanning with port 0 disabled would fail */
3820         if (!netif_running(dev)) {
3821                 err = -ENETDOWN;
3822                 goto out;
3823         }
3824
3825         /* In monitor mode, the scan results are always empty.
3826          * Probe responses are passed to the driver as received
3827          * frames and could be processed in software. */
3828         if (priv->iw_mode == IW_MODE_MONITOR) {
3829                 err = -EOPNOTSUPP;
3830                 goto out;
3831         }
3832
3833         /* Note : because we don't lock out the irq handler, the way
3834          * we access scan variables in priv is critical.
3835          *      o scan_inprogress : not touched by irq handler
3836          *      o scan_mode : not touched by irq handler
3837          *      o scan_result : irq is strict producer, non-irq is strict
3838          *              consumer.
3839          *      o scan_len : synchronised with scan_result
3840          * Before modifying anything on those variables, please think hard !
3841          * Jean II */
3842
3843         /* If there is still some left-over scan results, get rid of it */
3844         if (priv->scan_result != NULL) {
3845                 /* What's likely is that a client did crash or was killed
3846                  * between triggering the scan request and reading the
3847                  * results, so we need to reset everything.
3848                  * Some clients that are too slow may suffer from that...
3849                  * Jean II */
3850                 kfree(priv->scan_result);
3851                 priv->scan_result = NULL;
3852         }
3853
3854         /* Save flags */
3855         priv->scan_mode = srq->flags;
3856
3857         /* Always trigger scanning, even if it's in progress.
3858          * This way, if the info frame get lost, we will recover somewhat
3859          * gracefully  - Jean II */
3860
3861         if (priv->has_hostscan) {
3862                 switch (priv->firmware_type) {
3863                 case FIRMWARE_TYPE_SYMBOL:
3864                         err = hermes_write_wordrec(hw, USER_BAP,
3865                                                    HERMES_RID_CNFHOSTSCAN_SYMBOL,
3866                                                    HERMES_HOSTSCAN_SYMBOL_ONCE |
3867                                                    HERMES_HOSTSCAN_SYMBOL_BCAST);
3868                         break;
3869                 case FIRMWARE_TYPE_INTERSIL: {
3870                         __le16 req[3];
3871
3872                         req[0] = cpu_to_le16(0x3fff);   /* All channels */
3873                         req[1] = cpu_to_le16(0x0001);   /* rate 1 Mbps */
3874                         req[2] = 0;                     /* Any ESSID */
3875                         err = HERMES_WRITE_RECORD(hw, USER_BAP,
3876                                                   HERMES_RID_CNFHOSTSCAN, &req);
3877                 }
3878                 break;
3879                 case FIRMWARE_TYPE_AGERE:
3880                         err = hermes_write_wordrec(hw, USER_BAP,
3881                                                    HERMES_RID_CNFSCANSSID_AGERE,
3882                                                    0);  /* Any ESSID */
3883                         if (err)
3884                                 break;
3885
3886                         err = hermes_inquire(hw, HERMES_INQ_SCAN);
3887                         break;
3888                 }
3889         } else
3890                 err = hermes_inquire(hw, HERMES_INQ_SCAN);
3891
3892         /* One more client */
3893         if (! err)
3894                 priv->scan_inprogress = 1;
3895
3896  out:
3897         orinoco_unlock(priv, &flags);
3898         return err;
3899 }
3900
3901 /* Translate scan data returned from the card to a card independant
3902  * format that the Wireless Tools will understand - Jean II
3903  * Return message length or -errno for fatal errors */
3904 static inline int orinoco_translate_scan(struct net_device *dev,
3905                                          char *buffer,
3906                                          char *scan,
3907                                          int scan_len)
3908 {
3909         struct orinoco_private *priv = netdev_priv(dev);
3910         int                     offset;         /* In the scan data */
3911         union hermes_scan_info *atom;
3912         int                     atom_len;
3913         u16                     capabilities;
3914         u16                     channel;
3915         struct iw_event         iwe;            /* Temporary buffer */
3916         char *                  current_ev = buffer;
3917         char *                  end_buf = buffer + IW_SCAN_MAX_DATA;
3918
3919         switch (priv->firmware_type) {
3920         case FIRMWARE_TYPE_AGERE:
3921                 atom_len = sizeof(struct agere_scan_apinfo);
3922                 offset = 0;
3923                 break;
3924         case FIRMWARE_TYPE_SYMBOL:
3925                 /* Lack of documentation necessitates this hack.
3926                  * Different firmwares have 68 or 76 byte long atoms.
3927                  * We try modulo first.  If the length divides by both,
3928                  * we check what would be the channel in the second
3929                  * frame for a 68-byte atom.  76-byte atoms have 0 there.
3930                  * Valid channel cannot be 0.  */
3931                 if (scan_len % 76)
3932                         atom_len = 68;
3933                 else if (scan_len % 68)
3934                         atom_len = 76;
3935                 else if (scan_len >= 1292 && scan[68] == 0)
3936                         atom_len = 76;
3937                 else
3938                         atom_len = 68;
3939                 offset = 0;
3940                 break;
3941         case FIRMWARE_TYPE_INTERSIL:
3942                 offset = 4;
3943                 if (priv->has_hostscan) {
3944                         atom_len = le16_to_cpup((__le16 *)scan);
3945                         /* Sanity check for atom_len */
3946                         if (atom_len < sizeof(struct prism2_scan_apinfo)) {
3947                                 printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n",
3948                                 dev->name, atom_len);
3949                                 return -EIO;
3950                         }
3951                 } else
3952                         atom_len = offsetof(struct prism2_scan_apinfo, atim);
3953                 break;
3954         default:
3955                 return -EOPNOTSUPP;
3956         }
3957
3958         /* Check that we got an whole number of atoms */
3959         if ((scan_len - offset) % atom_len) {
3960                 printk(KERN_ERR "%s: Unexpected scan data length %d, "
3961                        "atom_len %d, offset %d\n", dev->name, scan_len,
3962                        atom_len, offset);
3963                 return -EIO;
3964         }
3965
3966         /* Read the entries one by one */
3967         for (; offset + atom_len <= scan_len; offset += atom_len) {
3968                 /* Get next atom */
3969                 atom = (union hermes_scan_info *) (scan + offset);
3970
3971                 /* First entry *MUST* be the AP MAC address */
3972                 iwe.cmd = SIOCGIWAP;
3973                 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
3974                 memcpy(iwe.u.ap_addr.sa_data, atom->a.bssid, ETH_ALEN);
3975                 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
3976
3977                 /* Other entries will be displayed in the order we give them */
3978
3979                 /* Add the ESSID */
3980                 iwe.u.data.length = le16_to_cpu(atom->a.essid_len);
3981                 if (iwe.u.data.length > 32)
3982                         iwe.u.data.length = 32;
3983                 iwe.cmd = SIOCGIWESSID;
3984                 iwe.u.data.flags = 1;
3985                 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
3986
3987                 /* Add mode */
3988                 iwe.cmd = SIOCGIWMODE;
3989                 capabilities = le16_to_cpu(atom->a.capabilities);
3990                 if (capabilities & 0x3) {
3991                         if (capabilities & 0x1)
3992                                 iwe.u.mode = IW_MODE_MASTER;
3993                         else
3994                                 iwe.u.mode = IW_MODE_ADHOC;
3995                         current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
3996                 }
3997
3998                 channel = atom->s.channel;
3999                 if ( (channel >= 1) && (channel <= NUM_CHANNELS) ) {
4000                         /* Add frequency */
4001                         iwe.cmd = SIOCGIWFREQ;
4002                         iwe.u.freq.m = channel_frequency[channel-1] * 100000;
4003                         iwe.u.freq.e = 1;
4004                         current_ev = iwe_stream_add_event(current_ev, end_buf,
4005                                                           &iwe, IW_EV_FREQ_LEN);
4006                 }
4007
4008                 /* Add quality statistics */
4009                 iwe.cmd = IWEVQUAL;
4010                 iwe.u.qual.updated = 0x10;      /* no link quality */
4011                 iwe.u.qual.level = (__u8) le16_to_cpu(atom->a.level) - 0x95;
4012                 iwe.u.qual.noise = (__u8) le16_to_cpu(atom->a.noise) - 0x95;
4013                 /* Wireless tools prior to 27.pre22 will show link quality
4014                  * anyway, so we provide a reasonable value. */
4015                 if (iwe.u.qual.level > iwe.u.qual.noise)
4016                         iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
4017                 else
4018                         iwe.u.qual.qual = 0;
4019                 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
4020
4021                 /* Add encryption capability */
4022                 iwe.cmd = SIOCGIWENCODE;
4023                 if (capabilities & 0x10)
4024                         iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
4025                 else
4026                         iwe.u.data.flags = IW_ENCODE_DISABLED;
4027                 iwe.u.data.length = 0;
4028                 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
4029
4030                 /* Bit rate is not available in Lucent/Agere firmwares */
4031                 if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
4032                         char *  current_val = current_ev + IW_EV_LCP_LEN;
4033                         int     i;
4034                         int     step;
4035
4036                         if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
4037                                 step = 2;
4038                         else
4039                                 step = 1;
4040
4041                         iwe.cmd = SIOCGIWRATE;
4042                         /* Those two flags are ignored... */
4043                         iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
4044                         /* Max 10 values */
4045                         for (i = 0; i < 10; i += step) {
4046                                 /* NULL terminated */
4047                                 if (atom->p.rates[i] == 0x0)
4048                                         break;
4049                                 /* Bit rate given in 500 kb/s units (+ 0x80) */
4050                                 iwe.u.bitrate.value = ((atom->p.rates[i] & 0x7f) * 500000);
4051                                 current_val = iwe_stream_add_value(current_ev, current_val,
4052                                                                    end_buf, &iwe,
4053                                                                    IW_EV_PARAM_LEN);
4054                         }
4055                         /* Check if we added any event */
4056                         if ((current_val - current_ev) > IW_EV_LCP_LEN)
4057                                 current_ev = current_val;
4058                 }
4059
4060                 /* The other data in the scan result are not really
4061                  * interesting, so for now drop it - Jean II */
4062         }
4063         return current_ev - buffer;
4064 }
4065
4066 /* Return results of a scan */
4067 static int orinoco_ioctl_getscan(struct net_device *dev,
4068                                  struct iw_request_info *info,
4069                                  struct iw_point *srq,
4070                                  char *extra)
4071 {
4072         struct orinoco_private *priv = netdev_priv(dev);
4073         int err = 0;
4074         unsigned long flags;
4075
4076         if (orinoco_lock(priv, &flags) != 0)
4077                 return -EBUSY;
4078
4079         /* If no results yet, ask to try again later */
4080         if (priv->scan_result == NULL) {
4081                 if (priv->scan_inprogress)
4082                         /* Important note : we don't want to block the caller
4083                          * until results are ready for various reasons.
4084                          * First, managing wait queues is complex and racy.
4085                          * Second, we grab some rtnetlink lock before comming
4086                          * here (in dev_ioctl()).
4087                          * Third, we generate an Wireless Event, so the
4088                          * caller can wait itself on that - Jean II */
4089                         err = -EAGAIN;
4090                 else
4091                         /* Client error, no scan results...
4092                          * The caller need to restart the scan. */
4093                         err = -ENODATA;
4094         } else {
4095                 /* We have some results to push back to user space */
4096
4097                 /* Translate to WE format */
4098                 int ret = orinoco_translate_scan(dev, extra,
4099                                                  priv->scan_result,
4100                                                  priv->scan_len);
4101
4102                 if (ret < 0) {
4103                         err = ret;
4104                         kfree(priv->scan_result);
4105                         priv->scan_result = NULL;
4106                 } else {
4107                         srq->length = ret;
4108
4109                         /* Return flags */
4110                         srq->flags = (__u16) priv->scan_mode;
4111
4112                         /* In any case, Scan results will be cleaned up in the
4113                          * reset function and when exiting the driver.
4114                          * The person triggering the scanning may never come to
4115                          * pick the results, so we need to do it in those places.
4116                          * Jean II */
4117
4118 #ifdef SCAN_SINGLE_READ
4119                         /* If you enable this option, only one client (the first
4120                          * one) will be able to read the result (and only one
4121                          * time). If there is multiple concurent clients that
4122                          * want to read scan results, this behavior is not
4123                          * advisable - Jean II */
4124                         kfree(priv->scan_result);
4125                         priv->scan_result = NULL;
4126 #endif /* SCAN_SINGLE_READ */
4127                         /* Here, if too much time has elapsed since last scan,
4128                          * we may want to clean up scan results... - Jean II */
4129                 }
4130
4131                 /* Scan is no longer in progress */
4132                 priv->scan_inprogress = 0;
4133         }
4134           
4135         orinoco_unlock(priv, &flags);
4136         return err;
4137 }
4138
4139 /* Commit handler, called after set operations */
4140 static int orinoco_ioctl_commit(struct net_device *dev,
4141                                 struct iw_request_info *info,
4142                                 void *wrqu,
4143                                 char *extra)
4144 {
4145         struct orinoco_private *priv = netdev_priv(dev);
4146         struct hermes *hw = &priv->hw;
4147         unsigned long flags;
4148         int err = 0;
4149
4150         if (!priv->open)
4151                 return 0;
4152
4153         if (priv->broken_disableport) {
4154                 orinoco_reset(dev);
4155                 return 0;
4156         }
4157
4158         if (orinoco_lock(priv, &flags) != 0)
4159                 return err;
4160
4161         err = hermes_disable_port(hw, 0);
4162         if (err) {
4163                 printk(KERN_WARNING "%s: Unable to disable port "
4164                        "while reconfiguring card\n", dev->name);
4165                 priv->broken_disableport = 1;
4166                 goto out;
4167         }
4168
4169         err = __orinoco_program_rids(dev);
4170         if (err) {
4171                 printk(KERN_WARNING "%s: Unable to reconfigure card\n",
4172                        dev->name);
4173                 goto out;
4174         }
4175
4176         err = hermes_enable_port(hw, 0);
4177         if (err) {
4178                 printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
4179                        dev->name);
4180                 goto out;
4181         }
4182
4183  out:
4184         if (err) {
4185                 printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
4186                 schedule_work(&priv->reset_work);
4187                 err = 0;
4188         }
4189
4190         orinoco_unlock(priv, &flags);
4191         return err;
4192 }
4193
4194 static const struct iw_priv_args orinoco_privtab[] = {
4195         { SIOCIWFIRSTPRIV + 0x0, 0, 0, "force_reset" },
4196         { SIOCIWFIRSTPRIV + 0x1, 0, 0, "card_reset" },
4197         { SIOCIWFIRSTPRIV + 0x2, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4198           0, "set_port3" },
4199         { SIOCIWFIRSTPRIV + 0x3, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4200           "get_port3" },
4201         { SIOCIWFIRSTPRIV + 0x4, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4202           0, "set_preamble" },
4203         { SIOCIWFIRSTPRIV + 0x5, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4204           "get_preamble" },
4205         { SIOCIWFIRSTPRIV + 0x6, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4206           0, "set_ibssport" },
4207         { SIOCIWFIRSTPRIV + 0x7, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
4208           "get_ibssport" },
4209         { SIOCIWFIRSTPRIV + 0x9, 0, IW_PRIV_TYPE_BYTE | MAX_RID_LEN,
4210           "get_rid" },
4211 };
4212
4213
4214 /*
4215  * Structures to export the Wireless Handlers
4216  */
4217
4218 static const iw_handler orinoco_handler[] = {
4219         [SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_commit,
4220         [SIOCGIWNAME  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getname,
4221         [SIOCSIWFREQ  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setfreq,
4222         [SIOCGIWFREQ  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getfreq,
4223         [SIOCSIWMODE  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setmode,
4224         [SIOCGIWMODE  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getmode,
4225         [SIOCSIWSENS  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens,
4226         [SIOCGIWSENS  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens,
4227         [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange,
4228         [SIOCSIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
4229         [SIOCGIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
4230         [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
4231         [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
4232         [SIOCSIWAP    -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap,
4233         [SIOCGIWAP    -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap,
4234         [SIOCSIWSCAN  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan,
4235         [SIOCGIWSCAN  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getscan,
4236         [SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setessid,
4237         [SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getessid,
4238         [SIOCSIWNICKN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setnick,
4239         [SIOCGIWNICKN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getnick,
4240         [SIOCSIWRATE  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setrate,
4241         [SIOCGIWRATE  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getrate,
4242         [SIOCSIWRTS   -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setrts,
4243         [SIOCGIWRTS   -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getrts,
4244         [SIOCSIWFRAG  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setfrag,
4245         [SIOCGIWFRAG  -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getfrag,
4246         [SIOCGIWRETRY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getretry,
4247         [SIOCSIWENCODE-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setiwencode,
4248         [SIOCGIWENCODE-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwencode,
4249         [SIOCSIWPOWER -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setpower,
4250         [SIOCGIWPOWER -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getpower,
4251 };
4252
4253
4254 /*
4255   Added typecasting since we no longer use iwreq_data -- Moustafa
4256  */
4257 static const iw_handler orinoco_private_handler[] = {
4258         [0] = (iw_handler) orinoco_ioctl_reset,
4259         [1] = (iw_handler) orinoco_ioctl_reset,
4260         [2] = (iw_handler) orinoco_ioctl_setport3,
4261         [3] = (iw_handler) orinoco_ioctl_getport3,
4262         [4] = (iw_handler) orinoco_ioctl_setpreamble,
4263         [5] = (iw_handler) orinoco_ioctl_getpreamble,
4264         [6] = (iw_handler) orinoco_ioctl_setibssport,
4265         [7] = (iw_handler) orinoco_ioctl_getibssport,
4266         [9] = (iw_handler) orinoco_ioctl_getrid,
4267 };
4268
4269 static const struct iw_handler_def orinoco_handler_def = {
4270         .num_standard = ARRAY_SIZE(orinoco_handler),
4271         .num_private = ARRAY_SIZE(orinoco_private_handler),
4272         .num_private_args = ARRAY_SIZE(orinoco_privtab),
4273         .standard = orinoco_handler,
4274         .private = orinoco_private_handler,
4275         .private_args = orinoco_privtab,
4276         .get_wireless_stats = orinoco_get_wireless_stats,
4277 };
4278
4279 static void orinoco_get_drvinfo(struct net_device *dev,
4280                                 struct ethtool_drvinfo *info)
4281 {
4282         struct orinoco_private *priv = netdev_priv(dev);
4283
4284         strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
4285         strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
4286         strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
4287         if (dev->class_dev.dev)
4288                 strncpy(info->bus_info, dev->class_dev.dev->bus_id,
4289                         sizeof(info->bus_info) - 1);
4290         else
4291                 snprintf(info->bus_info, sizeof(info->bus_info) - 1,
4292                          "PCMCIA %p", priv->hw.iobase);
4293 }
4294
4295 static struct ethtool_ops orinoco_ethtool_ops = {
4296         .get_drvinfo = orinoco_get_drvinfo,
4297         .get_link = ethtool_op_get_link,
4298 };
4299
4300 /********************************************************************/
4301 /* Module initialization                                            */
4302 /********************************************************************/
4303
4304 EXPORT_SYMBOL(alloc_orinocodev);
4305 EXPORT_SYMBOL(free_orinocodev);
4306
4307 EXPORT_SYMBOL(__orinoco_up);
4308 EXPORT_SYMBOL(__orinoco_down);
4309 EXPORT_SYMBOL(orinoco_reinit_firmware);
4310
4311 EXPORT_SYMBOL(orinoco_interrupt);
4312
4313 /* Can't be declared "const" or the whole __initdata section will
4314  * become const */
4315 static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
4316         " (David Gibson <hermes@gibson.dropbear.id.au>, "
4317         "Pavel Roskin <proski@gnu.org>, et al)";
4318
4319 static int __init init_orinoco(void)
4320 {
4321         printk(KERN_DEBUG "%s\n", version);
4322         return 0;
4323 }
4324
4325 static void __exit exit_orinoco(void)
4326 {
4327 }
4328
4329 module_init(init_orinoco);
4330 module_exit(exit_orinoco);