1 /*
2  *	Wavelan Pcmcia driver
3  *
4  *		Jean II - HPLB '96
5  *
6  * Reorganisation and extension of the driver.
7  *
8  * This file contain all definition and declarations necessary for the
9  * wavelan pcmcia driver. This file is a private header, so it should
10  * be included only on wavelan_cs.c !!!
11  */
12 
13 #ifndef WAVELAN_CS_H
14 #define WAVELAN_CS_H
15 
16 /************************** DOCUMENTATION **************************/
17 /*
18  * This driver provide a Linux interface to the Wavelan Pcmcia hardware
19  * The Wavelan is a product of Lucent (http://www.wavelan.com/).
20  * This division was formerly part of NCR and then AT&T.
21  * Wavelan are also distributed by DEC (RoamAbout DS)...
22  *
23  * To know how to use this driver, read the PCMCIA HOWTO.
24  * If you want to exploit the many other fonctionalities, look comments
25  * in the code...
26  *
27  * This driver is the result of the effort of many peoples (see below).
28  */
29 
30 /* ------------------------ SPECIFIC NOTES ------------------------ */
31 /*
32  * Web page
33  * --------
34  *	I try to maintain a web page with the Wireless LAN Howto at :
35  *	    http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html
36  *
37  * SMP
38  * ---
39  *	We now are SMP compliant (I eventually fixed the remaining bugs).
40  *	The driver has been tested on a dual P6-150 and survived my usual
41  *	set of torture tests.
42  *	Anyway, I spent enough time chasing interrupt re-entrancy during
43  *	errors or reconfigure, and I designed the locked/unlocked sections
44  *	of the driver with great care, and with the recent addition of
45  *	the spinlock (thanks to the new API), we should be quite close to
46  *	the truth.
47  *	The SMP/IRQ locking is quite coarse and conservative (i.e. not fast),
48  *	but better safe than sorry (especially at 2 Mb/s ;-).
49  *
50  *	I have also looked into disabling only our interrupt on the card
51  *	(via HACR) instead of all interrupts in the processor (via cli),
52  *	so that other driver are not impacted, and it look like it's
53  *	possible, but it's very tricky to do right (full of races). As
54  *	the gain would be mostly for SMP systems, it can wait...
55  *
56  * Debugging and options
57  * ---------------------
58  *	You will find below a set of '#define" allowing a very fine control
59  *	on the driver behaviour and the debug messages printed.
60  *	The main options are :
61  *	o WAVELAN_ROAMING, for the experimental roaming support.
62  *	o SET_PSA_CRC, to have your card correctly recognised by
63  *	  an access point and the Point-to-Point diagnostic tool.
64  *	o USE_PSA_CONFIG, to read configuration from the PSA (EEprom)
65  *	  (otherwise we always start afresh with some defaults)
66  *
67  * wavelan_cs.o is darn too big
68  * -------------------------
69  *	That's true ! There is a very simple way to reduce the driver
70  *	object by 33% (yes !). Comment out the following line :
71  *		#include <linux/wireless.h>
72  *	Other compile options can also reduce the size of it...
73  *
74  * MAC address and hardware detection :
75  * ----------------------------------
76  *	The detection code of the wavelan chech that the first 3
77  *	octets of the MAC address fit the company code. This type of
78  *	detection work well for AT&T cards (because the AT&T code is
79  *	hardcoded in wavelan.h), but of course will fail for other
80  *	manufacturer.
81  *
82  *	If you are sure that your card is derived from the wavelan,
83  *	here is the way to configure it :
84  *	1) Get your MAC address
85  *		a) With your card utilities (wfreqsel, instconf, ...)
86  *		b) With the driver :
87  *			o compile the kernel with DEBUG_CONFIG_INFO enabled
88  *			o Boot and look the card messages
89  *	2) Set your MAC code (3 octets) in MAC_ADDRESSES[][3] (wavelan.h)
90  *	3) Compile & verify
91  *	4) Send me the MAC code - I will include it in the next version...
92  *
93  */
94 
95 /* --------------------- WIRELESS EXTENSIONS --------------------- */
96 /*
97  * This driver is the first one to support "wireless extensions".
98  * This set of extensions provide you some way to control the wireless
99  * caracteristics of the hardware in a standard way and support for
100  * applications for taking advantage of it (like Mobile IP).
101  *
102  * You will need to enable the CONFIG_NET_RADIO define in the kernel
103  * configuration to enable the wireless extensions (this is the one
104  * giving access to the radio network device choice).
105  *
106  * It might also be a good idea as well to fetch the wireless tools to
107  * configure the device and play a bit.
108  */
109 
110 /* ---------------------------- FILES ---------------------------- */
111 /*
112  * wavelan_cs.c :	The actual code for the driver - C functions
113  *
114  * wavelan_cs.h :	Private header : local types / vars for the driver
115  *
116  * wavelan.h :		Description of the hardware interface & structs
117  *
118  * i82593.h :		Description if the Ethernet controller
119  */
120 
121 /* --------------------------- HISTORY --------------------------- */
122 /*
123  * The history of the Wavelan drivers is as complicated as history of
124  * the Wavelan itself (NCR -> AT&T -> Lucent).
125  *
126  * All started with Anders Klemets <klemets@paul.rutgers.edu>,
127  * writting a Wavelan ISA driver for the MACH microkernel. Girish
128  * Welling <welling@paul.rutgers.edu> had also worked on it.
129  * Keith Moore modify this for the Pcmcia hardware.
130  *
131  * Robert Morris <rtm@das.harvard.edu> port these two drivers to BSDI
132  * and add specific Pcmcia support (there is currently no equivalent
133  * of the PCMCIA package under BSD...).
134  *
135  * Jim Binkley <jrb@cs.pdx.edu> port both BSDI drivers to FreeBSD.
136  *
137  * Bruce Janson <bruce@cs.usyd.edu.au> port the BSDI ISA driver to Linux.
138  *
139  * Anthony D. Joseph <adj@lcs.mit.edu> started modify Bruce driver
140  * (with help of the BSDI PCMCIA driver) for PCMCIA.
141  * Yunzhou Li <yunzhou@strat.iol.unh.edu> finished is work.
142  * Joe Finney <joe@comp.lancs.ac.uk> patched the driver to start
143  * correctly 2.00 cards (2.4 GHz with frequency selection).
144  * David Hinds <dahinds@users.sourceforge.net> integrated the whole in his
145  * Pcmcia package (+ bug corrections).
146  *
147  * I (Jean Tourrilhes - jt@hplb.hpl.hp.com) then started to make some
148  * patchs to the Pcmcia driver. After, I added code in the ISA driver
149  * for Wireless Extensions and full support of frequency selection
150  * cards. Now, I'm doing the same to the Pcmcia driver + some
151  * reorganisation.
152  * Loeke Brederveld <lbrederv@wavelan.com> from Lucent has given me
153  * much needed informations on the Wavelan hardware.
154  */
155 
156 /* By the way : for the copyright & legal stuff :
157  * Almost everybody wrote code under GNU or BSD license (or alike),
158  * and want that their original copyright remain somewhere in the
159  * code (for myself, I go with the GPL).
160  * Nobody want to take responsibility for anything, except the fame...
161  */
162 
163 /* --------------------------- CREDITS --------------------------- */
164 /*
165  * Credits:
166  *    Special thanks to Jan Hoogendoorn of AT&T GIS Utrecht and
167  *	Loeke Brederveld of Lucent for providing extremely useful
168  *	information about WaveLAN PCMCIA hardware
169  *
170  *    This driver is based upon several other drivers, in particular:
171  *	David Hinds' Linux driver for the PCMCIA 3c589 ethernet adapter
172  *	Bruce Janson's Linux driver for the AT-bus WaveLAN adapter
173  *	Anders Klemets' PCMCIA WaveLAN adapter driver
174  *	Robert Morris' BSDI driver for the PCMCIA WaveLAN adapter
175  *
176  * Additional Credits:
177  *
178  *    This software was originally developed under Linux 1.2.3
179  *	(Slackware 2.0 distribution).
180  *    And then under Linux 2.0.x (Debian 1.1 -> 2.2 - pcmcia 2.8.18+)
181  *	with an HP OmniBook 4000 and then a 5500.
182  *
183  *    It is based on other device drivers and information either written
184  *    or supplied by:
185  *	James Ashton (jaa101@syseng.anu.edu.au),
186  *	Ajay Bakre (bakre@paul.rutgers.edu),
187  *	Donald Becker (becker@super.org),
188  *	Jim Binkley <jrb@cs.pdx.edu>,
189  *	Loeke Brederveld <lbrederv@wavelan.com>,
190  *	Allan Creighton (allanc@cs.su.oz.au),
191  *	Brent Elphick <belphick@uwaterloo.ca>,
192  *	Joe Finney <joe@comp.lancs.ac.uk>,
193  *	Matthew Geier (matthew@cs.su.oz.au),
194  *	Remo di Giovanni (remo@cs.su.oz.au),
195  *	Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM),
196  *	David Hinds <dahinds@users.sourceforge.net>,
197  *	Jan Hoogendoorn (c/o marteijn@lucent.com),
198  *      Bruce Janson <bruce@cs.usyd.edu.au>,
199  *	Anthony D. Joseph <adj@lcs.mit.edu>,
200  *	Anders Klemets (klemets@paul.rutgers.edu),
201  *	Yunzhou Li <yunzhou@strat.iol.unh.edu>,
202  *	Marc Meertens (mmeertens@lucent.com),
203  *	Keith Moore,
204  *	Robert Morris (rtm@das.harvard.edu),
205  *	Ian Parkin (ian@cs.su.oz.au),
206  *	John Rosenberg (johnr@cs.su.oz.au),
207  *	George Rossi (george@phm.gov.au),
208  *	Arthur Scott (arthur@cs.su.oz.au),
209  *	Stanislav Sinyagin <stas@isf.ru>
210  *	Peter Storey,
211  *	Jean Tourrilhes <jt@hpl.hp.com>,
212  *	Girish Welling (welling@paul.rutgers.edu)
213  *	Clark Woodworth <clark@hiway1.exit109.com>
214  *	Yongguang Zhang <ygz@isl.hrl.hac.com>...
215  */
216 
217 /* ------------------------- IMPROVEMENTS ------------------------- */
218 /*
219  * I proudly present :
220  *
221  * Changes made in 2.8.22 :
222  * ----------------------
223  *	- improved wv_set_multicast_list
224  *	- catch spurious interrupt
225  *	- correct release of the device
226  *
227  * Changes mades in release :
228  * ------------------------
229  *	- Reorganisation of the code, function name change
230  *	- Creation of private header (wavelan_cs.h)
231  *	- Reorganised debug messages
232  *	- More comments, history, ...
233  *	- Configure earlier (in "insert" instead of "open")
234  *        and do things only once
235  *	- mmc_init : configure the PSA if not done
236  *	- mmc_init : 2.00 detection better code for 2.00 init
237  *	- better info at startup
238  *	- Correct a HUGE bug (volatile & uncalibrated busy loop)
239  *	  in wv_82593_cmd => config speedup
240  *	- Stop receiving & power down on close (and power up on open)
241  *	  use "ifconfig down" & "ifconfig up ; route add -net ..."
242  *	- Send packets : add watchdog instead of pooling
243  *	- Receive : check frame wrap around & try to recover some frames
244  *	- wavelan_set_multicast_list : avoid reset
245  *	- add wireless extensions (ioctl & get_wireless_stats)
246  *	  get/set nwid/frequency on fly, info for /proc/net/wireless
247  *	- Suppress useless stuff from lp (net_local), but add link
248  *	- More inlines
249  *	- Lot of others minor details & cleanups
250  *
251  * Changes made in second release :
252  * ------------------------------
253  *	- Optimise wv_85893_reconfig stuff, fix potential problems
254  *	- Change error values for ioctl
255  *	- Non blocking wv_ru_stop() + call wv_reset() in case of problems
256  *	- Remove development printk from wavelan_watchdog()
257  *	- Remove of the watchdog to wavelan_close instead of wavelan_release
258  *	  fix potential problems...
259  *	- Start debugging suspend stuff (but it's still a bit weird)
260  *	- Debug & optimize dump header/packet in Rx & Tx (debug)
261  *	- Use "readb" and "writeb" to be kernel 2.1 compliant
262  *	- Better handling of bogus interrupts
263  *	- Wireless extension : SETSPY and GETSPY
264  *	- Remove old stuff (stats - for those needing it, just ask me...)
265  *	- Make wireless extensions optional
266  *
267  * Changes made in third release :
268  * -----------------------------
269  *	- cleanups & typos
270  *	- modif wireless ext (spy -> only one pointer)
271  *	- new private ioctl to set/get quality & level threshold
272  *	- Init : correct default value of level threshold for pcmcia
273  *	- kill watchdog in hw_reset
274  *	- more 2.1 support (copy_to/from_user instead of memcpy_to/fromfs)
275  *	- Add message level (debug stuff in /var/adm/debug & errors not
276  *	  displayed at console and still in /var/adm/messages)
277  *
278  * Changes made in fourth release :
279  * ------------------------------
280  *	- multicast support (yes !) thanks to Yongguang Zhang.
281  *
282  * Changes made in fifth release (2.9.0) :
283  * -------------------------------------
284  *	- Revisited multicast code (it was mostly wrong).
285  *	- protect code in wv_82593_reconfig with dev->tbusy (oups !)
286  *
287  * Changes made in sixth release (2.9.1a) :
288  * --------------------------------------
289  *	- Change the detection code for multi manufacturer code support
290  *	- Correct bug (hang kernel) in init when we were "rejecting" a card
291  *
292  * Changes made in seventh release (2.9.1b) :
293  * ----------------------------------------
294  *	- Update to wireless extensions changes
295  *	- Silly bug in card initial configuration (psa_conf_status)
296  *
297  * Changes made in eigth release :
298  * -----------------------------
299  *	- Small bug in debug code (probably not the last one...)
300  *	- 1.2.13 support (thanks to Clark Woodworth)
301  *
302  * Changes made for release in 2.9.2b :
303  * ----------------------------------
304  *	- Level threshold is now a standard wireless extension (version 4 !)
305  *	- modules parameters types for kernel > 2.1.17
306  *	- updated man page
307  *	- Others cleanup from David Hinds
308  *
309  * Changes made for release in 2.9.5 :
310  * ---------------------------------
311  *	- byte count stats (courtesy of David Hinds)
312  *	- Remove dev_tint stuff (courtesy of David Hinds)
313  *	- Others cleanup from David Hinds
314  *	- Encryption setting from Brent Elphick (thanks a lot !)
315  *	- 'base' to 'u_long' for the Alpha (thanks to Stanislav Sinyagin)
316  *
317  * Changes made for release in 2.9.6 :
318  * ---------------------------------
319  *	- fix bug : no longuer disable watchdog in case of bogus interrupt
320  *	- increase timeout in config code for picky hardware
321  *	- mask unused bits in status (Wireless Extensions)
322  *
323  * Changes integrated by Justin Seger <jseger@MIT.EDU> & David Hinds :
324  * -----------------------------------------------------------------
325  *	- Roaming "hack" from Joe Finney <joe@comp.lancs.ac.uk>
326  *	- PSA CRC code from Bob Gray <rgray@bald.cs.dartmouth.edu>
327  *	- Better initialisation of the i82593 controller
328  *	  from Joseph K. O'Sullivan <josullvn+@cs.cmu.edu>
329  *
330  * Changes made for release in 3.0.10 :
331  * ----------------------------------
332  *	- Fix eject "hang" of the driver under 2.2.X :
333  *		o create wv_flush_stale_links()
334  *		o Rename wavelan_release to wv_pcmcia_release & move up
335  *		o move unregister_netdev to wavelan_detach()
336  *		o wavelan_release() no longer call wavelan_detach()
337  *		o Suppress "release" timer
338  *		o Other cleanups & fixes
339  *	- New MAC address in the probe
340  *	- Reorg PSA_CRC code (endian neutral & cleaner)
341  *	- Correct initialisation of the i82593 from Lucent manual
342  *	- Put back the watchdog, with larger timeout
343  *	- TRANSMIT_NO_CRC is a "normal" error, so recover from it
344  *	  from Derrick J Brashear <shadow@dementia.org>
345  *	- Better handling of TX and RX normal failure conditions
346  *	- #ifdef out all the roaming code
347  *	- Add ESSID & "AP current address" ioctl stubs
348  *	- General cleanup of the code
349  *
350  * Changes made for release in 3.0.13 :
351  * ----------------------------------
352  *	- Re-enable compilation of roaming code by default, but with
353  *	  do_roaming = 0
354  *	- Nuke `nwid=nwid^ntohs(beacon->domain_id)' in wl_roam_gather
355  *	  at the demand of John Carol Langford <jcl@gs176.sp.cs.cmu.edu>
356  *	- Introduced WAVELAN_ROAMING_EXT for incomplete ESSID stuff.
357  *
358  * Changes made for release in 3.0.15 :
359  * ----------------------------------
360  *	- Change e-mail and web page addresses
361  *	- Watchdog timer is now correctly expressed in HZ, not in jiffies
362  *	- Add channel number to the list of frequencies in range
363  *	- Add the (short) list of bit-rates in range
364  *	- Developp a new sensitivity... (sens.value & sens.fixed)
365  *
366  * Changes made for release in 3.1.2 :
367  * ---------------------------------
368  *	- Fix check for root permission (break instead of exit)
369  *	- New nwid & encoding setting (Wireless Extension 9)
370  *
371  * Changes made for release in 3.1.12 :
372  * ----------------------------------
373  *	- reworked wv_82593_cmd to avoid using the IRQ handler and doing
374  *	  ugly things with interrupts.
375  *	- Add IRQ protection in 82593_config/ru_start/ru_stop/watchdog
376  *	- Update to new network API (softnet - 2.3.43) :
377  *		o replace dev->tbusy (David + me)
378  *		o replace dev->tstart (David + me)
379  *		o remove dev->interrupt (David)
380  *		o add SMP locking via spinlock in splxx (me)
381  *		o add spinlock in interrupt handler (me)
382  *		o use kernel watchdog instead of ours (me)
383  *		o verify that all the changes make sense and work (me)
384  *	- Re-sync kernel/pcmcia versions (not much actually)
385  *	- A few other cleanups (David & me)...
386  *
387  * Changes made for release in 3.1.22 :
388  * ----------------------------------
389  *	- Check that SMP works, remove annoying log message
390  *
391  * Changes made for release in 3.1.24 :
392  * ----------------------------------
393  *	- Fix unfrequent card lockup when watchdog was reseting the hardware :
394  *		o control first busy loop in wv_82593_cmd()
395  *		o Extend spinlock protection in wv_hw_config()
396  *
397  * Changes made for release in 3.2.1 :
398  * ---------------------------------
399  *	- Set dev->trans_start to avoid filling the logs
400  *		(and generating useless abort commands)
401  *
402  * Wishes & dreams:
403  * ----------------
404  *	- Cleanup and integrate the roaming code
405  *	  (std debug, set DomainID, decay avg and co...)
406  */
407 
408 /***************************** INCLUDES *****************************/
409 
410 /* Linux headers that we need */
411 #include <linux/config.h>
412 #include <linux/module.h>
413 #include <linux/kernel.h>
414 #include <linux/init.h>
415 #include <linux/sched.h>
416 #include <linux/ptrace.h>
417 #include <linux/slab.h>
418 #include <linux/string.h>
419 #include <linux/timer.h>
420 #include <linux/interrupt.h>
421 #include <linux/spinlock.h>
422 #include <linux/in.h>
423 #include <linux/delay.h>
424 #include <asm/uaccess.h>
425 #include <asm/io.h>
426 #include <asm/system.h>
427 #include <asm/bitops.h>
428 
429 #include <linux/netdevice.h>
430 #include <linux/etherdevice.h>
431 #include <linux/skbuff.h>
432 #include <linux/if_arp.h>
433 #include <linux/ioport.h>
434 #include <linux/fcntl.h>
435 #include <linux/ethtool.h>
436 
437 #ifdef CONFIG_NET_PCMCIA_RADIO
438 #include <linux/wireless.h>		/* Wireless extensions */
439 #endif
440 
441 /* Pcmcia headers that we need */
442 #include <pcmcia/cs_types.h>
443 #include <pcmcia/cs.h>
444 #include <pcmcia/cistpl.h>
445 #include <pcmcia/cisreg.h>
446 #include <pcmcia/ds.h>
447 #include <pcmcia/version.h>
448 
449 /* Wavelan declarations */
450 #include "i82593.h"	/* Definitions for the Intel chip */
451 
452 #include "wavelan.h"	/* Others bits of the hardware */
453 
454 /************************** DRIVER OPTIONS **************************/
455 /*
456  * `#define' or `#undef' the following constant to change the behaviour
457  * of the driver...
458  */
459 #define WAVELAN_ROAMING		/* Include experimental roaming code */
460 #undef WAVELAN_ROAMING_EXT	/* Enable roaming wireless extensions */
461 #undef SET_PSA_CRC		/* Set the CRC in PSA (slower) */
462 #define USE_PSA_CONFIG		/* Use info from the PSA */
463 #undef STRUCT_CHECK		/* Verify padding of structures */
464 #undef EEPROM_IS_PROTECTED	/* Doesn't seem to be necessary */
465 #define MULTICAST_AVOID		/* Avoid extra multicast (I'm sceptical) */
466 #undef SET_MAC_ADDRESS		/* Experimental */
467 
468 #ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
469 /* Warning : these stuff will slow down the driver... */
470 #define WIRELESS_SPY		/* Enable spying addresses */
471 #undef HISTOGRAM		/* Enable histogram of sig level... */
472 #endif
473 
474 /****************************** DEBUG ******************************/
475 
476 #undef DEBUG_MODULE_TRACE	/* Module insertion/removal */
477 #undef DEBUG_CALLBACK_TRACE	/* Calls made by Linux */
478 #undef DEBUG_INTERRUPT_TRACE	/* Calls to handler */
479 #undef DEBUG_INTERRUPT_INFO	/* type of interrupt & so on */
480 #define DEBUG_INTERRUPT_ERROR	/* problems */
481 #undef DEBUG_CONFIG_TRACE	/* Trace the config functions */
482 #undef DEBUG_CONFIG_INFO	/* What's going on... */
483 #define DEBUG_CONFIG_ERRORS	/* Errors on configuration */
484 #undef DEBUG_TX_TRACE		/* Transmission calls */
485 #undef DEBUG_TX_INFO		/* Header of the transmitted packet */
486 #undef DEBUG_TX_FAIL		/* Normal failure conditions */
487 #define DEBUG_TX_ERROR		/* Unexpected conditions */
488 #undef DEBUG_RX_TRACE		/* Transmission calls */
489 #undef DEBUG_RX_INFO		/* Header of the transmitted packet */
490 #undef DEBUG_RX_FAIL		/* Normal failure conditions */
491 #define DEBUG_RX_ERROR		/* Unexpected conditions */
492 #undef DEBUG_PACKET_DUMP	/* Dump packet on the screen */
493 #undef DEBUG_IOCTL_TRACE	/* Misc call by Linux */
494 #undef DEBUG_IOCTL_INFO		/* Various debug info */
495 #define DEBUG_IOCTL_ERROR	/* What's going wrong */
496 #define DEBUG_BASIC_SHOW	/* Show basic startup info */
497 #undef DEBUG_VERSION_SHOW	/* Print version info */
498 #undef DEBUG_PSA_SHOW		/* Dump psa to screen */
499 #undef DEBUG_MMC_SHOW		/* Dump mmc to screen */
500 #undef DEBUG_SHOW_UNUSED	/* Show also unused fields */
501 #undef DEBUG_I82593_SHOW	/* Show i82593 status */
502 #undef DEBUG_DEVICE_SHOW	/* Show device parameters */
503 
504 /************************ CONSTANTS & MACROS ************************/
505 
506 #ifdef DEBUG_VERSION_SHOW
507 static const char *version = "wavelan_cs.c : v23 (SMP + wireless extensions) 20/12/00\n";
508 #endif
509 
510 /* Watchdog temporisation */
511 #define	WATCHDOG_JIFFIES	(256*HZ/100)
512 
513 /* Fix a bug in some old wireless extension definitions */
514 #ifndef IW_ESSID_MAX_SIZE
515 #define IW_ESSID_MAX_SIZE	32
516 #endif
517 
518 /* ------------------------ PRIVATE IOCTL ------------------------ */
519 
520 /* Wireless Extension Backward compatibility - Jean II
521  * If the new wireless device private ioctl range is not defined,
522  * default to standard device private ioctl range */
523 #ifndef SIOCIWFIRSTPRIV
524 #define SIOCIWFIRSTPRIV	SIOCDEVPRIVATE
525 #endif /* SIOCIWFIRSTPRIV */
526 
527 #define SIOCSIPQTHR	SIOCIWFIRSTPRIV		/* Set quality threshold */
528 #define SIOCGIPQTHR	SIOCIWFIRSTPRIV + 1	/* Get quality threshold */
529 #define SIOCSIPROAM     SIOCIWFIRSTPRIV + 2	/* Set roaming state */
530 #define SIOCGIPROAM     SIOCIWFIRSTPRIV + 3	/* Get roaming state */
531 
532 #define SIOCSIPHISTO	SIOCIWFIRSTPRIV + 6	/* Set histogram ranges */
533 #define SIOCGIPHISTO	SIOCIWFIRSTPRIV + 7	/* Get histogram values */
534 
535 /*************************** WaveLAN Roaming  **************************/
536 #ifdef WAVELAN_ROAMING		/* Conditional compile, see above in options */
537 
538 #define WAVELAN_ROAMING_DEBUG	 0	/* 1 = Trace of handover decisions */
539 					/* 2 = Info on each beacon rcvd... */
540 #define MAX_WAVEPOINTS		7	/* Max visible at one time */
541 #define WAVEPOINT_HISTORY	5	/* SNR sample history slow search */
542 #define WAVEPOINT_FAST_HISTORY	2	/* SNR sample history fast search */
543 #define SEARCH_THRESH_LOW	10	/* SNR to enter cell search */
544 #define SEARCH_THRESH_HIGH	13	/* SNR to leave cell search */
545 #define WAVELAN_ROAMING_DELTA	1	/* Hysteresis value (+/- SNR) */
546 #define CELL_TIMEOUT		2*HZ	/* in jiffies */
547 
548 #define FAST_CELL_SEARCH	1	/* Boolean values... */
549 #define NWID_PROMISC		1	/* for code clarity. */
550 
551 typedef struct wavepoint_beacon
552 {
553   unsigned char		dsap,		/* Unused */
554 			ssap,		/* Unused */
555 			ctrl,		/* Unused */
556 			O,U,I,		/* Unused */
557 			spec_id1,	/* Unused */
558 			spec_id2,	/* Unused */
559 			pdu_type,	/* Unused */
560 			seq;		/* WavePoint beacon sequence number */
561   unsigned short	domain_id,	/* WavePoint Domain ID */
562 			nwid;		/* WavePoint NWID */
563 } wavepoint_beacon;
564 
565 typedef struct wavepoint_history
566 {
567   unsigned short	nwid;		/* WavePoint's NWID */
568   int			average_slow;	/* SNR running average */
569   int			average_fast;	/* SNR running average */
570   unsigned char	  sigqual[WAVEPOINT_HISTORY]; /* Ringbuffer of recent SNR's */
571   unsigned char		qualptr;	/* Index into ringbuffer */
572   unsigned char		last_seq;	/* Last seq. no seen for WavePoint */
573   struct wavepoint_history *next;	/* Next WavePoint in table */
574   struct wavepoint_history *prev;	/* Previous WavePoint in table */
575   unsigned long		last_seen;	/* Time of last beacon recvd, jiffies */
576 } wavepoint_history;
577 
578 struct wavepoint_table
579 {
580   wavepoint_history	*head;		/* Start of ringbuffer */
581   int			num_wavepoints;	/* No. of WavePoints visible */
582   unsigned char		locked;		/* Table lock */
583 };
584 
585 #endif	/* WAVELAN_ROAMING */
586 
587 /****************************** TYPES ******************************/
588 
589 /* Shortcuts */
590 typedef struct net_device	device;
591 typedef struct net_device_stats	en_stats;
592 typedef struct iw_statistics	iw_stats;
593 typedef struct iw_quality	iw_qual;
594 typedef struct iw_freq		iw_freq;
595 typedef struct net_local	net_local;
596 typedef struct timer_list	timer_list;
597 
598 /* Basic types */
599 typedef u_char		mac_addr[WAVELAN_ADDR_SIZE];	/* Hardware address */
600 
601 /*
602  * Static specific data for the interface.
603  *
604  * For each network interface, Linux keep data in two structure. "device"
605  * keep the generic data (same format for everybody) and "net_local" keep
606  * the additional specific data.
607  * Note that some of this specific data is in fact generic (en_stats, for
608  * example).
609  */
610 struct net_local
611 {
612   dev_node_t 	node;		/* ???? What is this stuff ???? */
613   device *	dev;		/* Reverse link... */
614   spinlock_t	spinlock;	/* Serialize access to the hardware (SMP) */
615   dev_link_t *	link;		/* pcmcia structure */
616   en_stats	stats;		/* Ethernet interface statistics */
617   int		nresets;	/* Number of hw resets */
618   u_char	configured;	/* If it is configured */
619   u_char	reconfig_82593;	/* Need to reconfigure the controller */
620   u_char	promiscuous;	/* Promiscuous mode */
621   u_char	allmulticast;	/* All Multicast mode */
622   int		mc_count;	/* Number of multicast addresses */
623 
624   int   	stop;		/* Current i82593 Stop Hit Register */
625   int   	rfp;		/* Last DMA machine receive pointer */
626   int		overrunning;	/* Receiver overrun flag */
627 
628 #ifdef WIRELESS_EXT
629   iw_stats	wstats;		/* Wireless specific stats */
630 #endif
631 
632 #ifdef WIRELESS_SPY
633   int		spy_number;		/* Number of addresses to spy */
634   mac_addr	spy_address[IW_MAX_SPY];	/* The addresses to spy */
635   iw_qual	spy_stat[IW_MAX_SPY];		/* Statistics gathered */
636 #endif	/* WIRELESS_SPY */
637 #ifdef HISTOGRAM
638   int		his_number;		/* Number of intervals */
639   u_char	his_range[16];		/* Boundaries of interval ]n-1; n] */
640   u_long	his_sum[16];		/* Sum in interval */
641 #endif	/* HISTOGRAM */
642 #ifdef WAVELAN_ROAMING
643   u_long	domain_id;	/* Domain ID we lock on for roaming */
644   int		filter_domains;	/* Check Domain ID of beacon found */
645  struct wavepoint_table	wavepoint_table;	/* Table of visible WavePoints*/
646   wavepoint_history *	curr_point;		/* Current wavepoint */
647   int			cell_search;		/* Searching for new cell? */
648   struct timer_list	cell_timer;		/* Garbage collection */
649 #endif	/* WAVELAN_ROAMING */
650 };
651 
652 /**************************** PROTOTYPES ****************************/
653 
654 #ifdef WAVELAN_ROAMING
655 /* ---------------------- ROAMING SUBROUTINES -----------------------*/
656 
657 wavepoint_history *wl_roam_check(unsigned short nwid, net_local *lp);
658 wavepoint_history *wl_new_wavepoint(unsigned short nwid, unsigned char seq, net_local *lp);
659 void wl_del_wavepoint(wavepoint_history *wavepoint, net_local *lp);
660 void wl_cell_expiry(unsigned long data);
661 wavepoint_history *wl_best_sigqual(int fast_search, net_local *lp);
662 void wl_update_history(wavepoint_history *wavepoint, unsigned char sigqual, unsigned char seq);
663 void wv_roam_handover(wavepoint_history *wavepoint, net_local *lp);
664 void wv_nwid_filter(unsigned char mode, net_local *lp);
665 void wv_roam_init(struct net_device *dev);
666 void wv_roam_cleanup(struct net_device *dev);
667 #endif	/* WAVELAN_ROAMING */
668 
669 /* ----------------------- MISC SUBROUTINES ------------------------ */
670 static inline void
671 	wv_splhi(net_local *,		/* Disable interrupts */
672 		 unsigned long *);	/* flags */
673 static inline void
674 	wv_splx(net_local *,		/* ReEnable interrupts */
675 		unsigned long *);	/* flags */
676 static void
677 	cs_error(client_handle_t,	/* Report error to cardmgr */
678 		 int,
679 		 int);
680 /* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */
681 static inline u_char		/* data */
682 	hasr_read(u_long);	/* Read the host interface : base address */
683 static inline void
684 	hacr_write(u_long,	/* Write to host interface : base address */
685 		   u_char),	/* data */
686 	hacr_write_slow(u_long,
687 		   u_char);
688 static void
689 	psa_read(device *,	/* Read the Parameter Storage Area */
690 		 int,		/* offset in PSA */
691 		 u_char *,	/* buffer to fill */
692 		 int),		/* size to read */
693 	psa_write(device *,	/* Write to the PSA */
694 		  int,		/* Offset in psa */
695 		  u_char *,	/* Buffer in memory */
696 		  int);		/* Length of buffer */
697 static inline void
698 	mmc_out(u_long,		/* Write 1 byte to the Modem Manag Control */
699 		u_short,
700 		u_char),
701 	mmc_write(u_long,	/* Write n bytes to the MMC */
702 		  u_char,
703 		  u_char *,
704 		  int);
705 static inline u_char		/* Read 1 byte from the MMC */
706 	mmc_in(u_long,
707 	       u_short);
708 static inline void
709 	mmc_read(u_long,	/* Read n bytes from the MMC */
710 		 u_char,
711 		 u_char *,
712 		 int),
713 	fee_wait(u_long,	/* Wait for frequency EEprom : base address */
714 		 int,		/* Base delay to wait for */
715 		 int);		/* Number of time to wait */
716 static void
717 	fee_read(u_long,	/* Read the frequency EEprom : base address */
718 		 u_short,	/* destination offset */
719 		 u_short *,	/* data buffer */
720 		 int);		/* number of registers */
721 /* ---------------------- I82593 SUBROUTINES ----------------------- */
722 static int
723 	wv_82593_cmd(device *,	/* synchronously send a command to i82593 */
724 		     char *,
725 		     int,
726 		     int);
727 static inline int
728 	wv_diag(device *);	/* Diagnostique the i82593 */
729 static int
730 	read_ringbuf(device *,	/* Read a receive buffer */
731 		     int,
732 		     char *,
733 		     int);
734 static inline void
735 	wv_82593_reconfig(device *);	/* Reconfigure the controller */
736 /* ------------------- DEBUG & INFO SUBROUTINES ------------------- */
737 static inline void
738 	wv_init_info(device *);	/* display startup info */
739 /* ------------------- IOCTL, STATS & RECONFIG ------------------- */
740 static en_stats	*
741 	wavelan_get_stats(device *);	/* Give stats /proc/net/dev */
742 /* ----------------------- PACKET RECEPTION ----------------------- */
743 static inline int
744 	wv_start_of_frame(device *,	/* Seek beggining of current frame */
745 			  int,	/* end of frame */
746 			  int);	/* start of buffer */
747 static inline void
748 	wv_packet_read(device *,	/* Read a packet from a frame */
749 		       int,
750 		       int),
751 	wv_packet_rcv(device *);	/* Read all packets waiting */
752 /* --------------------- PACKET TRANSMISSION --------------------- */
753 static inline void
754 	wv_packet_write(device *,	/* Write a packet to the Tx buffer */
755 			void *,
756 			short);
757 static int
758 	wavelan_packet_xmit(struct sk_buff *,	/* Send a packet */
759 			    device *);
760 /* -------------------- HARDWARE CONFIGURATION -------------------- */
761 static inline int
762 	wv_mmc_init(device *);	/* Initialize the modem */
763 static int
764 	wv_ru_stop(device *),	/* Stop the i82593 receiver unit */
765 	wv_ru_start(device *);	/* Start the i82593 receiver unit */
766 static int
767 	wv_82593_config(device *);	/* Configure the i82593 */
768 static inline int
769 	wv_pcmcia_reset(device *);	/* Reset the pcmcia interface */
770 static int
771 	wv_hw_config(device *);	/* Reset & configure the whole hardware */
772 static inline void
773 	wv_hw_reset(device *);	/* Same, + start receiver unit */
774 static inline int
775 	wv_pcmcia_config(dev_link_t *);	/* Configure the pcmcia interface */
776 static void
777 	wv_pcmcia_release(u_long),	/* Remove a device */
778 	wv_flush_stale_links(void);	/* "detach" all possible devices */
779 /* ---------------------- INTERRUPT HANDLING ---------------------- */
780 static void
781 	wavelan_interrupt(int,	/* Interrupt handler */
782 			  void *,
783 			  struct pt_regs *);
784 static void
785 	wavelan_watchdog(device *);	/* Transmission watchdog */
786 /* ------------------- CONFIGURATION CALLBACKS ------------------- */
787 static int
788 	wavelan_open(device *),		/* Open the device */
789 	wavelan_close(device *);	/* Close the device */
790 static dev_link_t *
791 	wavelan_attach(void);		/* Create a new device */
792 static void
793 	wavelan_detach(dev_link_t *);	/* Destroy a removed device */
794 static int
795 	wavelan_event(event_t,		/* Manage pcmcia events */
796 		      int,
797 		      event_callback_args_t *);
798 
799 /**************************** VARIABLES ****************************/
800 
801 static dev_info_t dev_info = "wavelan_cs";
802 static dev_link_t *dev_list = NULL;	/* Linked list of devices */
803 
804 /*
805  * Parameters that can be set with 'insmod'
806  * The exact syntax is 'insmod wavelan_cs.o <var>=<value>'
807  */
808 
809 /* Bit map of interrupts to choose from */
810 /* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4 and 3 */
811 static int	irq_mask = 0xdeb8;
812 static int 	irq_list[4] = { -1 };
813 
814 /* Shared memory speed, in ns */
815 static int	mem_speed = 0;
816 
817 /* New module interface */
818 MODULE_PARM(irq_mask, "i");
819 MODULE_PARM(irq_list, "1-4i");
820 MODULE_PARM(mem_speed, "i");
821 
822 #ifdef WAVELAN_ROAMING		/* Conditional compile, see above in options */
823 /* Enable roaming mode ? No ! Please keep this to 0 */
824 static int	do_roaming = 0;
825 MODULE_PARM(do_roaming, "i");
826 #endif	/* WAVELAN_ROAMING */
827 
828 /* My modifications and rewrite were GPL only - Jean II */
829 MODULE_LICENSE("GPL");
830 
831 #endif	/* WAVELAN_CS_H */
832 
833