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