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