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