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