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