1/*=============================================================================
2 *
3 * A  PCMCIA client driver for the Raylink wireless LAN card.
4 * The starting point for this module was the skeleton.c in the
5 * PCMCIA 2.9.12 package written by David Hinds, dahinds@users.sourceforge.net
6 *
7 *
8 * Copyright (c) 1998  Corey Thomas (corey@world.std.com)
9 *
10 * This driver is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 only of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * It is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 *
23 * Changes:
24 * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/08/2000
25 * - reorganize kmallocs in ray_attach, checking all for failure
26 *   and releasing the previous allocations if one fails
27 *
28 *
29=============================================================================*/
30
31#include <linux/config.h>
32#include <linux/module.h>
33#include <linux/kernel.h>
34#include <linux/sched.h>
35#include <linux/proc_fs.h>
36#include <linux/ptrace.h>
37#include <linux/slab.h>
38#include <linux/string.h>
39#include <linux/timer.h>
40#include <linux/init.h>
41
42#include <asm/io.h>
43#include <asm/system.h>
44#include <asm/byteorder.h>
45
46#include <linux/netdevice.h>
47#include <linux/etherdevice.h>
48#include <linux/if_arp.h>
49#include <linux/ioport.h>
50#include <linux/skbuff.h>
51#include <linux/ethtool.h>
52#include <asm/uaccess.h>
53
54#include <pcmcia/version.h>
55#include <pcmcia/cs_types.h>
56#include <pcmcia/cs.h>
57#include <pcmcia/cistpl.h>
58#include <pcmcia/cisreg.h>
59#include <pcmcia/ds.h>
60#include <pcmcia/mem_op.h>
61
62#ifdef CONFIG_NET_PCMCIA_RADIO
63#include <linux/wireless.h>
64
65/* Warning : these stuff will slow down the driver... */
66#define WIRELESS_SPY		/* Enable spying addresses */
67/* Definitions we need for spy */
68typedef struct iw_statistics	iw_stats;
69typedef struct iw_quality	iw_qual;
70typedef u_char	mac_addr[ETH_ALEN];	/* Hardware address */
71#endif	/* CONFIG_NET_PCMCIA_RADIO */
72
73#include "rayctl.h"
74#include "ray_cs.h"
75
76/* All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
77   you do not define PCMCIA_DEBUG at all, all the debug code will be
78   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
79   be present but disabled -- but it can then be enabled for specific
80   modules at load time with a 'pc_debug=#' option to insmod.
81*/
82
83#ifdef RAYLINK_DEBUG
84#define PCMCIA_DEBUG RAYLINK_DEBUG
85#endif
86#ifdef PCMCIA_DEBUG
87static int ray_debug;
88static int pc_debug = PCMCIA_DEBUG;
89MODULE_PARM(pc_debug, "i");
90/* #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); */
91#define DEBUG(n, args...) if (pc_debug>(n)) printk(args);
92#else
93#define DEBUG(n, args...)
94#endif
95/** Prototypes based on PCMCIA skeleton driver *******************************/
96static void ray_config(dev_link_t *link);
97static void ray_release(u_long arg);
98static int ray_event(event_t event, int priority, event_callback_args_t *args);
99static dev_link_t *ray_attach(void);
100static void ray_detach(dev_link_t *);
101
102/***** Prototypes indicated by device structure ******************************/
103static int ray_dev_close(struct net_device *dev);
104static int ray_dev_config(struct net_device *dev, struct ifmap *map);
105static struct net_device_stats *ray_get_stats(struct net_device *dev);
106static int ray_dev_init(struct net_device *dev);
107static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
108static int ray_open(struct net_device *dev);
109static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev);
110static void set_multicast_list(struct net_device *dev);
111static void ray_update_multi_list(struct net_device *dev, int all);
112static int translate_frame(ray_dev_t *local, struct tx_msg *ptx,
113                unsigned char *data, int len);
114static void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type,
115                unsigned char *data);
116static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len);
117#if WIRELESS_EXT > 7	    /* If wireless extension exist in the kernel */
118static iw_stats * ray_get_wireless_stats(struct net_device *	dev);
119#endif	/* WIRELESS_EXT > 7 */
120
121/***** Prototypes for raylink functions **************************************/
122static int asc_to_int(char a);
123static void authenticate(ray_dev_t *local);
124static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type);
125static void authenticate_timeout(u_long);
126static int get_free_ccs(ray_dev_t *local);
127static int get_free_tx_ccs(ray_dev_t *local);
128static void init_startup_params(ray_dev_t *local);
129static int parse_addr(char *in_str, UCHAR *out);
130static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, UCHAR type);
131static int ray_init(struct net_device *dev);
132static int interrupt_ecf(ray_dev_t *local, int ccs);
133static void ray_reset(struct net_device *dev);
134static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len);
135static void verify_dl_startup(u_long);
136
137/* Prototypes for interrpt time functions **********************************/
138static void ray_interrupt (int reg, void *dev_id, struct pt_regs *regs);
139static void clear_interrupt(ray_dev_t *local);
140static void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs,
141                       unsigned int pkt_addr, int rx_len);
142static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int len);
143static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs);
144static void release_frag_chain(ray_dev_t *local, struct rcs *prcs);
145static void rx_authenticate(ray_dev_t *local, struct rcs *prcs,
146                     unsigned int pkt_addr, int rx_len);
147static void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr,
148             int rx_len);
149static void associate(ray_dev_t *local);
150
151/* Card command functions */
152static int dl_startup_params(struct net_device *dev);
153static void join_net(u_long local);
154static void start_net(u_long local);
155/* void start_net(ray_dev_t *local); */
156
157/* Create symbol table for registering with kernel in init_module */
158EXPORT_SYMBOL(ray_dev_ioctl);
159EXPORT_SYMBOL(ray_rx);
160
161/*===========================================================================*/
162/* Parameters that can be set with 'insmod' */
163/* Bit map of interrupts to choose from */
164/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
165static u_long irq_mask = 0xdeb8;
166
167/* ADHOC=0, Infrastructure=1 */
168static int net_type = ADHOC;
169
170/* Hop dwell time in Kus (1024 us units defined by 802.11) */
171static int hop_dwell = 128;
172
173/* Beacon period in Kus */
174static int beacon_period = 256;
175
176/* power save mode (0 = off, 1 = save power) */
177static int psm;
178
179/* String for network's Extended Service Set ID. 32 Characters max */
180static char *essid;
181
182/* Default to encapsulation unless translation requested */
183static int translate = 1;
184
185static int country = USA;
186
187static int sniffer;
188
189static int bc;
190
191/* 48 bit physical card address if overriding card's real physical
192 * address is required.  Since IEEE 802.11 addresses are 48 bits
193 * like ethernet, an int can't be used, so a string is used. To
194 * allow use of addresses starting with a decimal digit, the first
195 * character must be a letter and will be ignored. This letter is
196 * followed by up to 12 hex digits which are the address.  If less
197 * than 12 digits are used, the address will be left filled with 0's.
198 * Note that bit 0 of the first byte is the broadcast bit, and evil
199 * things will happen if it is not 0 in a card address.
200 */
201static char *phy_addr = NULL;
202
203
204/* The dev_info variable is the "key" that is used to match up this
205   device driver with appropriate cards, through the card configuration
206   database.
207*/
208static dev_info_t dev_info = "ray_cs";
209
210/* A linked list of "instances" of the ray device.  Each actual
211   PCMCIA card corresponds to one device instance, and is described
212   by one dev_link_t structure (defined in ds.h).
213*/
214static dev_link_t *dev_list = NULL;
215
216/* A dev_link_t structure has fields for most things that are needed
217   to keep track of a socket, but there will usually be some device
218   specific information that also needs to be kept track of.  The
219   'priv' pointer in a dev_link_t structure can be used to point to
220   a device-specific private data structure, like this.
221*/
222static unsigned int ray_mem_speed = 500;
223
224MODULE_AUTHOR("Corey Thomas <corey@world.std.com>");
225MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");
226MODULE_LICENSE("GPL");
227
228MODULE_PARM(irq_mask,"i");
229MODULE_PARM(net_type,"i");
230MODULE_PARM(hop_dwell,"i");
231MODULE_PARM(beacon_period,"i");
232MODULE_PARM(psm,"i");
233MODULE_PARM(essid,"s");
234MODULE_PARM(translate,"i");
235MODULE_PARM(country,"i");
236MODULE_PARM(sniffer,"i");
237MODULE_PARM(bc,"i");
238MODULE_PARM(phy_addr,"s");
239MODULE_PARM(ray_mem_speed, "i");
240
241static UCHAR b5_default_startup_parms[] = {
242    0,   0,                         /* Adhoc station */
243   'L','I','N','U','X', 0,  0,  0,  /* 32 char ESSID */
244    0,  0,  0,  0,  0,  0,  0,  0,
245    0,  0,  0,  0,  0,  0,  0,  0,
246    0,  0,  0,  0,  0,  0,  0,  0,
247    1,  0,                          /* Active scan, CA Mode */
248    0,  0,  0,  0,  0,  0,          /* No default MAC addr  */
249    0x7f, 0xff,                     /* Frag threshold */
250    0x00, 0x80,                     /* Hop time 128 Kus*/
251    0x01, 0x00,                     /* Beacon period 256 Kus */
252    0x01, 0x07, 0xa3,               /* DTIM, retries, ack timeout*/
253    0x1d, 0x82, 0x4e,               /* SIFS, DIFS, PIFS */
254    0x7f, 0xff,                     /* RTS threshold */
255    0x04, 0xe2, 0x38, 0xA4,         /* scan_dwell, max_scan_dwell */
256    0x05,                           /* assoc resp timeout thresh */
257    0x08, 0x02, 0x08,               /* adhoc, infra, super cycle max*/
258    0,                              /* Promiscuous mode */
259    0x0c, 0x0bd,                    /* Unique word */
260    0x32,                           /* Slot time */
261    0xff, 0xff,                     /* roam-low snr, low snr count */
262    0x05, 0xff,                     /* Infra, adhoc missed bcn thresh */
263    0x01, 0x0b, 0x4f,               /* USA, hop pattern, hop pat length */
264/* b4 - b5 differences start here */
265    0x00, 0x3f,                     /* CW max */
266    0x00, 0x0f,                     /* CW min */
267    0x04, 0x08,                     /* Noise gain, limit offset */
268    0x28, 0x28,                     /* det rssi, med busy offsets */
269    7,                              /* det sync thresh */
270    0, 2, 2,                        /* test mode, min, max */
271    0,                              /* allow broadcast SSID probe resp */
272    0, 0,                           /* privacy must start, can join */
273    2, 0, 0, 0, 0, 0, 0, 0          /* basic rate set */
274};
275
276static UCHAR b4_default_startup_parms[] = {
277    0,   0,                         /* Adhoc station */
278   'L','I','N','U','X', 0,  0,  0,  /* 32 char ESSID */
279    0,  0,  0,  0,  0,  0,  0,  0,
280    0,  0,  0,  0,  0,  0,  0,  0,
281    0,  0,  0,  0,  0,  0,  0,  0,
282    1,  0,                          /* Active scan, CA Mode */
283    0,  0,  0,  0,  0,  0,          /* No default MAC addr  */
284    0x7f, 0xff,                     /* Frag threshold */
285    0x02, 0x00,                     /* Hop time */
286    0x00, 0x01,                     /* Beacon period */
287    0x01, 0x07, 0xa3,               /* DTIM, retries, ack timeout*/
288    0x1d, 0x82, 0xce,               /* SIFS, DIFS, PIFS */
289    0x7f, 0xff,                     /* RTS threshold */
290    0xfb, 0x1e, 0xc7, 0x5c,         /* scan_dwell, max_scan_dwell */
291    0x05,                           /* assoc resp timeout thresh */
292    0x04, 0x02, 0x4,                /* adhoc, infra, super cycle max*/
293    0,                              /* Promiscuous mode */
294    0x0c, 0x0bd,                    /* Unique word */
295    0x4e,                           /* Slot time (TBD seems wrong)*/
296    0xff, 0xff,                     /* roam-low snr, low snr count */
297    0x05, 0xff,                     /* Infra, adhoc missed bcn thresh */
298    0x01, 0x0b, 0x4e,               /* USA, hop pattern, hop pat length */
299/* b4 - b5 differences start here */
300    0x3f, 0x0f,                     /* CW max, min */
301    0x04, 0x08,                     /* Noise gain, limit offset */
302    0x28, 0x28,                     /* det rssi, med busy offsets */
303    7,                              /* det sync thresh */
304    0, 2, 2                         /* test mode, min, max*/
305};
306/*===========================================================================*/
307static unsigned char eth2_llc[] = {0xaa, 0xaa, 3, 0, 0, 0};
308
309static char hop_pattern_length[] = { 1,
310	     USA_HOP_MOD,             EUROPE_HOP_MOD,
311	     JAPAN_HOP_MOD,           KOREA_HOP_MOD,
312	     SPAIN_HOP_MOD,           FRANCE_HOP_MOD,
313	     ISRAEL_HOP_MOD,          AUSTRALIA_HOP_MOD,
314	     JAPAN_TEST_HOP_MOD
315};
316
317static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.std.com>";
318
319/*===========================================================================*/
320static void cs_error(client_handle_t handle, int func, int ret)
321{
322    error_info_t err = { func, ret };
323    pcmcia_report_error(handle, &err);
324}
325/*======================================================================
326
327    This bit of code is used to avoid unregistering network devices
328    at inappropriate times.  2.2 and later kernels are fairly picky
329    about when this can happen.
330
331======================================================================*/
332
333static void flush_stale_links(void)
334{
335    dev_link_t *link, *next;
336    for (link = dev_list; link; link = next) {
337	next = link->next;
338	if (link->state & DEV_STALE_LINK)
339	    ray_detach(link);
340    }
341}
342
343/*=============================================================================
344    ray_attach() creates an "instance" of the driver, allocating
345    local data structures for one device.  The device is registered
346    with Card Services.
347    The dev_link structure is initialized, but we don't actually
348    configure the card at this point -- we wait until we receive a
349    card insertion event.
350=============================================================================*/
351static dev_link_t *ray_attach(void)
352{
353    client_reg_t client_reg;
354    dev_link_t *link;
355    ray_dev_t *local;
356    int ret;
357    struct net_device *dev;
358
359    DEBUG(1, "ray_attach()\n");
360    flush_stale_links();
361
362    /* Initialize the dev_link_t structure */
363    link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
364
365    if (!link)
366	    return NULL;
367
368    /* Allocate space for private device-specific data */
369    dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
370
371    if (!dev)
372	    goto fail_alloc_dev;
373
374    local = kmalloc(sizeof(ray_dev_t), GFP_KERNEL);
375
376    if (!local)
377	    goto fail_alloc_local;
378
379    memset(link, 0, sizeof(struct dev_link_t));
380    memset(dev, 0, sizeof(struct net_device));
381    memset(local, 0, sizeof(ray_dev_t));
382
383    link->release.function = &ray_release;
384    link->release.data = (u_long)link;
385
386    /* The io structure describes IO port mapping. None used here */
387    link->io.NumPorts1 = 0;
388    link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
389    link->io.IOAddrLines = 5;
390
391    /* Interrupt setup. For PCMCIA, driver takes what's given */
392    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
393    link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
394    link->irq.IRQInfo2 = irq_mask;
395    link->irq.Handler = &ray_interrupt;
396
397    /* General socket configuration */
398    link->conf.Attributes = CONF_ENABLE_IRQ;
399    link->conf.Vcc = 50;
400    link->conf.IntType = INT_MEMORY_AND_IO;
401    link->conf.ConfigIndex = 1;
402    link->conf.Present = PRESENT_OPTION;
403
404    link->priv = dev;
405    link->irq.Instance = dev;
406
407    dev->priv = local;
408    local->finder = link;
409    local->card_status = CARD_INSERTED;
410    local->authentication_state = UNAUTHENTICATED;
411    local->num_multi = 0;
412    DEBUG(2,"ray_attach link = %p,  dev = %p,  local = %p, intr = %p\n",
413          link,dev,local,&ray_interrupt);
414
415    /* Raylink entries in the device structure */
416    dev->hard_start_xmit = &ray_dev_start_xmit;
417    dev->set_config = &ray_dev_config;
418    dev->get_stats  = &ray_get_stats;
419    dev->do_ioctl = &ray_dev_ioctl;
420#if WIRELESS_EXT > 7	    /* If wireless extension exist in the kernel */
421    dev->get_wireless_stats = ray_get_wireless_stats;
422#endif
423
424    dev->set_multicast_list = &set_multicast_list;
425
426    DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n");
427    ether_setup(dev);
428    dev->init = &ray_dev_init;
429    dev->open = &ray_open;
430    dev->stop = &ray_dev_close;
431    netif_stop_queue(dev);
432
433    /* Register with Card Services */
434    link->next = dev_list;
435    dev_list = link;
436    client_reg.dev_info = &dev_info;
437    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
438    client_reg.EventMask =
439        CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
440        CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
441        CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
442    client_reg.event_handler = &ray_event;
443    client_reg.Version = 0x0210;
444    client_reg.event_callback_args.client_data = link;
445
446    DEBUG(2,"ray_cs ray_attach calling CardServices(RegisterClient...)\n");
447
448    init_timer(&local->timer);
449
450    ret = pcmcia_register_client(&link->handle, &client_reg);
451    if (ret != 0) {
452        printk("ray_cs ray_attach RegisterClient unhappy - detaching\n");
453        cs_error(link->handle, RegisterClient, ret);
454        ray_detach(link);
455        return NULL;
456    }
457    DEBUG(2,"ray_cs ray_attach ending\n");
458    return link;
459
460fail_alloc_local:
461    kfree(dev);
462fail_alloc_dev:
463    kfree(link);
464    return NULL;
465} /* ray_attach */
466/*=============================================================================
467    This deletes a driver "instance".  The device is de-registered
468    with Card Services.  If it has been released, all local data
469    structures are freed.  Otherwise, the structures will be freed
470    when the device is released.
471=============================================================================*/
472static void ray_detach(dev_link_t *link)
473{
474    dev_link_t **linkp;
475
476    DEBUG(1, "ray_detach(0x%p)\n", link);
477
478    /* Locate device structure */
479    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
480        if (*linkp == link) break;
481    if (*linkp == NULL)
482        return;
483
484    /* If the device is currently configured and active, we won't
485      actually delete it yet.  Instead, it is marked so that when
486      the release() function is called, that will trigger a proper
487      detach().
488    */
489    del_timer(&link->release);
490    if (link->state & DEV_CONFIG) {
491        ray_release((u_long)link);
492        if(link->state & DEV_STALE_CONFIG) {
493            link->state |= DEV_STALE_LINK;
494            return;
495        }
496    }
497
498    /* Break the link with Card Services */
499    if (link->handle)
500        pcmcia_deregister_client(link->handle);
501
502    /* Unlink device structure, free pieces */
503    *linkp = link->next;
504    if (link->priv) {
505        struct net_device *dev = link->priv;
506	if (link->dev) unregister_netdev(dev);
507        if (dev->priv)
508            kfree(dev->priv);
509        kfree(link->priv);
510    }
511    kfree(link);
512    DEBUG(2,"ray_cs ray_detach ending\n");
513} /* ray_detach */
514/*=============================================================================
515    ray_config() is run after a CARD_INSERTION event
516    is received, to configure the PCMCIA socket, and to make the
517    ethernet device available to the system.
518=============================================================================*/
519#define CS_CHECK(fn, args...) \
520while ((last_ret=fn(args))!=0) goto cs_failed
521#define MAX_TUPLE_SIZE 128
522static void ray_config(dev_link_t *link)
523{
524    client_handle_t handle = link->handle;
525    tuple_t tuple;
526    cisparse_t parse;
527    int last_fn = 0, last_ret = 0;
528    int i;
529    u_char buf[MAX_TUPLE_SIZE];
530    win_req_t req;
531    memreq_t mem;
532    struct net_device *dev = (struct net_device *)link->priv;
533    ray_dev_t *local = (ray_dev_t *)dev->priv;
534
535    DEBUG(1, "ray_config(0x%p)\n", link);
536
537    /* This reads the card's CONFIG tuple to find its configuration regs */
538    tuple.DesiredTuple = CISTPL_CONFIG;
539    CS_CHECK(pcmcia_get_first_tuple, handle, &tuple);
540    tuple.TupleData = buf;
541    tuple.TupleDataMax = MAX_TUPLE_SIZE;
542    tuple.TupleOffset = 0;
543    CS_CHECK(pcmcia_get_tuple_data, handle, &tuple);
544    CS_CHECK(pcmcia_parse_tuple, handle, &tuple, &parse);
545    link->conf.ConfigBase = parse.config.base;
546    link->conf.Present = parse.config.rmask[0];
547
548    /* Determine card type and firmware version */
549    buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0;
550    tuple.DesiredTuple = CISTPL_VERS_1;
551    CS_CHECK(pcmcia_get_first_tuple, handle, &tuple);
552    tuple.TupleData = buf;
553    tuple.TupleDataMax = MAX_TUPLE_SIZE;
554    tuple.TupleOffset = 2;
555    CS_CHECK(pcmcia_get_tuple_data, handle, &tuple);
556
557    for (i=0; i<tuple.TupleDataLen - 4; i++)
558        if (buf[i] == 0) buf[i] = ' ';
559    printk(KERN_INFO "ray_cs Detected: %s\n",buf);
560
561    /* Configure card */
562    link->state |= DEV_CONFIG;
563
564    /* Now allocate an interrupt line.  Note that this does not
565       actually assign a handler to the interrupt.
566    */
567    CS_CHECK(pcmcia_request_irq, link->handle, &link->irq);
568    dev->irq = link->irq.AssignedIRQ;
569
570    /* This actually configures the PCMCIA socket -- setting up
571       the I/O windows and the interrupt mapping.
572    */
573    CS_CHECK(pcmcia_request_configuration, link->handle, &link->conf);
574
575/*** Set up 32k window for shared memory (transmit and control) ************/
576    req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
577    req.Base = 0;
578    req.Size = 0x8000;
579    req.AccessSpeed = ray_mem_speed;
580    CS_CHECK(pcmcia_request_window, &link->handle, &req, &link->win);
581    mem.CardOffset = 0x0000; mem.Page = 0;
582    CS_CHECK(pcmcia_map_mem_page, link->win, &mem);
583    local->sram = (UCHAR *)(ioremap(req.Base,req.Size));
584
585/*** Set up 16k window for shared memory (receive buffer) ***************/
586    req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
587    req.Base = 0;
588    req.Size = 0x4000;
589    req.AccessSpeed = ray_mem_speed;
590    CS_CHECK(pcmcia_request_window, &link->handle, &req, &local->rmem_handle);
591    mem.CardOffset = 0x8000; mem.Page = 0;
592    CS_CHECK(pcmcia_map_mem_page, local->rmem_handle, &mem);
593    local->rmem = (UCHAR *)(ioremap(req.Base,req.Size));
594
595/*** Set up window for attribute memory ***********************************/
596    req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT;
597    req.Base = 0;
598    req.Size = 0x1000;
599    req.AccessSpeed = ray_mem_speed;
600    CS_CHECK(pcmcia_request_window, &link->handle, &req, &local->amem_handle);
601    mem.CardOffset = 0x0000; mem.Page = 0;
602    CS_CHECK(pcmcia_map_mem_page, local->amem_handle, &mem);
603    local->amem = (UCHAR *)(ioremap(req.Base,req.Size));
604
605    DEBUG(3,"ray_config sram=%p\n",local->sram);
606    DEBUG(3,"ray_config rmem=%p\n",local->rmem);
607    DEBUG(3,"ray_config amem=%p\n",local->amem);
608    if (ray_init(dev) < 0) {
609        ray_release((u_long)link);
610        return;
611    }
612
613    i = register_netdev(dev);
614    if (i != 0) {
615        printk("ray_config register_netdev() failed\n");
616        ray_release((u_long)link);
617        return;
618    }
619
620    strcpy(local->node.dev_name, dev->name);
621    link->dev = &local->node;
622
623    link->state &= ~DEV_CONFIG_PENDING;
624    printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ",
625       dev->name, dev->irq);
626    for (i = 0; i < 6; i++)
627    printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
628
629    return;
630
631cs_failed:
632    cs_error(link->handle, last_fn, last_ret);
633
634    ray_release((u_long)link);
635} /* ray_config */
636/*===========================================================================*/
637static int ray_init(struct net_device *dev)
638{
639    int i;
640    UCHAR *p;
641    struct ccs *pccs;
642    ray_dev_t *local = (ray_dev_t *)dev->priv;
643    dev_link_t *link = local->finder;
644    DEBUG(1, "ray_init(0x%p)\n", dev);
645    if (!(link->state & DEV_PRESENT)) {
646        DEBUG(0,"ray_init - device not present\n");
647        return -1;
648    }
649
650    local->net_type = net_type;
651    local->sta_type = TYPE_STA;
652
653    /* Copy the startup results to local memory */
654    memcpy_fromio(&local->startup_res, local->sram + ECF_TO_HOST_BASE,\
655           sizeof(struct startup_res_6));
656
657    /* Check Power up test status and get mac address from card */
658    if (local->startup_res.startup_word != 0x80) {
659    printk(KERN_INFO "ray_init ERROR card status = %2x\n",
660           local->startup_res.startup_word);
661        local->card_status = CARD_INIT_ERROR;
662        return -1;
663    }
664
665    local->fw_ver = local->startup_res.firmware_version[0];
666    local->fw_bld = local->startup_res.firmware_version[1];
667    local->fw_var = local->startup_res.firmware_version[2];
668    DEBUG(1,"ray_init firmware version %d.%d \n",local->fw_ver, local->fw_bld);
669
670    local->tib_length = 0x20;
671    if ((local->fw_ver == 5) && (local->fw_bld >= 30))
672        local->tib_length = local->startup_res.tib_length;
673    DEBUG(2,"ray_init tib_length = 0x%02x\n", local->tib_length);
674    /* Initialize CCS's to buffer free state */
675    pccs = (struct ccs *)(local->sram + CCS_BASE);
676    for (i=0;  i<NUMBER_OF_CCS;  i++) {
677        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
678    }
679    init_startup_params(local);
680
681    /* copy mac address to startup parameters */
682    if (parse_addr(phy_addr, local->sparm.b4.a_mac_addr))
683    {
684        p = local->sparm.b4.a_mac_addr;
685    }
686    else
687    {
688        memcpy(&local->sparm.b4.a_mac_addr,
689               &local->startup_res.station_addr, ADDRLEN);
690        p = local->sparm.b4.a_mac_addr;
691    }
692
693    clear_interrupt(local); /* Clear any interrupt from the card */
694    local->card_status = CARD_AWAITING_PARAM;
695    DEBUG(2,"ray_init ending\n");
696    return 0;
697} /* ray_init */
698/*===========================================================================*/
699/* Download startup parameters to the card and command it to read them       */
700static int dl_startup_params(struct net_device *dev)
701{
702    int ccsindex;
703    ray_dev_t *local = (ray_dev_t *)dev->priv;
704    struct ccs *pccs;
705    dev_link_t *link = local->finder;
706
707    DEBUG(1,"dl_startup_params entered\n");
708    if (!(link->state & DEV_PRESENT)) {
709        DEBUG(2,"ray_cs dl_startup_params - device not present\n");
710        return -1;
711    }
712
713    /* Copy parameters to host to ECF area */
714    if (local->fw_ver == 0x55)
715        memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b4,
716               sizeof(struct b4_startup_params));
717    else
718        memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b5,
719               sizeof(struct b5_startup_params));
720
721
722    /* Fill in the CCS fields for the ECF */
723    if ((ccsindex = get_free_ccs(local)) < 0) return -1;
724    local->dl_param_ccs = ccsindex;
725    pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
726    writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd);
727    DEBUG(2,"dl_startup_params start ccsindex = %d\n", local->dl_param_ccs);
728    /* Interrupt the firmware to process the command */
729    if (interrupt_ecf(local, ccsindex)) {
730        printk(KERN_INFO "ray dl_startup_params failed - "
731           "ECF not ready for intr\n");
732        local->card_status = CARD_DL_PARAM_ERROR;
733        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
734        return -2;
735    }
736    local->card_status = CARD_DL_PARAM;
737    /* Start kernel timer to wait for dl startup to complete. */
738    local->timer.expires = jiffies + HZ/2;
739    local->timer.data = (long)local;
740    local->timer.function = &verify_dl_startup;
741    add_timer(&local->timer);
742    DEBUG(2,"ray_cs dl_startup_params started timer for verify_dl_startup\n");
743    return 0;
744} /* dl_startup_params */
745/*===========================================================================*/
746static void init_startup_params(ray_dev_t *local)
747{
748    int i;
749
750    if (country > JAPAN_TEST) country = USA;
751    else
752        if (country < USA) country = USA;
753    /* structure for hop time and beacon period is defined here using
754     * New 802.11D6.1 format.  Card firmware is still using old format
755     * until version 6.
756     *    Before                    After
757     *    a_hop_time ms byte        a_hop_time ms byte
758     *    a_hop_time 2s byte        a_hop_time ls byte
759     *    a_hop_time ls byte        a_beacon_period ms byte
760     *    a_beacon_period           a_beacon_period ls byte
761     *
762     *    a_hop_time = uS           a_hop_time = KuS
763     *    a_beacon_period = hops    a_beacon_period = KuS
764     */                             /* 64ms = 010000 */
765    if (local->fw_ver == 0x55)  {
766        memcpy((UCHAR *)&local->sparm.b4, b4_default_startup_parms,
767               sizeof(struct b4_startup_params));
768        /* Translate sane kus input values to old build 4/5 format */
769        /* i = hop time in uS truncated to 3 bytes */
770        i = (hop_dwell * 1024) & 0xffffff;
771        local->sparm.b4.a_hop_time[0] = (i >> 16) & 0xff;
772        local->sparm.b4.a_hop_time[1] = (i >> 8) & 0xff;
773        local->sparm.b4.a_beacon_period[0] = 0;
774        local->sparm.b4.a_beacon_period[1] =
775            ((beacon_period/hop_dwell) - 1) & 0xff;
776        local->sparm.b4.a_curr_country_code = country;
777        local->sparm.b4.a_hop_pattern_length =
778            hop_pattern_length[(int)country] - 1;
779        if (bc)
780        {
781            local->sparm.b4.a_ack_timeout = 0x50;
782            local->sparm.b4.a_sifs = 0x3f;
783        }
784    }
785    else {    /* Version 5 uses real kus values */
786        memcpy((UCHAR *)&local->sparm.b5, b5_default_startup_parms,
787               sizeof(struct b5_startup_params));
788
789        local->sparm.b5.a_hop_time[0] = (hop_dwell >> 8) & 0xff;
790        local->sparm.b5.a_hop_time[1] = hop_dwell & 0xff;
791        local->sparm.b5.a_beacon_period[0] = (beacon_period >> 8) & 0xff;
792        local->sparm.b5.a_beacon_period[1] = beacon_period & 0xff;
793        if (psm)
794            local->sparm.b5.a_power_mgt_state = 1;
795        local->sparm.b5.a_curr_country_code = country;
796        local->sparm.b5.a_hop_pattern_length =
797            hop_pattern_length[(int)country];
798    }
799
800    local->sparm.b4.a_network_type = net_type & 0x01;
801    local->sparm.b4.a_acting_as_ap_status = TYPE_STA;
802
803    if (essid != NULL)
804        strncpy(local->sparm.b4.a_current_ess_id, essid, ESSID_SIZE);
805} /* init_startup_params */
806/*===========================================================================*/
807static void verify_dl_startup(u_long data)
808{
809    ray_dev_t *local = (ray_dev_t *)data;
810    struct ccs *pccs = ((struct ccs *)(local->sram + CCS_BASE)) + local->dl_param_ccs;
811    UCHAR status;
812    dev_link_t *link = local->finder;
813
814    if (!(link->state & DEV_PRESENT)) {
815        DEBUG(2,"ray_cs verify_dl_startup - device not present\n");
816        return;
817    }
818#ifdef PCMCIA_DEBUG
819    if (pc_debug > 2) {
820    int i;
821    printk(KERN_DEBUG "verify_dl_startup parameters sent via ccs %d:\n",
822           local->dl_param_ccs);
823        for (i=0; i<sizeof(struct b5_startup_params); i++) {
824            printk(" %2x", (unsigned int) readb(local->sram + HOST_TO_ECF_BASE + i));
825        }
826    printk("\n");
827    }
828#endif
829
830    status = readb(&pccs->buffer_status);
831    if (status!= CCS_BUFFER_FREE)
832    {
833        printk(KERN_INFO "Download startup params failed.  Status = %d\n",
834           status);
835        local->card_status = CARD_DL_PARAM_ERROR;
836        return;
837    }
838    if (local->sparm.b4.a_network_type == ADHOC)
839        start_net((u_long)local);
840    else
841        join_net((u_long)local);
842
843    return;
844} /* end verify_dl_startup */
845/*===========================================================================*/
846/* Command card to start a network */
847static void start_net(u_long data)
848{
849    ray_dev_t *local = (ray_dev_t *)data;
850    struct ccs *pccs;
851    int ccsindex;
852    dev_link_t *link = local->finder;
853    if (!(link->state & DEV_PRESENT)) {
854        DEBUG(2,"ray_cs start_net - device not present\n");
855        return;
856    }
857    /* Fill in the CCS fields for the ECF */
858    if ((ccsindex = get_free_ccs(local)) < 0) return;
859    pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
860    writeb(CCS_START_NETWORK, &pccs->cmd);
861    writeb(0, &pccs->var.start_network.update_param);
862    /* Interrupt the firmware to process the command */
863    if (interrupt_ecf(local, ccsindex)) {
864        DEBUG(1,"ray start net failed - card not ready for intr\n");
865        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
866        return;
867    }
868    local->card_status = CARD_DOING_ACQ;
869    return;
870} /* end start_net */
871/*===========================================================================*/
872/* Command card to join a network */
873static void join_net(u_long data)
874{
875    ray_dev_t *local = (ray_dev_t *)data;
876
877    struct ccs *pccs;
878    int ccsindex;
879    dev_link_t *link = local->finder;
880
881    if (!(link->state & DEV_PRESENT)) {
882        DEBUG(2,"ray_cs join_net - device not present\n");
883        return;
884    }
885    /* Fill in the CCS fields for the ECF */
886    if ((ccsindex = get_free_ccs(local)) < 0) return;
887    pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
888    writeb(CCS_JOIN_NETWORK, &pccs->cmd);
889    writeb(0, &pccs->var.join_network.update_param);
890    writeb(0, &pccs->var.join_network.net_initiated);
891    /* Interrupt the firmware to process the command */
892    if (interrupt_ecf(local, ccsindex)) {
893        DEBUG(1,"ray join net failed - card not ready for intr\n");
894        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
895        return;
896    }
897    local->card_status = CARD_DOING_ACQ;
898    return;
899}
900/*============================================================================
901    After a card is removed, ray_release() will unregister the net
902    device, and release the PCMCIA configuration.  If the device is
903    still open, this will be postponed until it is closed.
904=============================================================================*/
905static void ray_release(u_long arg)
906{
907    dev_link_t *link = (dev_link_t *)arg;
908    struct net_device *dev = link->priv;
909    ray_dev_t *local = dev->priv;
910    int i;
911
912    DEBUG(1, "ray_release(0x%p)\n", link);
913    /* If the device is currently in use, we won't release until it
914      is actually closed.
915    */
916    if (link->open) {
917        DEBUG(1, "ray_cs: release postponed, '%s' still open\n",
918              link->dev->dev_name);
919        link->state |= DEV_STALE_CONFIG;
920        return;
921    }
922    del_timer(&local->timer);
923    link->state &= ~DEV_CONFIG;
924
925    iounmap(local->sram);
926    iounmap(local->rmem);
927    iounmap(local->amem);
928    /* Do bother checking to see if these succeed or not */
929    i = pcmcia_release_window(link->win);
930    if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(link->win) ret = %x\n",i);
931    i = pcmcia_release_window(local->amem_handle);
932    if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);
933    i = pcmcia_release_window(local->rmem_handle);
934    if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);
935    i = pcmcia_release_configuration(link->handle);
936    if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseConfiguration ret = %x\n",i);
937    i = pcmcia_release_irq(link->handle, &link->irq);
938    if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i);
939
940    DEBUG(2,"ray_release ending\n");
941} /* ray_release */
942/*=============================================================================
943    The card status event handler.  Mostly, this schedules other
944    stuff to run after an event is received.  A CARD_REMOVAL event
945    also sets some flags to discourage the net drivers from trying
946    to talk to the card any more.
947
948    When a CARD_REMOVAL event is received, we immediately set a flag
949    to block future accesses to this device.  All the functions that
950    actually access the device should check this flag to make sure
951    the card is still present.
952=============================================================================*/
953static int ray_event(event_t event, int priority,
954                     event_callback_args_t *args)
955{
956    dev_link_t *link = args->client_data;
957    struct net_device *dev = link->priv;
958    ray_dev_t *local = (ray_dev_t *)dev->priv;
959    DEBUG(1, "ray_event(0x%06x)\n", event);
960
961    switch (event) {
962    case CS_EVENT_CARD_REMOVAL:
963        link->state &= ~DEV_PRESENT;
964        netif_device_detach(dev);
965        if (link->state & DEV_CONFIG) {
966            mod_timer(&link->release, jiffies + HZ/20);
967            del_timer(&local->timer);
968        }
969        break;
970    case CS_EVENT_CARD_INSERTION:
971        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
972        ray_config(link);
973        break;
974    case CS_EVENT_PM_SUSPEND:
975        link->state |= DEV_SUSPEND;
976        /* Fall through... */
977    case CS_EVENT_RESET_PHYSICAL:
978        if (link->state & DEV_CONFIG) {
979            if (link->open)
980            	netif_device_detach(dev);
981
982            pcmcia_release_configuration(link->handle);
983        }
984        break;
985    case CS_EVENT_PM_RESUME:
986        link->state &= ~DEV_SUSPEND;
987        /* Fall through... */
988    case CS_EVENT_CARD_RESET:
989        if (link->state & DEV_CONFIG) {
990            pcmcia_request_configuration(link->handle, &link->conf);
991            if (link->open) {
992                ray_reset(dev);
993		netif_device_attach(dev);
994            }
995        }
996        break;
997    }
998    return 0;
999    DEBUG(2,"ray_event ending\n");
1000} /* ray_event */
1001/*===========================================================================*/
1002int ray_dev_init(struct net_device *dev)
1003{
1004#ifdef RAY_IMMEDIATE_INIT
1005    int i;
1006#endif	/* RAY_IMMEDIATE_INIT */
1007    ray_dev_t *local = dev->priv;
1008    dev_link_t *link = local->finder;
1009
1010    DEBUG(1,"ray_dev_init(dev=%p)\n",dev);
1011    if (!(link->state & DEV_PRESENT)) {
1012        DEBUG(2,"ray_dev_init - device not present\n");
1013        return -1;
1014    }
1015#ifdef RAY_IMMEDIATE_INIT
1016    /* Download startup parameters */
1017    if ( (i = dl_startup_params(dev)) < 0)
1018    {
1019        printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
1020           "returns 0x%x\n",i);
1021        return -1;
1022    }
1023#else	/* RAY_IMMEDIATE_INIT */
1024    /* Postpone the card init so that we can still configure the card,
1025     * for example using the Wireless Extensions. The init will happen
1026     * in ray_open() - Jean II */
1027    DEBUG(1,"ray_dev_init: postponing card init to ray_open() ; Status = %d\n",
1028	  local->card_status);
1029#endif	/* RAY_IMMEDIATE_INIT */
1030
1031    /* copy mac and broadcast addresses to linux device */
1032    memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
1033    memset(dev->broadcast, 0xff, ETH_ALEN);
1034
1035    DEBUG(2,"ray_dev_init ending\n");
1036    return 0;
1037}
1038/*===========================================================================*/
1039static int ray_dev_config(struct net_device *dev, struct ifmap *map)
1040{
1041    ray_dev_t *local = dev->priv;
1042    dev_link_t *link = local->finder;
1043    /* Dummy routine to satisfy device structure */
1044    DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map);
1045    if (!(link->state & DEV_PRESENT)) {
1046        DEBUG(2,"ray_dev_config - device not present\n");
1047        return -1;
1048    }
1049
1050    return 0;
1051}
1052/*===========================================================================*/
1053static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
1054{
1055    ray_dev_t *local = dev->priv;
1056    dev_link_t *link = local->finder;
1057    short length;
1058
1059    if (!(link->state & DEV_PRESENT)) {
1060        DEBUG(2,"ray_dev_start_xmit - device not present\n");
1061        return -1;
1062    }
1063    DEBUG(3,"ray_dev_start_xmit(skb=%p, dev=%p)\n",skb,dev);
1064    if (local->authentication_state == NEED_TO_AUTH) {
1065        DEBUG(0,"ray_cs Sending authentication request.\n");
1066        if (!build_auth_frame (local, local->auth_id, OPEN_AUTH_REQUEST)) {
1067            local->authentication_state = AUTHENTICATED;
1068            netif_stop_queue(dev);
1069            return 1;
1070        }
1071    }
1072
1073    length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1074    switch (ray_hw_xmit( skb->data, length, dev, DATA_TYPE)) {
1075        case XMIT_NO_CCS:
1076        case XMIT_NEED_AUTH:
1077	    netif_stop_queue(dev);
1078            return 1;
1079        case XMIT_NO_INTR:
1080        case XMIT_MSG_BAD:
1081        case XMIT_OK:
1082        default:
1083            dev->trans_start = jiffies;
1084            dev_kfree_skb(skb);
1085            return 0;
1086    }
1087    return 0;
1088} /* ray_dev_start_xmit */
1089/*===========================================================================*/
1090static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev,
1091                UCHAR msg_type)
1092{
1093    ray_dev_t *local = (ray_dev_t *)dev->priv;
1094    struct ccs *pccs;
1095    int ccsindex;
1096    int offset;
1097    struct tx_msg *ptx; /* Address of xmit buffer in PC space */
1098    short int addr;     /* Address of xmit buffer in card space */
1099
1100    DEBUG(3,"ray_hw_xmit(data=%p, len=%d, dev=%p)\n",data,len,dev);
1101    if (len + TX_HEADER_LENGTH > TX_BUF_SIZE)
1102    {
1103        printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",len);
1104        return XMIT_MSG_BAD;
1105    }
1106	switch (ccsindex = get_free_tx_ccs(local)) {
1107	case ECCSBUSY:
1108		DEBUG(2,"ray_hw_xmit tx_ccs table busy\n");
1109	case ECCSFULL:
1110        DEBUG(2,"ray_hw_xmit No free tx ccs\n");
1111	case ECARDGONE:
1112	netif_stop_queue(dev);
1113        return XMIT_NO_CCS;
1114	default:
1115		break;
1116	}
1117    addr = TX_BUF_BASE + (ccsindex << 11);
1118
1119    if (msg_type == DATA_TYPE) {
1120        local->stats.tx_bytes += len;
1121        local->stats.tx_packets++;
1122    }
1123
1124    ptx = (struct tx_msg *)(local->sram + addr);
1125
1126    ray_build_header(local, ptx, msg_type, data);
1127    if (translate) {
1128        offset = translate_frame(local, ptx, data, len);
1129    }
1130    else { /* Encapsulate frame */
1131        /* TBD TIB length will move address of ptx->var */
1132        memcpy_toio(&ptx->var, data, len);
1133        offset = 0;
1134    }
1135
1136    /* fill in the CCS */
1137    pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
1138    len += TX_HEADER_LENGTH + offset;
1139    writeb(CCS_TX_REQUEST, &pccs->cmd);
1140    writeb(addr >> 8, &pccs->var.tx_request.tx_data_ptr[0]);
1141    writeb(local->tib_length, &pccs->var.tx_request.tx_data_ptr[1]);
1142    writeb(len >> 8, &pccs->var.tx_request.tx_data_length[0]);
1143    writeb(len & 0xff, &pccs->var.tx_request.tx_data_length[1]);
1144/* TBD still need psm_cam? */
1145    writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode);
1146    writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate);
1147    writeb(0, &pccs->var.tx_request.antenna);
1148    DEBUG(3,"ray_hw_xmit default_tx_rate = 0x%x\n",\
1149          local->net_default_tx_rate);
1150
1151    /* Interrupt the firmware to process the command */
1152    if (interrupt_ecf(local, ccsindex)) {
1153        DEBUG(2,"ray_hw_xmit failed - ECF not ready for intr\n");
1154/* TBD very inefficient to copy packet to buffer, and then not
1155   send it, but the alternative is to queue the messages and that
1156   won't be done for a while.  Maybe set tbusy until a CCS is free?
1157*/
1158        writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
1159        return XMIT_NO_INTR;
1160    }
1161    return XMIT_OK;
1162} /* end ray_hw_xmit */
1163/*===========================================================================*/
1164static int translate_frame(ray_dev_t *local, struct tx_msg *ptx, unsigned char *data,
1165                    int len)
1166{
1167    unsigned short int proto = ((struct ethhdr *)data)->h_proto;
1168    if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
1169        DEBUG(3,"ray_cs translate_frame DIX II\n");
1170        /* Copy LLC header to card buffer */
1171        memcpy_toio((UCHAR *)&ptx->var, eth2_llc, sizeof(eth2_llc));
1172        memcpy_toio( ((UCHAR *)&ptx->var) + sizeof(eth2_llc), (UCHAR *)&proto, 2);
1173        if ((proto == 0xf380) || (proto == 0x3781)) {
1174            /* This is the selective translation table, only 2 entries */
1175            writeb(0xf8, (UCHAR *) &((struct snaphdr_t *)ptx->var)->org[3]);
1176        }
1177        /* Copy body of ethernet packet without ethernet header */
1178        memcpy_toio((UCHAR *)&ptx->var + sizeof(struct snaphdr_t), \
1179                    data + ETH_HLEN,  len - ETH_HLEN);
1180        return (int) sizeof(struct snaphdr_t) - ETH_HLEN;
1181    }
1182    else { /* already  802 type, and proto is length */
1183        DEBUG(3,"ray_cs translate_frame 802\n");
1184        if (proto == 0xffff) { /* evil netware IPX 802.3 without LLC */
1185        DEBUG(3,"ray_cs translate_frame evil IPX\n");
1186            memcpy_toio((UCHAR *)&ptx->var, data + ETH_HLEN,  len - ETH_HLEN);
1187            return 0 - ETH_HLEN;
1188        }
1189        memcpy_toio((UCHAR *)&ptx->var, data + ETH_HLEN,  len - ETH_HLEN);
1190        return 0 - ETH_HLEN;
1191    }
1192    /* TBD do other frame types */
1193} /* end translate_frame */
1194/*===========================================================================*/
1195static void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type,
1196                unsigned char *data)
1197{
1198    writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1);
1199/*** IEEE 802.11 Address field assignments *************
1200                TODS FROMDS   addr_1     addr_2          addr_3   addr_4
1201Adhoc           0    0        dest       src (terminal)  BSSID    N/A
1202AP to Terminal  0    1        dest       AP(BSSID)       source   N/A
1203Terminal to AP  1    0        AP(BSSID)  src (terminal)  dest     N/A
1204AP to AP        1    1        dest AP    src AP          dest     source
1205*******************************************************/
1206    if (local->net_type == ADHOC) {
1207        writeb(0, &ptx->mac.frame_ctl_2);
1208        memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, 2 * ADDRLEN);
1209        memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
1210    }
1211    else /* infrastructure */
1212    {
1213        if (local->sparm.b4.a_acting_as_ap_status)
1214        {
1215            writeb(FC2_FROM_DS, &ptx->mac.frame_ctl_2);
1216            memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, ADDRLEN);
1217            memcpy_toio(ptx->mac.addr_2, local->bss_id, 6);
1218            memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_source, ADDRLEN);
1219        }
1220        else /* Terminal */
1221        {
1222            writeb(FC2_TO_DS, &ptx->mac.frame_ctl_2);
1223            memcpy_toio(ptx->mac.addr_1, local->bss_id, ADDRLEN);
1224            memcpy_toio(ptx->mac.addr_2, ((struct ethhdr *)data)->h_source, ADDRLEN);
1225            memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_dest, ADDRLEN);
1226        }
1227    }
1228} /* end encapsulate_frame */
1229
1230
1231/*===========================================================================*/
1232
1233static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
1234{
1235	u32 ethcmd;
1236
1237	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
1238		return -EFAULT;
1239
1240	switch (ethcmd) {
1241	case ETHTOOL_GDRVINFO: {
1242		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
1243		strncpy(info.driver, "ray_cs", sizeof(info.driver)-1);
1244		if (copy_to_user(useraddr, &info, sizeof(info)))
1245			return -EFAULT;
1246		return 0;
1247	}
1248	}
1249
1250	return -EOPNOTSUPP;
1251}
1252
1253/*====================================================================*/
1254
1255static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1256{
1257    ray_dev_t *local = (ray_dev_t *)dev->priv;
1258    dev_link_t *link = local->finder;
1259    int err = 0;
1260#if WIRELESS_EXT > 7
1261    struct iwreq *wrq = (struct iwreq *) ifr;
1262#endif	/* WIRELESS_EXT > 7 */
1263
1264    if (!(link->state & DEV_PRESENT)) {
1265        DEBUG(2,"ray_dev_ioctl - device not present\n");
1266        return -1;
1267    }
1268    DEBUG(2,"ray_cs IOCTL dev=%p, ifr=%p, cmd = 0x%x\n",dev,ifr,cmd);
1269    /* Validate the command */
1270    switch (cmd)
1271    {
1272    case SIOCETHTOOL:
1273      err = netdev_ethtool_ioctl(dev, (void *) ifr->ifr_data);
1274      break;
1275
1276#if WIRELESS_EXT > 7
1277      /* --------------- WIRELESS EXTENSIONS --------------- */
1278      /* Get name */
1279    case SIOCGIWNAME:
1280      strcpy(wrq->u.name, "IEEE 802.11-FH");
1281      break;
1282
1283      /* Get frequency/channel */
1284    case SIOCGIWFREQ:
1285      wrq->u.freq.m = local->sparm.b5.a_hop_pattern;
1286      wrq->u.freq.e = 0;
1287      break;
1288
1289      /* Set frequency/channel */
1290    case SIOCSIWFREQ:
1291      /* Reject if card is already initialised */
1292      if(local->card_status != CARD_AWAITING_PARAM)
1293	{
1294	  err = -EBUSY;
1295	  break;
1296	}
1297
1298      /* Setting by channel number */
1299      if ((wrq->u.freq.m > USA_HOP_MOD) || (wrq->u.freq.e > 0))
1300	err = -EOPNOTSUPP;
1301      else
1302	  local->sparm.b5.a_hop_pattern = wrq->u.freq.m;
1303      break;
1304
1305      /* Get current network name (ESSID) */
1306    case SIOCGIWESSID:
1307      if (wrq->u.data.pointer)
1308	{
1309	  char essid[IW_ESSID_MAX_SIZE + 1];
1310	  /* Get the essid that was set */
1311	  memcpy(essid, local->sparm.b5.a_current_ess_id,
1312		 IW_ESSID_MAX_SIZE);
1313	  essid[IW_ESSID_MAX_SIZE] = '\0';
1314
1315	  /* Push it out ! */
1316	  wrq->u.data.length = strlen(essid) + 1;
1317	  wrq->u.data.flags = 1; /* active */
1318	  copy_to_user(wrq->u.data.pointer, essid, sizeof(essid));
1319	}
1320      break;
1321
1322      /* Set desired network name (ESSID) */
1323    case SIOCSIWESSID:
1324      /* Reject if card is already initialised */
1325      if(local->card_status != CARD_AWAITING_PARAM)
1326	{
1327	  err = -EBUSY;
1328	  break;
1329	}
1330
1331	if (wrq->u.data.pointer)
1332	{
1333	    char	card_essid[IW_ESSID_MAX_SIZE + 1];
1334
1335	    /* Check if we asked for `any' */
1336	    if(wrq->u.data.flags == 0)
1337	    {
1338		/* Corey : can you do that ? */
1339		err = -EOPNOTSUPP;
1340	    }
1341	    else
1342	    {
1343		/* Check the size of the string */
1344		if(wrq->u.data.length >
1345		   IW_ESSID_MAX_SIZE + 1)
1346		{
1347		    err = -E2BIG;
1348		    break;
1349		}
1350		if (copy_from_user(card_essid,
1351				   wrq->u.data.pointer,
1352				   wrq->u.data.length)) {
1353			err = -EFAULT;
1354			break;
1355		}
1356		card_essid[IW_ESSID_MAX_SIZE] = '\0';
1357
1358		/* Set the ESSID in the card */
1359		memcpy(local->sparm.b5.a_current_ess_id, card_essid,
1360		       IW_ESSID_MAX_SIZE);
1361	    }
1362	}
1363	break;
1364
1365      /* Get current Access Point (BSSID in our case) */
1366    case SIOCGIWAP:
1367      memcpy(wrq->u.ap_addr.sa_data, local->bss_id, ETH_ALEN);
1368      wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
1369      break;
1370
1371      /* Get the current bit-rate */
1372    case SIOCGIWRATE:
1373      if(local->net_default_tx_rate == 3)
1374	wrq->u.bitrate.value = 2000000;		/* Hum... */
1375      else
1376	wrq->u.bitrate.value = local->net_default_tx_rate * 500000;
1377      wrq->u.bitrate.fixed = 0;		/* We are in auto mode */
1378      break;
1379
1380      /* Set the desired bit-rate */
1381    case SIOCSIWRATE:
1382      /* Check if rate is in range */
1383      if((wrq->u.bitrate.value != 1000000) &&
1384	 (wrq->u.bitrate.value != 2000000))
1385	{
1386	  err = -EINVAL;
1387	  break;
1388	}
1389      /* Hack for 1.5 Mb/s instead of 2 Mb/s */
1390      if((local->fw_ver == 0x55) &&		/* Please check */
1391	 (wrq->u.bitrate.value == 2000000))
1392	local->net_default_tx_rate = 3;
1393      else
1394	local->net_default_tx_rate = wrq->u.bitrate.value/500000;
1395      break;
1396
1397      /* Get the current RTS threshold */
1398    case SIOCGIWRTS:
1399      wrq->u.rts.value = (local->sparm.b5.a_rts_threshold[0] << 8)
1400	+ local->sparm.b5.a_rts_threshold[1];
1401#if WIRELESS_EXT > 8
1402      wrq->u.rts.disabled = (wrq->u.rts.value == 32767);
1403#endif /* WIRELESS_EXT > 8 */
1404      wrq->u.rts.fixed = 1;
1405      break;
1406
1407      /* Set the desired RTS threshold */
1408    case SIOCSIWRTS:
1409    {
1410	int rthr = wrq->u.rts.value;
1411
1412      /* Reject if card is already initialised */
1413      if(local->card_status != CARD_AWAITING_PARAM)
1414	{
1415	  err = -EBUSY;
1416	  break;
1417	}
1418
1419	/* if(wrq->u.rts.fixed == 0) we should complain */
1420#if WIRELESS_EXT > 8
1421	if(wrq->u.rts.disabled)
1422	    rthr = 32767;
1423	else
1424#endif /* WIRELESS_EXT > 8 */
1425	    if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */
1426	    {
1427		err = -EINVAL;
1428		break;
1429	    }
1430	local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF;
1431	local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF;
1432    }
1433    break;
1434
1435      /* Get the current fragmentation threshold */
1436    case SIOCGIWFRAG:
1437      wrq->u.frag.value = (local->sparm.b5.a_frag_threshold[0] << 8)
1438	+ local->sparm.b5.a_frag_threshold[1];
1439#if WIRELESS_EXT > 8
1440      wrq->u.frag.disabled = (wrq->u.frag.value == 32767);
1441#endif /* WIRELESS_EXT > 8 */
1442      wrq->u.frag.fixed = 1;
1443      break;
1444
1445      /* Set the desired fragmentation threshold */
1446    case SIOCSIWFRAG:
1447    {
1448	int fthr = wrq->u.frag.value;
1449
1450      /* Reject if card is already initialised */
1451      if(local->card_status != CARD_AWAITING_PARAM)
1452	{
1453	  err = -EBUSY;
1454	  break;
1455	}
1456
1457	/* if(wrq->u.frag.fixed == 0) should complain */
1458#if WIRELESS_EXT > 8
1459	if(wrq->u.frag.disabled)
1460	    fthr = 32767;
1461	else
1462#endif /* WIRELESS_EXT > 8 */
1463	    if((fthr < 256) || (fthr > 2347)) /* To check out ! */
1464	    {
1465		err = -EINVAL;
1466		break;
1467	    }
1468	local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF;
1469	local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF;
1470    }
1471    break;
1472
1473#endif	/* WIRELESS_EXT > 7 */
1474#if WIRELESS_EXT > 8
1475
1476      /* Get the current mode of operation */
1477    case SIOCGIWMODE:
1478      if(local->sparm.b5.a_network_type)
1479	wrq->u.mode = IW_MODE_INFRA;
1480      else
1481	wrq->u.mode = IW_MODE_ADHOC;
1482      break;
1483
1484      /* Set the current mode of operation */
1485    case SIOCSIWMODE:
1486    {
1487	char card_mode = 1;
1488
1489      /* Reject if card is already initialised */
1490      if(local->card_status != CARD_AWAITING_PARAM)
1491	{
1492	  err = -EBUSY;
1493	  break;
1494	}
1495
1496	switch (wrq->u.mode)
1497	{
1498	case IW_MODE_ADHOC:
1499	    card_mode = 0;
1500	    // Fall through
1501	case IW_MODE_INFRA:
1502	    local->sparm.b5.a_network_type = card_mode;
1503	    break;
1504	default:
1505	    err = -EINVAL;
1506	}
1507    }
1508    break;
1509
1510#endif /* WIRELESS_EXT > 8 */
1511#if WIRELESS_EXT > 7
1512      /* ------------------ IWSPY SUPPORT ------------------ */
1513      /* Define the range (variations) of above parameters */
1514    case SIOCGIWRANGE:
1515      /* Basic checking... */
1516      if(wrq->u.data.pointer != (caddr_t) 0)
1517	{
1518	  struct iw_range	range;
1519	  memset((char *) &range, 0, sizeof(struct iw_range));
1520
1521	  /* Set the length (very important for backward compatibility) */
1522	  wrq->u.data.length = sizeof(struct iw_range);
1523
1524#if WIRELESS_EXT > 10
1525	  /* Set the Wireless Extension versions */
1526	  range.we_version_compiled = WIRELESS_EXT;
1527	  range.we_version_source = 9;
1528#endif /* WIRELESS_EXT > 10 */
1529
1530	  /* Set information in the range struct */
1531	  range.throughput = 1.1 * 1000 * 1000;	/* Put the right number here */
1532	  range.num_channels = hop_pattern_length[(int)country];
1533	  range.num_frequency = 0;
1534	  range.max_qual.qual = 0;
1535	  range.max_qual.level = 255;	/* What's the correct value ? */
1536	  range.max_qual.noise = 255;	/* Idem */
1537	  range.num_bitrates = 2;
1538	  range.bitrate[0] = 1000000;	/* 1 Mb/s */
1539	  range.bitrate[1] = 2000000;	/* 2 Mb/s */
1540
1541	  /* Copy structure to the user buffer */
1542	  if(copy_to_user(wrq->u.data.pointer, &range,
1543			  sizeof(struct iw_range)))
1544	    err = -EFAULT;
1545	}
1546      break;
1547
1548#ifdef WIRELESS_SPY
1549      /* Set addresses to spy */
1550    case SIOCSIWSPY:
1551      /* Check the number of addresses */
1552      if(wrq->u.data.length > IW_MAX_SPY)
1553	{
1554	  err = -E2BIG;
1555	  break;
1556	}
1557      local->spy_number = wrq->u.data.length;
1558
1559      /* If there is some addresses to copy */
1560      if(local->spy_number > 0)
1561	{
1562	  struct sockaddr	address[IW_MAX_SPY];
1563	  int			i;
1564
1565	  /* Copy addresses to the driver */
1566	  if(copy_from_user(address, wrq->u.data.pointer,
1567			    sizeof(struct sockaddr) * local->spy_number))
1568	    {
1569	      err = -EFAULT;
1570	      break;
1571	    }
1572
1573	  /* Copy addresses to the lp structure */
1574	  for(i = 0; i < local->spy_number; i++)
1575	    memcpy(local->spy_address[i], address[i].sa_data, ETH_ALEN);
1576
1577	  /* Reset structure... */
1578	  memset(local->spy_stat, 0x00, sizeof(iw_qual) * IW_MAX_SPY);
1579
1580#ifdef DEBUG_IOCTL_INFO
1581	  printk(KERN_DEBUG "SetSpy - Set of new addresses is :\n");
1582	  for(i = 0; i < local->spy_number; i++)
1583	    printk(KERN_DEBUG "%02X:%02X:%02X:%02X:%02X:%02X\n",
1584		   local->spy_address[i][0],
1585		   local->spy_address[i][1],
1586		   local->spy_address[i][2],
1587		   local->spy_address[i][3],
1588		   local->spy_address[i][4],
1589		   local->spy_address[i][5]);
1590#endif	/* DEBUG_IOCTL_INFO */
1591	}
1592      break;
1593
1594      /* Get the spy list and spy stats */
1595    case SIOCGIWSPY:
1596      /* Set the number of addresses */
1597      wrq->u.data.length = local->spy_number;
1598
1599      /* If the user want to have the addresses back... */
1600      if((local->spy_number > 0) && (wrq->u.data.pointer != (caddr_t) 0))
1601	{
1602	  struct sockaddr	address[IW_MAX_SPY];
1603	  int			i;
1604
1605	  /* Copy addresses from the lp structure */
1606	  for(i = 0; i < local->spy_number; i++)
1607	    {
1608	      memcpy(address[i].sa_data, local->spy_address[i], ETH_ALEN);
1609	      address[i].sa_family = ARPHRD_ETHER;
1610	    }
1611
1612	  /* Copy addresses to the user buffer */
1613	  if(copy_to_user(wrq->u.data.pointer, address,
1614		       sizeof(struct sockaddr) * local->spy_number))
1615	    {
1616	      err = -EFAULT;
1617	      break;
1618	    }
1619
1620	  /* Copy stats to the user buffer (just after) */
1621	  if(copy_to_user(wrq->u.data.pointer +
1622		       (sizeof(struct sockaddr) * local->spy_number),
1623		       local->spy_stat, sizeof(iw_qual) * local->spy_number))
1624	    {
1625	      err = -EFAULT;
1626	      break;
1627	    }
1628
1629	  /* Reset updated flags */
1630	  for(i = 0; i < local->spy_number; i++)
1631	    local->spy_stat[i].updated = 0x0;
1632	}	/* if(pointer != NULL) */
1633
1634      break;
1635#endif	/* WIRELESS_SPY */
1636
1637      /* ------------------ PRIVATE IOCTL ------------------ */
1638#ifndef SIOCIWFIRSTPRIV
1639#define SIOCIWFIRSTPRIV	SIOCDEVPRIVATE
1640#endif /* SIOCIWFIRSTPRIV */
1641#define SIOCSIPFRAMING	SIOCIWFIRSTPRIV		/* Set framing mode */
1642#define SIOCGIPFRAMING	SIOCIWFIRSTPRIV + 1	/* Get framing mode */
1643#define SIOCGIPCOUNTRY	SIOCIWFIRSTPRIV + 3	/* Get country code */
1644    case SIOCSIPFRAMING:
1645      if(!capable(CAP_NET_ADMIN))	/* For private IOCTLs, we need to check permissions */
1646	{
1647	  err = -EPERM;
1648	  break;
1649	}
1650      translate = *(wrq->u.name);	/* Set framing mode */
1651      break;
1652    case SIOCGIPFRAMING:
1653      *(wrq->u.name) = translate;
1654      break;
1655    case SIOCGIPCOUNTRY:
1656      *(wrq->u.name) = country;
1657      break;
1658    case SIOCGIWPRIV:
1659      /* Export our "private" intercace */
1660      if(wrq->u.data.pointer != (caddr_t) 0)
1661	{
1662	  struct iw_priv_args	priv[] =
1663	  {	/* cmd,		set_args,	get_args,	name */
1664	    { SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" },
1665	    { SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" },
1666	    { SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" },
1667	  };
1668	  /* Set the number of ioctl available */
1669	  wrq->u.data.length = 3;
1670	  /* Copy structure to the user buffer */
1671	  if(copy_to_user(wrq->u.data.pointer, (u_char *) priv,
1672		       sizeof(priv)))
1673	    err = -EFAULT;
1674	}
1675      break;
1676#endif	/* WIRELESS_EXT > 7 */
1677
1678
1679        default:
1680            DEBUG(0,"ray_dev_ioctl cmd = 0x%x\n", cmd);
1681            err = -EOPNOTSUPP;
1682    }
1683    return err;
1684} /* end ray_dev_ioctl */
1685/*===========================================================================*/
1686#if WIRELESS_EXT > 7	    /* If wireless extension exist in the kernel */
1687static iw_stats * ray_get_wireless_stats(struct net_device *	dev)
1688{
1689  ray_dev_t *	local = (ray_dev_t *) dev->priv;
1690  dev_link_t *link = local->finder;
1691  struct status *p = (struct status *)(local->sram + STATUS_BASE);
1692
1693  if(local == (ray_dev_t *) NULL)
1694    return (iw_stats *) NULL;
1695
1696  local->wstats.status = local->card_status;
1697#ifdef WIRELESS_SPY
1698  if((local->spy_number > 0) && (local->sparm.b5.a_network_type == 0))
1699    {
1700      /* Get it from the first node in spy list */
1701      local->wstats.qual.qual = local->spy_stat[0].qual;
1702      local->wstats.qual.level = local->spy_stat[0].level;
1703      local->wstats.qual.noise = local->spy_stat[0].noise;
1704      local->wstats.qual.updated = local->spy_stat[0].updated;
1705    }
1706#endif /* WIRELESS_SPY */
1707
1708  if((link->state & DEV_PRESENT)) {
1709    local->wstats.qual.noise = readb(&p->rxnoise);
1710    local->wstats.qual.updated |= 4;
1711  }
1712
1713  return &local->wstats;
1714} /* end ray_get_wireless_stats */
1715#endif	/* WIRELESS_EXT > 7 */
1716/*===========================================================================*/
1717static int ray_open(struct net_device *dev)
1718{
1719    dev_link_t *link;
1720    ray_dev_t *local = (ray_dev_t *)dev->priv;
1721
1722    MOD_INC_USE_COUNT;
1723
1724    DEBUG(1, "ray_open('%s')\n", dev->name);
1725
1726    for (link = dev_list; link; link = link->next)
1727        if (link->priv == dev) break;
1728    if (!DEV_OK(link)) {
1729        MOD_DEC_USE_COUNT;
1730        return -ENODEV;
1731    }
1732
1733    if (link->open == 0) local->num_multi = 0;
1734    link->open++;
1735
1736    /* If the card is not started, time to start it ! - Jean II */
1737    if(local->card_status == CARD_AWAITING_PARAM) {
1738	int i;
1739
1740	DEBUG(1,"ray_open: doing init now !\n");
1741
1742	/* Download startup parameters */
1743	if ( (i = dl_startup_params(dev)) < 0)
1744	  {
1745	    printk(KERN_INFO "ray_dev_init dl_startup_params failed - "
1746		   "returns 0x%x\n",i);
1747	    return -1;
1748	  }
1749     }
1750
1751    if (sniffer) netif_stop_queue(dev);
1752    else         netif_start_queue(dev);
1753
1754    DEBUG(2,"ray_open ending\n");
1755    return 0;
1756} /* end ray_open */
1757/*===========================================================================*/
1758static int ray_dev_close(struct net_device *dev)
1759{
1760    dev_link_t *link;
1761
1762    DEBUG(1, "ray_dev_close('%s')\n", dev->name);
1763
1764    for (link = dev_list; link; link = link->next)
1765        if (link->priv == dev) break;
1766    if (link == NULL)
1767        return -ENODEV;
1768
1769    link->open--;
1770    netif_stop_queue(dev);
1771    if (link->state & DEV_STALE_CONFIG)
1772	mod_timer(&link->release, jiffies + HZ/20);
1773
1774    /* In here, we should stop the hardware (stop card from beeing active)
1775     * and set local->card_status to CARD_AWAITING_PARAM, so that while the
1776     * card is closed we can chage its configuration.
1777     * Probably also need a COR reset to get sane state - Jean II */
1778
1779    MOD_DEC_USE_COUNT;
1780
1781    return 0;
1782} /* end ray_dev_close */
1783/*===========================================================================*/
1784static void ray_reset(struct net_device *dev) {
1785    DEBUG(1,"ray_reset entered\n");
1786    return;
1787}
1788/*===========================================================================*/
1789/* Cause a firmware interrupt if it is ready for one                         */
1790/* Return nonzero if not ready                                               */
1791static int interrupt_ecf(ray_dev_t *local, int ccs)
1792{
1793    int i = 50;
1794    dev_link_t *link = local->finder;
1795
1796    if (!(link->state & DEV_PRESENT)) {
1797        DEBUG(2,"ray_cs interrupt_ecf - device not present\n");
1798        return -1;
1799    }
1800    DEBUG(2,"interrupt_ecf(local=%p, ccs = 0x%x\n",local,ccs);
1801
1802    while ( i &&
1803            (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) & ECF_INTR_SET))
1804        i--;
1805    if (i == 0) {
1806        DEBUG(2,"ray_cs interrupt_ecf card not ready for interrupt\n");
1807        return -1;
1808    }
1809	/* Fill the mailbox, then kick the card */
1810    writeb(ccs, local->sram + SCB_BASE);
1811    writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET);
1812    return 0;
1813} /* interrupt_ecf */
1814/*===========================================================================*/
1815/* Get next free transmit CCS                                                */
1816/* Return - index of current tx ccs                                          */
1817static int get_free_tx_ccs(ray_dev_t *local)
1818{
1819    int i;
1820    struct ccs *pccs = (struct ccs *)(local->sram + CCS_BASE);
1821    dev_link_t *link = local->finder;
1822
1823    if (!(link->state & DEV_PRESENT)) {
1824        DEBUG(2,"ray_cs get_free_tx_ccs - device not present\n");
1825        return ECARDGONE;
1826    }
1827
1828    if (test_and_set_bit(0,&local->tx_ccs_lock)) {
1829        DEBUG(1,"ray_cs tx_ccs_lock busy\n");
1830        return ECCSBUSY;
1831    }
1832
1833    for (i=0; i < NUMBER_OF_TX_CCS; i++) {
1834        if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) {
1835            writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status);
1836            writeb(CCS_END_LIST, &(pccs+i)->link);
1837			local->tx_ccs_lock = 0;
1838            return i;
1839        }
1840    }
1841	local->tx_ccs_lock = 0;
1842    DEBUG(2,"ray_cs ERROR no free tx CCS for raylink card\n");
1843    return ECCSFULL;
1844} /* get_free_tx_ccs */
1845/*===========================================================================*/
1846/* Get next free CCS                                                         */
1847/* Return - index of current ccs                                             */
1848static int get_free_ccs(ray_dev_t *local)
1849{
1850    int i;
1851    struct ccs *pccs = (struct ccs *)(local->sram + CCS_BASE);
1852    dev_link_t *link = local->finder;
1853
1854    if (!(link->state & DEV_PRESENT)) {
1855        DEBUG(2,"ray_cs get_free_ccs - device not present\n");
1856        return ECARDGONE;
1857    }
1858    if (test_and_set_bit(0,&local->ccs_lock)) {
1859        DEBUG(1,"ray_cs ccs_lock busy\n");
1860        return ECCSBUSY;
1861    }
1862
1863    for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) {
1864        if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) {
1865            writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status);
1866            writeb(CCS_END_LIST, &(pccs+i)->link);
1867			local->ccs_lock = 0;
1868            return i;
1869        }
1870    }
1871	local->ccs_lock = 0;
1872    DEBUG(1,"ray_cs ERROR no free CCS for raylink card\n");
1873    return ECCSFULL;
1874} /* get_free_ccs */
1875/*===========================================================================*/
1876static void authenticate_timeout(u_long data)
1877{
1878    ray_dev_t *local = (ray_dev_t *)data;
1879    del_timer(&local->timer);
1880    printk(KERN_INFO "ray_cs Authentication with access point failed"
1881       " - timeout\n");
1882    join_net((u_long)local);
1883}
1884/*===========================================================================*/
1885static int asc_to_int(char a)
1886{
1887    if (a < '0') return -1;
1888    if (a <= '9') return (a - '0');
1889    if (a < 'A') return -1;
1890    if (a <= 'F') return (10 + a - 'A');
1891    if (a < 'a') return -1;
1892    if (a <= 'f') return (10 + a - 'a');
1893    return -1;
1894}
1895/*===========================================================================*/
1896static int parse_addr(char *in_str, UCHAR *out)
1897{
1898    int len;
1899    int i,j,k;
1900    int status;
1901
1902    if (in_str == NULL) return 0;
1903    if ((len = strlen(in_str)) < 2) return 0;
1904    memset(out, 0, ADDRLEN);
1905
1906    status = 1;
1907    j = len - 1;
1908    if (j > 12) j = 12;
1909    i = 5;
1910
1911    while (j > 0)
1912    {
1913        if ((k = asc_to_int(in_str[j--])) != -1) out[i] = k;
1914        else return 0;
1915
1916        if (j == 0) break;
1917        if ((k = asc_to_int(in_str[j--])) != -1) out[i] += k << 4;
1918        else return 0;
1919        if (!i--) break;
1920    }
1921    return status;
1922}
1923/*===========================================================================*/
1924static struct net_device_stats *ray_get_stats(struct net_device *dev)
1925{
1926    ray_dev_t *local = (ray_dev_t *)dev->priv;
1927    dev_link_t *link = local->finder;
1928    struct status *p = (struct status *)(local->sram + STATUS_BASE);
1929    if (!(link->state & DEV_PRESENT)) {
1930        DEBUG(2,"ray_cs net_device_stats - device not present\n");
1931        return &local->stats;
1932    }
1933    if (readb(&p->mrx_overflow_for_host))
1934    {
1935        local->stats.rx_over_errors += ntohs(readb(&p->mrx_overflow));
1936        writeb(0,&p->mrx_overflow);
1937        writeb(0,&p->mrx_overflow_for_host);
1938    }
1939    if (readb(&p->mrx_checksum_error_for_host))
1940    {
1941        local->stats.rx_crc_errors += ntohs(readb(&p->mrx_checksum_error));
1942        writeb(0,&p->mrx_checksum_error);
1943        writeb(0,&p->mrx_checksum_error_for_host);
1944    }
1945    if (readb(&p->rx_hec_error_for_host))
1946    {
1947        local->stats.rx_frame_errors += ntohs(readb(&p->rx_hec_error));
1948        writeb(0,&p->rx_hec_error);
1949        writeb(0,&p->rx_hec_error_for_host);
1950    }
1951    return &local->stats;
1952}
1953/*===========================================================================*/
1954static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len)
1955{
1956    ray_dev_t *local = (ray_dev_t *)dev->priv;
1957    dev_link_t *link = local->finder;
1958    int ccsindex;
1959    int i;
1960    struct ccs *pccs;
1961
1962    if (!(link->state & DEV_PRESENT)) {
1963        DEBUG(2,"ray_update_parm - device not present\n");
1964        return;
1965    }
1966
1967    if ((ccsindex = get_free_ccs(local)) < 0)
1968    {
1969        DEBUG(0,"ray_update_parm - No free ccs\n");
1970        return;
1971    }
1972    pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
1973    writeb(CCS_UPDATE_PARAMS, &pccs->cmd);
1974    writeb(objid, &pccs->var.update_param.object_id);
1975    writeb(1, &pccs->var.update_param.number_objects);
1976    writeb(0, &pccs->var.update_param.failure_cause);
1977    for (i=0; i<len; i++) {
1978        writeb(value[i], local->sram + HOST_TO_ECF_BASE);
1979    }
1980    /* Interrupt the firmware to process the command */
1981    if (interrupt_ecf(local, ccsindex)) {
1982        DEBUG(0,"ray_cs associate failed - ECF not ready for intr\n");
1983        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
1984    }
1985}
1986/*===========================================================================*/
1987static void ray_update_multi_list(struct net_device *dev, int all)
1988{
1989    struct dev_mc_list *dmi, **dmip;
1990    int ccsindex;
1991    struct ccs *pccs;
1992    int i = 0;
1993    ray_dev_t *local = (ray_dev_t *)dev->priv;
1994    dev_link_t *link = local->finder;
1995    UCHAR *p = local->sram + HOST_TO_ECF_BASE;
1996
1997    if (!(link->state & DEV_PRESENT)) {
1998        DEBUG(2,"ray_update_multi_list - device not present\n");
1999        return;
2000    }
2001    else
2002        DEBUG(2,"ray_update_multi_list(%p)\n",dev);
2003    if ((ccsindex = get_free_ccs(local)) < 0)
2004    {
2005        DEBUG(1,"ray_update_multi - No free ccs\n");
2006        return;
2007    }
2008    pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
2009    writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd);
2010
2011    if (all) {
2012        writeb(0xff, &pccs->var);
2013        local->num_multi = 0xff;
2014    }
2015    else {
2016        /* Copy the kernel's list of MC addresses to card */
2017        for (dmip=&dev->mc_list; (dmi=*dmip)!=NULL; dmip=&dmi->next) {
2018            memcpy_toio(p, dmi->dmi_addr, ETH_ALEN);
2019            DEBUG(1,"ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",dmi->dmi_addr[0],dmi->dmi_addr[1],dmi->dmi_addr[2],dmi->dmi_addr[3],dmi->dmi_addr[4],dmi->dmi_addr[5]);
2020            p += ETH_ALEN;
2021            i++;
2022        }
2023        if (i > 256/ADDRLEN) i = 256/ADDRLEN;
2024        writeb((UCHAR)i, &pccs->var);
2025        DEBUG(1,"ray_cs update_multi %d addresses in list\n", i);
2026        /* Interrupt the firmware to process the command */
2027        local->num_multi = i;
2028    }
2029    if (interrupt_ecf(local, ccsindex)) {
2030        DEBUG(1,"ray_cs update_multi failed - ECF not ready for intr\n");
2031        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
2032    }
2033} /* end ray_update_multi_list */
2034/*===========================================================================*/
2035static void set_multicast_list(struct net_device *dev)
2036{
2037    ray_dev_t *local = (ray_dev_t *)dev->priv;
2038    UCHAR promisc;
2039
2040    DEBUG(2,"ray_cs set_multicast_list(%p)\n",dev);
2041
2042    if (dev->flags & IFF_PROMISC)
2043    {
2044        if (local->sparm.b5.a_promiscuous_mode == 0) {
2045            DEBUG(1,"ray_cs set_multicast_list promisc on\n");
2046            local->sparm.b5.a_promiscuous_mode = 1;
2047            promisc = 1;
2048            ray_update_parm(dev,  OBJID_promiscuous_mode, \
2049                            &promisc, sizeof(promisc));
2050        }
2051    }
2052    else {
2053        if (local->sparm.b5.a_promiscuous_mode == 1) {
2054            DEBUG(1,"ray_cs set_multicast_list promisc off\n");
2055            local->sparm.b5.a_promiscuous_mode = 0;
2056            promisc = 0;
2057            ray_update_parm(dev,  OBJID_promiscuous_mode, \
2058                            &promisc, sizeof(promisc));
2059        }
2060    }
2061
2062    if (dev->flags & IFF_ALLMULTI) ray_update_multi_list(dev, 1);
2063    else
2064    {
2065        if (local->num_multi != dev->mc_count) ray_update_multi_list(dev, 0);
2066    }
2067} /* end set_multicast_list */
2068/*=============================================================================
2069 * All routines below here are run at interrupt time.
2070=============================================================================*/
2071static void ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
2072{
2073    struct net_device *dev = (struct net_device *)dev_id;
2074    dev_link_t *link;
2075    ray_dev_t *local;
2076    struct ccs *pccs;
2077    struct rcs *prcs;
2078    UCHAR rcsindex;
2079    UCHAR tmp;
2080    UCHAR cmd;
2081    UCHAR status;
2082
2083    if (dev == NULL) /* Note that we want interrupts with dev->start == 0 */
2084    return;
2085
2086    DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev);
2087
2088    local = (ray_dev_t *)dev->priv;
2089    link = (dev_link_t *)local->finder;
2090    if ( ! (link->state & DEV_PRESENT) || link->state & DEV_SUSPEND ) {
2091        DEBUG(2,"ray_cs interrupt from device not present or suspended.\n");
2092        return;
2093    }
2094    rcsindex = readb(&((struct scb *)(local->sram))->rcs_index);
2095
2096    if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS))
2097    {
2098        DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex);
2099        clear_interrupt(local);
2100        return;
2101    }
2102    if (rcsindex < NUMBER_OF_CCS) /* If it's a returned CCS */
2103    {
2104        pccs = ((struct ccs *) (local->sram + CCS_BASE)) + rcsindex;
2105        cmd = readb(&pccs->cmd);
2106        status = readb(&pccs->buffer_status);
2107        switch (cmd)
2108        {
2109        case CCS_DOWNLOAD_STARTUP_PARAMS: /* Happens in firmware someday */
2110            del_timer(&local->timer);
2111            if (status == CCS_COMMAND_COMPLETE) {
2112                DEBUG(1,"ray_cs interrupt download_startup_parameters OK\n");
2113            }
2114            else {
2115                DEBUG(1,"ray_cs interrupt download_startup_parameters fail\n");
2116            }
2117            break;
2118        case CCS_UPDATE_PARAMS:
2119            DEBUG(1,"ray_cs interrupt update params done\n");
2120            if (status != CCS_COMMAND_COMPLETE) {
2121                tmp = readb(&pccs->var.update_param.failure_cause);
2122            DEBUG(0,"ray_cs interrupt update params failed - reason %d\n",tmp);
2123            }
2124            break;
2125        case CCS_REPORT_PARAMS:
2126            DEBUG(1,"ray_cs interrupt report params done\n");
2127            break;
2128        case CCS_UPDATE_MULTICAST_LIST: /* Note that this CCS isn't returned */
2129            DEBUG(1,"ray_cs interrupt CCS Update Multicast List done\n");
2130            break;
2131        case CCS_UPDATE_POWER_SAVINGS_MODE:
2132            DEBUG(1,"ray_cs interrupt update power save mode done\n");
2133            break;
2134        case CCS_START_NETWORK:
2135        case CCS_JOIN_NETWORK:
2136            if (status == CCS_COMMAND_COMPLETE) {
2137                if (readb(&pccs->var.start_network.net_initiated) == 1) {
2138                    DEBUG(0,"ray_cs interrupt network \"%s\" started\n",\
2139                          local->sparm.b4.a_current_ess_id);
2140                }
2141                else {
2142                    DEBUG(0,"ray_cs interrupt network \"%s\" joined\n",\
2143                          local->sparm.b4.a_current_ess_id);
2144                }
2145                memcpy_fromio(&local->bss_id,pccs->var.start_network.bssid,ADDRLEN);
2146
2147                if (local->fw_ver == 0x55) local->net_default_tx_rate = 3;
2148                else local->net_default_tx_rate =
2149                         readb(&pccs->var.start_network.net_default_tx_rate);
2150                local->encryption = readb(&pccs->var.start_network.encryption);
2151                if (!sniffer && (local->net_type == INFRA)
2152                    && !(local->sparm.b4.a_acting_as_ap_status)) {
2153                    authenticate(local);
2154                }
2155                local->card_status = CARD_ACQ_COMPLETE;
2156            }
2157            else {
2158                local->card_status = CARD_ACQ_FAILED;
2159
2160                del_timer(&local->timer);
2161                local->timer.expires = jiffies + HZ*5;
2162                local->timer.data = (long)local;
2163                if (status == CCS_START_NETWORK) {
2164                    DEBUG(0,"ray_cs interrupt network \"%s\" start failed\n",\
2165                          local->sparm.b4.a_current_ess_id);
2166                    local->timer.function = &start_net;
2167                }
2168                else {
2169                    DEBUG(0,"ray_cs interrupt network \"%s\" join failed\n",\
2170                          local->sparm.b4.a_current_ess_id);
2171                    local->timer.function = &join_net;
2172                }
2173                add_timer(&local->timer);
2174            }
2175            break;
2176        case CCS_START_ASSOCIATION:
2177            if (status == CCS_COMMAND_COMPLETE) {
2178                local->card_status = CARD_ASSOC_COMPLETE;
2179                DEBUG(0,"ray_cs association successful\n");
2180            }
2181            else
2182            {
2183                DEBUG(0,"ray_cs association failed,\n");
2184                local->card_status = CARD_ASSOC_FAILED;
2185                join_net((u_long)local);
2186            }
2187            break;
2188        case CCS_TX_REQUEST:
2189            if (status == CCS_COMMAND_COMPLETE) {
2190                DEBUG(3,"ray_cs interrupt tx request complete\n");
2191            }
2192            else {
2193                DEBUG(1,"ray_cs interrupt tx request failed\n");
2194            }
2195            if (!sniffer) netif_start_queue(dev);
2196            netif_wake_queue(dev);
2197            break;
2198        case CCS_TEST_MEMORY:
2199            DEBUG(1,"ray_cs interrupt mem test done\n");
2200            break;
2201        case CCS_SHUTDOWN:
2202            DEBUG(1,"ray_cs interrupt Unexpected CCS returned - Shutdown\n");
2203            break;
2204        case CCS_DUMP_MEMORY:
2205            DEBUG(1,"ray_cs interrupt dump memory done\n");
2206            break;
2207        case CCS_START_TIMER:
2208            DEBUG(2,"ray_cs interrupt DING - raylink timer expired\n");
2209            break;
2210        default:
2211            DEBUG(1,"ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",\
2212                  rcsindex, cmd);
2213        }
2214        writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
2215    }
2216    else /* It's an RCS */
2217    {
2218        prcs = ((struct rcs *)(local->sram + CCS_BASE)) + rcsindex;
2219
2220        switch (readb(&prcs->interrupt_id))
2221        {
2222        case PROCESS_RX_PACKET:
2223            ray_rx(dev, local, prcs);
2224            break;
2225        case REJOIN_NET_COMPLETE:
2226            DEBUG(1,"ray_cs interrupt rejoin net complete\n");
2227            local->card_status = CARD_ACQ_COMPLETE;
2228            /* do we need to clear tx buffers CCS's? */
2229            if (local->sparm.b4.a_network_type == ADHOC) {
2230                if (!sniffer) netif_start_queue(dev);
2231            }
2232            else {
2233                memcpy_fromio(&local->bss_id, prcs->var.rejoin_net_complete.bssid, ADDRLEN);
2234                DEBUG(1,"ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n",\
2235                      local->bss_id[0], local->bss_id[1], local->bss_id[2],\
2236                      local->bss_id[3], local->bss_id[4], local->bss_id[5]);
2237                if (!sniffer) authenticate(local);
2238            }
2239            break;
2240        case ROAMING_INITIATED:
2241            DEBUG(1,"ray_cs interrupt roaming initiated\n");
2242            netif_stop_queue(dev);
2243            local->card_status = CARD_DOING_ACQ;
2244            break;
2245        case JAPAN_CALL_SIGN_RXD:
2246            DEBUG(1,"ray_cs interrupt japan call sign rx\n");
2247            break;
2248        default:
2249            DEBUG(1,"ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",\
2250                  rcsindex, (unsigned int) readb(&prcs->interrupt_id));
2251            break;
2252        }
2253        writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
2254    }
2255    clear_interrupt(local);
2256} /* ray_interrupt */
2257/*===========================================================================*/
2258static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs)
2259{
2260    int rx_len;
2261    unsigned int pkt_addr;
2262    UCHAR *pmsg;
2263    DEBUG(4,"ray_rx process rx packet\n");
2264
2265    /* Calculate address of packet within Rx buffer */
2266    pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
2267                + readb(&prcs->var.rx_packet.rx_data_ptr[1])) & RX_BUFF_END;
2268    /* Length of first packet fragment */
2269    rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8)
2270        + readb(&prcs->var.rx_packet.rx_data_length[1]);
2271
2272    local->last_rsl = readb(&prcs->var.rx_packet.rx_sig_lev);
2273    pmsg = local->rmem + pkt_addr;
2274    switch(readb(pmsg))
2275    {
2276    case DATA_TYPE:
2277        DEBUG(4,"ray_rx data type\n");
2278        rx_data(dev, prcs, pkt_addr, rx_len);
2279        break;
2280    case AUTHENTIC_TYPE:
2281        DEBUG(4,"ray_rx authentic type\n");
2282        if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
2283        else rx_authenticate(local, prcs, pkt_addr, rx_len);
2284        break;
2285    case DEAUTHENTIC_TYPE:
2286        DEBUG(4,"ray_rx deauth type\n");
2287        if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
2288        else rx_deauthenticate(local, prcs, pkt_addr, rx_len);
2289        break;
2290    case NULL_MSG_TYPE:
2291        DEBUG(3,"ray_cs rx NULL msg\n");
2292        break;
2293    case BEACON_TYPE:
2294        DEBUG(4,"ray_rx beacon type\n");
2295        if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
2296
2297        copy_from_rx_buff(local, (UCHAR *)&local->last_bcn, pkt_addr,
2298                          rx_len < sizeof(struct beacon_rx) ?
2299                          rx_len : sizeof(struct beacon_rx));
2300
2301	local->beacon_rxed = 1;
2302        /* Get the statistics so the card counters never overflow */
2303        ray_get_stats(dev);
2304            break;
2305    default:
2306        DEBUG(0,"ray_cs unknown pkt type %2x\n", (unsigned int) readb(pmsg));
2307        break;
2308    }
2309
2310} /* end ray_rx */
2311/*===========================================================================*/
2312static void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr,
2313             int rx_len)
2314{
2315    struct sk_buff *skb = NULL;
2316    struct rcs *prcslink = prcs;
2317    ray_dev_t *local = dev->priv;
2318    UCHAR *rx_ptr;
2319    int total_len;
2320    int tmp;
2321#ifdef WIRELESS_SPY
2322    int siglev = local->last_rsl;
2323    u_char linksrcaddr[ETH_ALEN];	/* Other end of the wireless link */
2324#endif
2325
2326    if (!sniffer) {
2327        if (translate) {
2328/* TBD length needs fixing for translated header */
2329            if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
2330                rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN))
2331            {
2332                DEBUG(0,"ray_cs invalid packet length %d received \n",rx_len);
2333                return;
2334            }
2335        }
2336        else /* encapsulated ethernet */ {
2337            if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
2338                rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN))
2339            {
2340                DEBUG(0,"ray_cs invalid packet length %d received \n",rx_len);
2341                return;
2342            }
2343        }
2344    }
2345    DEBUG(4,"ray_cs rx_data packet\n");
2346    /* If fragmented packet, verify sizes of fragments add up */
2347    if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
2348        DEBUG(1,"ray_cs rx'ed fragment\n");
2349        tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
2350            +  readb(&prcs->var.rx_packet.totalpacketlength[1]);
2351        total_len = tmp;
2352        prcslink = prcs;
2353        do {
2354            tmp -= (readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8)
2355                +   readb(&prcslink->var.rx_packet.rx_data_length[1]);
2356            if (readb(&prcslink->var.rx_packet.next_frag_rcs_index) == 0xFF
2357                || tmp < 0) break;
2358            prcslink = ((struct rcs *)(local->sram + CCS_BASE))
2359                + readb(&prcslink->link_field);
2360        } while (1);
2361
2362        if (tmp < 0)
2363        {
2364            DEBUG(0,"ray_cs rx_data fragment lengths don't add up\n");
2365            local->stats.rx_dropped++;
2366            release_frag_chain(local, prcs);
2367            return;
2368        }
2369    }
2370    else { /* Single unfragmented packet */
2371        total_len = rx_len;
2372    }
2373
2374    skb = dev_alloc_skb( total_len+5 );
2375    if (skb == NULL)
2376    {
2377        DEBUG(0,"ray_cs rx_data could not allocate skb\n");
2378        local->stats.rx_dropped++;
2379        if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF)
2380            release_frag_chain(local, prcs);
2381        return;
2382    }
2383    skb_reserve( skb, 2);   /* Align IP on 16 byte (TBD check this)*/
2384    skb->dev = dev;
2385
2386    DEBUG(4,"ray_cs rx_data total_len = %x, rx_len = %x\n",total_len,rx_len);
2387
2388/************************/
2389    /* Reserve enough room for the whole damn packet. */
2390    rx_ptr = skb_put( skb, total_len);
2391    /* Copy the whole packet to sk_buff */
2392    rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len);
2393    /* Get source address */
2394#ifdef WIRELESS_SPY
2395    memcpy(linksrcaddr, ((struct mac_header *)skb->data)->addr_2, ETH_ALEN);
2396#endif
2397    /* Now, deal with encapsulation/translation/sniffer */
2398    if (!sniffer) {
2399        if (!translate) {
2400            /* Encapsulated ethernet, so just lop off 802.11 MAC header */
2401/* TBD reserve            skb_reserve( skb, RX_MAC_HEADER_LENGTH); */
2402            skb_pull( skb, RX_MAC_HEADER_LENGTH);
2403        }
2404        else {
2405            /* Do translation */
2406            untranslate(local, skb, total_len);
2407        }
2408    }
2409    else
2410    {  /* sniffer mode, so just pass whole packet */  };
2411
2412/************************/
2413    /* Now pick up the rest of the fragments if any */
2414    tmp = 17;
2415    if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
2416        prcslink = prcs;
2417        DEBUG(1,"ray_cs rx_data in fragment loop\n");
2418        do {
2419            prcslink = ((struct rcs *)(local->sram + CCS_BASE))
2420                + readb(&prcslink->var.rx_packet.next_frag_rcs_index);
2421            rx_len = (( readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8)
2422                      + readb(&prcslink->var.rx_packet.rx_data_length[1]))
2423                & RX_BUFF_END;
2424            pkt_addr = (( readb(&prcslink->var.rx_packet.rx_data_ptr[0]) << 8)
2425                        + readb(&prcslink->var.rx_packet.rx_data_ptr[1]))
2426                & RX_BUFF_END;
2427
2428            rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr, rx_len);
2429
2430        } while (tmp-- &&
2431                 readb(&prcslink->var.rx_packet.next_frag_rcs_index) != 0xFF);
2432        release_frag_chain(local, prcs);
2433    }
2434
2435    skb->protocol = eth_type_trans(skb,dev);
2436    netif_rx(skb);
2437    dev->last_rx = jiffies;
2438    local->stats.rx_packets++;
2439    local->stats.rx_bytes += total_len;
2440
2441    /* Gather signal strength per address */
2442#ifdef WIRELESS_SPY
2443    /* For the Access Point or the node having started the ad-hoc net
2444     * note : ad-hoc work only in some specific configurations, but we
2445     * kludge in ray_get_wireless_stats... */
2446    if(!memcmp(linksrcaddr, local->bss_id, ETH_ALEN))
2447      {
2448	/* Update statistics */
2449	/*local->wstats.qual.qual = none ? */
2450	local->wstats.qual.level = siglev;
2451	/*local->wstats.qual.noise = none ? */
2452	local->wstats.qual.updated = 0x2;
2453      }
2454    /* Now, for the addresses in the spy list */
2455    {
2456      int	i;
2457      /* Look all addresses */
2458      for(i = 0; i < local->spy_number; i++)
2459	/* If match */
2460	if(!memcmp(linksrcaddr, local->spy_address[i], ETH_ALEN))
2461	  {
2462	    /* Update statistics */
2463	    /*local->spy_stat[i].qual = none ? */
2464	    local->spy_stat[i].level = siglev;
2465	    /*local->spy_stat[i].noise = none ? */
2466	    local->spy_stat[i].updated = 0x2;
2467	  }
2468    }
2469#endif	/* WIRELESS_SPY */
2470} /* end rx_data */
2471/*===========================================================================*/
2472static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
2473{
2474    snaphdr_t *psnap = (snaphdr_t *)(skb->data + RX_MAC_HEADER_LENGTH);
2475    struct mac_header *pmac = (struct mac_header *)skb->data;
2476    unsigned short type = *(unsigned short *)psnap->ethertype;
2477    unsigned int xsap = *(unsigned int *)psnap & 0x00ffffff;
2478    unsigned int org = (*(unsigned int *)psnap->org) & 0x00ffffff;
2479    int delta;
2480    struct ethhdr *peth;
2481    UCHAR srcaddr[ADDRLEN];
2482    UCHAR destaddr[ADDRLEN];
2483
2484    if (pmac->frame_ctl_2 & FC2_FROM_DS) {
2485	if (pmac->frame_ctl_2 & FC2_TO_DS) { /* AP to AP */
2486	    memcpy(destaddr, pmac->addr_3, ADDRLEN);
2487	    memcpy(srcaddr, ((unsigned char *)pmac->addr_3) + ADDRLEN, ADDRLEN);
2488	} else { /* AP to terminal */
2489	    memcpy(destaddr, pmac->addr_1, ADDRLEN);
2490	    memcpy(srcaddr, pmac->addr_3, ADDRLEN);
2491	}
2492    } else { /* Terminal to AP */
2493	if (pmac->frame_ctl_2 & FC2_TO_DS) {
2494	    memcpy(destaddr, pmac->addr_3, ADDRLEN);
2495	    memcpy(srcaddr, pmac->addr_2, ADDRLEN);
2496	} else { /* Adhoc */
2497	    memcpy(destaddr, pmac->addr_1, ADDRLEN);
2498	    memcpy(srcaddr, pmac->addr_2, ADDRLEN);
2499	}
2500    }
2501
2502#ifdef PCMCIA_DEBUG
2503    if (pc_debug > 3) {
2504    int i;
2505    printk(KERN_DEBUG "skb->data before untranslate");
2506    for (i=0;i<64;i++)
2507        printk("%02x ",skb->data[i]);
2508    printk("\n" KERN_DEBUG "type = %08x, xsap = %08x, org = %08x\n",
2509           type,xsap,org);
2510    printk(KERN_DEBUG "untranslate skb->data = %p\n",skb->data);
2511    }
2512#endif
2513
2514    if ( xsap != SNAP_ID) {
2515        /* not a snap type so leave it alone */
2516        DEBUG(3,"ray_cs untranslate NOT SNAP %x\n", *(unsigned int *)psnap & 0x00ffffff);
2517
2518        delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2519        peth = (struct ethhdr *)(skb->data + delta);
2520        peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
2521    }
2522    else { /* Its a SNAP */
2523        if (org == BRIDGE_ENCAP) { /* EtherII and nuke the LLC  */
2524        DEBUG(3,"ray_cs untranslate Bridge encap\n");
2525            delta = RX_MAC_HEADER_LENGTH
2526                + sizeof(struct snaphdr_t) - ETH_HLEN;
2527            peth = (struct ethhdr *)(skb->data + delta);
2528            peth->h_proto = type;
2529        }
2530        else {
2531            if (org == RFC1042_ENCAP) {
2532                switch (type) {
2533                case RAY_IPX_TYPE:
2534                case APPLEARP_TYPE:
2535                    DEBUG(3,"ray_cs untranslate RFC IPX/AARP\n");
2536                    delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2537                    peth = (struct ethhdr *)(skb->data + delta);
2538                    peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
2539                    break;
2540                default:
2541                    DEBUG(3,"ray_cs untranslate RFC default\n");
2542                    delta = RX_MAC_HEADER_LENGTH +
2543                        sizeof(struct snaphdr_t) - ETH_HLEN;
2544                    peth = (struct ethhdr *)(skb->data + delta);
2545                    peth->h_proto = type;
2546                    break;
2547                }
2548            }
2549            else {
2550                printk("ray_cs untranslate very confused by packet\n");
2551                delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
2552                peth = (struct ethhdr *)(skb->data + delta);
2553                peth->h_proto = type;
2554            }
2555        }
2556    }
2557/* TBD reserve  skb_reserve(skb, delta); */
2558    skb_pull(skb, delta);
2559    DEBUG(3,"untranslate after skb_pull(%d), skb->data = %p\n",delta,skb->data);
2560    memcpy(peth->h_dest, destaddr, ADDRLEN);
2561    memcpy(peth->h_source, srcaddr, ADDRLEN);
2562#ifdef PCMCIA_DEBUG
2563    if (pc_debug > 3) {
2564    int i;
2565    printk(KERN_DEBUG "skb->data after untranslate:");
2566    for (i=0;i<64;i++)
2567        printk("%02x ",skb->data[i]);
2568    printk("\n");
2569    }
2570#endif
2571} /* end untranslate */
2572/*===========================================================================*/
2573/* Copy data from circular receive buffer to PC memory.
2574 * dest     = destination address in PC memory
2575 * pkt_addr = source address in receive buffer
2576 * len      = length of packet to copy
2577 */
2578static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int length)
2579{
2580    int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1);
2581    if (wrap_bytes <= 0)
2582    {
2583        memcpy_fromio(dest,local->rmem + pkt_addr,length);
2584    }
2585    else /* Packet wrapped in circular buffer */
2586    {
2587        memcpy_fromio(dest,local->rmem+pkt_addr,length - wrap_bytes);
2588        memcpy_fromio(dest + length - wrap_bytes, local->rmem, wrap_bytes);
2589    }
2590    return length;
2591}
2592/*===========================================================================*/
2593static void release_frag_chain(ray_dev_t *local, struct rcs* prcs)
2594{
2595    struct rcs *prcslink = prcs;
2596    int tmp = 17;
2597    unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index);
2598
2599    while (tmp--) {
2600        writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
2601        if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
2602            DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex);
2603            break;
2604        }
2605        prcslink = ((struct rcs *)(local->sram + CCS_BASE)) + rcsindex;
2606        rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index);
2607    }
2608    writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
2609}
2610/*===========================================================================*/
2611static void authenticate(ray_dev_t *local)
2612{
2613    dev_link_t *link = local->finder;
2614    DEBUG(0,"ray_cs Starting authentication.\n");
2615    if (!(link->state & DEV_PRESENT)) {
2616        DEBUG(2,"ray_cs authenticate - device not present\n");
2617        return;
2618    }
2619
2620    del_timer(&local->timer);
2621    if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
2622        local->timer.function = &join_net;
2623    }
2624    else {
2625        local->timer.function = &authenticate_timeout;
2626    }
2627    local->timer.expires = jiffies + HZ*2;
2628    local->timer.data = (long)local;
2629    add_timer(&local->timer);
2630    local->authentication_state = AWAITING_RESPONSE;
2631} /* end authenticate */
2632/*===========================================================================*/
2633static void rx_authenticate(ray_dev_t *local, struct rcs *prcs,
2634                     unsigned int pkt_addr, int rx_len)
2635{
2636    UCHAR buff[256];
2637    struct rx_msg *msg = (struct rx_msg *)buff;
2638
2639    del_timer(&local->timer);
2640
2641    copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
2642    /* if we are trying to get authenticated */
2643    if (local->sparm.b4.a_network_type == ADHOC) {
2644        DEBUG(1,"ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n", msg->var[0],msg->var[1],msg->var[2],msg->var[3],msg->var[4],msg->var[5]);
2645        if (msg->var[2] == 1) {
2646                    DEBUG(0,"ray_cs Sending authentication response.\n");
2647                    if (!build_auth_frame (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
2648                        local->authentication_state = NEED_TO_AUTH;
2649                        memcpy(local->auth_id, msg->mac.addr_2, ADDRLEN);
2650                    }
2651        }
2652    }
2653    else /* Infrastructure network */
2654    {
2655        if (local->authentication_state == AWAITING_RESPONSE) {
2656            /* Verify authentication sequence #2 and success */
2657            if (msg->var[2] == 2) {
2658                if ((msg->var[3] | msg->var[4]) == 0) {
2659                    DEBUG(1,"Authentication successful\n");
2660                    local->card_status = CARD_AUTH_COMPLETE;
2661                    associate(local);
2662                    local->authentication_state = AUTHENTICATED;
2663                }
2664                else {
2665                    DEBUG(0,"Authentication refused\n");
2666                    local->card_status = CARD_AUTH_REFUSED;
2667                    join_net((u_long)local);
2668                    local->authentication_state = UNAUTHENTICATED;
2669                }
2670            }
2671        }
2672    }
2673
2674} /* end rx_authenticate */
2675/*===========================================================================*/
2676static void associate(ray_dev_t *local)
2677{
2678    struct ccs *pccs;
2679    dev_link_t *link = local->finder;
2680    struct net_device *dev = link->priv;
2681    int ccsindex;
2682    if (!(link->state & DEV_PRESENT)) {
2683        DEBUG(2,"ray_cs associate - device not present\n");
2684        return;
2685    }
2686    /* If no tx buffers available, return*/
2687    if ((ccsindex = get_free_ccs(local)) < 0)
2688    {
2689/* TBD should never be here but... what if we are? */
2690        DEBUG(1,"ray_cs associate - No free ccs\n");
2691        return;
2692    }
2693    DEBUG(1,"ray_cs Starting association with access point\n");
2694    pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
2695    /* fill in the CCS */
2696    writeb(CCS_START_ASSOCIATION, &pccs->cmd);
2697    /* Interrupt the firmware to process the command */
2698    if (interrupt_ecf(local, ccsindex)) {
2699        DEBUG(1,"ray_cs associate failed - ECF not ready for intr\n");
2700        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
2701
2702        del_timer(&local->timer);
2703        local->timer.expires = jiffies + HZ*2;
2704        local->timer.data = (long)local;
2705        local->timer.function = &join_net;
2706        add_timer(&local->timer);
2707        local->card_status = CARD_ASSOC_FAILED;
2708        return;
2709    }
2710    if (!sniffer) netif_start_queue(dev);
2711
2712} /* end associate */
2713/*===========================================================================*/
2714static void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs,
2715                       unsigned int pkt_addr, int rx_len)
2716{
2717/*  UCHAR buff[256];
2718    struct rx_msg *msg = (struct rx_msg *)buff;
2719*/
2720    DEBUG(0,"Deauthentication frame received\n");
2721    local->authentication_state = UNAUTHENTICATED;
2722    /* Need to reauthenticate or rejoin depending on reason code */
2723/*  copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
2724 */
2725}
2726/*===========================================================================*/
2727static void clear_interrupt(ray_dev_t *local)
2728{
2729    writeb(0, local->amem + CIS_OFFSET + HCS_INTR_OFFSET);
2730}
2731/*===========================================================================*/
2732#ifdef CONFIG_PROC_FS
2733#define MAXDATA (PAGE_SIZE - 80)
2734
2735static char *card_status[] = {
2736    "Card inserted - uninitialized",     /* 0 */
2737    "Card not downloaded",               /* 1 */
2738    "Waiting for download parameters",   /* 2 */
2739    "Card doing acquisition",            /* 3 */
2740    "Acquisition complete",              /* 4 */
2741    "Authentication complete",           /* 5 */
2742    "Association complete",              /* 6 */
2743    "???", "???", "???", "???",          /* 7 8 9 10 undefined */
2744    "Card init error",                   /* 11 */
2745    "Download parameters error",         /* 12 */
2746    "???",                               /* 13 */
2747    "Acquisition failed",                /* 14 */
2748    "Authentication refused",            /* 15 */
2749    "Association failed"                 /* 16 */
2750};
2751
2752static char *nettype[] = {"Adhoc", "Infra "};
2753static char *framing[] = {"Encapsulation", "Translation"}
2754;
2755/*===========================================================================*/
2756static int ray_cs_proc_read(char *buf, char **start, off_t offset, int len)
2757{
2758/* Print current values which are not available via other means
2759 * eg ifconfig
2760 */
2761    int i;
2762    dev_link_t *link;
2763    struct net_device *dev;
2764    ray_dev_t *local;
2765    UCHAR *p;
2766    struct freq_hop_element *pfh;
2767    UCHAR c[33];
2768
2769    link = dev_list;
2770    if (!link)
2771    	return 0;
2772    dev = (struct net_device *)link->priv;
2773    if (!dev)
2774    	return 0;
2775    local = (ray_dev_t *)dev->priv;
2776    if (!local)
2777    	return 0;
2778
2779    len = 0;
2780
2781    len += sprintf(buf + len, "Raylink Wireless LAN driver status\n");
2782    len += sprintf(buf + len, "%s\n", rcsid);
2783    /* build 4 does not report version, and field is 0x55 after memtest */
2784    len += sprintf(buf + len, "Firmware version     = ");
2785    if (local->fw_ver == 0x55)
2786        len += sprintf(buf + len, "4 - Use dump_cis for more details\n");
2787    else
2788        len += sprintf(buf + len, "%2d.%02d.%02d\n",
2789                   local->fw_ver, local->fw_bld, local->fw_var);
2790
2791    for (i=0; i<32; i++) c[i] = local->sparm.b5.a_current_ess_id[i];
2792    c[32] = 0;
2793    len += sprintf(buf + len, "%s network ESSID = \"%s\"\n",
2794                   nettype[local->sparm.b5.a_network_type], c);
2795
2796    p = local->bss_id;
2797    len += sprintf(buf + len,
2798                   "BSSID                = %02x:%02x:%02x:%02x:%02x:%02x\n",
2799                   p[0],p[1],p[2],p[3],p[4],p[5]);
2800
2801    len += sprintf(buf + len, "Country code         = %d\n",
2802                   local->sparm.b5.a_curr_country_code);
2803
2804    i = local->card_status;
2805    if (i < 0) i = 10;
2806    if (i > 16) i = 10;
2807    len += sprintf(buf + len, "Card status          = %s\n", card_status[i]);
2808
2809    len += sprintf(buf + len, "Framing mode         = %s\n",framing[translate]);
2810
2811    len += sprintf(buf + len, "Last pkt signal lvl  = %d\n", local->last_rsl);
2812
2813    if (local->beacon_rxed) {
2814	/* Pull some fields out of last beacon received */
2815	len += sprintf(buf + len, "Beacon Interval      = %d Kus\n",
2816		       local->last_bcn.beacon_intvl[0]
2817		       + 256 * local->last_bcn.beacon_intvl[1]);
2818
2819    p = local->last_bcn.elements;
2820    if (p[0] == C_ESSID_ELEMENT_ID) p += p[1] + 2;
2821    else {
2822        len += sprintf(buf + len, "Parse beacon failed at essid element id = %d\n",p[0]);
2823        return len;
2824    }
2825
2826    if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) {
2827        len += sprintf(buf + len, "Supported rate codes = ");
2828        for (i=2; i<p[1] + 2; i++)
2829            len += sprintf(buf + len, "0x%02x ", p[i]);
2830        len += sprintf(buf + len, "\n");
2831        p += p[1] + 2;
2832    }
2833    else {
2834        len += sprintf(buf + len, "Parse beacon failed at rates element\n");
2835        return len;
2836    }
2837
2838	if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) {
2839	    pfh = (struct freq_hop_element *)p;
2840	    len += sprintf(buf + len, "Hop dwell            = %d Kus\n",
2841			   pfh->dwell_time[0] + 256 * pfh->dwell_time[1]);
2842	    len += sprintf(buf + len, "Hop set              = %d \n", pfh->hop_set);
2843	    len += sprintf(buf + len, "Hop pattern          = %d \n", pfh->hop_pattern);
2844	    len += sprintf(buf + len, "Hop index            = %d \n", pfh->hop_index);
2845	    p += p[1] + 2;
2846	}
2847	else {
2848	    len += sprintf(buf + len, "Parse beacon failed at FH param element\n");
2849	    return len;
2850	}
2851    } else {
2852	len += sprintf(buf + len, "No beacons received\n");
2853    }
2854    return len;
2855}
2856
2857#endif
2858/*===========================================================================*/
2859static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
2860{
2861    int addr;
2862    struct ccs *pccs;
2863    struct tx_msg *ptx;
2864    int ccsindex;
2865
2866    /* If no tx buffers available, return */
2867    if ((ccsindex = get_free_tx_ccs(local)) < 0)
2868    {
2869        DEBUG(1,"ray_cs send authenticate - No free tx ccs\n");
2870        return -1;
2871    }
2872
2873    pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
2874
2875    /* Address in card space */
2876    addr = TX_BUF_BASE + (ccsindex << 11);
2877    /* fill in the CCS */
2878    writeb(CCS_TX_REQUEST, &pccs->cmd);
2879    writeb(addr >> 8, pccs->var.tx_request.tx_data_ptr);
2880    writeb(0x20, pccs->var.tx_request.tx_data_ptr + 1);
2881    writeb(TX_AUTHENTICATE_LENGTH_MSB, pccs->var.tx_request.tx_data_length);
2882    writeb(TX_AUTHENTICATE_LENGTH_LSB,pccs->var.tx_request.tx_data_length + 1);
2883    writeb(0, &pccs->var.tx_request.pow_sav_mode);
2884
2885    ptx = (struct tx_msg *)(local->sram + addr);
2886    /* fill in the mac header */
2887    writeb(PROTOCOL_VER | AUTHENTIC_TYPE, &ptx->mac.frame_ctl_1);
2888    writeb(0, &ptx->mac.frame_ctl_2);
2889
2890    memcpy_toio(ptx->mac.addr_1, dest, ADDRLEN);
2891    memcpy_toio(ptx->mac.addr_2, local->sparm.b4.a_mac_addr, ADDRLEN);
2892    memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
2893
2894    /* Fill in msg body with protocol 00 00, sequence 01 00 ,status 00 00 */
2895    memset_io(ptx->var, 0, 6);
2896    writeb(auth_type & 0xff, ptx->var + 2);
2897
2898    /* Interrupt the firmware to process the command */
2899    if (interrupt_ecf(local, ccsindex)) {
2900        DEBUG(1,"ray_cs send authentication request failed - ECF not ready for intr\n");
2901        writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
2902        return -1;
2903    }
2904    return 0;
2905} /* End build_auth_frame */
2906
2907/*===========================================================================*/
2908#ifdef CONFIG_PROC_FS
2909static void raycs_write(const char *name, write_proc_t *w, void *data)
2910{
2911	struct proc_dir_entry * entry = create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
2912	if (entry) {
2913		entry->write_proc = w;
2914		entry->data = data;
2915	}
2916}
2917
2918static int write_essid(struct file *file, const char *buffer, unsigned long count, void *data)
2919{
2920	static char proc_essid[33];
2921	int len = count;
2922
2923	if (len > 32)
2924		len = 32;
2925	memset(proc_essid, 0, 33);
2926	if (copy_from_user(proc_essid, buffer, len))
2927		return -EFAULT;
2928	essid = proc_essid;
2929	return count;
2930}
2931
2932static int write_int(struct file *file, const char *buffer, unsigned long count, void *data)
2933{
2934	static char proc_number[10];
2935	char *p;
2936	int nr, len;
2937
2938	if (!count)
2939		return 0;
2940
2941	if (count > 9)
2942		return -EINVAL;
2943	if (copy_from_user(proc_number, buffer, count))
2944		return -EFAULT;
2945	p = proc_number;
2946	nr = 0;
2947	len = count;
2948	do {
2949		unsigned int c = *p - '0';
2950		if (c > 9)
2951			return -EINVAL;
2952		nr = nr*10 + c;
2953		p++;
2954	} while (--len);
2955	*(int *)data = nr;
2956	return count;
2957}
2958#endif
2959
2960static int __init init_ray_cs(void)
2961{
2962    int rc;
2963
2964    DEBUG(1, "%s\n", rcsid);
2965    rc = register_pcmcia_driver(&dev_info, &ray_attach, &ray_detach);
2966    DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",rc);
2967
2968#ifdef CONFIG_PROC_FS
2969    proc_mkdir("driver/ray_cs", 0);
2970
2971    create_proc_info_entry("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_read);
2972    raycs_write("driver/ray_cs/essid", write_essid, NULL);
2973    raycs_write("driver/ray_cs/net_type", write_int, &net_type);
2974    raycs_write("driver/ray_cs/translate", write_int, &translate);
2975#endif
2976    if (translate != 0) translate = 1;
2977    return 0;
2978} /* init_ray_cs */
2979
2980/*===========================================================================*/
2981
2982static void __exit exit_ray_cs(void)
2983{
2984    DEBUG(0, "ray_cs: cleanup_module\n");
2985
2986
2987#ifdef CONFIG_PROC_FS
2988    remove_proc_entry("ray_cs", proc_root_driver);
2989#endif
2990
2991    unregister_pcmcia_driver(&dev_info);
2992    while (dev_list != NULL)
2993        ray_detach(dev_list);
2994
2995#ifdef CONFIG_PROC_FS
2996    remove_proc_entry("driver/ray_cs/ray_cs", NULL);
2997    remove_proc_entry("driver/ray_cs/essid", NULL);
2998    remove_proc_entry("driver/ray_cs/net_type", NULL);
2999    remove_proc_entry("driver/ray_cs/translate", NULL);
3000    remove_proc_entry("driver/ray_cs", NULL);
3001#endif
3002} /* exit_ray_cs */
3003
3004module_init(init_ray_cs);
3005module_exit(exit_ray_cs);
3006
3007/*===========================================================================*/
3008