File: /usr/src/linux/drivers/net/wireless/orinoco.c

1     /* orinoco.c 0.07	- (formerly known as dldwd_cs.c and orinoco_cs.c)
2      *
3      * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
4      * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
5      * EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and others).
6      * It should also be usable on various Prism II based cards such as the
7      * Linksys, D-Link and Farallon Skyline. It should also work on Symbol
8      * cards such as the 3Com AirConnect and Ericsson WLAN.
9      *
10      * Copyright (C) 2000 David Gibson, Linuxcare Australia <hermes@gibson.dropbear.id.au>
11      *	With some help from :
12      * Copyright (C) 2001 Jean Tourrilhes, HP Labs <jt@hpl.hp.com>
13      * Copyright (C) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
14      *
15      * Based on dummy_cs.c 1.27 2000/06/12 21:27:25
16      *
17      * Portions based on wvlan_cs.c 1.0.6, Copyright Andreas Neuhaus <andy@fasta.fh-dortmund.de>
18      *      http://www.fasta.fh-dortmund.de/users/andy/wvlan/
19      *
20      * The contents of this file are subject to the Mozilla Public License
21      * Version 1.1 (the "License"); you may not use this file except in
22      * compliance with the License. You may obtain a copy of the License
23      * at http://www.mozilla.org/MPL/
24      *
25      * Software distributed under the License is distributed on an "AS IS"
26      * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
27      * the License for the specific language governing rights and
28      * limitations under the License.
29      *
30      * The initial developer of the original code is David A. Hinds
31      * <dahinds@users.sourceforge.net>.  Portions created by David
32      * A. Hinds are Copyright (C) 1999 David A. Hinds.  All Rights
33      * Reserved.
34      *
35      * Alternatively, the contents of this file may be used under the
36      * terms of the GNU General Public License version 2 (the "GPL"), in
37      * which case the provisions of the GPL are applicable instead of the
38      * above.  If you wish to allow the use of your version of this file
39      * only under the terms of the GPL and not to allow others to use your
40      * version of this file under the MPL, indicate your decision by
41      * deleting the provisions above and replace them with the notice and
42      * other provisions required by the GPL.  If you do not delete the
43      * provisions above, a recipient may use your version of this file
44      * under either the MPL or the GPL.
45      */
46     
47     /* Notes on locking:
48      *
49      * The basic principle of operation is that everything except the
50      * interrupt handler is serialized through a single spinlock in the
51      * dldwd_priv_t structure, using dldwd_lock() and
52      * dldwd_unlock() (which in turn use spin_lock_bh() and spin_unlock_bh()).
53      *
54      * The kernel's IRQ handling stuff ensures that the interrupt handler
55      * does not re-enter itself. The interrupt handler is written such
56      * that everything it does is safe without a lock: chiefly this means
57      * that the Rx path uses one of the Hermes chipset's BAPs while
58      * everything else uses the other.
59      *
60      * For the moment access to the device statistics from the interrupt
61      * handler is unsafe - we just put up with any resulting errors in the
62      * statisics. FIXME: This should probably be changed to store the
63      * stats in atomic types.
64      *
65      * EXCEPT that we don't want the irq handler running when we actually
66      * reset or shut down the card, because strange things might happen
67      * (probably the worst would be one packet of garbage, but you can't
68      * be too careful). For this we use __dldwd_stop_irqs() which will set
69      * a flag to disable the interrupt handler, and wait for any
70      * outstanding instances of the handler to complete. THIS WILL LOSE
71      * INTERRUPTS! so it shouldn't be used except for resets, when we
72      * don't care about that.*/
73     
74     /*
75      * Tentative changelog...
76      *
77      * v0.01 -> v0.02 - 21/3/2001 - Jean II
78      *	o Allow to use regular ethX device name instead of dldwdX
79      *	o Warning on IBSS with ESSID=any for firmware 6.06
80      *	o Put proper range.throughput values (optimistic)
81      *	o IWSPY support (IOCTL and stat gather in Rx path)
82      *	o Allow setting frequency in Ad-Hoc mode
83      *	o Disable WEP setting if !has_wep to work on old firmware
84      *	o Fix txpower range
85      *	o Start adding support for Samsung/Compaq firmware
86      *
87      * v0.02 -> v0.03 - 23/3/2001 - Jean II
88      *	o Start adding Symbol support - need to check all that
89      *	o Fix Prism2/Symbol WEP to accept 128 bits keys
90      *	o Add Symbol WEP (add authentication type)
91      *	o Add Prism2/Symbol rate
92      *	o Add PM timeout (holdover duration)
93      *	o Enable "iwconfig eth0 key off" and friends (toggle flags)
94      *	o Enable "iwconfig eth0 power unicast/all" (toggle flags)
95      *	o Try with an intel card. It report firmware 1.01, behave like
96      *	  an antiquated firmware, however on windows it says 2.00. Yuck !
97      *	o Workaround firmware bug in allocate buffer (Intel 1.01)
98      *	o Finish external renaming to orinoco...
99      *	o Testing with various Wavelan firmwares
100      *
101      * v0.03 -> v0.04 - 30/3/2001 - Jean II
102      *	o Update to Wireless 11 -> add retry limit/lifetime support
103      *	o Tested with a D-Link DWL 650 card, fill in firmware support
104      *	o Warning on Vcc mismatch (D-Link 3.3v card in Lucent 5v only slot)
105      *	o Fixed the Prims2 WEP bugs that I introduced in v0.03 :-(
106      *	  It work on D-Link *only* after a tcpdump. Weird...
107      *	  And still doesn't work on Intel card. Grrrr...
108      *	o Update the mode after a setport3
109      *	o Add preamble setting for Symbol cards (not yet enabled)
110      *	o Don't complain as much about Symbol cards...
111      *
112      * v0.04 -> v0.04b - 22/4/2001 - David Gibson
113      *      o Removed the 'eth' parameter - always use ethXX as the
114      *        interface name instead of dldwdXX.  The other was racy
115      *        anyway.
116      *	o Clean up RID definitions in hermes.h, other cleanups
117      *
118      * v0.04b -> v0.04c - 24/4/2001 - Jean II
119      *	o Tim Hurley <timster@seiki.bliztech.com> reported a D-Link card
120      *	  with vendor 02 and firmware 0.08. Added in the capabilities...
121      *	o Tested Lucent firmware 7.28, everything works...
122      *
123      * v0.04c -> v0.05 - 3/5/2001 - Benjamin Herrenschmidt
124      *	o Spin-off Pcmcia code. This file is renamed orinoco.c,
125      *	  and orinoco_cs.c now contains only the Pcmcia specific stuff
126      *	o Add Airport driver support on top of orinoco.c (see airport.c)
127      *
128      * v0.05 -> v0.05a - 4/5/2001 - Jean II
129      *	o Revert to old Pcmcia code to fix breakage of Ben's changes...
130      *
131      * v0.05a -> v0.05b - 4/5/2001 - Jean II
132      *	o add module parameter 'ignore_cis_vcc' for D-Link @ 5V
133      *	o D-Link firmware doesn't support multicast. We just print a few
134      *	  error messages, but otherwise everything works...
135      *	o For David : set/getport3 works fine, just upgrade iwpriv...
136      *
137      * v0.05b -> v0.05c - 5/5/2001 - Benjamin Herrenschmidt
138      *	o Adapt airport.c to latest changes in orinoco.c
139      *	o Remove deferred power enabling code
140      *
141      * v0.05c -> v0.05d - 5/5/2001 - Jean II
142      *	o Workaround to SNAP decapsulate frame from LinkSys AP
143      *	  original patch from : Dong Liu <dliu@research.bell-labs.com>
144      *	  (note : the memcmp bug was mine - fixed)
145      *	o Remove set_retry stuff, no firmware support it (bloat--).
146      *
147      * v0.05d -> v0.06 - 25/5/2001 - Jean II
148      *		Original patch from "Hong Lin" <alin@redhat.com>,
149      *		"Ian Kinner" <ikinner@redhat.com>
150      *		and "David Smith" <dsmith@redhat.com>
151      *	o Init of priv->tx_rate_ctrl in firmware specific section.
152      *	o Prism2/Symbol rate, upto should be 0xF and not 0x15. Doh !
153      *	o Spectrum card always need cor_reset (for every reset)
154      *	o Fix cor_reset to not loose bit 7 in the register
155      *	o flush_stale_links to remove zombie Pcmcia instances
156      *	o Ack previous hermes event before reset
157      *		Me (with my little hands)
158      *	o Allow orinoco.c to call cor_reset via priv->card_reset_handler
159      *	o Add priv->need_card_reset to toggle this feature
160      *	o Fix various buglets when setting WEP in Symbol firmware
161      *	  Now, encryption is fully functional on Symbol cards. Youpi !
162      *
163      * v0.06 -> v0.06b - 25/5/2001 - Jean II
164      *	o IBSS on Symbol use port_mode = 4. Please don't ask...
165      *
166      * v0.06b -> v0.06c - 29/5/2001 - Jean II
167      *	o Show first spy address in /proc/net/wireless for IBSS mode as well
168      *
169      * v0.06c -> v0.06d - 6/7/2001 - David Gibson
170      *      o Change a bunch of KERN_INFO messages to KERN_DEBUG, as per Linus'
171      *        wishes to reduce the number of unecessary messages.
172      *	o Removed bogus message on CRC error.
173      *	o Merged fixeds for v0.08 Prism 2 firmware from William Waghorn
174      *	  <willwaghorn@yahoo.co.uk>
175      *	o Slight cleanup/re-arrangement of firmware detection code.
176      *
177      * v0.06d -> v0.06e - 1/8/2001 - David Gibson
178      *	o Removed some redundant global initializers (orinoco_cs.c).
179      *	o Added some module metadataa
180      *
181      * v0.06e -> v0.06f - 14/8/2001 - David Gibson
182      *	o Wording fix to license
183      *	o Added a 'use_alternate_encaps' module parameter for APs which need an oui of
184      *	  00:00:00.  We really need a better way of handling this, but the module flag
185      *	  is better than nothing for now.
186      *
187      * v0.06f -> v0.07 - 20/8/2001 - David Gibson
188      *	o Removed BAP error retries from hermes_bap_seek().  For Tx we now
189      *	  let the upper layers handle the retry, we retry explicitly in the
190      *	  Rx path, but don't make as much noise about it.
191      *	o Firmware detection cleanups.
192      *
193      *
194      * TODO - Jean II
195      *	o inline functions (lot's of candidate, need to reorder code)
196      *	o Test PrismII/Symbol cards & firmware versions
197      *	o Mini-PCI support (some people have reported success - JII)
198      */
199     
200     #include <linux/module.h>
201     #include <linux/kernel.h>
202     #include <linux/init.h>
203     #include <linux/sched.h>
204     #include <linux/ptrace.h>
205     #include <linux/slab.h>
206     #include <linux/string.h>
207     #include <linux/timer.h>
208     #include <linux/ioport.h>
209     #include <asm/uaccess.h>
210     #include <asm/io.h>
211     #include <asm/system.h>
212     #include <linux/proc_fs.h>
213     #include <linux/netdevice.h>
214     #include <linux/if_arp.h>
215     #include <linux/etherdevice.h>
216     #include <linux/wireless.h>
217     #include <linux/list.h>
218     
219     #include <pcmcia/version.h>
220     #include <pcmcia/cs_types.h>
221     #include <pcmcia/cs.h>
222     #include <pcmcia/cistpl.h>
223     #include <pcmcia/cisreg.h>
224     #include <pcmcia/ds.h>
225     #include <pcmcia/bus_ops.h>
226     
227     #include "hermes.h"
228     #include "orinoco.h"
229     
230     static char version[] __initdata = "orinoco.c 0.07 (David Gibson <hermes@gibson.dropbear.id.au> and others)";
231     MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
232     MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
233     MODULE_LICENSE("Dual MPL/GPL");
234     
235     /* Level of debugging. Used in the macros in orinoco.h */
236     #ifdef ORINOCO_DEBUG
237     int dldwd_debug = ORINOCO_DEBUG;
238     MODULE_PARM(dldwd_debug, "i");
239     #endif
240     
241     /* FIXME: We need a better way of handling this */
242     /* Set this flag to use 00:00:00 for the encapsulation oui instead of 00:00:F8 */
243     static int use_alternate_encaps; /* =0 */
244     MODULE_PARM(use_alternate_encaps, "i");
245     
246     const long channel_frequency[] = {
247     	2412, 2417, 2422, 2427, 2432, 2437, 2442,
248     	2447, 2452, 2457, 2462, 2467, 2472, 2484
249     };
250     
251     #define NUM_CHANNELS ( sizeof(channel_frequency) / sizeof(channel_frequency[0]) )
252     
253     /* This tables gives the actual meanings of the bitrate IDs returned by the firmware.
254        It gives the rate in halfMb/s, negative indicates auto mode */
255     const int rate_list[] = { 0, 2, 4, -22, 11, 22, -4, -11, 0, 0, 0, 0};
256     
257     #define NUM_RATES (sizeof(rate_list) / sizeof(rate_list[0]))
258     
259     struct p80211_hdr {
260     	uint16_t frame_ctl;
261     	uint16_t duration_id;
262     	uint8_t addr1[ETH_ALEN];
263     	uint8_t addr2[ETH_ALEN];
264     	uint8_t addr3[ETH_ALEN];
265     	uint16_t seq_ctl;
266     	uint8_t addr4[ETH_ALEN];
267     	uint16_t data_len;
268     } __attribute__ ((packed));
269     
270     /* Frame control field constants */
271     #define DLDWD_FCTL_VERS			0x0002
272     #define DLDWD_FCTL_FTYPE		0x000c
273     #define DLDWD_FCTL_STYPE		0x00f0
274     #define DLDWD_FCTL_TODS			0x0100
275     #define DLDWD_FCTL_FROMDS		0x0200
276     #define DLDWD_FCTL_MOREFRAGS		0x0400
277     #define DLDWD_FCTL_RETRY		0x0800
278     #define DLDWD_FCTL_PM			0x1000
279     #define DLDWD_FCTL_MOREDATA		0x2000
280     #define DLDWD_FCTL_WEP			0x4000
281     #define DLDWD_FCTL_ORDER		0x8000
282     
283     #define DLDWD_FTYPE_MGMT		0x0000
284     #define DLDWD_FTYPE_CTL			0x0004
285     #define DLDWD_FTYPE_DATA		0x0008
286     
287     #define __PACKED__ __attribute__ ((packed))
288     
289     struct p8022_hdr {
290     	uint8_t dsap __PACKED__;
291     	uint8_t ssap __PACKED__;
292     	uint8_t ctrl __PACKED__;
293     	uint8_t oui[3] __PACKED__;
294     };
295     
296     struct dldwd_frame_hdr {
297     	hermes_frame_desc_t desc __PACKED__;
298     	struct p80211_hdr p80211 __PACKED__;
299     	struct ethhdr p8023 __PACKED__;
300     	struct p8022_hdr p8022 __PACKED__;
301     	uint16_t ethertype __PACKED__;
302     };
303     
304     #define P8023_OFFSET		(sizeof(hermes_frame_desc_t) + \
305     				sizeof(struct p80211_hdr))
306     #define ENCAPS_OVERHEAD		(sizeof(struct p8022_hdr) + 2)
307     
308     /* 802.2 LLL header SNAP used for SNAP encapsulation over 802.11 */
309     struct p8022_hdr encaps_hdr = {
310     	0xaa, 0xaa, 0x03, {0x00, 0x00, 0xf8}
311     };
312     struct p8022_hdr alternate_encaps_hdr = {
313     	0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}
314     };
315     
316     /* How many times to retry if we get an EIO reading the BAP in the Rx path */
317     #define RX_EIO_RETRY		10
318     
319     typedef struct dldwd_commsqual {
320     	uint16_t qual, signal, noise;
321     } __PACKED__ dldwd_commsqual_t;
322     
323     
324     /*
325      * Function prototypes
326      */
327     
328     static void dldwd_stat_gather(struct net_device *dev,
329     			      struct sk_buff *skb,
330     			      struct dldwd_frame_hdr *hdr);
331     
332     static struct net_device_stats *dldwd_get_stats(struct net_device *dev);
333     static struct iw_statistics *dldwd_get_wireless_stats(struct net_device *dev);
334     
335     /* Hardware control routines */
336     
337     static int __dldwd_hw_reset(dldwd_priv_t *priv);
338     static int __dldwd_hw_setup_wep(dldwd_priv_t *priv);
339     static int dldwd_hw_get_bssid(dldwd_priv_t *priv, char buf[ETH_ALEN]);
340     static int dldwd_hw_get_essid(dldwd_priv_t *priv, int *active, char buf[IW_ESSID_MAX_SIZE+1]);
341     static long dldwd_hw_get_freq(dldwd_priv_t *priv);
342     static int dldwd_hw_get_bitratelist(dldwd_priv_t *priv, int *numrates,
343     				    int32_t *rates, int max);
344     
345     /* Interrupt handling routines */
346     static void __dldwd_ev_tick(dldwd_priv_t *priv, hermes_t *hw);
347     static void __dldwd_ev_wterr(dldwd_priv_t *priv, hermes_t *hw);
348     static void __dldwd_ev_infdrop(dldwd_priv_t *priv, hermes_t *hw);
349     static void __dldwd_ev_info(dldwd_priv_t *priv, hermes_t *hw);
350     static void __dldwd_ev_rx(dldwd_priv_t *priv, hermes_t *hw);
351     static void __dldwd_ev_txexc(dldwd_priv_t *priv, hermes_t *hw);
352     static void __dldwd_ev_tx(dldwd_priv_t *priv, hermes_t *hw);
353     static void __dldwd_ev_alloc(dldwd_priv_t *priv, hermes_t *hw);
354     
355     static int dldwd_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq);
356     static int dldwd_ioctl_setiwencode(struct net_device *dev, struct iw_point *erq);
357     static int dldwd_ioctl_getiwencode(struct net_device *dev, struct iw_point *erq);
358     static int dldwd_ioctl_setessid(struct net_device *dev, struct iw_point *erq);
359     static int dldwd_ioctl_getessid(struct net_device *dev, struct iw_point *erq);
360     static int dldwd_ioctl_setnick(struct net_device *dev, struct iw_point *nrq);
361     static int dldwd_ioctl_getnick(struct net_device *dev, struct iw_point *nrq);
362     static int dldwd_ioctl_setfreq(struct net_device *dev, struct iw_freq *frq);
363     static int dldwd_ioctl_getsens(struct net_device *dev, struct iw_param *srq);
364     static int dldwd_ioctl_setsens(struct net_device *dev, struct iw_param *srq);
365     static int dldwd_ioctl_setrts(struct net_device *dev, struct iw_param *rrq);
366     static int dldwd_ioctl_setfrag(struct net_device *dev, struct iw_param *frq);
367     static int dldwd_ioctl_getfrag(struct net_device *dev, struct iw_param *frq);
368     static int dldwd_ioctl_setrate(struct net_device *dev, struct iw_param *frq);
369     static int dldwd_ioctl_getrate(struct net_device *dev, struct iw_param *frq);
370     static int dldwd_ioctl_setpower(struct net_device *dev, struct iw_param *prq);
371     static int dldwd_ioctl_getpower(struct net_device *dev, struct iw_param *prq);
372     static int dldwd_ioctl_setport3(struct net_device *dev, struct iwreq *wrq);
373     static int dldwd_ioctl_getport3(struct net_device *dev, struct iwreq *wrq);
374     static void __dldwd_set_multicast_list(struct net_device *dev);
375     
376     /* /proc debugging stuff */
377     static int dldwd_proc_init(void);
378     static void dldwd_proc_cleanup(void);
379     
380     /*
381      * Inline functions
382      */
383     static inline void
384     dldwd_lock(dldwd_priv_t *priv)
385     {
386     	spin_lock_bh(&priv->lock);
387     }
388     
389     static inline void
390     dldwd_unlock(dldwd_priv_t *priv)
391     {
392     	spin_unlock_bh(&priv->lock);
393     }
394     
395     static inline int
396     dldwd_irqs_allowed(dldwd_priv_t *priv)
397     {
398     	return test_bit(DLDWD_STATE_DOIRQ, &priv->state);
399     }
400     
401     static inline void
402     __dldwd_stop_irqs(dldwd_priv_t *priv)
403     {
404     	hermes_t *hw = &priv->hw;
405     
406     	hermes_set_irqmask(hw, 0);
407     	clear_bit(DLDWD_STATE_DOIRQ, &priv->state);
408     	while (test_bit(DLDWD_STATE_INIRQ, &priv->state))
409     		;
410     }
411     
412     static inline void
413     __dldwd_start_irqs(dldwd_priv_t *priv, uint16_t irqmask)
414     {
415     	hermes_t *hw = &priv->hw;
416     
417     	TRACE_ENTER(priv->ndev.name);
418     
419     	__cli();
420     	set_bit(DLDWD_STATE_DOIRQ, &priv->state);
421     	hermes_set_irqmask(hw, irqmask);
422     	__sti();
423     
424     	TRACE_EXIT(priv->ndev.name);
425     }
426     
427     static inline void
428     set_port_type(dldwd_priv_t *priv)
429     {
430     	switch (priv->iw_mode) {
431     	case IW_MODE_INFRA:
432     		priv->port_type = 1;
433     		priv->allow_ibss = 0;
434     		break;
435     	case IW_MODE_ADHOC:
436     		if (priv->prefer_port3) {
437     			priv->port_type = 3;
438     			priv->allow_ibss = 0;
439     		} else {
440     			priv->port_type = priv->ibss_port;
441     			priv->allow_ibss = 1;
442     		}
443     		break;
444     	default:
445     		printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
446     		       priv->ndev.name);
447     	}
448     }
449     
450     extern void
451     dldwd_set_multicast_list(struct net_device *dev)
452     {
453     	dldwd_priv_t *priv = dev->priv;
454     
455     	dldwd_lock(priv);
456     	__dldwd_set_multicast_list(dev);
457     	dldwd_unlock(priv);
458     }
459     
460     /*
461      * Hardware control routines
462      */
463     
464     static int
465     __dldwd_hw_reset(dldwd_priv_t *priv)
466     {
467     	hermes_t *hw = &priv->hw;
468     	int err;
469     
470     	if (! priv->broken_reset)
471     		return hermes_reset(hw);
472     	else {
473     		hw->inten = 0;
474     		hermes_write_regn(hw, INTEN, 0);
475     		err = hermes_disable_port(hw, 0);
476     		hermes_write_regn(hw, EVACK, 0xffff);
477     		return err;
478     	}
479     }
480     
481     void
482     dldwd_shutdown(dldwd_priv_t *priv)
483     {
484     /* 	hermes_t *hw = &priv->hw; */
485     	int err = 0;
486     
487     	TRACE_ENTER(priv->ndev.name);
488     
489     	dldwd_lock(priv);
490     	__dldwd_stop_irqs(priv);
491     
492     	err = __dldwd_hw_reset(priv);
493     	if (err && err != -ENODEV) /* If the card is gone, we don't care about shutting it down */
494     		printk(KERN_ERR "%s: Error %d shutting down Hermes chipset\n", priv->ndev.name, err);
495     
496     	dldwd_unlock(priv);
497     
498     	TRACE_EXIT(priv->ndev.name);
499     }
500     
501     int
502     dldwd_reset(dldwd_priv_t *priv)
503     {
504     	struct net_device *dev = &priv->ndev;
505     	hermes_t *hw = &priv->hw;
506     	int err = 0;
507     	hermes_id_t idbuf;
508     	int frame_size;
509     
510     	TRACE_ENTER(priv->ndev.name);
511     
512     	/* Stop other people bothering us */
513     	dldwd_lock(priv);
514     	__dldwd_stop_irqs(priv);
515     
516     	/* Check if we need a card reset */
517     	if((priv->need_card_reset) && (priv->card_reset_handler != NULL))
518     		priv->card_reset_handler(priv);
519     
520     	/* Do standard firmware reset if we can */
521     	err = __dldwd_hw_reset(priv);
522     	if (err)
523     		goto out;
524     
525     	frame_size = TX_NICBUF_SIZE;
526     	/* This stupid bug is present in Intel firmware 1.10, and
527     	 * may be fixed in later firmwares - Jean II */
528     	if(priv->broken_allocate)
529     		frame_size = TX_NICBUF_SIZE_BUG;
530     	err = hermes_allocate(hw, frame_size, &priv->txfid);
531     	if (err)
532     		goto out;
533     
534     	/* Now set up all the parameters on the card */
535     	
536     	/* Set up the link mode */
537     	
538     	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PORTTYPE, priv->port_type);
539     	if (err)
540     		goto out;
541     	if (priv->has_ibss) {
542     		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_CREATEIBSS,
543     					   priv->allow_ibss);
544     		if (err)
545     			goto out;
546     		if((strlen(priv->desired_essid) == 0) && (priv->allow_ibss)
547     		   && (!priv->has_ibss_any)) {
548     			printk(KERN_WARNING "%s: This firmware requires an \
549     ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
550     			/* With wvlan_cs, in this case, we would crash.
551     			 * hopefully, this driver will behave better...
552     			 * Jean II */
553     		}
554     	}
555     
556     	/* Set up encryption */
557     	if (priv->has_wep) {
558     		err = __dldwd_hw_setup_wep(priv);
559     		if (err)
560     			goto out;
561     	}
562     
563     	/* Set the desired ESSID */
564     	idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
565     	memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
566     	err = hermes_write_ltv(hw, USER_BAP, (priv->port_type == 3) ?
567     			       HERMES_RID_CNF_OWN_SSID : HERMES_RID_CNF_DESIRED_SSID,
568     			       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
569     			       &idbuf);
570     	if (err)
571     		goto out;
572     
573     	/* Set the station name */
574     	idbuf.len = cpu_to_le16(strlen(priv->nick));
575     	memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
576     	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNF_NICKNAME,
577     			       HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
578     			       &idbuf);
579     	if (err)
580     		goto out;
581     
582     	/* Set the channel/frequency */
583     	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_CHANNEL, priv->channel);
584     	if (err)
585     		goto out;
586     
587     	/* Set AP density */
588     	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYSTEM_SCALE, priv->ap_density);
589     	if (err)
590     		goto out;
591     
592     	/* Set RTS threshold */
593     	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_RTS_THRESH, priv->rts_thresh);
594     	if (err)
595     		goto out;
596     
597     	/* Set fragmentation threshold or MWO robustness */
598     	if (priv->has_mwo)
599     		err = hermes_write_wordrec(hw, USER_BAP,
600     					   HERMES_RID_CNF_MWO_ROBUST, priv->mwo_robust);
601     	else
602     		err = hermes_write_wordrec(hw, USER_BAP,
603     					   HERMES_RID_CNF_FRAG_THRESH, priv->frag_thresh);
604     	if (err)
605     		goto out;
606     
607     	/* Set bitrate */
608     	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_TX_RATE_CTRL,
609     				   priv->tx_rate_ctrl);
610     	if (err)
611     		goto out;
612     
613     	/* Set power management */
614     	if (priv->has_pm) {
615     		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_ENABLE,
616     					   priv->pm_on);
617     		if (err)
618     			goto out;
619     		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_MCAST_RX,
620     					   priv->pm_mcast);
621     		if (err)
622     			goto out;
623     		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_PERIOD,
624     					   priv->pm_period);
625     		if (err)
626     			goto out;
627     		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_HOLDOVER,
628     					   priv->pm_timeout);
629     		if (err)
630     			goto out;
631     	}
632     
633     	/* Set preamble - only for Symbol so far... */
634     	if (priv->has_preamble) {
635     		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYMBOL_PREAMBLE,
636     					   priv->preamble);
637     		if (err) {
638     			printk(KERN_WARNING "%s: Can't set preamble!\n", dev->name);
639     			goto out;
640     		}
641     	}
642     
643     	/* Set promiscuity / multicast*/
644     	priv->promiscuous = 0;
645     	priv->allmulti = 0;
646     	priv->mc_count = 0;
647     	__dldwd_set_multicast_list(dev);
648     	
649     	err = hermes_enable_port(hw, DLDWD_MACPORT);
650     	if (err)
651     		goto out;
652     	
653     	__dldwd_start_irqs(priv, HERMES_EV_RX | HERMES_EV_ALLOC |
654     			   HERMES_EV_TX | HERMES_EV_TXEXC |
655     			   HERMES_EV_WTERR | HERMES_EV_INFO |
656     			   HERMES_EV_INFDROP);
657     
658      out:
659     	dldwd_unlock(priv);
660     
661     	TRACE_EXIT(priv->ndev.name);
662     
663     	return err;
664     }
665     
666     static int __dldwd_hw_setup_wep(dldwd_priv_t *priv)
667     {
668     	hermes_t *hw = &priv->hw;
669     	int err = 0;
670     	int	master_wep_flag;
671     	int	auth_flag;
672     
673     	switch (priv->firmware_type) {
674     	case FIRMWARE_TYPE_LUCENT: /* Lucent style WEP */
675     		if (priv->wep_on) {
676     			err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_TX_KEY, priv->tx_key);
677     			if (err)
678     				return err;
679     			
680     			err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNF_KEYS, &priv->keys);
681     			if (err)
682     				return err;
683     		}
684     		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_WEP_ON, priv->wep_on);
685     		if (err)
686     			return err;
687     		break;
688     
689     	case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
690     	case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
691     		master_wep_flag = 0;		/* Off */
692     		if (priv->wep_on) {
693     			char keybuf[LARGE_KEY_SIZE+1];
694     			int keylen;
695     			int i;
696     
697     			/* Fudge around firmware weirdness */
698     			keylen = priv->keys[priv->tx_key].len;
699     
700     			/* Write all 4 keys */
701     			for(i = 0; i < MAX_KEYS; i++) {
702     				memset(keybuf, 0, sizeof(keybuf));
703     				memcpy(keybuf, priv->keys[i].data,
704     				       priv->keys[i].len);
705     				err = hermes_write_ltv(hw, USER_BAP,
706     						       HERMES_RID_CNF_PRISM2_KEY0 + i,
707     						       HERMES_BYTES_TO_RECLEN(keylen),
708     						       keybuf);
709     				if (err)
710     					return err;
711     			}
712     
713     			/* Write the index of the key used in transmission */
714     			err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PRISM2_TX_KEY,
715     						   priv->tx_key);
716     			if (err)
717     				return err;
718     
719     			/* Authentication is where Intersil and Symbol
720     			 * firmware differ... */
721     			if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL) {
722     				/* Symbol cards : set the authentication :
723     				 * 0 -> no encryption, 1 -> open,
724     				 * 2 -> shared key
725     				 * 3 -> shared key 128 -> AP only */
726     				if(priv->wep_restrict)
727     					auth_flag = 2;
728     				else
729     					auth_flag = 1;
730     				err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYMBOL_AUTH_TYPE, auth_flag);
731     				if (err)
732     					return err;
733     				/* Master WEP setting is always 3 */
734     				master_wep_flag = 3;
735     			} else {
736     				/* Prism2 card : we need to modify master
737     				 * WEP setting */
738     				if(priv->wep_restrict)
739     					master_wep_flag = 3;
740     				else
741     					master_wep_flag = 1;
742     			}
743     		}
744     		
745     		/* Master WEP setting : on/off */
746     		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PRISM2_WEP_ON, master_wep_flag);
747     		if (err)
748     			return err;	
749     		break;
750     
751     	default:
752     		if (priv->wep_on) {
753     			printk(KERN_ERR "%s: WEP enabled, although not supported!\n",
754     			       priv->ndev.name);
755     			return -EINVAL;
756     		}
757     	}
758     
759     	return 0;
760     }
761     
762     static int dldwd_hw_get_bssid(dldwd_priv_t *priv, char buf[ETH_ALEN])
763     {
764     	hermes_t *hw = &priv->hw;
765     	int err = 0;
766     
767     	dldwd_lock(priv);
768     
769     	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_BSSID,
770     			      ETH_ALEN, NULL, buf);
771     
772     	dldwd_unlock(priv);
773     
774     	return err;
775     }
776     
777     static int dldwd_hw_get_essid(dldwd_priv_t *priv, int *active,
778     			      char buf[IW_ESSID_MAX_SIZE+1])
779     {
780     	hermes_t *hw = &priv->hw;
781     	int err = 0;
782     	hermes_id_t essidbuf;
783     	char *p = (char *)(&essidbuf.val);
784     	int len;
785     
786     	TRACE_ENTER(priv->ndev.name);
787     
788     	dldwd_lock(priv);
789     
790     	if (strlen(priv->desired_essid) > 0) {
791     		/* We read the desired SSID from the hardware rather
792     		   than from priv->desired_essid, just in case the
793     		   firmware is allowed to change it on us. I'm not
794     		   sure about this */
795     		/* My guess is that the OWN_SSID should always be whatever
796     		 * we set to the card, whereas CURRENT_SSID is the one that
797     		 * may change... - Jean II */
798     		uint16_t rid;
799     
800     		*active = 1;
801     
802     		rid = (priv->port_type == 3) ? HERMES_RID_CNF_OWN_SSID :
803     			HERMES_RID_CNF_DESIRED_SSID;
804     		
805     		err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
806     				      NULL, &essidbuf);
807     		if (err)
808     			goto fail_unlock;
809     	} else {
810     		*active = 0;
811     
812     		err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_SSID,
813     				      sizeof(essidbuf), NULL, &essidbuf);
814     		if (err)
815     			goto fail_unlock;
816     	}
817     
818     	len = le16_to_cpu(essidbuf.len);
819     
820     	memset(buf, 0, sizeof(buf));
821     	memcpy(buf, p, len);
822     	buf[len] = '\0';
823     
824      fail_unlock:
825     	dldwd_unlock(priv);
826     
827     	TRACE_EXIT(priv->ndev.name);
828     
829     	return err;       
830     }
831     
832     static long dldwd_hw_get_freq(dldwd_priv_t *priv)
833     {
834     	
835     	hermes_t *hw = &priv->hw;
836     	int err = 0;
837     	uint16_t channel;
838     	long freq = 0;
839     
840     	dldwd_lock(priv);
841     	
842     	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENT_CHANNEL, &channel);
843     	if (err)
844     		goto out;
845     
846     	if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
847     		struct net_device *dev = &priv->ndev;
848     
849     		printk(KERN_WARNING "%s: Channel out of range (%d)!\n", dev->name, channel);
850     		err = -EBUSY;
851     		goto out;
852     
853     	}
854     	freq = channel_frequency[channel-1] * 100000;
855     
856      out:
857     	dldwd_unlock(priv);
858     
859     	if (err > 0)
860     		err = -EBUSY;
861     	return err ? err : freq;
862     }
863     
864     static int dldwd_hw_get_bitratelist(dldwd_priv_t *priv, int *numrates,
865     				    int32_t *rates, int max)
866     {
867     	hermes_t *hw = &priv->hw;
868     	hermes_id_t list;
869     	unsigned char *p = (unsigned char *)&list.val;
870     	int err = 0;
871     	int num;
872     	int i;
873     
874     	dldwd_lock(priv);
875     	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_DATARATES, sizeof(list),
876     			      NULL, &list);
877     	dldwd_unlock(priv);
878     
879     	if (err)
880     		return err;
881     	
882     	num = le16_to_cpu(list.len);
883     	*numrates = num;
884     	num = MIN(num, max);
885     
886     	for (i = 0; i < num; i++) {
887     		rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
888     	}
889     
890     	return 0;
891     }
892     
893     #ifndef ORINOCO_DEBUG
894     static inline void show_rx_frame(struct dldwd_frame_hdr *frame) {}
895     #else
896     static void show_rx_frame(struct dldwd_frame_hdr *frame)
897     {
898     	printk(KERN_DEBUG "RX descriptor:\n");
899     	printk(KERN_DEBUG "  status      = 0x%04x\n", frame->desc.status);
900     	printk(KERN_DEBUG "  res1        = 0x%04x\n", frame->desc.res1);
901     	printk(KERN_DEBUG "  res2        = 0x%04x\n", frame->desc.res2);
902     	printk(KERN_DEBUG "  q_info      = 0x%04x\n", frame->desc.q_info);
903     	printk(KERN_DEBUG "  res3        = 0x%04x\n", frame->desc.res3);
904     	printk(KERN_DEBUG "  res4        = 0x%04x\n", frame->desc.res4);
905     	printk(KERN_DEBUG "  tx_ctl      = 0x%04x\n", frame->desc.tx_ctl);
906     
907     	printk(KERN_DEBUG "IEEE 802.11 header:\n");
908     	printk(KERN_DEBUG "  frame_ctl   = 0x%04x\n",
909     	       frame->p80211.frame_ctl);
910     	printk(KERN_DEBUG "  duration_id = 0x%04x\n",
911     	       frame->p80211.duration_id);
912     	printk(KERN_DEBUG "  addr1       = %02x:%02x:%02x:%02x:%02x:%02x\n",
913     	       frame->p80211.addr1[0], frame->p80211.addr1[1],
914     	       frame->p80211.addr1[2], frame->p80211.addr1[3],
915     	       frame->p80211.addr1[4], frame->p80211.addr1[5]);
916     	printk(KERN_DEBUG "  addr2       = %02x:%02x:%02x:%02x:%02x:%02x\n",
917     	       frame->p80211.addr2[0], frame->p80211.addr2[1],
918     	       frame->p80211.addr2[2], frame->p80211.addr2[3],
919     	       frame->p80211.addr2[4], frame->p80211.addr2[5]);
920     	printk(KERN_DEBUG "  addr3       = %02x:%02x:%02x:%02x:%02x:%02x\n",
921     	       frame->p80211.addr3[0], frame->p80211.addr3[1],
922     	       frame->p80211.addr3[2], frame->p80211.addr3[3],
923     	       frame->p80211.addr3[4], frame->p80211.addr3[5]);
924     	printk(KERN_DEBUG "  seq_ctl     = 0x%04x\n",
925     	       frame->p80211.seq_ctl);
926     	printk(KERN_DEBUG "  addr4       = %02x:%02x:%02x:%02x:%02x:%02x\n",
927     	       frame->p80211.addr4[0], frame->p80211.addr4[1],
928     	       frame->p80211.addr4[2], frame->p80211.addr4[3],
929     	       frame->p80211.addr4[4], frame->p80211.addr4[5]);
930     	printk(KERN_DEBUG "  data_len    = 0x%04x\n",
931     	       frame->p80211.data_len);
932     
933     	printk(KERN_DEBUG "IEEE 802.3 header:\n");
934     	printk(KERN_DEBUG "  dest        = %02x:%02x:%02x:%02x:%02x:%02x\n",
935     	       frame->p8023.h_dest[0], frame->p8023.h_dest[1],
936     	       frame->p8023.h_dest[2], frame->p8023.h_dest[3],
937     	       frame->p8023.h_dest[4], frame->p8023.h_dest[5]);
938     	printk(KERN_DEBUG "  src         = %02x:%02x:%02x:%02x:%02x:%02x\n",
939     	       frame->p8023.h_source[0], frame->p8023.h_source[1],
940     	       frame->p8023.h_source[2], frame->p8023.h_source[3],
941     	       frame->p8023.h_source[4], frame->p8023.h_source[5]);
942     	printk(KERN_DEBUG "  len         = 0x%04x\n", frame->p8023.h_proto);
943     
944     	printk(KERN_DEBUG "IEEE 802.2 LLC/SNAP header:\n");
945     	printk(KERN_DEBUG "  DSAP        = 0x%02x\n", frame->p8022.dsap);
946     	printk(KERN_DEBUG "  SSAP        = 0x%02x\n", frame->p8022.ssap);
947     	printk(KERN_DEBUG "  ctrl        = 0x%02x\n", frame->p8022.ctrl);
948     	printk(KERN_DEBUG "  OUI         = %02x:%02x:%02x\n",
949     	       frame->p8022.oui[0], frame->p8022.oui[1], frame->p8022.oui[2]);
950     	printk(KERN_DEBUG "  ethertype  = 0x%04x\n", frame->ethertype);
951     }
952     #endif
953     
954     /*
955      * Interrupt handler
956      */
957     void dldwd_interrupt(int irq, void * dev_id, struct pt_regs *regs)
958     {
959     	dldwd_priv_t *priv = (dldwd_priv_t *) dev_id;
960     	hermes_t *hw = &priv->hw;
961     	struct net_device *dev = &priv->ndev;
962     	int count = IRQ_LOOP_MAX;
963     	uint16_t evstat, events;
964     	static int old_time = 0, timecount = 0; /* Eugh, revolting hack for now */
965     
966     	if (test_and_set_bit(DLDWD_STATE_INIRQ, &priv->state))
967     		BUG();
968     
969     	if (! dldwd_irqs_allowed(priv)) {
970     		clear_bit(DLDWD_STATE_INIRQ, &priv->state);
971     		return;
972     	}
973     
974     	DEBUG(3, "%s: dldwd_interrupt()\n", priv->ndev.name);
975     
976     	while (1) {
977     		if (jiffies != old_time)
978     			timecount = 0;
979     		if ( (++timecount > 50) || (! count--) ) {
980     			printk(KERN_CRIT "%s: IRQ handler is looping too \
981     much! Shutting down.\n",
982     			       dev->name);
983     			/* Perform an emergency shutdown */
984     			clear_bit(DLDWD_STATE_DOIRQ, &priv->state);
985     			hermes_set_irqmask(hw, 0);
986     			break;
987     		}
988     
989     		evstat = hermes_read_regn(hw, EVSTAT);
990     		DEBUG(3, "__dldwd_interrupt(): count=%d EVSTAT=0x%04x inten=0x%04x\n",
991     		      count, evstat, hw->inten);
992     
993     		events = evstat & hw->inten;
994     
995     		if (! events) {
996     			if (netif_queue_stopped(dev)) {
997     				/* There seems to be a firmware bug which
998     				   sometimes causes the card to give an
999     				   interrupt with no event set, when there
1000     				   sould be a Tx completed event. */
1001     				DEBUG(3, "%s: Interrupt with no event (ALLOCFID=0x%04x)\n",
1002     				      dev->name, (int)hermes_read_regn(hw, ALLOCFID));
1003     				events = HERMES_EV_TX | HERMES_EV_ALLOC;
1004     			} else /* Nothing's happening, we're done */
1005     				break;
1006     		}
1007     
1008     		/* Check the card hasn't been removed */
1009     		if (! hermes_present(hw)) {
1010     			DEBUG(0, "dldwd_interrupt(): card removed\n");
1011     			break;
1012     		}
1013     
1014     		if (events & HERMES_EV_TICK)
1015     			__dldwd_ev_tick(priv, hw);
1016     		if (events & HERMES_EV_WTERR)
1017     			__dldwd_ev_wterr(priv, hw);
1018     		if (events & HERMES_EV_INFDROP)
1019     			__dldwd_ev_infdrop(priv, hw);
1020     		if (events & HERMES_EV_INFO)
1021     			__dldwd_ev_info(priv, hw);
1022     		if (events & HERMES_EV_RX)
1023     			__dldwd_ev_rx(priv, hw);
1024     		if (events & HERMES_EV_TXEXC)
1025     			__dldwd_ev_txexc(priv, hw);
1026     		if (events & HERMES_EV_TX)
1027     			__dldwd_ev_tx(priv, hw);
1028     		if (events & HERMES_EV_ALLOC)
1029     			__dldwd_ev_alloc(priv, hw);
1030     		
1031     		hermes_write_regn(hw, EVACK, events);
1032     	}
1033     
1034     	clear_bit(DLDWD_STATE_INIRQ, &priv->state);
1035     }
1036     
1037     static void __dldwd_ev_tick(dldwd_priv_t *priv, hermes_t *hw)
1038     {
1039     	printk(KERN_DEBUG "%s: TICK\n", priv->ndev.name);
1040     }
1041     
1042     static void __dldwd_ev_wterr(dldwd_priv_t *priv, hermes_t *hw)
1043     {
1044     	/* This seems to happen a fair bit under load, but ignoring it
1045     	   seems to work fine...*/
1046     	DEBUG(1, "%s: MAC controller error (WTERR). Ignoring.\n",
1047     	      priv->ndev.name);
1048     }
1049     
1050     static void __dldwd_ev_infdrop(dldwd_priv_t *priv, hermes_t *hw)
1051     {
1052     	printk(KERN_WARNING "%s: Information frame lost.\n", priv->ndev.name);
1053     }
1054     
1055     static void __dldwd_ev_info(dldwd_priv_t *priv, hermes_t *hw)
1056     {
1057     	DEBUG(3, "%s: Information frame received.\n", priv->ndev.name);
1058     	/* We don't actually do anything about it - we assume the MAC
1059     	   controller can deal with it */
1060     }
1061     
1062     static void __dldwd_ev_rx(dldwd_priv_t *priv, hermes_t *hw)
1063     {
1064     	struct net_device *dev = &priv->ndev;
1065     	struct net_device_stats *stats = &priv->stats;
1066     	struct iw_statistics *wstats = &priv->wstats;
1067     	struct sk_buff *skb = NULL;
1068     	int l = RX_EIO_RETRY;
1069     	uint16_t rxfid, status;
1070     	int length, data_len, data_off;
1071     	char *p;
1072     	struct dldwd_frame_hdr hdr;
1073     	struct ethhdr *eh;
1074     	int err;
1075     
1076     	rxfid = hermes_read_regn(hw, RXFID);
1077     	DEBUG(3, "__dldwd_ev_rx(): RXFID=0x%04x\n", rxfid);
1078     
1079     	/* We read in the entire frame header here. This isn't really
1080     	   necessary, since we ignore most of it, but it's
1081     	   conceptually simpler. We can tune this later if
1082     	   necessary. */
1083     	do {
1084     		err = hermes_bap_pread(hw, IRQ_BAP, &hdr, sizeof(hdr),
1085     				       rxfid, 0);
1086     	} while ( (err == -EIO) && (--l) );
1087     	if (err) {
1088     		if (err == -EIO)
1089     			DEBUG(1, "%s: EIO reading frame header.\n", dev->name);
1090     		else
1091     			printk(KERN_ERR "%s: error %d reading frame header. "
1092     			       "Frame dropped.\n", dev->name, err);
1093     		stats->rx_errors++;
1094     		goto drop;
1095     	}
1096     	DEBUG(2, "%s: BAP read suceeded: l=%d\n", dev->name, l);
1097     
1098     	status = le16_to_cpu(hdr.desc.status);
1099     	
1100     	if (status & HERMES_RXSTAT_ERR) {
1101     		if ((status & HERMES_RXSTAT_ERR) == HERMES_RXSTAT_BADCRC) {
1102     			stats->rx_crc_errors++;
1103     			DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", dev->name);
1104     			show_rx_frame(&hdr);
1105     		} else if ((status & HERMES_RXSTAT_ERR)
1106     			   == HERMES_RXSTAT_UNDECRYPTABLE) {
1107     			wstats->discard.code++;
1108     			printk(KERN_WARNING "%s: Undecryptable frame on Rx. Frame dropped.\n",
1109     			       dev->name);
1110     		} else {
1111     			wstats->discard.misc++;
1112     			printk("%s: Unknown Rx error (0x%x). Frame dropped.\n",
1113     			       dev->name, status & HERMES_RXSTAT_ERR);
1114     		}
1115     		stats->rx_errors++;
1116     		goto drop;
1117     	}
1118     
1119     	length = le16_to_cpu(hdr.p80211.data_len);
1120     	/* Yes, you heard right, that's le16. 802.2 and 802.3 are
1121     	   big-endian, but 802.11 is little-endian believe it or
1122     	   not. */
1123     	/* Correct. 802.3 is big-endian byte order and little endian bit
1124     	 * order, whereas 802.11 is little endian for both byte and bit
1125     	 * order. That's specified in the 802.11 spec. - Jean II */
1126     	
1127     	/* Sanity check */
1128     	if (length > MAX_FRAME_SIZE) {
1129     		printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
1130     		       dev->name, length);
1131     		stats->rx_length_errors++;
1132     		stats->rx_errors++;
1133     		goto drop;
1134     	}
1135     
1136     	/* We need space for the packet data itself, plus an ethernet
1137     	   header, plus 2 bytes so we can align the IP header on a
1138     	   32bit boundary, plus 1 byte so we can read in odd length
1139     	   packets from the card, which has an IO granularity of 16
1140     	   bits */  
1141     	skb = dev_alloc_skb(length+ETH_HLEN+2+1);
1142     	if (!skb) {
1143     		printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
1144     		       dev->name);
1145     		stats->rx_dropped++;
1146     		goto drop;
1147     	}
1148     
1149     	skb_reserve(skb, 2); /* This way the IP header is aligned */
1150     
1151     	/* Handle decapsulation
1152     	 * In most cases, the firmware tell us about SNAP frames.
1153     	 * For some reason, the SNAP frames sent by LinkSys APs
1154     	 * are not properly recognised by most firmwares.
1155     	 * So, check ourselves (note : only 3 bytes out of 6).
1156     	 */
1157     	if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
1158     	   ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
1159     	   (!memcmp(&hdr.p8022, &encaps_hdr, 3))) {
1160     		/* These indicate a SNAP within 802.2 LLC within
1161     		   802.11 frame which we'll need to de-encapsulate to
1162     		   the original EthernetII frame. */
1163     
1164     		/* Remove SNAP header, reconstruct EthernetII frame */
1165     		data_len = length - ENCAPS_OVERHEAD;
1166     		data_off = sizeof(hdr);
1167     
1168     		eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);
1169     
1170     		memcpy(eh, &hdr.p8023, sizeof(hdr.p8023));
1171     		eh->h_proto = hdr.ethertype;
1172     	} else {
1173     		/* All other cases indicate a genuine 802.3 frame.
1174     		 * No decapsulation needed */
1175     
1176     		/* Otherwise, we just throw the whole thing in,
1177     		 * and hope the protocol layer can deal with it
1178     		 * as 802.3 */
1179     		data_len = length;
1180     		data_off = P8023_OFFSET;
1181     	}
1182     
1183     	p = skb_put(skb, data_len);
1184     	do {
1185     		err = hermes_bap_pread(hw, IRQ_BAP, p, RUP_EVEN(data_len),
1186     				       rxfid, data_off);
1187     	} while ( (err == -EIO) && (--l) );
1188     	if (err) {
1189     		if (err == -EIO)
1190     			DEBUG(1, "%s: EIO reading frame header.\n", dev->name);
1191     		else
1192     			printk(KERN_ERR "%s: error %d reading frame header. "
1193     			       "Frame dropped.\n", dev->name, err);
1194     		stats->rx_errors++;
1195     		goto drop;
1196     	}
1197     	DEBUG(2, "%s: BAP read suceeded: l=%d\n", dev->name, l);
1198     
1199     	dev->last_rx = jiffies;
1200     	skb->dev = dev;
1201     	skb->protocol = eth_type_trans(skb, dev);
1202     	skb->ip_summed = CHECKSUM_NONE;
1203     	
1204     	/* Process the wireless stats if needed */
1205     	dldwd_stat_gather(dev, skb, &hdr);
1206     
1207     	/* Pass the packet to the networking stack */
1208     	netif_rx(skb);
1209     	stats->rx_packets++;
1210     	stats->rx_bytes += length;
1211     
1212     	return;
1213     
1214      drop:	
1215     	if (skb)
1216     		dev_kfree_skb_irq(skb);
1217     	return;
1218     }
1219     
1220     static void __dldwd_ev_txexc(dldwd_priv_t *priv, hermes_t *hw)
1221     {
1222     	struct net_device *dev = &priv->ndev;
1223     	struct net_device_stats *stats = &priv->stats;
1224     
1225     	printk(KERN_WARNING "%s: Tx error!\n", dev->name);
1226     
1227     	netif_wake_queue(dev);
1228     	stats->tx_errors++;
1229     }
1230     
1231     static void __dldwd_ev_tx(dldwd_priv_t *priv, hermes_t *hw)
1232     {
1233     	struct net_device *dev = &priv->ndev;
1234     	struct net_device_stats *stats = &priv->stats;
1235     
1236     	DEBUG(3, "%s: Transmit completed\n", dev->name);
1237     
1238     	stats->tx_packets++;
1239     	netif_wake_queue(dev);
1240     }
1241     
1242     static void __dldwd_ev_alloc(dldwd_priv_t *priv, hermes_t *hw)
1243     {
1244     	uint16_t allocfid;
1245     
1246     	allocfid = hermes_read_regn(hw, ALLOCFID);
1247     	DEBUG(3, "%s: Allocation complete FID=0x%04x\n", priv->ndev.name, allocfid);
1248     
1249     	/* For some reason we don't seem to get transmit completed events properly */
1250     	if (allocfid == priv->txfid)
1251     		__dldwd_ev_tx(priv, hw);
1252     
1253     /* 	hermes_write_regn(hw, ALLOCFID, 0); */
1254     }
1255     
1256     static void determine_firmware(struct net_device *dev)
1257     {
1258     	dldwd_priv_t *priv = dev->priv;
1259     	hermes_t *hw = &priv->hw;
1260     	int err;
1261     	struct sta_id {
1262     		uint16_t id, vendor, major, minor;
1263     	} __PACKED__ sta_id;
1264     	uint32_t firmver;
1265     
1266     	/* Get the firmware version */
1267     	err = HERMES_READ_RECORD(hw, USER_BAP,
1268     				 HERMES_RID_STAIDENTITY, &sta_id);
1269     	if (err) {
1270     		printk(KERN_WARNING "%s: Error %d reading firmware info. Wildly guessing capabilities...\n",
1271     		       dev->name, err);
1272     		memset(&sta_id, 0, sizeof(sta_id));
1273     	}
1274     	le16_to_cpus(&sta_id.id);
1275     	le16_to_cpus(&sta_id.vendor);
1276     	le16_to_cpus(&sta_id.major);
1277     	le16_to_cpus(&sta_id.minor);
1278     
1279     	firmver = ((uint32_t)sta_id.major << 16) | sta_id.minor;
1280     
1281     	printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
1282     	       dev->name, sta_id.id, sta_id.vendor,
1283     	       sta_id.major, sta_id.minor);
1284     
1285     	/* Determine capabilities from the firmware version */
1286     
1287     	if (sta_id.vendor == 1) {
1288     		/* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
1289     		   ELSE, Meloc, HP, IBM, Dell 1150 */
1290     		printk(KERN_DEBUG "%s: Looks like a Lucent/Agere firmware "
1291     		       "version %d.%02d\n", dev->name,
1292     		       sta_id.major, sta_id.minor);
1293     
1294     		priv->firmware_type = FIRMWARE_TYPE_LUCENT;
1295     		priv->tx_rate_ctrl = 0x3;	/* 11 Mb/s auto */
1296     		priv->need_card_reset = 0;
1297     		priv->broken_reset = 0;
1298     		priv->broken_allocate = 0;
1299     		priv->has_port3 = 1;		/* Still works in 7.28 */
1300     		priv->has_ibss = (firmver >= 0x60006);
1301     		priv->has_ibss_any = (firmver >= 0x60010);
1302     		priv->has_wep = (firmver >= 0x40020);
1303     		priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
1304     					  Gold cards from the others? */
1305     		priv->has_mwo = (firmver >= 0x60000);
1306     		priv->has_pm = (firmver >= 0x40020);
1307     		priv->has_preamble = 0;
1308     		priv->ibss_port = 1;
1309     		/* Tested with Lucent firmware :
1310     		 *	1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
1311     		 * Tested CableTron firmware : 4.32 => Anton */
1312     	} else if ((sta_id.vendor == 2) &&
1313     		   ((firmver == 0x10001) || (firmver == 0x20001))) {
1314     		/* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
1315     		/* Intel MAC : 00:02:B3:* */
1316     		/* 3Com MAC : 00:50:DA:* */
1317     		printk(KERN_DEBUG "%s: Looks like a Symbol firmware "
1318     		       "(unknown version)\n", dev->name);
1319     
1320     		/* FIXME : we need to get Symbol firmware revision.
1321     		 * I tried to use SYMBOL_***ARY_VER, but it didn't
1322     		 * returned anything proper... */
1323     		priv->firmware_type = FIRMWARE_TYPE_SYMBOL;
1324     		priv->tx_rate_ctrl = 0xF;	/* 11 Mb/s auto */
1325     		priv->need_card_reset = 1;
1326     		priv->broken_reset = 0;
1327     		priv->broken_allocate = 1;
1328     		priv->has_port3 = 1;
1329     		priv->has_ibss = 1; /* FIXME */
1330     		priv->has_wep = 1; /* FIXME */
1331     		priv->has_big_wep = 1;	/* RID_SYMBOL_KEY_LENGTH */
1332     		priv->has_mwo = 0;
1333     		priv->has_pm = 1; /* FIXME */
1334     		priv->has_preamble = 0; /* FIXME */
1335     		priv->ibss_port = 4;
1336     		/* Tested with Intel firmware : v15 => Jean II */
1337     	} else {
1338     		printk(KERN_DEBUG "%s: Looks like an Intersil firmware "
1339     		       "version %d.%02d\n", dev->name,
1340     		       sta_id.major, sta_id.minor);
1341     
1342     		priv->firmware_type = FIRMWARE_TYPE_INTERSIL;
1343     		priv->tx_rate_ctrl = 0xF;	/* 11 Mb/s auto */
1344     		priv->need_card_reset = 0;
1345     		priv->broken_reset = 0;
1346     		priv->broken_allocate = 0;
1347     		priv->has_port3 = 1;
1348     		priv->has_ibss = (firmver >= 0x00007); /* FIXME */
1349     		priv->has_wep = (firmver >= 0x00008);
1350     		priv->has_big_wep = 0;
1351     		priv->has_mwo = 0;
1352     		priv->has_pm = (firmver >= 0x00007);
1353     		priv->has_preamble = 0;
1354     
1355     		if (firmver >= 0x00008)
1356     			priv->ibss_port = 0;
1357     		else {
1358     			printk(KERN_NOTICE "%s: Intersil firmware earlier "
1359     			       "than v0.08 - several features not supported.",
1360     			       dev->name);
1361     			priv->ibss_port = 1;
1362     		}
1363     	}
1364     }
1365     
1366     /*
1367      * struct net_device methods
1368      */
1369     
1370     int
1371     dldwd_init(struct net_device *dev)
1372     {
1373     	dldwd_priv_t *priv = dev->priv;
1374     	hermes_t *hw = &priv->hw;
1375     	int err = 0;
1376     	hermes_id_t nickbuf;
1377     	uint16_t reclen;
1378     	int len;
1379     
1380     	TRACE_ENTER("dldwd");
1381     	
1382     	dldwd_lock(priv);
1383     
1384     	/* Do standard firmware reset */
1385     	err = hermes_reset(hw);
1386     	if (err != 0) {
1387     		printk(KERN_ERR "%s: failed to reset hardware (err = %d)\n",
1388     		       dev->name, err);
1389     		goto out;
1390     	}
1391     
1392     	determine_firmware(dev);
1393     
1394     	if (priv->has_port3)
1395     		printk(KERN_DEBUG "%s: Ad-hoc demo mode supported.\n", dev->name);
1396     	if (priv->has_ibss)
1397     		printk(KERN_DEBUG "%s: IEEE standard IBSS ad-hoc mode supported.\n",
1398     		       dev->name);
1399     	if (priv->has_wep) {
1400     		printk(KERN_DEBUG "%s: WEP supported, ", dev->name);
1401     		if (priv->has_big_wep)
1402     			printk("\"128\"-bit key.\n");
1403     		else
1404     			printk("40-bit key.\n");
1405     	}
1406     
1407     	/* Get the MAC address */
1408     	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNF_MACADDR,
1409     			      ETH_ALEN, NULL, dev->dev_addr);
1410     	if (err) {
1411     		printk(KERN_WARNING "%s: failed to read MAC address!\n",
1412     		       dev->name);
1413     		goto out;
1414     	}
1415     
1416     	printk(KERN_DEBUG "%s: MAC address %02X:%02X:%02X:%02X:%02X:%02X\n",
1417     	       dev->name, dev->dev_addr[0], dev->dev_addr[1],
1418     	       dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4],
1419     	       dev->dev_addr[5]);
1420     
1421     	/* Get the station name */
1422     	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNF_NICKNAME,
1423     			      sizeof(nickbuf), &reclen, &nickbuf);
1424     	if (err) {
1425     		printk(KERN_ERR "%s: failed to read station name!n",
1426     		       dev->name);
1427     		goto out;
1428     	}
1429     	if ( nickbuf.len )
1430     		len = MIN(IW_ESSID_MAX_SIZE, le16_to_cpu(nickbuf.len));
1431     	else
1432     		len = MIN(IW_ESSID_MAX_SIZE, 2 * reclen);
1433     	memcpy(priv->nick, &nickbuf.val, len);
1434     	priv->nick[len] = '\0';
1435     
1436     	printk(KERN_DEBUG "%s: Station name \"%s\"\n", dev->name, priv->nick);
1437     
1438     	/* Get allowed channels */
1439     	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CHANNEL_LIST, &priv->channel_mask);
1440     	if (err) {
1441     		printk(KERN_ERR "%s: failed to read channel list!\n",
1442     		       dev->name);
1443     		goto out;
1444     	}
1445     
1446     	/* Get initial AP density */
1447     	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYSTEM_SCALE, &priv->ap_density);
1448     	if (err) {
1449     		printk(KERN_ERR "%s: failed to read AP density!\n", dev->name);
1450     		goto out;
1451     	}
1452     
1453     	/* Get initial RTS threshold */
1454     	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_RTS_THRESH, &priv->rts_thresh);
1455     	if (err) {
1456     		printk(KERN_ERR "%s: failed to read RTS threshold!\n", dev->name);
1457     		goto out;
1458     	}
1459     
1460     	/* Get initial fragmentation settings */
1461     	if (priv->has_mwo)
1462     		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_MWO_ROBUST,
1463     					  &priv->mwo_robust);
1464     	else
1465     		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_FRAG_THRESH,
1466     					  &priv->frag_thresh);
1467     	if (err) {
1468     		printk(KERN_ERR "%s: failed to read fragmentation settings!\n", dev->name);
1469     		goto out;
1470     	}
1471     
1472     	/* Power management setup */
1473     	if (priv->has_pm) {
1474     		priv->pm_on = 0;
1475     		priv->pm_mcast = 1;
1476     		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_PERIOD,
1477     					  &priv->pm_period);
1478     		if (err) {
1479     			printk(KERN_ERR "%s: failed to read power management period!\n",
1480     			       dev->name);
1481     			goto out;
1482     		}
1483     		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_HOLDOVER,
1484     					  &priv->pm_timeout);
1485     		if (err) {
1486     			printk(KERN_ERR "%s: failed to read power management timeout!\n",
1487     			       dev->name);
1488     			goto out;
1489     		}
1490     	}
1491     
1492     	/* Preamble setup */
1493     	if (priv->has_preamble) {
1494     		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYMBOL_PREAMBLE, &priv->preamble);
1495     		if (err)
1496     			goto out;
1497     	}
1498     		
1499     	/* Set up the default configuration */
1500     	priv->iw_mode = IW_MODE_INFRA;
1501     	/* By default use IEEE/IBSS ad-hoc mode if we have it */
1502     	priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
1503     	set_port_type(priv);
1504     
1505     	priv->promiscuous = 0;
1506     	priv->allmulti = 0;
1507     	priv->wep_on = 0;
1508     	priv->tx_key = 0;
1509     
1510     	printk(KERN_DEBUG "%s: ready\n", dev->name);
1511     
1512      out:
1513     	dldwd_unlock(priv);
1514     
1515     	TRACE_EXIT("dldwd");
1516     
1517     	return err;
1518     }
1519     
1520     struct net_device_stats *
1521     dldwd_get_stats(struct net_device *dev)
1522     {
1523     	dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
1524     	
1525     	return &priv->stats;
1526     }
1527     
1528     struct iw_statistics *
1529     dldwd_get_wireless_stats(struct net_device *dev)
1530     {
1531     	dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
1532     	hermes_t *hw = &priv->hw;
1533     	struct iw_statistics *wstats = &priv->wstats;
1534     	int err = 0;
1535     
1536     	if (!priv->hw_ready)
1537     		return NULL;
1538     
1539     	dldwd_lock(priv);
1540     
1541     	if (priv->iw_mode == IW_MODE_ADHOC) {
1542     		memset(&wstats->qual, 0, sizeof(wstats->qual));
1543     #ifdef WIRELESS_SPY
1544     		/* If a spy address is defined, we report stats of the
1545     		 * first spy address - Jean II */
1546     		if (priv->spy_number > 0) {
1547     			wstats->qual.qual = priv->spy_stat[0].qual;
1548     			wstats->qual.level = priv->spy_stat[0].level;
1549     			wstats->qual.noise = priv->spy_stat[0].noise;
1550     			wstats->qual.updated = priv->spy_stat[0].updated;
1551     		}
1552     #endif /* WIRELESS_SPY */
1553     	} else {
1554     		dldwd_commsqual_t cq;
1555     
1556     		err = HERMES_READ_RECORD(hw, USER_BAP,
1557     					 HERMES_RID_COMMSQUALITY, &cq);
1558     		
1559     		le16_to_cpus(&cq.qual);
1560     		le16_to_cpus(&cq.signal);
1561     		le16_to_cpus(&cq.noise);
1562     		
1563     		DEBUG(3, "%s: Global stats = %X-%X-%X\n", dev->name,
1564     		      cq.qual, cq.signal, cq.noise);
1565     
1566     		/* Why are we using MIN/MAX ? We don't really care
1567     		 * if the value goes above max, because we export the
1568     		 * raw dBm values anyway. The normalisation should be done
1569     		 * in user space - Jean II */
1570     		wstats->qual.qual = MAX(MIN(cq.qual, 0x8b-0x2f), 0);
1571     		wstats->qual.level = MAX(MIN(cq.signal, 0x8a), 0x2f) - 0x95;
1572     		wstats->qual.noise = MAX(MIN(cq.noise, 0x8a), 0x2f) - 0x95;
1573     		wstats->qual.updated = 7;
1574     	}
1575     
1576     	dldwd_unlock(priv);
1577     
1578     	if (err)
1579     		return NULL;
1580     		
1581     	return wstats;
1582     }
1583     
1584     #ifdef WIRELESS_SPY
1585     static inline void dldwd_spy_gather(struct net_device *dev,
1586     				    u_char *mac,
1587     				    dldwd_commsqual_t *cq)
1588     {
1589     	dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
1590     	int i;
1591     
1592     	/* Gather wireless spy statistics: for each packet, compare the
1593     	 * source address with out list, and if match, get the stats... */
1594     	for (i = 0; i < priv->spy_number; i++)
1595     		if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {
1596     			priv->spy_stat[i].qual = MAX(MIN(cq->qual, 0x8b-0x2f), 0);
1597     			priv->spy_stat[i].level = MAX(MIN(cq->signal, 0x8a), 0x2f) - 0x95;
1598     			priv->spy_stat[i].noise = MAX(MIN(cq->noise, 0x8a), 0x2f) - 0x95;
1599     			priv->spy_stat[i].updated = 7;
1600     		}
1601     }
1602     #endif /* WIRELESS_SPY */
1603     
1604     void
1605     dldwd_stat_gather( struct net_device *dev,
1606     		   struct sk_buff *skb,
1607     		   struct dldwd_frame_hdr *hdr)
1608     {
1609     	dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
1610     	dldwd_commsqual_t cq;
1611     
1612     	/* Using spy support with lots of Rx packets, like in an
1613     	 * infrastructure (AP), will really slow down everything, because
1614     	 * the MAC address must be compared to each entry of the spy list.
1615     	 * If the user really asks for it (set some address in the
1616     	 * spy list), we do it, but he will pay the price.
1617     	 * Note that to get here, you need both WIRELESS_SPY
1618     	 * compiled in AND some addresses in the list !!!
1619     	 */
1620     #ifdef WIRELESS_EXT
1621     	/* Note : gcc will optimise the whole section away if
1622     	 * WIRELESS_SPY is not defined... - Jean II */
1623     	if (
1624     #ifdef WIRELESS_SPY
1625     		(priv->spy_number > 0) ||
1626     #endif
1627     		0 )
1628     	{
1629     		u_char *stats = (u_char *) &(hdr->desc.q_info);
1630     		/* This code may look strange. Everywhere we are using 16 bit
1631     		 * ints except here. I've verified that these are are the
1632     		 * correct values. Please check on PPC - Jean II */
1633     		cq.signal = stats[1];	/* High order byte */
1634     		cq.noise = stats[0];	/* Low order byte */
1635     		cq.qual = stats[0] - stats[1];	/* Better than nothing */
1636     
1637     		DEBUG(3, "%s: Packet stats = %X-%X-%X\n", dev->name,
1638     		      cq.qual, cq.signal, cq.noise);
1639     
1640     #ifdef WIRELESS_SPY
1641     		dldwd_spy_gather(dev, skb->mac.raw + ETH_ALEN, &cq);  
1642     #endif
1643     	}
1644     #endif /* WIRELESS_EXT */
1645     }
1646     
1647     int
1648     dldwd_xmit(struct sk_buff *skb, struct net_device *dev)
1649     {
1650     	dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
1651     	struct net_device_stats *stats = &priv->stats;
1652     	hermes_t *hw = &priv->hw;
1653     	int err = 0;
1654     	uint16_t txfid = priv->txfid;
1655     	char *p;
1656     	struct ethhdr *eh;
1657     	int len, data_len, data_off;
1658     	struct dldwd_frame_hdr hdr;
1659     	hermes_response_t resp;
1660     
1661     	if (! netif_running(dev)) {
1662     		printk(KERN_ERR "%s: Tx on stopped device!\n",
1663     		       dev->name);
1664     		return 1;
1665     
1666     	}
1667     	
1668     	if (netif_queue_stopped(dev)) {
1669     		printk(KERN_ERR "%s: Tx while transmitter busy!\n", 
1670     		       dev->name);
1671     		return 1;
1672     	}
1673     	
1674     	dldwd_lock(priv);
1675     
1676     	/* Length of the packet body */
1677     	len = MAX(skb->len - ETH_HLEN, ETH_ZLEN);
1678     
1679     	eh = (struct ethhdr *)skb->data;
1680     
1681     	/* Build the IEEE 802.11 header */
1682     	memset(&hdr, 0, sizeof(hdr));
1683     	memcpy(hdr.p80211.addr1, eh->h_dest, ETH_ALEN);
1684     	memcpy(hdr.p80211.addr2, eh->h_source, ETH_ALEN);
1685     	hdr.p80211.frame_ctl = DLDWD_FTYPE_DATA;
1686     
1687     	/* Encapsulate Ethernet-II frames */
1688     	if (ntohs(eh->h_proto) > 1500) { /* Ethernet-II frame */
1689     		data_len = len;
1690     		data_off = sizeof(hdr);
1691     		p = skb->data + ETH_HLEN;
1692     
1693     		/* 802.11 header */
1694     		hdr.p80211.data_len = cpu_to_le16(data_len + ENCAPS_OVERHEAD);
1695     
1696     		/* 802.3 header */
1697     		memcpy(hdr.p8023.h_dest, eh->h_dest, ETH_ALEN);
1698     		memcpy(hdr.p8023.h_source, eh->h_source, ETH_ALEN);
1699     		hdr.p8023.h_proto = htons(data_len + ENCAPS_OVERHEAD);
1700     		
1701     		/* 802.2 header */
1702     		/* FIXME: ugh, what a hack for the 00:00:00 APs.  Need to find a better way */
1703     		if (use_alternate_encaps)
1704     			memcpy(&hdr.p8022, &alternate_encaps_hdr, sizeof(alternate_encaps_hdr));
1705     		else
1706     			memcpy(&hdr.p8022, &encaps_hdr, sizeof(encaps_hdr));
1707     
1708     		hdr.ethertype = eh->h_proto;
1709     		err  = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
1710     					 txfid, 0);
1711     		if (err) {
1712     			if (err == -EIO)
1713     				/* We get these errors reported by the
1714     				   firmware every so often apparently at
1715     				   random.  Let the upper layers
1716     				   handle the retry */
1717     				DEBUG(1, "%s: DEBUG: EIO writing packet header to BAP\n", dev->name);
1718     			else
1719     				printk(KERN_ERR "%s: Error %d writing packet header to BAP\n",
1720     				       dev->name, err);
1721     			stats->tx_errors++;
1722     			goto fail;
1723     		}
1724     	} else { /* IEEE 802.3 frame */
1725     		data_len = len + ETH_HLEN;
1726     		data_off = P8023_OFFSET;
1727     		p = skb->data;
1728     		
1729     		/* 802.11 header */
1730     		hdr.p80211.data_len = cpu_to_le16(len);
1731     		err = hermes_bap_pwrite(hw, USER_BAP, &hdr, P8023_OFFSET,
1732     					txfid, 0);
1733     		if (err) {
1734     			printk(KERN_ERR
1735     			       "%s: Error %d writing packet header to BAP\n",
1736     			       dev->name, err);
1737     			stats->tx_errors++;
1738     			goto fail;
1739     		}
1740     	}
1741     
1742     	/* Round up for odd length packets */
1743     	err = hermes_bap_pwrite(hw, USER_BAP, p, RUP_EVEN(data_len), txfid, data_off);
1744     	if (err) {
1745     		if (err == -EIO)
1746     			DEBUG(1, "%s: DEBUG: EIO writing packet header to BAP\n", dev->name);
1747     		else
1748     			printk(KERN_ERR "%s: Error %d writing packet header to BAP",
1749     			       dev->name, err);
1750     		stats->tx_errors++;
1751     		goto fail;
1752     	}
1753     
1754     	/* Finally, we actually initiate the send */
1755     	err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, txfid, &resp);
1756     	if (err) {
1757     		printk(KERN_ERR "%s: Error %d transmitting packet\n", dev->name, err);
1758     		stats->tx_errors++;
1759     		goto fail;
1760     	}
1761     
1762     	dev->trans_start = jiffies;
1763     	stats->tx_bytes += data_off + data_len;
1764     
1765     	netif_stop_queue(dev);
1766     
1767     	dldwd_unlock(priv);
1768     
1769     	dev_kfree_skb(skb);
1770     
1771     	return 0;
1772      fail:
1773     
1774     	dldwd_unlock(priv);
1775     	return err;
1776     }
1777     
1778     void
1779     dldwd_tx_timeout(struct net_device *dev)
1780     {
1781     	dldwd_priv_t *priv = (dldwd_priv_t *)dev->priv;
1782     	struct net_device_stats *stats = &priv->stats;
1783     	int err = 0;
1784     
1785     	printk(KERN_WARNING "%s: Tx timeout! Resetting card.\n", dev->name);
1786     
1787     	stats->tx_errors++;
1788     
1789     	err = dldwd_reset(priv);
1790     	if (err)
1791     		printk(KERN_ERR "%s: Error %d resetting card on Tx timeout!\n",
1792     		       dev->name, err);
1793     	else {
1794     		dev->trans_start = jiffies;
1795     		netif_wake_queue(dev);
1796     	}
1797     }
1798     
1799     static int dldwd_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq)
1800     {
1801     	dldwd_priv_t *priv = dev->priv;
1802     	int err = 0;
1803     	int mode;
1804     	struct iw_range range;
1805     	int numrates;
1806     	int i, k;
1807     
1808     	TRACE_ENTER(dev->name);
1809     
1810     	err = verify_area(VERIFY_WRITE, rrq->pointer, sizeof(range));
1811     	if (err)
1812     		return err;
1813     
1814     	rrq->length = sizeof(range);
1815     
1816     	dldwd_lock(priv);
1817     	mode = priv->iw_mode;
1818     	dldwd_unlock(priv);
1819     
1820     	memset(&range, 0, sizeof(range));
1821     
1822     	/* Much of this shamelessly taken from wvlan_cs.c. No idea
1823     	 * what it all means -dgibson */
1824     #if WIRELESS_EXT > 10
1825     	range.we_version_compiled = WIRELESS_EXT;
1826     	range.we_version_source = 11;
1827     #endif /* WIRELESS_EXT > 10 */
1828     
1829     	range.min_nwid = range.max_nwid = 0; /* We don't use nwids */
1830     
1831     	/* Set available channels/frequencies */
1832     	range.num_channels = NUM_CHANNELS;
1833     	k = 0;
1834     	for (i = 0; i < NUM_CHANNELS; i++) {
1835     		if (priv->channel_mask & (1 << i)) {
1836     			range.freq[k].i = i + 1;
1837     			range.freq[k].m = channel_frequency[i] * 100000;
1838     			range.freq[k].e = 1;
1839     			k++;
1840     		}
1841     		
1842     		if (k >= IW_MAX_FREQUENCIES)
1843     			break;
1844     	}
1845     	range.num_frequency = k;
1846     
1847     	range.sensitivity = 3;
1848     
1849     	if ((mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){
1850     		/* Quality stats meaningless in ad-hoc mode */
1851     		range.max_qual.qual = 0;
1852     		range.max_qual.level = 0;
1853     		range.max_qual.noise = 0;
1854     	} else {
1855     		range.max_qual.qual = 0x8b - 0x2f;
1856     		range.max_qual.level = 0x2f - 0x95 - 1;
1857     		range.max_qual.noise = 0x2f - 0x95 - 1;
1858     	}
1859     
1860     	err = dldwd_hw_get_bitratelist(priv, &numrates,
1861     				       range.bitrate, IW_MAX_BITRATES);
1862     	if (err)
1863     		return err;
1864     	range.num_bitrates = numrates;
1865     	
1866     	/* Set an indication of the max TCP throughput in bit/s that we can
1867     	 * expect using this interface. May be use for QoS stuff...
1868     	 * Jean II */
1869     	if(numrates > 2)
1870     		range.throughput = 5 * 1000 * 1000;	/* ~5 Mb/s */
1871     	else
1872     		range.throughput = 1.5 * 1000 * 1000;	/* ~1.5 Mb/s */
1873     
1874     	range.min_rts = 0;
1875     	range.max_rts = 2347;
1876     	range.min_frag = 256;
1877     	range.max_frag = 2346;
1878     
1879     	dldwd_lock(priv);
1880     	if (priv->has_wep) {
1881     		range.max_encoding_tokens = MAX_KEYS;
1882     
1883     		range.encoding_size[0] = SMALL_KEY_SIZE;
1884     		range.num_encoding_sizes = 1;
1885     
1886     		if (priv->has_big_wep) {
1887     			range.encoding_size[1] = LARGE_KEY_SIZE;
1888     			range.num_encoding_sizes = 2;
1889     		}
1890     	} else {
1891     		range.num_encoding_sizes = 0;
1892     		range.max_encoding_tokens = 0;
1893     	}
1894     	dldwd_unlock(priv);
1895     		
1896     	range.min_pmp = 0;
1897     	range.max_pmp = 65535000;
1898     	range.min_pmt = 0;
1899     	range.max_pmt = 65535 * 1000;	/* ??? */
1900     	range.pmp_flags = IW_POWER_PERIOD;
1901     	range.pmt_flags = IW_POWER_TIMEOUT;
1902     	range.pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
1903     
1904     	range.num_txpower = 1;
1905     	range.txpower[0] = 15; /* 15dBm */
1906     	range.txpower_capa = IW_TXPOW_DBM;
1907     
1908     #if WIRELESS_EXT > 10
1909     	range.retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
1910     	range.retry_flags = IW_RETRY_LIMIT;
1911     	range.r_time_flags = IW_RETRY_LIFETIME;
1912     	range.min_retry = 0;
1913     	range.max_retry = 65535;	/* ??? */
1914     	range.min_r_time = 0;
1915     	range.max_r_time = 65535 * 1000;	/* ??? */
1916     #endif /* WIRELESS_EXT > 10 */
1917     
1918     	if (copy_to_user(rrq->pointer, &range, sizeof(range)))
1919     		return -EFAULT;
1920     
1921     	TRACE_EXIT(dev->name);
1922     
1923     	return 0;
1924     }
1925     
1926     static int dldwd_ioctl_setiwencode(struct net_device *dev, struct iw_point *erq)
1927     {
1928     	dldwd_priv_t *priv = dev->priv;
1929     	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
1930     	int setindex = priv->tx_key;
1931     	int enable = priv->wep_on;
1932     	int restricted = priv->wep_restrict;
1933     	uint16_t xlen = 0;
1934     	int err = 0;
1935     	char keybuf[MAX_KEY_SIZE];
1936     
1937     	if (erq->pointer) {
1938     		/* We actually have a key to set */
1939     		if(erq->length > MAX_KEY_SIZE)
1940     			return -EINVAL;
1941     
1942     		if (copy_from_user(keybuf, erq->pointer, erq->length))
1943     			return -EFAULT;
1944     	}
1945     	
1946     	dldwd_lock(priv);
1947     	
1948     	if (erq->pointer) {
1949     		if (erq->length > MAX_KEY_SIZE) {
1950     			err = -E2BIG;
1951     			goto out;
1952     		}
1953     		
1954     		if ( (erq->length > LARGE_KEY_SIZE)
1955     		     || ( ! priv->has_big_wep && (erq->length > SMALL_KEY_SIZE))  ) {
1956     			err = -EINVAL;
1957     			goto out;
1958     		}
1959     		
1960     		if ((index < 0) || (index >= MAX_KEYS))
1961     			index = priv->tx_key;
1962     		
1963     		if (erq->length > SMALL_KEY_SIZE) {
1964     			xlen = LARGE_KEY_SIZE;
1965     		} else if (erq->length > 0) {
1966     			xlen = SMALL_KEY_SIZE;
1967     		} else
1968     			xlen = 0;
1969     		
1970     		/* Switch on WEP if off */
1971     		if ((!enable) && (xlen > 0)) {
1972     			setindex = index;
1973     			enable = 1;
1974     		}
1975     	} else {
1976     		/* Important note : if the user do "iwconfig eth0 enc off",
1977     		 * we will arrive there with an index of -1. This is valid
1978     		 * but need to be taken care off... Jean II */
1979     		if ((index < 0) || (index >= MAX_KEYS)) {
1980     			if((index != -1) || (erq->flags == 0)) {
1981     				err = -EINVAL;
1982     				goto out;
1983     			}
1984     		} else {
1985     			/* Set the index : Check that the key is valid */
1986     			if(priv->keys[index].len == 0) {
1987     				err = -EINVAL;
1988     				goto out;
1989     			}
1990     			setindex = index;
1991     		}
1992     	}
1993     	
1994     	if (erq->flags & IW_ENCODE_DISABLED)
1995     		enable = 0;
1996     	/* Only for Prism2 & Symbol cards (so far) - Jean II */
1997     	if (erq->flags & IW_ENCODE_OPEN)
1998     		restricted = 0;
1999     	if (erq->flags & IW_ENCODE_RESTRICTED)
2000     		restricted = 1;
2001     
2002     	if (erq->pointer) {
2003     		priv->keys[index].len = cpu_to_le16(xlen);
2004     		memset(priv->keys[index].data, 0, sizeof(priv->keys[index].data));
2005     		memcpy(priv->keys[index].data, keybuf, erq->length);
2006     	}
2007     	priv->tx_key = setindex;
2008     	priv->wep_on = enable;
2009     	priv->wep_restrict = restricted;
2010     	
2011      out:
2012     	dldwd_unlock(priv);
2013     
2014     	return 0;
2015     }
2016     
2017     static int dldwd_ioctl_getiwencode(struct net_device *dev, struct iw_point *erq)
2018     {
2019     	dldwd_priv_t *priv = dev->priv;
2020     	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
2021     	uint16_t xlen = 0;
2022     	char keybuf[MAX_KEY_SIZE];
2023     
2024     	
2025     	dldwd_lock(priv);
2026     
2027     	if ((index < 0) || (index >= MAX_KEYS))
2028     		index = priv->tx_key;
2029     
2030     	erq->flags = 0;
2031     	if (! priv->wep_on)
2032     		erq->flags |= IW_ENCODE_DISABLED;
2033     	erq->flags |= index + 1;
2034     	
2035     	/* Only for symbol cards - Jean II */
2036     	if (priv->firmware_type != FIRMWARE_TYPE_LUCENT) {
2037     		if(priv->wep_restrict)
2038     			erq->flags |= IW_ENCODE_RESTRICTED;
2039     		else
2040     			erq->flags |= IW_ENCODE_OPEN;
2041     	}
2042     
2043     	xlen = le16_to_cpu(priv->keys[index].len);
2044     
2045     	erq->length = xlen;
2046     
2047     	if (erq->pointer) {
2048     		memcpy(keybuf, priv->keys[index].data, MAX_KEY_SIZE);
2049     	}
2050     	
2051     	dldwd_unlock(priv);
2052     
2053     	if (erq->pointer) {
2054     		if (copy_to_user(erq->pointer, keybuf, xlen))
2055     			return -EFAULT;
2056     	}
2057     
2058     	return 0;
2059     }
2060     
2061     static int dldwd_ioctl_setessid(struct net_device *dev, struct iw_point *erq)
2062     {
2063     	dldwd_priv_t *priv = dev->priv;
2064     	char essidbuf[IW_ESSID_MAX_SIZE+1];
2065     
2066     	/* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
2067     	 * anyway... - Jean II */
2068     
2069     	memset(&essidbuf, 0, sizeof(essidbuf));
2070     
2071     	if (erq->flags) { 
2072     		if (erq->length > IW_ESSID_MAX_SIZE)
2073     			return -E2BIG;
2074     		
2075     		if (copy_from_user(&essidbuf, erq->pointer, erq->length))
2076     			return -EFAULT;
2077     
2078     		essidbuf[erq->length] = '\0';
2079     	}
2080     
2081     	dldwd_lock(priv);
2082     
2083     	memcpy(priv->desired_essid, essidbuf, IW_ESSID_MAX_SIZE+1);
2084     
2085     	dldwd_unlock(priv);
2086     
2087     	return 0;
2088     }
2089     
2090     static int dldwd_ioctl_getessid(struct net_device *dev, struct iw_point *erq)
2091     {
2092     	dldwd_priv_t *priv = dev->priv;
2093     	char essidbuf[IW_ESSID_MAX_SIZE+1];
2094     	int active;
2095     	int err = 0;
2096     
2097     	TRACE_ENTER(dev->name);
2098     
2099     	err = dldwd_hw_get_essid(priv, &active, essidbuf);
2100     	if (err)
2101     		return err;
2102     
2103     	erq->flags = 1;
2104     	erq->length = strlen(essidbuf) + 1;
2105     	if (erq->pointer)
2106     		if ( copy_to_user(erq->pointer, essidbuf, erq->length) )
2107     			return -EFAULT;
2108     
2109     	TRACE_EXIT(dev->name);
2110     	
2111     	return 0;
2112     }
2113     
2114     static int dldwd_ioctl_setnick(struct net_device *dev, struct iw_point *nrq)
2115     {
2116     	dldwd_priv_t *priv = dev->priv;
2117     	char nickbuf[IW_ESSID_MAX_SIZE+1];
2118     
2119     	if (nrq->length > IW_ESSID_MAX_SIZE)
2120     		return -E2BIG;
2121     
2122     	memset(nickbuf, 0, sizeof(nickbuf));
2123     
2124     	if (copy_from_user(nickbuf, nrq->pointer, nrq->length))
2125     		return -EFAULT;
2126     
2127     	nickbuf[nrq->length] = '\0';
2128     	
2129     	dldwd_lock(priv);
2130     
2131     	memcpy(priv->nick, nickbuf, sizeof(priv->nick));
2132     
2133     	dldwd_unlock(priv);
2134     
2135     	return 0;
2136     }
2137     
2138     static int dldwd_ioctl_getnick(struct net_device *dev, struct iw_point *nrq)
2139     {
2140     	dldwd_priv_t *priv = dev->priv;
2141     	char nickbuf[IW_ESSID_MAX_SIZE+1];
2142     
2143     	dldwd_lock(priv);
2144     	memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
2145     	dldwd_unlock(priv);
2146     
2147     	nrq->length = strlen(nickbuf)+1;
2148     
2149     	if (copy_to_user(nrq->pointer, nickbuf, sizeof(nickbuf)))
2150     		return -EFAULT;
2151     
2152     	return 0;
2153     }
2154     
2155     static int dldwd_ioctl_setfreq(struct net_device *dev, struct iw_freq *frq)
2156     {
2157     	dldwd_priv_t *priv = dev->priv;
2158     	int chan = -1;
2159     
2160     	/* We can only use this in Ad-Hoc demo mode to set the operating
2161     	 * frequency, or in IBSS mode to set the frequency where the IBSS
2162     	 * will be created - Jean II */
2163     	if (priv->iw_mode != IW_MODE_ADHOC)
2164     		return -EOPNOTSUPP;
2165     
2166     	if ( (frq->e == 0) && (frq->m <= 1000) ) {
2167     		/* Setting by channel number */
2168     		chan = frq->m;
2169     	} else {
2170     		/* Setting by frequency - search the table */
2171     		int mult = 1;
2172     		int i;
2173     
2174     		for (i = 0; i < (6 - frq->e); i++)
2175     			mult *= 10;
2176     
2177     		for (i = 0; i < NUM_CHANNELS; i++)
2178     			if (frq->m == (channel_frequency[i] * mult))
2179     				chan = i+1;
2180     	}
2181     
2182     	if ( (chan < 1) || (chan > NUM_CHANNELS) ||
2183     	     ! (priv->channel_mask & (1 << (chan-1)) ) )
2184     		return -EINVAL;
2185     
2186     	dldwd_lock(priv);
2187     	priv->channel = chan;
2188     	dldwd_unlock(priv);
2189     
2190     	return 0;
2191     }
2192     
2193     static int dldwd_ioctl_getsens(struct net_device *dev, struct iw_param *srq)
2194     {
2195     	dldwd_priv_t *priv = dev->priv;
2196     	hermes_t *hw = &priv->hw;
2197     	uint16_t val;
2198     	int err;
2199     
2200     	dldwd_lock(priv);
2201     	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_SYSTEM_SCALE, &val);
2202     	dldwd_unlock(priv);
2203     
2204     	if (err)
2205     		return err;
2206     
2207     	srq->value = val;
2208     	srq->fixed = 0; /* auto */
2209     
2210     	return 0;
2211     }
2212     
2213     static int dldwd_ioctl_setsens(struct net_device *dev, struct iw_param *srq)
2214     {
2215     	dldwd_priv_t *priv = dev->priv;
2216     	int val = srq->value;
2217     
2218     	if ((val < 1) || (val > 3))
2219     		return -EINVAL;
2220     	
2221     	dldwd_lock(priv);
2222     	priv->ap_density = val;
2223     	dldwd_unlock(priv);
2224     
2225     	return 0;
2226     }
2227     
2228     static int dldwd_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
2229     {
2230     	dldwd_priv_t *priv = dev->priv;
2231     	int val = rrq->value;
2232     
2233     	if (rrq->disabled)
2234     		val = 2347;
2235     
2236     	if ( (val < 0) || (val > 2347) )
2237     		return -EINVAL;
2238     
2239     	dldwd_lock(priv);
2240     	priv->rts_thresh = val;
2241     	dldwd_unlock(priv);
2242     
2243     	return 0;
2244     }
2245     
2246     static int dldwd_ioctl_setfrag(struct net_device *dev, struct iw_param *frq)
2247     {
2248     	dldwd_priv_t *priv = dev->priv;
2249     	int err = 0;
2250     
2251     	dldwd_lock(priv);
2252     
2253     	if (priv->has_mwo) {
2254     		if (frq->disabled)
2255     			priv->mwo_robust = 0;
2256     		else {
2257     			if (frq->fixed)
2258     				printk(KERN_WARNING "%s: Fixed fragmentation not \
2259     supported on this firmware. Using MWO robust instead.\n", dev->name);
2260     			priv->mwo_robust = 1;
2261     		}
2262     	} else {
2263     		if (frq->disabled)
2264     			priv->frag_thresh = 2346;
2265     		else {
2266     			if ( (frq->value < 256) || (frq->value > 2346) )
2267     				err = -EINVAL;
2268     			else
2269     				priv->frag_thresh = frq->value & ~0x1; /* must be even */
2270     		}
2271     	}
2272     
2273     	dldwd_unlock(priv);
2274     
2275     	return err;
2276     }
2277     
2278     static int dldwd_ioctl_getfrag(struct net_device *dev, struct iw_param *frq)
2279     {
2280     	dldwd_priv_t *priv = dev->priv;
2281     	hermes_t *hw = &priv->hw;
2282     	int err = 0;
2283     	uint16_t val;
2284     
2285     	dldwd_lock(priv);
2286     	
2287     	if (priv->has_mwo) {
2288     		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_MWO_ROBUST, &val);
2289     		if (err)
2290     			val = 0;
2291     
2292     		frq->value = val ? 2347 : 0;
2293     		frq->disabled = ! val;
2294     		frq->fixed = 0;
2295     	} else {
2296     		err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_FRAG_THRESH, &val);
2297     		if (err)
2298     			val = 0;
2299     
2300     		frq->value = val;
2301     		frq->disabled = (val >= 2346);
2302     		frq->fixed = 1;
2303     	}
2304     
2305     	dldwd_unlock(priv);
2306     	
2307     	return err;
2308     }
2309     
2310     static int dldwd_ioctl_setrate(struct net_device *dev, struct iw_param *rrq)
2311     {
2312     	dldwd_priv_t *priv = dev->priv;
2313     	int err = 0;
2314     	int rate_ctrl = -1;
2315     	int fixed, upto;
2316     	int brate;
2317     	int i;
2318     
2319     	dldwd_lock(priv);
2320     
2321     	/* Normalise value */
2322     	brate = rrq->value / 500000;
2323     
2324     	switch (priv->firmware_type) {
2325     	case FIRMWARE_TYPE_LUCENT: /* Lucent style rate */
2326     		if (! rrq->fixed) {
2327     			if (brate > 0)
2328     				brate = -brate;
2329     			else
2330     				brate = -22;
2331     		}
2332     	
2333     		for (i = 0; i < NUM_RATES; i++)
2334     			if (rate_list[i] == brate) {
2335     				rate_ctrl = i;
2336     				break;
2337     			}
2338     	
2339     		if ( (rate_ctrl < 1) || (rate_ctrl >= NUM_RATES) )
2340     			err = -EINVAL;
2341     		else
2342     			priv->tx_rate_ctrl = rate_ctrl;
2343     		break;
2344     	case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
2345     	case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
2346     		switch(brate) {
2347     		case 0:
2348     			fixed = 0x0;
2349     			upto = 0xF;
2350     			break;
2351     		case 2:
2352     			fixed = 0x1;
2353     			upto = 0x1;
2354     			break;
2355     		case 4:
2356     			fixed = 0x2;
2357     			upto = 0x3;
2358     			break;
2359     		case 11:
2360     			fixed = 0x4;
2361     			upto = 0x7;
2362     			break;
2363     		case 22:
2364     			fixed = 0x8;
2365     			upto = 0xF;
2366     			break;
2367     		default:
2368     			fixed = 0x0;
2369     			upto = 0x0;
2370     		}
2371     		if (rrq->fixed)
2372     			rate_ctrl = fixed;
2373     		else
2374     			rate_ctrl = upto;
2375     		if (rate_ctrl == 0)
2376     			err = -EINVAL;
2377     		else
2378     			priv->tx_rate_ctrl = rate_ctrl;
2379     		break;
2380     	}
2381     
2382     	dldwd_unlock(priv);
2383     
2384     	return err;
2385     }
2386     
2387     static int dldwd_ioctl_getrate(struct net_device *dev, struct iw_param *rrq)
2388     {
2389     	dldwd_priv_t *priv = dev->priv;
2390     	hermes_t *hw = &priv->hw;
2391     	int err = 0;
2392     	uint16_t val;
2393     	int brate = 0;
2394     
2395     	dldwd_lock(priv);
2396     	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_TX_RATE_CTRL, &val);
2397     	if (err)
2398     		goto out;
2399     	
2400     	switch (priv->firmware_type) {
2401     	case FIRMWARE_TYPE_LUCENT: /* Lucent style rate */
2402     		brate = rate_list[val];
2403     	
2404     		if (brate < 0) {
2405     			rrq->fixed = 0;
2406     
2407     			err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENT_TX_RATE, &val);
2408     			if (err)
2409     				goto out;
2410     
2411     			if (val == 6)
2412     				brate = 11;
2413     			else
2414     				brate = 2*val;
2415     		} else
2416     			rrq->fixed = 1;
2417     		break;
2418     	case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
2419     	case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
2420     		/* Check if auto or fixed (crude approximation) */
2421     		if((val & 0x1) && (val > 1)) {
2422     			rrq->fixed = 0;
2423     
2424     			err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENT_TX_RATE, &val);
2425     			if (err)
2426     				goto out;
2427     		} else
2428     			rrq->fixed = 1;
2429     
2430     		if(val >= 8)
2431     			brate = 22;
2432     		else if(val >= 4)
2433     			brate = 11;
2434     		else if(val >= 2)
2435     			brate = 4;
2436     		else
2437     			brate = 2;
2438     		break;
2439     	}
2440     
2441     	rrq->value = brate * 500000;
2442     	rrq->disabled = 0;
2443     
2444      out:
2445     	dldwd_unlock(priv);
2446     
2447     	return err;
2448     }
2449     
2450     static int dldwd_ioctl_setpower(struct net_device *dev, struct iw_param *prq)
2451     {
2452     	dldwd_priv_t *priv = dev->priv;
2453     	int err = 0;
2454     
2455     
2456     	dldwd_lock(priv);
2457     
2458     	if (prq->disabled) {
2459     		priv->pm_on = 0;
2460     	} else {
2461     		switch (prq->flags & IW_POWER_MODE) {
2462     		case IW_POWER_UNICAST_R:
2463     			priv->pm_mcast = 0;
2464     			priv->pm_on = 1;
2465     			break;
2466     		case IW_POWER_ALL_R:
2467     			priv->pm_mcast = 1;
2468     			priv->pm_on = 1;
2469     			break;
2470     		case IW_POWER_ON:
2471     			/* No flags : but we may have a value - Jean II */
2472     			break;
2473     		default:
2474     			err = -EINVAL;
2475     		}
2476     		if (err)
2477     			goto out;
2478     		
2479     		if (prq->flags & IW_POWER_TIMEOUT) {
2480     			priv->pm_on = 1;
2481     			priv->pm_timeout = prq->value / 1000;
2482     		}
2483     		if (prq->flags & IW_POWER_PERIOD) {
2484     			priv->pm_on = 1;
2485     			priv->pm_period = prq->value / 1000;
2486     		}
2487     		/* It's valid to not have a value if we are just toggling
2488     		 * the flags... Jean II */
2489     		if(!priv->pm_on) {
2490     			err = -EINVAL;
2491     			goto out;
2492     		}			
2493     	}
2494     
2495      out:
2496     	dldwd_unlock(priv);
2497     
2498     	return err;
2499     }
2500     
2501     static int dldwd_ioctl_getpower(struct net_device *dev, struct iw_param *prq)
2502     {
2503     	dldwd_priv_t *priv = dev->priv;
2504     	hermes_t *hw = &priv->hw;
2505     	int err = 0;
2506     	uint16_t enable, period, timeout, mcast;
2507     
2508     	dldwd_lock(priv);
2509     	
2510     	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_ENABLE, &enable);
2511     	if (err)
2512     		goto out;
2513     
2514     	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_PERIOD, &period);
2515     	if (err)
2516     		goto out;
2517     
2518     	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_HOLDOVER, &timeout);
2519     	if (err)
2520     		goto out;
2521     
2522     	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNF_PM_MCAST_RX, &mcast);
2523     	if (err)
2524     		goto out;
2525     
2526     	prq->disabled = !enable;
2527     	/* Note : by default, display the period */
2528     	if ((prq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
2529     		prq->flags = IW_POWER_TIMEOUT;
2530     		prq->value = timeout * 1000;
2531     	} else {
2532     		prq->flags = IW_POWER_PERIOD;
2533     		prq->value = period * 1000;
2534     	}
2535     	if (mcast)
2536     		prq->flags |= IW_POWER_ALL_R;
2537     	else
2538     		prq->flags |= IW_POWER_UNICAST_R;
2539     
2540      out:
2541     	dldwd_unlock(priv);
2542     
2543     	return err;
2544     }
2545     
2546     #if WIRELESS_EXT > 10
2547     static int dldwd_ioctl_getretry(struct net_device *dev, struct iw_param *rrq)
2548     {
2549     	dldwd_priv_t *priv = dev->priv;
2550     	hermes_t *hw = &priv->hw;
2551     	int err = 0;
2552     	uint16_t short_limit, long_limit, lifetime;
2553     
2554     	dldwd_lock(priv);
2555     	
2556     	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORT_RETRY_LIMIT, &short_limit);
2557     	if (err)
2558     		goto out;
2559     
2560     	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONG_RETRY_LIMIT, &long_limit);
2561     	if (err)
2562     		goto out;
2563     
2564     	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAX_TX_LIFETIME, &lifetime);
2565     	if (err)
2566     		goto out;
2567     
2568     	rrq->disabled = 0;		/* Can't be disabled */
2569     
2570     	/* Note : by default, display the retry number */
2571     	if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
2572     		rrq->flags = IW_RETRY_LIFETIME;
2573     		rrq->value = lifetime * 1000;	/* ??? */
2574     	} else {
2575     		/* By default, display the min number */
2576     		if ((rrq->flags & IW_RETRY_MAX)) {
2577     			rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
2578     			rrq->value = long_limit;
2579     		} else {
2580     			rrq->flags = IW_RETRY_LIMIT;
2581     			rrq->value = short_limit;
2582     			if(short_limit != long_limit)
2583     				rrq->flags |= IW_RETRY_MIN;
2584     		}
2585     	}
2586     
2587      out:
2588     	dldwd_unlock(priv);
2589     
2590     	return err;
2591     }
2592     #endif /* WIRELESS_EXT > 10 */
2593     
2594     static int dldwd_ioctl_setibssport(struct net_device *dev, struct iwreq *wrq)
2595     {
2596     	dldwd_priv_t *priv = dev->priv;
2597     	int val = *( (int *) wrq->u.name );
2598     
2599     	dldwd_lock(priv);
2600     	priv->ibss_port = val ;
2601     
2602     	/* Actually update the mode we are using */
2603     	set_port_type(priv);
2604     
2605     	dldwd_unlock(priv);
2606     	return 0;
2607     }
2608     
2609     static int dldwd_ioctl_getibssport(struct net_device *dev, struct iwreq *wrq)
2610     {
2611     	dldwd_priv_t *priv = dev->priv;
2612     	int *val = (int *)wrq->u.name;
2613     
2614     	dldwd_lock(priv);
2615     	*val = priv->ibss_port;
2616     	dldwd_unlock(priv);
2617     
2618     	return 0;
2619     }
2620     
2621     static int dldwd_ioctl_setport3(struct net_device *dev, struct iwreq *wrq)
2622     {
2623     	dldwd_priv_t *priv = dev->priv;
2624     	int val = *( (int *) wrq->u.name );
2625     	int err = 0;
2626     
2627     	dldwd_lock(priv);
2628     	switch (val) {
2629     	case 0: /* Try to do IEEE ad-hoc mode */
2630     		if (! priv->has_ibss) {
2631     			err = -EINVAL;
2632     			break;
2633     		}
2634     		DEBUG(2, "%s: Prefer IBSS Ad-Hoc mode\n", dev->name);
2635     		priv->prefer_port3 = 0;
2636     			
2637     		break;
2638     
2639     	case 1: /* Try to do Lucent proprietary ad-hoc mode */
2640     		if (! priv->has_port3) {
2641     			err = -EINVAL;
2642     			break;
2643     		}
2644     		DEBUG(2, "%s: Prefer Ad-Hoc demo mode\n", dev->name);
2645     		priv->prefer_port3 = 1;
2646     		break;
2647     
2648     	default:
2649     		err = -EINVAL;
2650     	}
2651     
2652     	if (! err)
2653     		/* Actually update the mode we are using */
2654     		set_port_type(priv);
2655     
2656     	dldwd_unlock(priv);
2657     
2658     	return err;
2659     }
2660     
2661     static int dldwd_ioctl_getport3(struct net_device *dev, struct iwreq *wrq)
2662     {
2663     	dldwd_priv_t *priv = dev->priv;
2664     	int *val = (int *)wrq->u.name;
2665     
2666     	dldwd_lock(priv);
2667     	*val = priv->prefer_port3;
2668     	dldwd_unlock(priv);
2669     
2670     	return 0;
2671     }
2672     
2673     /* Spy is used for link quality/strength measurements in Ad-Hoc mode
2674      * Jean II */
2675     static int dldwd_ioctl_setspy(struct net_device *dev, struct iw_point *srq)
2676     {
2677     	dldwd_priv_t *priv = dev->priv;
2678     	struct sockaddr address[IW_MAX_SPY];
2679     	int number = srq->length;
2680     	int i;
2681     	int err = 0;
2682     
2683     	/* Check the number of addresses */
2684     	if (number > IW_MAX_SPY)
2685     		return -E2BIG;
2686     
2687     	/* Get the data in the driver */
2688     	if (srq->pointer) {
2689     		if (copy_from_user(address, srq->pointer,
2690     				   sizeof(struct sockaddr) * number))
2691     			return -EFAULT;
2692     	}
2693     
2694     	/* Make sure nobody mess with the structure while we do */
2695     	dldwd_lock(priv);
2696     
2697     	/* dldwd_lock() doesn't disable interrupts, so make sure the
2698     	 * interrupt rx path don't get confused while we copy */
2699     	priv->spy_number = 0;
2700     
2701     	if (number > 0) {
2702     		/* Extract the addresses */
2703     		for (i = 0; i < number; i++)
2704     			memcpy(priv->spy_address[i], address[i].sa_data,
2705     			       ETH_ALEN);
2706     		/* Reset stats */
2707     		memset(priv->spy_stat, 0,
2708     		       sizeof(struct iw_quality) * IW_MAX_SPY);
2709     		/* Set number of addresses */
2710     		priv->spy_number = number;
2711     	}
2712     
2713     	/* Time to show what we have done... */
2714     	DEBUG(0, "%s: New spy list:\n", dev->name);
2715     	for (i = 0; i < number; i++) {
2716     		DEBUG(0, "%s: %d - %02x:%02x:%02x:%02x:%02x:%02x\n",
2717     		      dev->name, i+1,
2718     		      priv->spy_address[i][0], priv->spy_address[i][1],
2719     		      priv->spy_address[i][2], priv->spy_address[i][3],
2720     		      priv->spy_address[i][4], priv->spy_address[i][5]);
2721     	}
2722     
2723     	/* Now, let the others play */
2724     	dldwd_unlock(priv);
2725     
2726     	return err;
2727     }
2728     
2729     static int dldwd_ioctl_getspy(struct net_device *dev, struct iw_point *srq)
2730     {
2731     	dldwd_priv_t *priv = dev->priv;
2732     	struct sockaddr address[IW_MAX_SPY];
2733     	struct iw_quality spy_stat[IW_MAX_SPY];
2734     	int number;
2735     	int i;
2736     
2737     	dldwd_lock(priv);
2738     
2739     	number = priv->spy_number;
2740     	if ((number > 0) && (srq->pointer)) {
2741     		/* Create address struct */
2742     		for (i = 0; i < number; i++) {
2743     			memcpy(address[i].sa_data, priv->spy_address[i],
2744     			       ETH_ALEN);
2745     			address[i].sa_family = AF_UNIX;
2746     		}
2747     		/* Copy stats */
2748     		/* In theory, we should disable irqs while copying the stats
2749     		 * because the rx path migh update it in the middle...
2750     		 * Bah, who care ? - Jean II */
2751     		memcpy(&spy_stat, priv->spy_stat,
2752     		       sizeof(struct iw_quality) * IW_MAX_SPY);
2753     		for (i=0; i < number; i++)
2754     			priv->spy_stat[i].updated = 0;
2755     	}
2756     
2757     	dldwd_unlock(priv);
2758     
2759     	/* Push stuff to user space */
2760     	srq->length = number;
2761     	if(copy_to_user(srq->pointer, address,
2762     			 sizeof(struct sockaddr) * number))
2763     		return -EFAULT;
2764     	if(copy_to_user(srq->pointer + (sizeof(struct sockaddr)*number),
2765     			&spy_stat, sizeof(struct iw_quality) * number))
2766     		return -EFAULT;
2767     
2768     	return 0;
2769     }
2770     
2771     int
2772     dldwd_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2773     {
2774     	dldwd_priv_t *priv = dev->priv;
2775     	struct iwreq *wrq = (struct iwreq *)rq;
2776     	int err = 0;
2777     	int changed = 0;
2778     
2779     	TRACE_ENTER(dev->name);
2780     
2781     	/* In theory, we could allow most of the the SET stuff to be done
2782     	 * In practice, the laps of time at startup when the card is not
2783     	 * ready is very short, so why bother...
2784     	 * Note that hw_ready is different from up/down (ifconfig), when
2785     	 * the device is not yet up, it is usually already ready...
2786     	 * Jean II */
2787     	if (!priv->hw_ready)
2788     		return -ENODEV;
2789     
2790     	switch (cmd) {
2791     	case SIOCGIWNAME:
2792     		DEBUG(1, "%s: SIOCGIWNAME\n", dev->name);
2793     		strcpy(wrq->u.name, "IEEE 802.11-DS");
2794     		break;
2795     		
2796     	case SIOCGIWAP:
2797     		DEBUG(1, "%s: SIOCGIWAP\n", dev->name);
2798     		wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
2799     		err = dldwd_hw_get_bssid(priv, wrq->u.ap_addr.sa_data);
2800     		break;
2801     
2802     	case SIOCGIWRANGE:
2803     		DEBUG(1, "%s: SIOCGIWRANGE\n", dev->name);
2804     		err = dldwd_ioctl_getiwrange(dev, &wrq->u.data);
2805     		break;
2806     
2807     	case SIOCSIWMODE:
2808     		DEBUG(1, "%s: SIOCSIWMODE\n", dev->name);
2809     		dldwd_lock(priv);
2810     		switch (wrq->u.mode) {
2811     		case IW_MODE_ADHOC:
2812     			if (! (priv->has_ibss || priv->has_port3) )
2813     				err = -EINVAL;
2814     			else {
2815     				priv->iw_mode = IW_MODE_ADHOC;
2816     				changed = 1;
2817     			}
2818     			break;
2819     
2820     		case IW_MODE_INFRA:
2821     			priv->iw_mode = IW_MODE_INFRA;
2822     			changed = 1;
2823     			break;
2824     
2825     		default:
2826     			err = -EINVAL;
2827     			break;
2828     		}
2829     		set_port_type(priv);
2830     		dldwd_unlock(priv);
2831     		break;
2832     
2833     	case SIOCGIWMODE:
2834     		DEBUG(1, "%s: SIOCGIWMODE\n", dev->name);
2835     		dldwd_lock(priv);
2836     		wrq->u.mode = priv->iw_mode;
2837     		dldwd_unlock(priv);
2838     		break;
2839     
2840     	case SIOCSIWENCODE:
2841     		DEBUG(1, "%s: SIOCSIWENCODE\n", dev->name);
2842     		if (! priv->has_wep) {
2843     			err = -EOPNOTSUPP;
2844     			break;
2845     		}
2846     
2847     		err = dldwd_ioctl_setiwencode(dev, &wrq->u.encoding);
2848     		if (! err)
2849     			changed = 1;
2850     		break;
2851     
2852     	case SIOCGIWENCODE:
2853     		DEBUG(1, "%s: SIOCGIWENCODE\n", dev->name);
2854     		if (! priv->has_wep) {
2855     			err = -EOPNOTSUPP;
2856     			break;
2857     		}
2858     
2859     		if (! capable(CAP_NET_ADMIN)) {
2860     			err = -EPERM;
2861     			break;
2862     		}
2863     
2864     		err = dldwd_ioctl_getiwencode(dev, &wrq->u.encoding);
2865     		break;
2866     
2867     	case SIOCSIWESSID:
2868     		DEBUG(1, "%s: SIOCSIWESSID\n", dev->name);
2869     		err = dldwd_ioctl_setessid(dev, &wrq->u.essid);
2870     		if (! err)
2871     			changed = 1;
2872     		break;
2873     
2874     	case SIOCGIWESSID:
2875     		DEBUG(1, "%s: SIOCGIWESSID\n", dev->name);
2876     		err = dldwd_ioctl_getessid(dev, &wrq->u.essid);
2877     		break;
2878     
2879     	case SIOCSIWNICKN:
2880     		DEBUG(1, "%s: SIOCSIWNICKN\n", dev->name);
2881     		err = dldwd_ioctl_setnick(dev, &wrq->u.data);
2882     		if (! err)
2883     			changed = 1;
2884     		break;
2885     
2886     	case SIOCGIWNICKN:
2887     		DEBUG(1, "%s: SIOCGIWNICKN\n", dev->name);
2888     		err = dldwd_ioctl_getnick(dev, &wrq->u.data);
2889     		break;
2890     
2891     	case SIOCGIWFREQ:
2892     		DEBUG(1, "%s: SIOCGIWFREQ\n", dev->name);
2893     		wrq->u.freq.m = dldwd_hw_get_freq(priv);
2894     		wrq->u.freq.e = 1;
2895     		break;
2896     
2897     	case SIOCSIWFREQ:
2898     		DEBUG(1, "%s: SIOCSIWFREQ\n", dev->name);
2899     		err = dldwd_ioctl_setfreq(dev, &wrq->u.freq);
2900     		if (! err)
2901     			changed = 1;
2902     		break;
2903     
2904     	case SIOCGIWSENS:
2905     		DEBUG(1, "%s: SIOCGIWSENS\n", dev->name);
2906     		err = dldwd_ioctl_getsens(dev, &wrq->u.sens);
2907     		break;
2908     
2909     	case SIOCSIWSENS:
2910     		DEBUG(1, "%s: SIOCSIWSENS\n", dev->name);
2911     		err = dldwd_ioctl_setsens(dev, &wrq->u.sens);
2912     		if (! err)
2913     			changed = 1;
2914     		break;
2915     
2916     	case SIOCGIWRTS:
2917     		DEBUG(1, "%s: SIOCGIWRTS\n", dev->name);
2918     		wrq->u.rts.value = priv->rts_thresh;
2919     		wrq->u.rts.disabled = (wrq->u.rts.value == 2347);
2920     		wrq->u.rts.fixed = 1;
2921     		break;
2922     
2923     	case SIOCSIWRTS:
2924     		DEBUG(1, "%s: SIOCSIWRTS\n", dev->name);
2925     		err = dldwd_ioctl_setrts(dev, &wrq->u.rts);
2926     		if (! err)
2927     			changed = 1;
2928     		break;
2929     
2930     	case SIOCSIWFRAG:
2931     		DEBUG(1, "%s: SIOCSIWFRAG\n", dev->name);
2932     		err = dldwd_ioctl_setfrag(dev, &wrq->u.frag);
2933     		if (! err)
2934     			changed = 1;
2935     		break;
2936     
2937     	case SIOCGIWFRAG:
2938     		DEBUG(1, "%s: SIOCGIWFRAG\n", dev->name);
2939     		err = dldwd_ioctl_getfrag(dev, &wrq->u.frag);
2940     		break;
2941     
2942     	case SIOCSIWRATE:
2943     		DEBUG(1, "%s: SIOCSIWRATE\n", dev->name);
2944     		err = dldwd_ioctl_setrate(dev, &wrq->u.bitrate);
2945     		if (! err)
2946     			changed = 1;
2947     		break;
2948     
2949     	case SIOCGIWRATE:
2950     		DEBUG(1, "%s: SIOCGIWRATE\n", dev->name);
2951     		err = dldwd_ioctl_getrate(dev, &wrq->u.bitrate);
2952     		break;
2953     
2954     	case SIOCSIWPOWER:
2955     		DEBUG(1, "%s: SIOCSIWPOWER\n", dev->name);
2956     		err = dldwd_ioctl_setpower(dev, &wrq->u.power);
2957     		if (! err)
2958     			changed = 1;
2959     		break;
2960     
2961     	case SIOCGIWPOWER:
2962     		DEBUG(1, "%s: SIOCGIWPOWER\n", dev->name);
2963     		err = dldwd_ioctl_getpower(dev, &wrq->u.power);
2964     		break;
2965     
2966     	case SIOCGIWTXPOW:
2967     		DEBUG(1, "%s: SIOCGIWTXPOW\n", dev->name);
2968     		/* The card only supports one tx power, so this is easy */
2969     		wrq->u.txpower.value = 15; /* dBm */
2970     		wrq->u.txpower.fixed = 1;
2971     		wrq->u.txpower.disabled = 0;
2972     		wrq->u.txpower.flags = IW_TXPOW_DBM;
2973     		break;
2974     
2975     #if WIRELESS_EXT > 10
2976     	case SIOCSIWRETRY:
2977     		DEBUG(1, "%s: SIOCSIWRETRY\n", dev->name);
2978     		err = -EOPNOTSUPP;
2979     		break;
2980     
2981     	case SIOCGIWRETRY:
2982     		DEBUG(1, "%s: SIOCGIWRETRY\n", dev->name);
2983     		err = dldwd_ioctl_getretry(dev, &wrq->u.retry);
2984     		break;
2985     #endif /* WIRELESS_EXT > 10 */
2986     
2987     	case SIOCSIWSPY:
2988     		DEBUG(1, "%s: SIOCSIWSPY\n", dev->name);
2989     
2990     		err = dldwd_ioctl_setspy(dev, &wrq->u.data);
2991     		break;
2992     
2993     	case SIOCGIWSPY:
2994     		DEBUG(1, "%s: SIOCGIWSPY\n", dev->name);
2995     
2996     		err = dldwd_ioctl_getspy(dev, &wrq->u.data);
2997     		break;
2998     
2999     	case SIOCGIWPRIV:
3000     		DEBUG(1, "%s: SIOCGIWPRIV\n", dev->name);
3001     		if (wrq->u.data.pointer) {
3002     			struct iw_priv_args privtab[] = {
3003     				{ SIOCDEVPRIVATE + 0x0, 0, 0, "force_reset" },
3004     				{ SIOCDEVPRIVATE + 0x1, 0, 0, "card_reset" },
3005     				{ SIOCDEVPRIVATE + 0x2,
3006     				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3007     				  0, "set_port3" },
3008     				{ SIOCDEVPRIVATE + 0x3, 0,
3009     				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3010     				  "get_port3" },
3011     				{ SIOCDEVPRIVATE + 0x4,
3012     				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3013     				  0, "set_preamble" },
3014     				{ SIOCDEVPRIVATE + 0x5, 0,
3015     				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3016     				  "get_preamble" },
3017     				{ SIOCDEVPRIVATE + 0x6,
3018     				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3019     				  0, "set_ibssport" },
3020     				{ SIOCDEVPRIVATE + 0x7, 0,
3021     				  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
3022     				  "get_ibssport" }
3023     			};
3024     
3025     			err = verify_area(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab));
3026     			if (err)
3027     				break;
3028     			
3029     			wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
3030     			if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
3031     				err = -EFAULT;
3032     		}
3033     		break;
3034     	       
3035     	case SIOCDEVPRIVATE + 0x0: /* force_reset */
3036     		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x0 (force_reset)\n",
3037     		      dev->name);
3038     		if (! capable(CAP_NET_ADMIN)) {
3039     			err = -EPERM;
3040     			break;
3041     		}
3042     		
3043     		printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
3044     		dldwd_reset(priv);
3045     		break;
3046     
3047     	case SIOCDEVPRIVATE + 0x1: /* card_reset */
3048     		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x1 (card_reset)\n",
3049     		      dev->name);
3050     		if (! capable(CAP_NET_ADMIN)) {
3051     			err = -EPERM;
3052     			break;
3053     		}
3054     		
3055     		printk(KERN_DEBUG "%s: Forcing card reset!\n", dev->name);
3056     		if(priv->card_reset_handler != NULL)
3057     			priv->card_reset_handler(priv);
3058     		dldwd_reset(priv);
3059     		break;
3060     
3061     	case SIOCDEVPRIVATE + 0x2: /* set_port3 */
3062     		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x2 (set_port3)\n",
3063     		      dev->name);
3064     		if (! capable(CAP_NET_ADMIN)) {
3065     			err = -EPERM;
3066     			break;
3067     		}
3068     
3069     		err = dldwd_ioctl_setport3(dev, wrq);
3070     		if (! err)
3071     			changed = 1;
3072     		break;
3073     
3074     	case SIOCDEVPRIVATE + 0x3: /* get_port3 */
3075     		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x3 (get_port3)\n",
3076     		      dev->name);
3077     		err = dldwd_ioctl_getport3(dev, wrq);
3078     		break;
3079     
3080     	case SIOCDEVPRIVATE + 0x4: /* set_preamble */
3081     		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x4 (set_preamble)\n",
3082     		      dev->name);
3083     		if (! capable(CAP_NET_ADMIN)) {
3084     			err = -EPERM;
3085     			break;
3086     		}
3087     
3088     		/* 802.11b has recently defined some short preamble.
3089     		 * Basically, the Phy header has been reduced in size.
3090     		 * This increase performance, especially at high rates
3091     		 * (the preamble is transmitted at 1Mb/s), unfortunately
3092     		 * this give compatibility troubles... - Jean II */
3093     		if(priv->has_preamble) {
3094     			int val = *( (int *) wrq->u.name );
3095     
3096     			dldwd_lock(priv);
3097     			if(val)
3098     				priv->preamble = 1;
3099     			else
3100     				priv->preamble = 0;
3101     			dldwd_unlock(priv);
3102     			changed = 1;
3103     		} else
3104     			err = -EOPNOTSUPP;
3105     		break;
3106     
3107     	case SIOCDEVPRIVATE + 0x5: /* get_preamble */
3108     		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x5 (get_preamble)\n",
3109     		      dev->name);
3110     		if(priv->has_preamble) {
3111     			int *val = (int *)wrq->u.name;
3112     
3113     			dldwd_lock(priv);
3114     			*val = priv->preamble;
3115     			dldwd_unlock(priv);
3116     		} else
3117     			err = -EOPNOTSUPP;
3118     		break;
3119     	case SIOCDEVPRIVATE + 0x6: /* set_ibssport */
3120     		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x6 (set_ibssport)\n",
3121     		      dev->name);
3122     		if (! capable(CAP_NET_ADMIN)) {
3123     			err = -EPERM;
3124     			break;
3125     		}
3126     
3127     		err = dldwd_ioctl_setibssport(dev, wrq);
3128     		if (! err)
3129     			changed = 1;
3130     		break;
3131     
3132     	case SIOCDEVPRIVATE + 0x7: /* get_ibssport */
3133     		DEBUG(1, "%s: SIOCDEVPRIVATE + 0x7 (get_ibssport)\n",
3134     		      dev->name);
3135     		err = dldwd_ioctl_getibssport(dev, wrq);
3136     		break;
3137     
3138     
3139     	default:
3140     		err = -EOPNOTSUPP;
3141     	}
3142     	
3143     	if (! err && changed && netif_running(dev)) {
3144     		err = dldwd_reset(priv);
3145     		if (err) {
3146     			/* Ouch ! What are we supposed to do ? */
3147     			printk(KERN_ERR "orinoco_cs: Failed to set parameters on %s\n",
3148     			       dev->name);
3149     			netif_stop_queue(dev);
3150     			dldwd_shutdown(priv);
3151     			priv->hw_ready = 0;
3152     		}
3153     	}		
3154     
3155     	TRACE_EXIT(dev->name);
3156     		
3157     	return err;
3158     }
3159     
3160     int
3161     dldwd_change_mtu(struct net_device *dev, int new_mtu)
3162     {
3163     	TRACE_ENTER(dev->name);
3164     
3165     	if ( (new_mtu < DLDWD_MIN_MTU) || (new_mtu > DLDWD_MAX_MTU) )
3166     		return -EINVAL;
3167     
3168     	dev->mtu = new_mtu;
3169     
3170     	TRACE_EXIT(dev->name);
3171     
3172     	return 0;
3173     }
3174     
3175     static void
3176     __dldwd_set_multicast_list(struct net_device *dev)
3177     {
3178     	dldwd_priv_t *priv = dev->priv;
3179     	hermes_t *hw = &priv->hw;
3180     	int err = 0;
3181     	int promisc, allmulti, mc_count;
3182     
3183     	/* We'll wait until it's ready. Anyway, the network doesn't call us
3184     	 * here until we are open - Jean II */
3185     	if (!priv->hw_ready)
3186     		return;
3187     
3188     
3189     	TRACE_ENTER(dev->name);
3190     
3191     	DEBUG(3, "dev->flags=0x%x, priv->promiscuous=%d, dev->mc_count=%d priv->mc_count=%d\n",
3192     	      dev->flags, priv->promiscuous, dev->mc_count, priv->mc_count);
3193     
3194     	/* The Hermes doesn't seem to have an allmulti mode, so we go
3195     	 * into promiscuous mode and let the upper levels deal. */
3196     	if ( (dev->flags & IFF_PROMISC) ) {
3197     		promisc = 1;
3198     		allmulti = 0;
3199     		mc_count = 0;
3200     	} else if ( (dev->flags & IFF_ALLMULTI) ||
3201     		    (dev->mc_count > HERMES_MAX_MULTICAST) ) {
3202     		promisc = 0;
3203     		allmulti = 1;
3204     		mc_count = HERMES_MAX_MULTICAST;
3205     	} else {
3206     		promisc = 0;
3207     		allmulti = 0;
3208     		mc_count = dev->mc_count;
3209     	}
3210     
3211     	DEBUG(3, "promisc=%d mc_count=%d\n",
3212     	      promisc, mc_count);
3213     
3214     	if (promisc != priv->promiscuous) { /* Don't touch the hardware if we don't have to */
3215     		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNF_PROMISCUOUS,
3216     					   promisc);
3217     		if (err) {
3218     			printk(KERN_ERR "%s: Error %d setting promiscuity to %d.\n",
3219     			       dev->name, err, promisc);
3220     		} else 
3221     			priv->promiscuous = promisc;
3222     	}
3223     
3224     	if (allmulti) {
3225     		/* FIXME: This method of doing allmulticast reception
3226     		   comes from the NetBSD driver. Haven't actually
3227     		   tested whether it works or not. */
3228     		hermes_multicast_t mclist;
3229     
3230     		memset(&mclist, 0, sizeof(mclist));
3231     		err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNF_MULTICAST_LIST, &mclist);
3232     		if (err)
3233     			printk(KERN_ERR "%s: Error %d setting multicast list.\n",
3234     			       dev->name, err);
3235     		else
3236     			priv->allmulti = 1;
3237     		       
3238     	} else if (mc_count || (! mc_count && priv->mc_count) ) {
3239     		struct dev_mc_list *p = dev->mc_list;
3240     		hermes_multicast_t mclist;
3241     		int i;
3242     
3243     		for (i = 0; i < mc_count; i++) {
3244     			/* First some paranoid checks */
3245     			if (! p) {
3246     				printk(KERN_ERR "%s: Multicast list shorter than mc_count.\n",
3247     				       dev->name);
3248     				break;
3249     			}
3250     			if (p->dmi_addrlen != ETH_ALEN) {
3251     
3252     				printk(KERN_ERR "%s: Bad address size (%d) in multicast list.\n",
3253     				       dev->name, p->dmi_addrlen);
3254     				break;
3255     			}
3256     
3257     			memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
3258     			p = p->next;
3259     		}
3260     
3261     		/* More paranoia */
3262     		if (p)
3263     			printk(KERN_ERR "%s: Multicast list longer than mc_count.\n",
3264     			       dev->name);
3265     
3266     		priv->mc_count = i;			
3267     
3268     		DEBUG(3, "priv->mc_count = %d\n", priv->mc_count);
3269     
3270     		err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNF_MULTICAST_LIST,
3271     				       HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
3272     				       &mclist);
3273     		if (err)
3274     			printk(KERN_ERR "%s: Error %d setting multicast list.\n",
3275     			       dev->name, err);
3276     		else
3277     			priv->allmulti = 0;
3278     	}
3279     
3280     	/* Since we can set the promiscuous flag when it wasn't asked
3281     	   for, make sure the net_device knows about it. */
3282     	if (priv->promiscuous)
3283     		dev->flags |= IFF_PROMISC;
3284     	else
3285     		dev->flags &= ~IFF_PROMISC;
3286     
3287     	if (priv->allmulti)
3288     		dev->flags |= IFF_ALLMULTI;
3289     	else
3290     		dev->flags &= ~IFF_ALLMULTI;
3291     
3292     	TRACE_EXIT(dev->name);
3293     }
3294     
3295     /*
3296      * procfs stuff
3297      */
3298     
3299     static struct proc_dir_entry *dir_base = NULL;
3300     
3301     /*
3302      * This function updates the total amount of data printed so far. It then
3303      * determines if the amount of data printed into a buffer  has reached the
3304      * offset requested. If it hasn't, then the buffer is shifted over so that
3305      * the next bit of data can be printed over the old bit. If the total
3306      * amount printed so far exceeds the total amount requested, then this
3307      * function returns 1, otherwise 0.
3308      */
3309     static int 
3310     
3311     shift_buffer(char *buffer, int requested_offset, int requested_len,
3312     	     int *total, int *slop, char **buf)
3313     {
3314     	int printed;
3315     	
3316     	printed = *buf - buffer;
3317     	if (*total + printed <= requested_offset) {
3318     		*total += printed;
3319     		*buf = buffer;
3320     	}
3321     	else {
3322     		if (*total < requested_offset) {
3323     			*slop = requested_offset - *total;
3324     		}
3325     		*total = requested_offset + printed - *slop;
3326     	}
3327     	if (*total > requested_offset + requested_len) {
3328     		return 1;
3329     	}
3330     	else {
3331     		return 0;
3332     	}
3333     }
3334     
3335     /*
3336      * This function calculates the actual start of the requested data
3337      * in the buffer. It also calculates actual length of data returned,
3338      * which could be less that the amount of data requested.
3339      */
3340     #define PROC_BUFFER_SIZE 4096
3341     #define PROC_SAFE_SIZE 3072
3342     
3343     static int
3344     calc_start_len(char *buffer, char **start, int requested_offset,
3345     	       int requested_len, int total, char *buf)
3346     {
3347     	int return_len, buffer_len;
3348     	
3349     	buffer_len = buf - buffer;
3350     	if (buffer_len >= PROC_BUFFER_SIZE - 1) {
3351     		printk(KERN_ERR "calc_start_len: exceeded /proc buffer size\n");
3352     	}
3353     	
3354     	/*
3355     	 * There may be bytes before and after the
3356     	 * chunk that was actually requested.
3357     	 */
3358     	return_len = total - requested_offset;
3359     	if (return_len < 0) {
3360     		return_len = 0;
3361     	}
3362     	*start = buf - return_len;
3363     	if (return_len > requested_len) {
3364     		return_len = requested_len;
3365     	}
3366     	return return_len;
3367     }
3368     
3369     static int
3370     dldwd_proc_get_hermes_regs(char *page, char **start, off_t requested_offset,
3371     			   int requested_len, int *eof, void *data)
3372     {
3373     	dldwd_priv_t *dev = (dldwd_priv_t *)data;
3374     	hermes_t *hw = &dev->hw;
3375     	char *buf;
3376     	int total = 0, slop = 0;
3377     
3378     	/* Hum, in this case hardware register are probably not readable... */
3379     	if (!dev->hw_ready)
3380     		return -ENODEV;
3381     
3382     	buf = page;
3383     
3384     #define DHERMESREG(name) buf += sprintf(buf, "%-16s: %04x\n", #name, hermes_read_regn(hw, name))
3385     
3386     	DHERMESREG(CMD);
3387     	DHERMESREG(PARAM0);
3388     	DHERMESREG(PARAM1);
3389     	DHERMESREG(PARAM2);
3390     	DHERMESREG(STATUS);
3391     	DHERMESREG(RESP0);
3392     	DHERMESREG(RESP1);
3393     	DHERMESREG(RESP2);
3394     	DHERMESREG(INFOFID);
3395     	DHERMESREG(RXFID);
3396     	DHERMESREG(ALLOCFID);
3397     	DHERMESREG(TXCOMPLFID);
3398     	DHERMESREG(SELECT0);
3399     	DHERMESREG(OFFSET0);
3400     	DHERMESREG(SELECT1);
3401     	DHERMESREG(OFFSET1);
3402     	DHERMESREG(EVSTAT);
3403     	DHERMESREG(INTEN);
3404     	DHERMESREG(EVACK);
3405     	DHERMESREG(CONTROL);
3406     	DHERMESREG(SWSUPPORT0);
3407     	DHERMESREG(SWSUPPORT1);
3408     	DHERMESREG(SWSUPPORT2);
3409     	DHERMESREG(AUXPAGE);
3410     	DHERMESREG(AUXOFFSET);
3411     	DHERMESREG(AUXDATA);
3412     #undef DHERMESREG
3413     
3414     	shift_buffer(page, requested_offset, requested_len, &total,
3415     		     &slop, &buf);
3416     	return calc_start_len(page, start, requested_offset, requested_len,
3417     			      total, buf);
3418     }
3419     
3420     struct {
3421     	uint16_t rid;
3422     	char *name;
3423     	int minlen, maxlen;
3424     	int displaytype;
3425     #define DISPLAY_WORDS	0
3426     #define DISPLAY_BYTES	1
3427     #define DISPLAY_STRING	2
3428     } record_table[] = {
3429     #define RTCNFENTRY(name, type) { HERMES_RID_CNF_##name, #name, 0, LTV_BUF_SIZE, type }
3430     	RTCNFENTRY(PORTTYPE, DISPLAY_WORDS),
3431     	RTCNFENTRY(MACADDR, DISPLAY_BYTES),
3432     	RTCNFENTRY(DESIRED_SSID, DISPLAY_STRING),
3433     	RTCNFENTRY(CHANNEL, DISPLAY_WORDS),
3434     	RTCNFENTRY(OWN_SSID, DISPLAY_STRING),
3435     	RTCNFENTRY(SYSTEM_SCALE, DISPLAY_WORDS),
3436     	RTCNFENTRY(MAX_DATA_LEN, DISPLAY_WORDS),
3437     	RTCNFENTRY(PM_ENABLE, DISPLAY_WORDS),
3438     	RTCNFENTRY(PM_MCAST_RX, DISPLAY_WORDS),
3439     	RTCNFENTRY(PM_PERIOD, DISPLAY_WORDS),
3440     	RTCNFENTRY(NICKNAME, DISPLAY_STRING),
3441     	RTCNFENTRY(WEP_ON, DISPLAY_WORDS),
3442     	RTCNFENTRY(MWO_ROBUST, DISPLAY_WORDS),
3443     	RTCNFENTRY(MULTICAST_LIST, DISPLAY_BYTES),
3444     	RTCNFENTRY(CREATEIBSS, DISPLAY_WORDS),
3445     	RTCNFENTRY(FRAG_THRESH, DISPLAY_WORDS),
3446     	RTCNFENTRY(RTS_THRESH, DISPLAY_WORDS),
3447     	RTCNFENTRY(TX_RATE_CTRL, DISPLAY_WORDS),
3448     	RTCNFENTRY(PROMISCUOUS, DISPLAY_WORDS),
3449     	RTCNFENTRY(KEYS, DISPLAY_BYTES),
3450     	RTCNFENTRY(TX_KEY, DISPLAY_WORDS),
3451     	RTCNFENTRY(TICKTIME, DISPLAY_WORDS),
3452     	RTCNFENTRY(PRISM2_TX_KEY, DISPLAY_WORDS),
3453     	RTCNFENTRY(PRISM2_KEY0, DISPLAY_BYTES),
3454     	RTCNFENTRY(PRISM2_KEY1, DISPLAY_BYTES),
3455     	RTCNFENTRY(PRISM2_KEY2, DISPLAY_BYTES),
3456     	RTCNFENTRY(PRISM2_KEY3, DISPLAY_BYTES),
3457     	RTCNFENTRY(PRISM2_WEP_ON, DISPLAY_WORDS),
3458     #undef RTCNFENTRY
3459     #define RTINFENTRY(name,type) { HERMES_RID_##name, #name, 0, LTV_BUF_SIZE, type }
3460     	RTINFENTRY(CHANNEL_LIST, DISPLAY_WORDS),
3461     	RTINFENTRY(STAIDENTITY, DISPLAY_WORDS),
3462     	RTINFENTRY(CURRENT_SSID, DISPLAY_STRING),
3463     	RTINFENTRY(CURRENT_BSSID, DISPLAY_BYTES),
3464     	RTINFENTRY(COMMSQUALITY, DISPLAY_WORDS),
3465     	RTINFENTRY(CURRENT_TX_RATE, DISPLAY_WORDS),
3466     	RTINFENTRY(WEP_AVAIL, DISPLAY_WORDS),
3467     	RTINFENTRY(CURRENT_CHANNEL, DISPLAY_WORDS),
3468     	RTINFENTRY(DATARATES, DISPLAY_BYTES),
3469     #undef RTINFENTRY
3470     };
3471     #define NUM_RIDS ( sizeof(record_table) / sizeof(record_table[0]) )
3472     
3473     static int
3474     dldwd_proc_get_hermes_recs(char *page, char **start, off_t requested_offset,
3475     			   int requested_len, int *eof, void *data)
3476     {
3477     	dldwd_priv_t *dev = (dldwd_priv_t *)data;
3478     	hermes_t *hw = &dev->hw;
3479     	char *buf;
3480     	int total = 0, slop = 0;
3481     	int i;
3482     	uint16_t length;
3483     	int err;
3484     
3485     	/* Hum, in this case hardware register are probably not readable... */
3486     	if (!dev->hw_ready)
3487     		return -ENODEV;
3488     		
3489     	buf = page;
3490     
3491     	/* print out all the config RIDs */
3492     	for (i = 0; i < NUM_RIDS; i++) {
3493     		uint16_t rid = record_table[i].rid;
3494     		int minlen = record_table[i].minlen;
3495     		int maxlen = record_table[i].maxlen;
3496     		int len;
3497     		uint8_t *val8;
3498     		uint16_t *val16;
3499     		int j;
3500     
3501     		val8 = kmalloc(maxlen + 2, GFP_KERNEL);
3502     		if (! val8)
3503     			return -ENOMEM;
3504     
3505     		err = hermes_read_ltv(hw, USER_BAP, rid, maxlen,
3506     				      &length, val8);
3507     		if (err) {
3508     			DEBUG(0, "Error %d reading RID 0x%04x\n", err, rid);
3509     			continue;
3510     		}
3511     		val16 = (uint16_t *)val8;
3512     
3513     		buf += sprintf(buf, "%-15s (0x%04x): length=%d (%d bytes)\tvalue=", record_table[i].name,
3514     			       rid, length, (length-1)*2);
3515     		len = MIN( MAX(minlen, (length-1)*2), maxlen);
3516     
3517     		switch (record_table[i].displaytype) {
3518     		case DISPLAY_WORDS:
3519     			for (j = 0; j < len / 2; j++) {
3520     				buf += sprintf(buf, "%04X-", le16_to_cpu(val16[j]));
3521     			}
3522     			buf--;
3523     			break;
3524     
3525     		case DISPLAY_BYTES:
3526     		default:
3527     			for (j = 0; j < len; j++) {
3528     				buf += sprintf(buf, "%02X:", val8[j]);
3529     			}
3530     			buf--;
3531     			break;
3532     
3533     		case DISPLAY_STRING:
3534     			len = MIN(len, le16_to_cpu(val16[0])+2);
3535     			val8[len] = '\0';
3536     			buf += sprintf(buf, "\"%s\"", (char *)&val16[1]);
3537     			break;
3538     		}
3539     
3540     		buf += sprintf(buf, "\n");
3541     
3542     		kfree(val8);
3543     
3544     		if (shift_buffer(page, requested_offset, requested_len,
3545     				 &total, &slop, &buf))
3546     			break;
3547     
3548     		if ( (buf - page) > PROC_SAFE_SIZE )
3549     			break;
3550     	}
3551     
3552     	return calc_start_len(page, start, requested_offset, requested_len,
3553     			      total, buf);
3554     }
3555     
3556     /* initialise the /proc subsystem for the hermes driver, creating the
3557      * separate entries */
3558     static int
3559     dldwd_proc_init(void)
3560     {
3561     	int err = 0;
3562     
3563     	TRACE_ENTER("dldwd");
3564     
3565     	/* create the directory for it to sit in */
3566     	dir_base = create_proc_entry("hermes", S_IFDIR, &proc_root);
3567     	if (dir_base == NULL) {
3568     		printk(KERN_ERR "Unable to initialise /proc/hermes.\n");
3569     		dldwd_proc_cleanup();
3570     		err = -ENOMEM;
3571     	}
3572     
3573     	TRACE_EXIT("dldwd");
3574     
3575     	return err;
3576     }
3577     
3578     int
3579     dldwd_proc_dev_init(dldwd_priv_t *dev)
3580     {
3581     	struct net_device *ndev = &dev->ndev;
3582     
3583     	dev->dir_dev = NULL;
3584     	/* create the directory for it to sit in */
3585     	dev->dir_dev = create_proc_entry(ndev->name, S_IFDIR | S_IRUGO | S_IXUGO,
3586     					 dir_base);
3587     	if (dev->dir_dev == NULL) {
3588     		printk(KERN_ERR "Unable to initialise /proc/hermes/%s.\n",  ndev->name);
3589     		goto fail;
3590     	}
3591     
3592     	dev->dir_regs = NULL;
3593     	dev->dir_regs = create_proc_read_entry("regs", S_IFREG | S_IRUGO,
3594     					       dev->dir_dev, dldwd_proc_get_hermes_regs, dev);
3595     	if (dev->dir_regs == NULL) {
3596     		printk(KERN_ERR "Unable to initialise /proc/hermes/%s/regs.\n",  ndev->name);
3597     		goto fail;
3598     	}
3599     
3600     	dev->dir_recs = NULL;
3601     	dev->dir_recs = create_proc_read_entry("recs", S_IFREG | S_IRUGO,
3602     					       dev->dir_dev, dldwd_proc_get_hermes_recs, dev);
3603     	if (dev->dir_recs == NULL) {
3604     		printk(KERN_ERR "Unable to initialise /proc/hermes/%s/recs.\n",  ndev->name);
3605     		goto fail;
3606     	}
3607     
3608     	return 0;
3609      fail:
3610     	dldwd_proc_dev_cleanup(dev);
3611     	return -ENOMEM;
3612     }
3613     
3614     void
3615     dldwd_proc_dev_cleanup(dldwd_priv_t *priv)
3616     {
3617     	struct net_device *ndev = &priv->ndev;
3618     
3619     	if (priv->dir_regs) {
3620     		remove_proc_entry("regs", priv->dir_dev);
3621     		priv->dir_regs = NULL;
3622     	}		
3623     	if (priv->dir_recs) {
3624     		remove_proc_entry("recs", priv->dir_dev);
3625     		priv->dir_recs = NULL;
3626     	}		
3627     	if (priv->dir_dev) {
3628     		remove_proc_entry(ndev->name, dir_base);
3629     		priv->dir_dev = NULL;
3630     	}
3631     }
3632     
3633     static void
3634     dldwd_proc_cleanup(void)
3635     {
3636     	TRACE_ENTER("dldwd");
3637     
3638     	if (dir_base) {
3639     		remove_proc_entry("hermes", &proc_root);
3640     		dir_base = NULL;
3641     	}
3642     	
3643     	TRACE_EXIT("dldwd");
3644     }
3645     
3646     int
3647     dldwd_setup(dldwd_priv_t* priv)
3648     {
3649     	struct net_device *dev = &priv->ndev;;
3650     
3651     	spin_lock_init(&priv->lock);
3652     
3653     	/* Set up the net_device */
3654     	ether_setup(dev);
3655     	dev->priv = priv;
3656     
3657     	/* Setup up default routines */
3658     	priv->card_reset_handler = NULL;	/* Caller may override */
3659     	dev->init = dldwd_init;
3660     	dev->open = NULL;		/* Caller *must* override */
3661     	dev->stop = NULL;
3662     	dev->hard_start_xmit = dldwd_xmit;
3663     	dev->tx_timeout = dldwd_tx_timeout;
3664     	dev->watchdog_timeo = HZ; /* 4 second timeout */
3665     
3666     	dev->get_stats = dldwd_get_stats;
3667     	dev->get_wireless_stats = dldwd_get_wireless_stats;
3668     
3669     	dev->do_ioctl = dldwd_ioctl;
3670     
3671     	dev->change_mtu = dldwd_change_mtu;
3672     	dev->set_multicast_list = dldwd_set_multicast_list;
3673     
3674     	netif_stop_queue(dev);
3675     
3676     	return 0;
3677     }
3678     
3679     #ifdef ORINOCO_DEBUG
3680     EXPORT_SYMBOL(dldwd_debug);
3681     #endif
3682     EXPORT_SYMBOL(dldwd_init);
3683     EXPORT_SYMBOL(dldwd_xmit);
3684     EXPORT_SYMBOL(dldwd_tx_timeout);
3685     EXPORT_SYMBOL(dldwd_ioctl);
3686     EXPORT_SYMBOL(dldwd_change_mtu);
3687     EXPORT_SYMBOL(dldwd_set_multicast_list);
3688     EXPORT_SYMBOL(dldwd_shutdown);
3689     EXPORT_SYMBOL(dldwd_reset);
3690     EXPORT_SYMBOL(dldwd_setup);
3691     EXPORT_SYMBOL(dldwd_proc_dev_init);
3692     EXPORT_SYMBOL(dldwd_proc_dev_cleanup);
3693     EXPORT_SYMBOL(dldwd_interrupt);
3694     
3695     static int __init init_dldwd(void)
3696     {
3697     	int err;
3698     
3699     	err = dldwd_proc_init();
3700     
3701     	printk(KERN_DEBUG "%s\n", version);
3702     
3703     	return 0;
3704     }
3705     
3706     static void __exit exit_dldwd(void)
3707     {
3708     	dldwd_proc_cleanup();
3709     }
3710     
3711     module_init(init_dldwd);
3712     module_exit(exit_dldwd);
3713