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