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