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