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