Import 2.3.18pre1
[davej-history.git] / drivers / net / pcmcia / ray_cs.c
blob547c0a4bd090ef0ec893806d034cb30764e008dd
1 /*=============================================================================
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, dhinds@allegro.stanford.edu
8 * Copyright (c) 1998 Corey Thomas (corey@world.std.com)
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.
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.
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
23 =============================================================================*/
25 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/sched.h>
28 #include <linux/proc_fs.h>
29 #include <linux/ptrace.h>
30 #include <linux/malloc.h>
31 #include <linux/string.h>
32 #include <linux/timer.h>
33 #include <asm/io.h>
34 #include <asm/system.h>
35 #include <asm/byteorder.h>
37 #include <linux/netdevice.h>
38 #include <linux/etherdevice.h>
39 #include <linux/ioport.h>
40 #include <linux/skbuff.h>
42 #include <pcmcia/version.h>
43 #include <pcmcia/cs_types.h>
44 #include <pcmcia/cs.h>
45 #include <pcmcia/cistpl.h>
46 #include <pcmcia/cisreg.h>
47 #include <pcmcia/ds.h>
48 #include <pcmcia/mem_op.h>
50 #include "rayctl.h"
51 #include "ray_cs.h"
53 /* All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
54 you do not define PCMCIA_DEBUG at all, all the debug code will be
55 left out. If you compile with PCMCIA_DEBUG=0, the debug code will
56 be present but disabled -- but it can then be enabled for specific
57 modules at load time with a 'pc_debug=#' option to insmod.
59 I found that adding -DPCMCIA_DEBUG to the compile options during
60 the 'make config' resulted in cardmgr not finding any sockets.
61 Therefore, this module uses RAYLINK_DEBUG instead.
62 The module option to use is ray_debug=#
63 where # is 1 for modest output
64 2 for more output
65 ...
68 #ifdef RAYLINK_DEBUG
69 static int ray_debug = RAYLINK_DEBUG;
70 MODULE_PARM(ray_debug, "i");
71 /* #define DEBUG(n, args...) if (ray_debug>(n)) printk(KERN_DEBUG args); */
72 #define DEBUG(n, args...) if (ray_debug>(n)) printk(args);
73 #else
74 #define DEBUG(n, args...)
75 #endif
76 /** Prototypes based on PCMCIA skeleton driver *******************************/
77 void ray_config(dev_link_t *link);
78 void ray_release(u_long arg);
79 int ray_event(event_t event, int priority, event_callback_args_t *args);
80 dev_link_t *ray_attach(void);
81 void ray_detach(dev_link_t *);
83 /***** Prototypes indicated by device structure ******************************/
84 int ray_dev_close(struct net_device *dev);
85 int ray_dev_config(struct net_device *dev, struct ifmap *map);
86 struct enet_statistics *ray_get_stats(struct net_device *dev);
87 int ray_dev_init(struct net_device *dev);
88 int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
89 int ray_open(struct net_device *dev);
90 int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev);
91 static void set_multicast_list(struct net_device *dev);
92 static void ray_update_multi_list(struct net_device *dev, int all);
93 int encapsulate_frame(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type,
94 unsigned char *data, int len);
95 int translate_frame(ray_dev_t *local, struct tx_msg *ptx,
96 unsigned char *data, int len);
97 void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type,
98 unsigned char *data);
99 void untranslate(ray_dev_t *local, struct sk_buff *skb, int len);
101 /***** Prototypes for raylink functions **************************************/
102 int asc_to_int(char a);
103 void authenticate(ray_dev_t *local);
104 int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type);
105 void authenticate_timeout(u_long);
106 int get_free_ccs(ray_dev_t *local);
107 int get_free_tx_ccs(ray_dev_t *local);
108 void init_startup_params(ray_dev_t *local);
109 int parse_addr(char *in_str, UCHAR *out);
110 int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, UCHAR type);
111 int ray_init(struct net_device *dev);
112 int interrupt_ecf(ray_dev_t *local, int ccs);
113 void ray_reset(struct net_device *dev);
114 void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len);
115 void verify_dl_startup(u_long);
117 /* Prototypes for interrpt time functions **********************************/
118 void ray_interrupt(int reg, void *dev_id, struct pt_regs *regs);
119 void clear_interrupt(ray_dev_t *local);
120 void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs,
121 unsigned int pkt_addr, int rx_len);
122 int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int len);
123 void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs);
124 void release_frag_chain(ray_dev_t *local, struct rcs *prcs);
125 void rx_authenticate(ray_dev_t *local, struct rcs *prcs,
126 unsigned int pkt_addr, int rx_len);
127 void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr,
128 int rx_len);
129 void associate(ray_dev_t *local);
131 /* Card command functions */
132 int dl_startup_params(struct net_device *dev);
133 void join_net(u_long local);
134 void start_net(u_long local);
135 /* void start_net(ray_dev_t *local); */
137 int ray_cs_proc_read(char *buf, char **start, off_t off, int len, int spare);
139 /* Create symbol table for registering with kernel in init_module */
140 EXPORT_SYMBOL(ray_dev_ioctl);
141 EXPORT_SYMBOL(ray_rx);
143 /*===========================================================================*/
144 /* Parameters that can be set with 'insmod' */
145 /* Bit map of interrupts to choose from */
146 /* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
147 static u_long irq_mask = 0xdeb8;
148 MODULE_PARM(irq_mask,"i");
150 /* ADHOC=0, Infrastructure=1 */
151 static int net_type = ADHOC;
152 MODULE_PARM(net_type,"i");
154 /* Hop dwell time in Kus (1024 us units defined by 802.11) */
155 static int hop_dwell = 128;
156 MODULE_PARM(hop_dwell,"i");
158 /* Beacon period in Kus */
159 static int beacon_period = 128;
160 MODULE_PARM(beacon_period,"i");
162 /* power save mode (0 = off, 1 = save power) */
163 static int psm = 0;
164 MODULE_PARM(psm,"i");
166 /* String for network's Extended Service Set ID. 32 Characters max */
167 static char *essid = NULL;
168 MODULE_PARM(essid,"s");
170 /* Default to encapsulation unless translation requested */
171 static int translate = 0;
172 MODULE_PARM(translate,"i");
174 static int country = USA;
175 MODULE_PARM(country,"i");
177 static int sniffer = 0;
178 MODULE_PARM(sniffer,"i");
180 static int bc = 0;
181 MODULE_PARM(bc,"i");
183 /* 48 bit physical card address if overriding card's real physical
184 * address is required. Since IEEE 802.11 addresses are 48 bits
185 * like ethernet, an int can't be used, so a string is used. To
186 * allow use of addresses starting with a decimal digit, the first
187 * character must be a letter and will be ignored. This letter is
188 * followed by up to 12 hex digits which are the address. If less
189 * than 12 digits are used, the address will be left filled with 0's.
190 * Note that bit 0 of the first byte is the broadcast bit, and evil
191 * things will happen if it is not 0 in a card address.
193 static char *phy_addr = NULL;
194 MODULE_PARM(phy_addr,"s");
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.
201 static dev_info_t dev_info = "ray_cs";
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).
207 static dev_link_t *dev_list = NULL;
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.
215 static const unsigned int ray_mem_speed = 0x2A;
217 static UCHAR b5_default_startup_parms[] = {
218 0, 0, /* Adhoc station */
219 'L','I','N','U','X', 0, 0, 0, /* 32 char ESSID */
220 0, 0, 0, 0, 0, 0, 0, 0,
221 0, 0, 0, 0, 0, 0, 0, 0,
222 0, 0, 0, 0, 0, 0, 0, 0,
223 1, 0, /* Active scan, CA Mode */
224 0, 0, 0, 0, 0, 0, /* No default MAC addr */
225 0x7f, 0xff, /* Frag threshold */
226 0x00, 0x80, /* Hop time 128 Kus*/
227 0x01, 0x00, /* Beacon period 256 Kus */
228 0x01, 0x07, 0xa3, /* DTIM, retries, ack timeout*/
229 0x1d, 0x82, 0x4e, /* SIFS, DIFS, PIFS */
230 0x7f, 0xff, /* RTS threshold */
231 0x04, 0xe2, 0x38, 0xA4, /* scan_dwell, max_scan_dwell */
232 0x05, /* assoc resp timeout thresh */
233 0x08, 0x02, 0x08, /* adhoc, infra, super cycle max*/
234 0, /* Promiscuous mode */
235 0x0c, 0x0bd, /* Unique word */
236 0x32, /* Slot time */
237 0xff, 0xff, /* roam-low snr, low snr count */
238 0x05, 0xff, /* Infra, adhoc missed bcn thresh */
239 0x01, 0x0b, 0x4f, /* USA, hop pattern, hop pat length */
240 /* b4 - b5 differences start here */
241 0x00, 0x3f, /* CW max */
242 0x00, 0x0f, /* CW min */
243 0x04, 0x08, /* Noise gain, limit offset */
244 0x28, 0x28, /* det rssi, med busy offsets */
245 7, /* det sync thresh */
246 0, 2, 2, /* test mode, min, max */
247 0, /* allow broadcast SSID probe resp */
248 0, 0, /* privacy must start, can join */
249 2, 0, 0, 0, 0, 0, 0, 0 /* basic rate set */
252 static UCHAR b4_default_startup_parms[] = {
253 0, 0, /* Adhoc station */
254 'L','I','N','U','X', 0, 0, 0, /* 32 char ESSID */
255 0, 0, 0, 0, 0, 0, 0, 0,
256 0, 0, 0, 0, 0, 0, 0, 0,
257 0, 0, 0, 0, 0, 0, 0, 0,
258 1, 0, /* Active scan, CA Mode */
259 0, 0, 0, 0, 0, 0, /* No default MAC addr */
260 0x7f, 0xff, /* Frag threshold */
261 0x02, 0x00, /* Hop time */
262 0x00, 0x01, /* Beacon period */
263 0x01, 0x07, 0xa3, /* DTIM, retries, ack timeout*/
264 0x1d, 0x82, 0xce, /* SIFS, DIFS, PIFS */
265 0x7f, 0xff, /* RTS threshold */
266 0xfb, 0x1e, 0xc7, 0x5c, /* scan_dwell, max_scan_dwell */
267 0x05, /* assoc resp timeout thresh */
268 0x04, 0x02, 0x4, /* adhoc, infra, super cycle max*/
269 0, /* Promiscuous mode */
270 0x0c, 0x0bd, /* Unique word */
271 0x4e, /* Slot time (TBD seems wrong)*/
272 0xff, 0xff, /* roam-low snr, low snr count */
273 0x05, 0xff, /* Infra, adhoc missed bcn thresh */
274 0x01, 0x0b, 0x4e, /* USA, hop pattern, hop pat length */
275 /* b4 - b5 differences start here */
276 0x3f, 0x0f, /* CW max, min */
277 0x04, 0x08, /* Noise gain, limit offset */
278 0x28, 0x28, /* det rssi, med busy offsets */
279 7, /* det sync thresh */
280 0, 2, 2 /* test mode, min, max*/
282 /*===========================================================================*/
283 static unsigned char eth2_llc[] = {0xaa, 0xaa, 3, 0, 0, 0};
285 static char rcsid[] = " $Id: ray_cs.c,v 1.60 1999/09/01 20:58:45 corey Exp $ - Corey Thomas corey@world.std.com";
287 #ifdef CONFIG_PROC_FS
288 struct proc_dir_entry ray_cs_proc_entry = {
289 0, /* Dynamic inode # */
290 6,"ray_cs", /* name length and name */
291 S_IFREG | S_IRUGO, /* mode */
292 1, 0, 0, /* nlinks, owner, group */
293 0, /* size (unused) */
294 NULL, /* operations (default) */
295 &ray_cs_proc_read, /* function to read data */
296 /* The end ?? */
298 #endif
299 /*===========================================================================*/
300 void cs_error(client_handle_t handle, int func, int ret)
302 error_info_t err = { func, ret };
303 CardServices(ReportError, handle, &err);
305 /*=============================================================================
306 ray_attach() creates an "instance" of the driver, allocating
307 local data structures for one device. The device is registered
308 with Card Services.
309 The dev_link structure is initialized, but we don't actually
310 configure the card at this point -- we wait until we receive a
311 card insertion event.
312 =============================================================================*/
313 dev_link_t *ray_attach(void)
315 client_reg_t client_reg;
316 dev_link_t *link;
317 ray_dev_t *local;
318 int ret;
319 struct net_device *dev;
321 DEBUG(1, "ray_attach()\n");
323 /* Initialize the dev_link_t structure */
324 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
325 memset(link, 0, sizeof(struct dev_link_t));
326 link->release.function = &ray_release;
327 link->release.data = (u_long)link;
329 /* The io structure describes IO port mapping. None used here */
330 link->io.NumPorts1 = 0;
331 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
332 link->io.IOAddrLines = 5;
334 /* Interrupt setup. For PCMCIA, driver takes what's given */
335 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
336 link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
337 link->irq.IRQInfo2 = irq_mask;
338 link->irq.Handler = &ray_interrupt;
340 /* General socket configuration */
341 link->conf.Attributes = CONF_ENABLE_IRQ;
342 link->conf.Vcc = 50;
343 link->conf.IntType = INT_MEMORY_AND_IO;
344 link->conf.ConfigIndex = 1;
345 link->conf.Present = PRESENT_OPTION;
347 /* Allocate space for private device-specific data */
348 dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
349 memset(dev, 0, sizeof(struct net_device));
350 link->priv = dev;
351 link->irq.Instance = dev;
353 local = kmalloc(sizeof(ray_dev_t), GFP_KERNEL);
354 memset(local, 0, sizeof(ray_dev_t));
355 dev->priv = local;
356 local->finder = link;
357 link->dev = &local->node;
358 local->card_status = CARD_INSERTED;
359 local->authentication_state = UNAUTHENTICATED;
360 local->num_multi = 0;
361 DEBUG(2,"ray_attach link = %p, dev = %p, local = %p, intr = %p\n",
362 link,dev,local,&ray_interrupt);
364 /* Raylink entries in the device structure */
365 dev->hard_start_xmit = &ray_dev_start_xmit;
366 dev->set_config = &ray_dev_config;
367 dev->get_stats = &ray_get_stats;
368 dev->do_ioctl = &ray_dev_ioctl;
370 dev->set_multicast_list = &set_multicast_list;
372 DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n");
373 ether_setup(dev);
374 dev->name = local->node.dev_name;
375 dev->init = &ray_dev_init;
376 dev->open = &ray_open;
377 dev->stop = &ray_dev_close;
378 dev->tbusy = 1;
380 /* Register with Card Services */
381 link->next = dev_list;
382 dev_list = link;
383 client_reg.dev_info = &dev_info;
384 client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
385 client_reg.EventMask =
386 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
387 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
388 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
389 client_reg.event_handler = &ray_event;
390 client_reg.Version = 0x0210;
391 client_reg.event_callback_args.client_data = link;
393 DEBUG(2,"ray_cs ray_attach calling CardServices(RegisterClient...)\n");
395 init_timer(&local->timer);
397 ret = CardServices(RegisterClient, &link->handle, &client_reg);
398 if (ret != 0) {
399 printk("ray_cs ray_attach RegisterClient unhappy - detaching\n");
400 cs_error(link->handle, RegisterClient, ret);
401 ray_detach(link);
402 return NULL;
404 DEBUG(2,"ray_cs ray_attach ending\n");
405 return link;
406 } /* ray_attach */
407 /*=============================================================================
408 This deletes a driver "instance". The device is de-registered
409 with Card Services. If it has been released, all local data
410 structures are freed. Otherwise, the structures will be freed
411 when the device is released.
412 =============================================================================*/
413 void ray_detach(dev_link_t *link)
415 dev_link_t **linkp;
416 struct net_device *dev;
417 long flags;
419 DEBUG(1, "ray_detach(0x%p)\n", link);
421 /* Locate device structure */
422 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
423 if (*linkp == link) break;
424 if (*linkp == NULL)
425 return;
427 save_flags(flags);
428 cli();
429 if (link->state & DEV_RELEASE_PENDING) {
430 del_timer(&link->release);
431 link->state &= ~DEV_RELEASE_PENDING;
433 restore_flags(flags);
435 /* If the device is currently configured and active, we won't
436 actually delete it yet. Instead, it is marked so that when
437 the release() function is called, that will trigger a proper
438 detach().
440 if (link->state & DEV_CONFIG) {
441 ray_release((u_long)link);
442 if(link->state & DEV_STALE_CONFIG) {
443 DEBUG(0,"ray_cs: detach postponed, '%s' "
444 "still locked\n", link->dev->dev_name);
445 link->state |= DEV_STALE_LINK;
446 return;
450 /* Break the link with Card Services */
451 if (link->handle)
452 CardServices(DeregisterClient, link->handle);
454 /* Unlink device structure, free pieces */
455 *linkp = link->next;
456 if (link->priv) {
457 dev = link->priv;
458 if (dev->priv)
459 kfree_s(dev->priv, sizeof(ray_dev_t));
461 kfree_s(link->priv, sizeof(struct net_device));
463 kfree_s(link, sizeof(struct dev_link_t));
464 DEBUG(2,"ray_cs ray_detach ending\n");
465 } /* ray_detach */
466 /*=============================================================================
467 ray_config() is run after a CARD_INSERTION event
468 is received, to configure the PCMCIA socket, and to make the
469 ethernet device available to the system.
470 =============================================================================*/
471 #define CS_CHECK(fn, args...) \
472 while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed
473 #define MAX_TUPLE_SIZE 80
474 void ray_config(dev_link_t *link)
476 client_handle_t handle = link->handle;
477 tuple_t tuple;
478 cisparse_t parse;
479 int last_fn, last_ret;
480 int i;
481 u_char buf[80];
482 win_req_t req;
483 memreq_t mem;
484 struct net_device *dev = (struct net_device *)link->priv;
485 ray_dev_t *local = (ray_dev_t *)dev->priv;
487 DEBUG(1, "ray_config(0x%p)\n", link);
489 /* This reads the card's CONFIG tuple to find its configuration regs */
490 tuple.DesiredTuple = CISTPL_CONFIG;
491 CS_CHECK(GetFirstTuple, handle, &tuple);
492 tuple.TupleData = buf;
493 tuple.TupleDataMax = MAX_TUPLE_SIZE;
494 tuple.TupleOffset = 0;
495 CS_CHECK(GetTupleData, handle, &tuple);
496 CS_CHECK(ParseTuple, handle, &tuple, &parse);
497 link->conf.ConfigBase = parse.config.base;
498 link->conf.Present = parse.config.rmask[0];
500 /* Configure card */
501 link->state |= DEV_CONFIG;
503 /* Now allocate an interrupt line. Note that this does not
504 actually assign a handler to the interrupt.
506 CS_CHECK(RequestIRQ, link->handle, &link->irq);
507 dev->irq = link->irq.AssignedIRQ;
509 /* This actually configures the PCMCIA socket -- setting up
510 the I/O windows and the interrupt mapping.
512 CS_CHECK(RequestConfiguration, link->handle, &link->conf);
514 /*** Set up 32k window for shared memory (transmit and control) ************/
515 req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
516 req.Base = 0;
517 req.Size = 0x8000;
518 req.AccessSpeed = ray_mem_speed;
519 link->win = (window_handle_t)link->handle;
520 CS_CHECK(RequestWindow, &link->win, &req);
521 mem.CardOffset = 0x0000; mem.Page = 0;
522 CS_CHECK(MapMemPage, link->win, &mem);
523 local->sram = (UCHAR *)(ioremap(req.Base,req.Size));
525 /*** Set up 16k window for shared memory (receive buffer) ***************/
526 req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT;
527 req.Base = 0;
528 req.Size = 0x4000;
529 req.AccessSpeed = ray_mem_speed;
530 local->rmem_handle = (window_handle_t)link->handle;
531 CS_CHECK(RequestWindow, &local->rmem_handle, &req);
532 mem.CardOffset = 0x8000; mem.Page = 0;
533 CS_CHECK(MapMemPage, local->rmem_handle, &mem);
534 local->rmem = (UCHAR *)(ioremap(req.Base,req.Size));
536 /*** Set up window for attribute memory ***********************************/
537 req.Attributes = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM | WIN_ENABLE | WIN_USE_WAIT;
538 req.Base = 0;
539 req.Size = 0x1000;
540 req.AccessSpeed = ray_mem_speed;
541 local->amem_handle = (window_handle_t)link->handle;
542 CS_CHECK(RequestWindow, &local->amem_handle, &req);
543 mem.CardOffset = 0x0000; mem.Page = 0;
544 CS_CHECK(MapMemPage, local->amem_handle, &mem);
545 local->amem = (UCHAR *)(ioremap(req.Base,req.Size));
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((u_long)link);
552 return;
555 i = register_netdev(dev);
556 if (i != 0) {
557 printk("ray_config register_netdev() failed\n");
558 ray_release((u_long)link);
559 return;
562 link->state &= ~DEV_CONFIG_PENDING;
563 DEBUG(0, "ray_cs device loaded\n");
565 return;
567 cs_failed:
568 cs_error(link->handle, last_fn, last_ret);
570 ray_release((u_long)link);
571 } /* ray_config */
572 /*===========================================================================*/
573 int ray_init(struct net_device *dev)
575 int i;
576 UCHAR *p;
577 struct ccs *pccs;
578 ray_dev_t *local = (ray_dev_t *)dev->priv;
579 dev_link_t *link = local->finder;
580 DEBUG(1, "ray_init(0x%p)\n", dev);
581 if (!(link->state & DEV_PRESENT)) {
582 DEBUG(0,"ray_init - device not present\n");
583 return -1;
586 local->net_type = net_type;
587 local->sta_type = TYPE_STA;
589 /* Copy the startup results to local memory */
590 memcpy_fromio(&local->startup_res, local->sram + ECF_TO_HOST_BASE,\
591 sizeof(struct startup_res_6));
593 /* Check Power up test status and get mac address from card */
594 if (local->startup_res.startup_word != 0x80) {
595 DEBUG(0,"ray_init ERROR card status = %2x\n", local->startup_res.startup_word);
596 local->card_status = CARD_INIT_ERROR;
597 return -1;
600 local->fw_ver = local->startup_res.firmware_version[0];
601 local->fw_bld = local->startup_res.firmware_version[1];
602 local->fw_var = local->startup_res.firmware_version[2];
603 DEBUG(1,"ray_init firmware version %d.%d \n",local->fw_ver, local->fw_bld);
605 local->tib_length = 0x20;
606 if ((local->fw_ver == 5) && (local->fw_bld >= 30))
607 local->tib_length = local->startup_res.tib_length;
608 DEBUG(2,"ray_init tib_length = 0x%02x\n", local->tib_length);
609 /* Initialize CCS's to buffer free state */
610 pccs = (struct ccs *)(local->sram + CCS_BASE);
611 for (i=0; i<NUMBER_OF_CCS; i++) {
612 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
614 init_startup_params(local);
616 /* copy mac address to startup parameters */
617 if (parse_addr(phy_addr, local->sparm.b4.a_mac_addr))
619 p = local->sparm.b4.a_mac_addr;
620 DEBUG(1,"ray_cs phy address overridden = %2x %2x %2x %2x %2x %2x\n",\
621 p[0],p[1],p[2],p[3],p[4],p[5]);
623 else
625 memcpy(&local->sparm.b4.a_mac_addr,
626 &local->startup_res.station_addr, ADDRLEN);
627 p = local->sparm.b4.a_mac_addr;
628 DEBUG(1,"ray_cs phy addr= %2x %2x %2x %2x %2x %2x\n",\
629 p[0],p[1],p[2],p[3],p[4],p[5]);
632 clear_interrupt(local); /* Clear any interrupt from the card */
633 local->card_status = CARD_AWAITING_PARAM;
634 DEBUG(2,"ray_init ending\n");
635 return 0;
636 } /* ray_init */
637 /*===========================================================================*/
638 /* Download startup parameters to the card and command it to read them */
639 int dl_startup_params(struct net_device *dev)
641 int ccsindex;
642 ray_dev_t *local = (ray_dev_t *)dev->priv;
643 struct ccs *pccs;
644 dev_link_t *link = local->finder;
646 DEBUG(1,"dl_startup_params entered\n");
647 if (!(link->state & DEV_PRESENT)) {
648 DEBUG(0,"ray_cs dl_startup_params - device not present\n");
649 return -1;
652 /* Copy parameters to host to ECF area */
653 if (local->fw_ver == 0x55)
654 memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b4,
655 sizeof(struct b4_startup_params));
656 else
657 memcpy_toio(local->sram + HOST_TO_ECF_BASE, &local->sparm.b5,
658 sizeof(struct b5_startup_params));
661 /* Fill in the CCS fields for the ECF */
662 if ((ccsindex = get_free_ccs(local)) == -1) return -1;
663 local->dl_param_ccs = ccsindex;
664 pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
665 writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd);
666 DEBUG(2,"dl_startup_params start ccsindex = %d\n", local->dl_param_ccs);
667 /* Interrupt the firmware to process the command */
668 if (interrupt_ecf(local, ccsindex)) {
669 DEBUG(0,"ray dl_startup_params failed - ECF not ready for intr\n");
670 local->card_status = CARD_DL_PARAM_ERROR;
671 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
672 return -2;
674 local->card_status = CARD_DL_PARAM;
675 /* Start kernel timer to wait for dl startup to complete. */
676 local->timer.expires = jiffies + HZ/2;
677 local->timer.data = (long)local;
678 local->timer.function = &verify_dl_startup;
679 add_timer(&local->timer);
680 DEBUG(2,"ray_cs dl_startup_params started timer for verify_dl_startup\n");
681 return 0;
682 } /* dl_startup_params */
683 /*===========================================================================*/
684 void init_startup_params(ray_dev_t *local)
686 int i;
687 static char hop_pattern_length[] = { 1,
688 USA_HOP_MOD, EUROPE_HOP_MOD,
689 JAPAN_HOP_MOD, KOREA_HOP_MOD,
690 SPAIN_HOP_MOD, FRANCE_HOP_MOD,
691 ISRAEL_HOP_MOD, AUSTRALIA_HOP_MOD,
692 JAPAN_TEST_HOP_MOD
695 if (country > JAPAN_TEST) country = USA;
696 else
697 if (country < USA) country = USA;
698 /* structure for hop time and beacon period is defined here using
699 * New 802.11D6.1 format. Card firmware is still using old format
700 * until version 6.
701 * Before After
702 * a_hop_time ms byte a_hop_time ms byte
703 * a_hop_time 2s byte a_hop_time ls byte
704 * a_hop_time ls byte a_beacon_period ms byte
705 * a_beacon_period a_beacon_period ls byte
707 * a_hop_time = uS a_hop_time = KuS
708 * a_beacon_period = hops a_beacon_period = KuS
709 */ /* 64ms = 010000 */
710 if (local->fw_ver == 0x55) {
711 memcpy((UCHAR *)&local->sparm.b4, b4_default_startup_parms,
712 sizeof(struct b4_startup_params));
713 /* Translate sane kus input values to old build 4/5 format */
714 /* i = hop time in uS truncated to 3 bytes */
715 i = (hop_dwell * 1024) & 0xffffff;
716 local->sparm.b4.a_hop_time[0] = (i >> 16) & 0xff;
717 local->sparm.b4.a_hop_time[1] = (i >> 8) & 0xff;
718 local->sparm.b4.a_beacon_period[0] = 0;
719 local->sparm.b4.a_beacon_period[1] =
720 ((beacon_period/hop_dwell) - 1) & 0xff;
721 local->sparm.b4.a_curr_country_code = country;
722 local->sparm.b4.a_hop_pattern_length =
723 hop_pattern_length[(int)country] - 1;
724 if (bc)
726 local->sparm.b4.a_ack_timeout = 0x50;
727 local->sparm.b4.a_sifs = 0x3f;
730 else { /* Version 5 uses real kus values */
731 memcpy((UCHAR *)&local->sparm.b5, b5_default_startup_parms,
732 sizeof(struct b5_startup_params));
734 local->sparm.b5.a_hop_time[0] = (hop_dwell >> 8) & 0xff;
735 local->sparm.b5.a_hop_time[1] = hop_dwell & 0xff;
736 local->sparm.b5.a_beacon_period[0] = (beacon_period >> 8) & 0xff;
737 local->sparm.b5.a_beacon_period[1] = beacon_period & 0xff;
738 if (psm)
739 local->sparm.b5.a_power_mgt_state = 1;
740 local->sparm.b5.a_curr_country_code = country;
741 local->sparm.b5.a_hop_pattern_length =
742 hop_pattern_length[(int)country];
745 local->sparm.b4.a_network_type = net_type & 0x01;
746 local->sparm.b4.a_acting_as_ap_status = TYPE_STA;
748 if (essid != NULL)
749 strncpy(local->sparm.b4.a_current_ess_id, essid, ESSID_SIZE);
750 } /* init_startup_params */
751 /*===========================================================================*/
752 void verify_dl_startup(u_long data)
754 ray_dev_t *local = (ray_dev_t *)data;
755 struct ccs *pccs = ((struct ccs *)(local->sram + CCS_BASE)) + local->dl_param_ccs;
756 UCHAR status;
757 /* UCHAR *p = local->sram + HOST_TO_ECF_BASE; */
758 dev_link_t *link = local->finder;
760 if (!(link->state & DEV_PRESENT)) {
761 DEBUG(0,"ray_cs verify_dl_startup - device not present\n");
762 return;
764 #ifdef RAYLINK_DEBUG
766 int i;
767 DEBUG(2,"verify_dl_startup parameters sent via ccs %d:\n",\
768 local->dl_param_ccs);
769 for (i=0; i<sizeof(struct b5_startup_params); i++)
771 DEBUG(1," %2x ", readb(local->sram + HOST_TO_ECF_BASE + i));
773 DEBUG(1,"\n");
775 #endif
777 status = readb(&pccs->buffer_status);
778 if (status!= CCS_BUFFER_FREE)
780 DEBUG(0,"Download startup params failed. Status = %d\n",status);
781 local->card_status = CARD_DL_PARAM_ERROR;
782 return;
784 if (local->sparm.b4.a_network_type == ADHOC)
785 start_net((u_long)local);
786 else
787 join_net((u_long)local);
789 return;
790 } /* end verify_dl_startup */
791 /*===========================================================================*/
792 /* Command card to start a network */
793 void start_net(u_long data)
795 ray_dev_t *local = (ray_dev_t *)data;
796 struct ccs *pccs;
797 int ccsindex;
798 dev_link_t *link = local->finder;
799 if (!(link->state & DEV_PRESENT)) {
800 DEBUG(0,"ray_cs start_net - device not present\n");
801 return;
803 /* Fill in the CCS fields for the ECF */
804 if ((ccsindex = get_free_ccs(local)) == -1) return;
805 pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
806 writeb(CCS_START_NETWORK, &pccs->cmd);
807 writeb(0, &pccs->var.start_network.update_param);
808 /* Interrupt the firmware to process the command */
809 if (interrupt_ecf(local, ccsindex)) {
810 DEBUG(1,"ray start net failed - card not ready for intr\n");
811 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
812 return;
814 local->card_status = CARD_DOING_ACQ;
815 return;
816 } /* end start_net */
817 /*===========================================================================*/
818 /* Command card to join a network */
819 void join_net(u_long data)
821 ray_dev_t *local = (ray_dev_t *)data;
823 struct ccs *pccs;
824 int ccsindex;
825 dev_link_t *link = local->finder;
827 if (!(link->state & DEV_PRESENT)) {
828 DEBUG(0,"ray_cs join_net - device not present\n");
829 return;
831 /* Fill in the CCS fields for the ECF */
832 if ((ccsindex = get_free_ccs(local)) == -1) return;
833 pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
834 writeb(CCS_JOIN_NETWORK, &pccs->cmd);
835 writeb(0, &pccs->var.join_network.update_param);
836 writeb(0, &pccs->var.join_network.net_initiated);
837 /* Interrupt the firmware to process the command */
838 if (interrupt_ecf(local, ccsindex)) {
839 DEBUG(1,"ray join net failed - card not ready for intr\n");
840 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
841 return;
843 local->card_status = CARD_DOING_ACQ;
844 return;
846 /*============================================================================
847 After a card is removed, ray_release() will unregister the net
848 device, and release the PCMCIA configuration. If the device is
849 still open, this will be postponed until it is closed.
850 =============================================================================*/
851 void ray_release(u_long arg)
853 dev_link_t *link = (dev_link_t *)arg;
854 struct net_device *dev = link->priv;
855 ray_dev_t *local = dev->priv;
856 int i;
858 DEBUG(1, "ray_release(0x%p)\n", link);
859 /* If the device is currently in use, we won't release until it
860 is actually closed.
862 if (link->open) {
863 DEBUG(1, "ray_cs: release postponed, '%s' still open\n",
864 link->dev->dev_name);
865 link->state |= DEV_STALE_CONFIG;
866 return;
868 del_timer(&local->timer);
869 if (link->dev != '\0') unregister_netdev(dev);
870 /* Unlink the device chain */
871 link->dev = NULL;
873 iounmap(local->sram);
874 iounmap(local->rmem);
875 iounmap(local->amem);
876 /* Do bother checking to see if these succeed or not */
877 i = CardServices(ReleaseWindow, link->win);
878 if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(link->win) ret = %x\n",i);
879 i = CardServices(ReleaseWindow, local->amem_handle);
880 if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->amem) ret = %x\n",i);
881 i = CardServices(ReleaseWindow, local->rmem_handle);
882 if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseWindow(local->rmem) ret = %x\n",i);
883 i = CardServices(ReleaseConfiguration, link->handle);
884 if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseConfiguration ret = %x\n",i);
885 i = CardServices(ReleaseIRQ, link->handle, &link->irq);
886 if ( i != CS_SUCCESS ) DEBUG(0,"ReleaseIRQ ret = %x\n",i);
888 link->state &= ~DEV_CONFIG;
889 if (link->state & DEV_STALE_LINK) ray_detach(link);
890 DEBUG(2,"ray_release ending\n");
891 } /* ray_release */
892 /*=============================================================================
893 The card status event handler. Mostly, this schedules other
894 stuff to run after an event is received. A CARD_REMOVAL event
895 also sets some flags to discourage the net drivers from trying
896 to talk to the card any more.
898 When a CARD_REMOVAL event is received, we immediately set a flag
899 to block future accesses to this device. All the functions that
900 actually access the device should check this flag to make sure
901 the card is still present.
902 =============================================================================*/
903 int ray_event(event_t event, int priority,
904 event_callback_args_t *args)
906 dev_link_t *link = args->client_data;
907 struct net_device *dev = link->priv;
908 ray_dev_t *local = (ray_dev_t *)dev->priv;
909 DEBUG(1, "ray_event(0x%06x)\n", event);
911 switch (event) {
912 case CS_EVENT_CARD_REMOVAL:
913 link->state &= ~DEV_PRESENT;
914 dev->tbusy = 1; dev->start = 0;
915 if (link->state & DEV_CONFIG) {
916 link->release.expires = jiffies + HZ/20;
917 add_timer(&link->release);
918 del_timer(&local->timer);
920 break;
921 case CS_EVENT_CARD_INSERTION:
922 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
923 ray_config(link);
924 break;
925 case CS_EVENT_PM_SUSPEND:
926 link->state |= DEV_SUSPEND;
927 /* Fall through... */
928 case CS_EVENT_RESET_PHYSICAL:
929 if (link->state & DEV_CONFIG) {
930 if (link->open) {
931 dev->tbusy = 1;
932 dev->start = 0;
934 CardServices(ReleaseConfiguration, link->handle);
936 break;
937 case CS_EVENT_PM_RESUME:
938 link->state &= ~DEV_SUSPEND;
939 /* Fall through... */
940 case CS_EVENT_CARD_RESET:
941 if (link->state & DEV_CONFIG) {
942 CardServices(RequestConfiguration, link->handle, &link->conf);
943 if (link->open) {
944 ray_reset(dev);
945 dev->tbusy = 0;
946 dev->start = 1;
949 break;
951 return 0;
952 DEBUG(2,"ray_event ending\n");
953 } /* ray_event */
954 /*===========================================================================*/
955 int init_module(void)
957 int rc;
958 servinfo_t serv;
960 DEBUG(1, "%s\n", rcsid);
961 CardServices(GetCardServicesInfo, &serv);
962 if (serv.Revision != CS_RELEASE_CODE) {
963 printk(KERN_NOTICE "ray: Card Services release does not match!\n");
964 return -1;
966 rc = register_pcmcia_driver(&dev_info, &ray_attach, &ray_detach);
967 DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",rc);
968 proc_register(&proc_root, &ray_cs_proc_entry);
969 if (translate != 0) translate = 1;
970 return 0;
971 } /* init_module */
972 /*===========================================================================*/
973 void cleanup_module(void)
975 DEBUG(0, "ray_cs: cleanup_module\n");
977 unregister_pcmcia_driver(&dev_info);
978 while (dev_list != NULL) {
979 if (dev_list->state & DEV_CONFIG) ray_release((u_long)dev_list);
980 ray_detach(dev_list);
982 proc_unregister(&proc_root, ray_cs_proc_entry.low_ino);
983 } /* cleanup_module */
984 /*===========================================================================*/
985 int ray_dev_init(struct net_device *dev)
987 int i;
988 ray_dev_t *local = dev->priv;
989 dev_link_t *link = local->finder;
991 DEBUG(1,"ray_dev_init(dev=%p)\n",dev);
992 if (!(link->state & DEV_PRESENT)) {
993 DEBUG(0,"ray_dev_init - device not present\n");
994 return -1;
996 /* Download startup parameters */
997 if ( (i = dl_startup_params(dev)) < 0)
999 DEBUG(0,"ray_dev_init dl_startup_params failed - returns 0x%x/n",i);
1000 return -1;
1003 /* copy mac and broadcast addresses to linux device */
1004 memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
1005 memset(dev->broadcast, 0xff, ETH_ALEN);
1007 #ifdef RAYLINK_DEBUG
1009 UCHAR *p;
1010 p = (UCHAR *)(local->startup_res.station_addr);
1011 DEBUG(1,"ray_dev_init card hardware mac addr = %2x %2x %2x %2x %2x %2x\n",\
1012 p[0],p[1],p[2],p[3],p[4],p[5]);
1014 #endif
1016 DEBUG(2,"ray_dev_init ending\n");
1017 return 0;
1019 /*===========================================================================*/
1020 int ray_dev_config(struct net_device *dev, struct ifmap *map)
1022 ray_dev_t *local = dev->priv;
1023 dev_link_t *link = local->finder;
1024 /* Dummy routine to satisfy device structure */
1025 DEBUG(1,"ray_dev_config(dev=%p,ifmap=%p)\n",dev,map);
1026 if (!(link->state & DEV_PRESENT)) {
1027 DEBUG(0,"ray_dev_config - device not present\n");
1028 return -1;
1031 return 0;
1033 /*===========================================================================*/
1034 int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
1036 ray_dev_t *local = dev->priv;
1037 dev_link_t *link = local->finder;
1038 short length;
1040 if (!(link->state & DEV_PRESENT)) {
1041 DEBUG(0,"ray_dev_start_xmit - device not present\n");
1042 return -1;
1044 DEBUG(3,"ray_dev_start_xmit(skb=%p, dev=%p)\n",skb,dev);
1045 if (dev->tbusy)
1047 DEBUG(2,"ray_dev_start_xmit busy\n");
1048 return 1;
1050 if (local->authentication_state == NEED_TO_AUTH) {
1051 DEBUG(0,"ray_cs Sending authentication request.\n");
1052 if (!build_auth_frame (local, local->auth_id, OPEN_AUTH_REQUEST)) {
1053 local->authentication_state = AUTHENTICATED;
1054 dev->tbusy = 1;
1055 return 1;
1059 length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
1060 switch (ray_hw_xmit( skb->data, length, dev, DATA_TYPE)) {
1061 case XMIT_NO_CCS:
1062 case XMIT_NEED_AUTH:
1063 dev->tbusy = 1;
1064 return 1;
1065 case XMIT_NO_INTR:
1066 case XMIT_MSG_BAD:
1067 case XMIT_OK:
1068 default:
1069 dev->trans_start = jiffies;
1070 dev_kfree_skb(skb);
1071 return 0;
1073 return 0;
1074 } /* ray_dev_start_xmit */
1075 /*===========================================================================*/
1076 int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev,
1077 UCHAR msg_type)
1079 ray_dev_t *local = (ray_dev_t *)dev->priv;
1080 struct ccs *pccs;
1081 int ccsindex;
1082 int offset;
1083 struct tx_msg *ptx; /* Address of xmit buffer in PC space */
1084 short int addr; /* Address of xmit buffer in card space */
1086 DEBUG(3,"ray_hw_xmit(data=%p, len=%d, dev=%p)\n",data,len,dev);
1087 if (len + TX_HEADER_LENGTH > TX_BUF_SIZE)
1089 DEBUG(0,"ray_hw_xmit packet to large %d bytes\n",len);
1090 return XMIT_MSG_BAD;
1092 if ((ccsindex = get_free_tx_ccs(local)) == -1)
1094 DEBUG(2,"ray_hw_xmit - No free tx ccs\n");
1095 dev->tbusy = 1;
1096 return XMIT_NO_CCS;
1098 addr = TX_BUF_BASE + (ccsindex << 11);
1100 if (msg_type == DATA_TYPE) {
1101 local->stats.tx_bytes += len;
1102 local->stats.tx_packets++;
1105 ptx = (struct tx_msg *)(local->sram + addr);
1107 ray_build_header(local, ptx, msg_type, data);
1108 if (translate) {
1109 offset = translate_frame(local, ptx, data, len);
1111 else { /* Encapsulate frame */
1112 /* TBD TIB length will move address of ptx->var */
1113 memcpy( (UCHAR *)&ptx->var, data, len);
1114 offset = 0;
1117 /* fill in the CCS */
1118 pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
1119 len += TX_HEADER_LENGTH + offset;
1120 writeb(CCS_TX_REQUEST, &pccs->cmd);
1121 writeb(addr >> 8, &pccs->var.tx_request.tx_data_ptr[0]);
1122 writeb(local->tib_length, &pccs->var.tx_request.tx_data_ptr[1]);
1123 writeb(len >> 8, &pccs->var.tx_request.tx_data_length[0]);
1124 writeb(len & 0xff, &pccs->var.tx_request.tx_data_length[1]);
1125 /* TBD still need psm_cam? */
1126 writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode);
1127 writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate);
1128 writeb(0, &pccs->var.tx_request.antenna);
1129 DEBUG(3,"ray_hw_xmit default_tx_rate = 0x%x\n",\
1130 local->net_default_tx_rate);
1132 /* Interrupt the firmware to process the command */
1133 if (interrupt_ecf(local, ccsindex)) {
1134 DEBUG(2,"ray_hw_xmit failed - ECF not ready for intr\n");
1135 /* TBD very inefficient to copy packet to buffer, and then not
1136 send it, but the alternative is to queue the messages and that
1137 won't be done for a while. Maybe set tbusy until a CCS is free?
1139 writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
1140 return XMIT_NO_INTR;
1142 return XMIT_OK;
1143 } /* end ray_hw_xmit */
1144 /*===========================================================================*/
1145 int translate_frame(ray_dev_t *local, struct tx_msg *ptx, unsigned char *data,
1146 int len)
1148 unsigned short int proto = ((struct ethhdr *)data)->h_proto;
1149 if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
1150 DEBUG(3,"ray_cs translate_frame DIX II\n");
1151 /* Copy LLC header to card buffer */
1152 memcpy_toio((UCHAR *)&ptx->var, eth2_llc, sizeof(eth2_llc));
1153 memcpy_toio( ((UCHAR *)&ptx->var) + sizeof(eth2_llc), (UCHAR *)&proto, 2);
1154 if ((proto == 0xf380) || (proto == 0x3781)) {
1155 /* This is the selective translation table, only 2 entries */
1156 writeb(0xf8, (UCHAR *) &((struct snaphdr_t *)ptx->var)->org[3]);
1158 /* Copy body of ethernet packet without ethernet header */
1159 memcpy_toio((UCHAR *)&ptx->var + sizeof(struct snaphdr_t), \
1160 data + ETH_HLEN, len - ETH_HLEN);
1161 return sizeof(struct snaphdr_t) - ETH_HLEN;
1163 else { /* already 802 type, and proto is length */
1164 DEBUG(3,"ray_cs translate_frame 802\n");
1165 if (proto == 0xffff) { /* evil netware IPX 802.3 without LLC */
1166 DEBUG(3,"ray_cs translate_frame evil IPX\n");
1167 memcpy_toio((UCHAR *)&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
1168 return 0 - ETH_HLEN;
1170 memcpy_toio((UCHAR *)&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
1171 return 0 - ETH_HLEN;
1173 /* TBD do other frame types */
1174 } /* end translate_frame */
1175 /*===========================================================================*/
1176 void ray_build_header(ray_dev_t *local, struct tx_msg *ptx, UCHAR msg_type,
1177 unsigned char *data)
1179 writeb(PROTOCOL_VER | msg_type, &ptx->mac.frame_ctl_1);
1180 /*** IEEE 802.11 Address field assignments *************
1181 addr_1 addr_2 addr_3
1182 AP destination AP(BSSID) source
1183 Infra Terminal AP terminal destination
1184 Adhoc destination terminal BSSID
1185 *******************************************************/
1186 if (local->net_type == ADHOC) {
1187 writeb(0, &ptx->mac.frame_ctl_2);
1188 memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, 2 * ADDRLEN);
1189 memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
1191 else /* infrastructure */
1193 if (local->sparm.b4.a_acting_as_ap_status)
1195 writeb(FC2_FROM_DS, &ptx->mac.frame_ctl_2);;
1196 memcpy_toio(ptx->mac.addr_1, ((struct ethhdr *)data)->h_dest, ADDRLEN);
1197 memcpy_toio(ptx->mac.addr_2, local->bss_id, 6);
1198 memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_source, ADDRLEN);
1200 else /* Terminal */
1202 writeb(FC2_TO_DS, &ptx->mac.frame_ctl_2);
1203 memcpy_toio(ptx->mac.addr_1, local->bss_id, ADDRLEN);
1204 memcpy_toio(ptx->mac.addr_2, ((struct ethhdr *)data)->h_source, ADDRLEN);
1205 memcpy_toio(ptx->mac.addr_3, ((struct ethhdr *)data)->h_dest, ADDRLEN);
1208 } /* end encapsulate_frame */
1209 /*===========================================================================*/
1210 int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1212 ray_dev_t *local = (ray_dev_t *)dev->priv;
1213 dev_link_t *link = local->finder;
1214 int err = 0;
1216 if (!(link->state & DEV_PRESENT)) {
1217 DEBUG(0,"ray_dev_ioctl - device not present\n");
1218 return -1;
1220 DEBUG(2,"ray_cs IOCTL dev=%p, ifr=%p, cmd = 0x%x\n",dev,ifr,cmd);
1221 /* Validate the command */
1222 switch (cmd)
1224 default:
1225 DEBUG(0,"ray_dev_ioctl cmd = 0x%x\n", cmd);
1226 err = -EOPNOTSUPP;
1228 return err;
1229 } /* end ray_dev_ioctl */
1230 /*===========================================================================*/
1231 int ray_open(struct net_device *dev)
1233 dev_link_t *link;
1234 ray_dev_t *local = (ray_dev_t *)dev->priv;
1236 DEBUG(1, "ray_open('%s')\n", dev->name);
1238 for (link = dev_list; link; link = link->next)
1239 if (link->priv == dev) break;
1240 if (!DEV_OK(link))
1241 return -ENODEV;
1243 if (link->open == 0) local->num_multi = 0;
1244 link->open++;
1245 MOD_INC_USE_COUNT;
1247 dev->interrupt = 0;
1248 if (sniffer) dev->tbusy = 1;
1249 else dev->tbusy = 0;
1250 dev->start = 1;
1252 DEBUG(2,"ray_open ending\n");
1253 return 0;
1254 } /* end ray_open */
1255 /*===========================================================================*/
1256 int ray_dev_close(struct net_device *dev)
1258 dev_link_t *link;
1260 DEBUG(1, "ray_dev_close('%s')\n", dev->name);
1262 for (link = dev_list; link; link = link->next)
1263 if (link->priv == dev) break;
1264 if (link == NULL)
1265 return -ENODEV;
1267 link->open--; dev->start = 0;
1268 if (link->state & DEV_STALE_CONFIG) {
1269 link->release.expires = jiffies + HZ/20;
1270 link->state |= DEV_RELEASE_PENDING;
1271 add_timer(&link->release);
1274 MOD_DEC_USE_COUNT;
1276 return 0;
1277 } /* end ray_dev_close */
1278 /*===========================================================================*/
1279 void ray_reset(struct net_device *dev) {
1280 DEBUG(1,"ray_reset entered\n");
1281 return;
1283 /*===========================================================================*/
1284 /* Cause a firmware interrupt if it is ready for one */
1285 /* Return nonzero if not ready */
1286 int interrupt_ecf(ray_dev_t *local, int ccs)
1288 int i = 50;
1289 /* UCHAR *p = (local->amem + CIS_OFFSET + ECF_INTR_OFFSET); */
1290 dev_link_t *link = local->finder;
1292 if (!(link->state & DEV_PRESENT)) {
1293 DEBUG(0,"ray_cs interrupt_ecf - device not present\n");
1294 return -1;
1296 DEBUG(2,"interrupt_ecf(local=%p, ccs = 0x%x\n",local,ccs);
1298 /* while ( i && (*p & ECF_INTR_SET)) i--; */
1299 while ( i &&
1300 (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) & ECF_INTR_SET))
1301 i--;
1302 if (i == 0) {
1303 DEBUG(2,"ray_cs interrupt_ecf card not ready for interrupt\n");
1304 return -1;
1307 *(local->sram + SCB_BASE) = ccs;
1308 writeb(ECF_INTR_SET, local->amem + CIS_OFFSET + ECF_INTR_OFFSET);
1309 return 0;
1310 } /* interrupt_ecf */
1311 /*===========================================================================*/
1312 /* Get next free transmit CCS */
1313 /* Return - index of current tx ccs */
1314 int get_free_tx_ccs(ray_dev_t *local)
1316 int i;
1317 struct ccs *pccs = (struct ccs *)(local->sram + CCS_BASE);
1318 dev_link_t *link = local->finder;
1320 if (!(link->state & DEV_PRESENT)) {
1321 DEBUG(0,"ray_cs get_free_tx_ccs - device not present\n");
1322 return -1;
1325 for (i=0; i < NUMBER_OF_TX_CCS; i++) {
1326 if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) {
1327 writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status);
1328 writeb(CCS_END_LIST, &(pccs+i)->link);
1329 return i;
1332 DEBUG(1,"ray_cs ERROR no free tx CCS for raylink card\n");
1333 return -1;
1334 } /* get_free_tx_ccs */
1335 /*===========================================================================*/
1336 /* Get next free CCS */
1337 /* Return - index of current ccs */
1338 int get_free_ccs(ray_dev_t *local)
1340 int i;
1341 struct ccs *pccs = (struct ccs *)(local->sram + CCS_BASE);
1342 dev_link_t *link = local->finder;
1344 if (!(link->state & DEV_PRESENT)) {
1345 DEBUG(0,"ray_cs get_free_ccs - device not present\n");
1346 return -1;
1348 for (i = NUMBER_OF_TX_CCS; i < NUMBER_OF_CCS; i++) {
1349 if (readb(&(pccs+i)->buffer_status) == CCS_BUFFER_FREE) {
1350 writeb(CCS_BUFFER_BUSY, &(pccs+i)->buffer_status);
1351 writeb(CCS_END_LIST, &(pccs+i)->link);
1352 return i;
1355 DEBUG(1,"ray_cs ERROR no free CCS for raylink card\n");
1356 return -1;
1357 } /* get_free_ccs */
1358 /*===========================================================================*/
1359 void authenticate_timeout(u_long data)
1361 ray_dev_t *local = (ray_dev_t *)data;
1362 del_timer(&local->timer);
1363 DEBUG(0,"ray_cs Authentication with access point failed - timeout\n");
1364 join_net((u_long)local);
1366 /*===========================================================================*/
1367 int asc_to_int(char a)
1369 if (a < '0') return -1;
1370 if (a <= '9') return (a - '0');
1371 if (a < 'A') return -1;
1372 if (a <= 'F') return (10 + a - 'A');
1373 if (a < 'a') return -1;
1374 if (a <= 'f') return (10 + a - 'a');
1375 return -1;
1377 /*===========================================================================*/
1378 int parse_addr(char *in_str, UCHAR *out)
1380 int len;
1381 int i,j,k;
1382 int status;
1384 if (in_str == NULL) return 0;
1385 if ((len = strlen(in_str)) < 2) return 0;
1386 memset(out, 0, ADDRLEN);
1388 status = 1;
1389 j = len - 1;
1390 if (j > 12) j = 12;
1391 i = 5;
1393 while (j > 0)
1395 if ((k = asc_to_int(in_str[j--])) != -1) out[i] = k;
1396 else return 0;
1398 if (j == 0) break;
1399 if ((k = asc_to_int(in_str[j--])) != -1) out[i] += k << 4;
1400 else return 0;
1401 if (!i--) break;
1403 return status;
1405 /*===========================================================================*/
1406 struct enet_statistics *ray_get_stats(struct net_device *dev)
1408 ray_dev_t *local = (ray_dev_t *)dev->priv;
1409 dev_link_t *link = local->finder;
1410 struct status *p = (struct status *)(local->sram + STATUS_BASE);
1411 if (!(link->state & DEV_PRESENT)) {
1412 DEBUG(0,"ray_cs enet_statistics - device not present\n");
1413 return &local->stats;
1415 if (p->mrx_overflow_for_host)
1417 local->stats.rx_over_errors += ntohs(p->mrx_overflow);
1418 p->mrx_overflow = 0;
1419 p->mrx_overflow_for_host = 0;
1421 if (p->mrx_checksum_error_for_host)
1423 local->stats.rx_crc_errors += ntohs(p->mrx_checksum_error);
1424 p->mrx_checksum_error = 0;
1425 p->mrx_checksum_error_for_host = 0;
1427 if (p->rx_hec_error_for_host)
1429 local->stats.rx_frame_errors += ntohs(p->rx_hec_error);
1430 p->rx_hec_error = 0;
1431 p->rx_hec_error_for_host = 0;
1433 return &local->stats;
1435 /*===========================================================================*/
1436 void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len)
1438 ray_dev_t *local = (ray_dev_t *)dev->priv;
1439 dev_link_t *link = local->finder;
1440 int ccsindex;
1441 int i;
1442 struct ccs *pccs;
1444 if (!(link->state & DEV_PRESENT)) {
1445 DEBUG(0,"ray_update_parm - device not present\n");
1446 return;
1449 if ((ccsindex = get_free_ccs(local)) == -1)
1451 DEBUG(0,"ray_update_parm - No free ccs\n");
1452 return;
1454 pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
1455 writeb(CCS_UPDATE_PARAMS, &pccs->cmd);
1456 writeb(objid, &pccs->var.update_param.object_id);
1457 writeb(1, &pccs->var.update_param.number_objects);
1458 writeb(0, &pccs->var.update_param.failure_cause);
1459 for (i=0; i<len; i++) {
1460 writeb(value[i], local->sram + HOST_TO_ECF_BASE);
1462 /* Interrupt the firmware to process the command */
1463 if (interrupt_ecf(local, ccsindex)) {
1464 DEBUG(0,"ray_cs associate failed - ECF not ready for intr\n");
1465 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
1468 /*===========================================================================*/
1469 static void ray_update_multi_list(struct net_device *dev, int all)
1471 struct dev_mc_list *dmi, **dmip;
1472 int ccsindex;
1473 struct ccs *pccs;
1474 int i = 0;
1475 ray_dev_t *local = (ray_dev_t *)dev->priv;
1476 dev_link_t *link = local->finder;
1477 UCHAR *p = local->sram + HOST_TO_ECF_BASE;
1479 if (!(link->state & DEV_PRESENT)) {
1480 DEBUG(1,"ray_update_multi_list - device not present\n");
1481 return;
1483 else
1484 DEBUG(1,"ray_update_multi_list(%p)\n",dev);
1485 if ((ccsindex = get_free_ccs(local)) == -1)
1487 DEBUG(1,"ray_update_multi - No free ccs\n");
1488 return;
1490 pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
1491 writeb(CCS_UPDATE_MULTICAST_LIST, &pccs->cmd);
1493 if (all) {
1494 writeb(0xff, &pccs->var);
1495 local->num_multi = 0xff;
1497 else {
1498 /* Copy the kernel's list of MC addresses to card */
1499 for (dmip=&dev->mc_list; (dmi=*dmip)!=NULL; dmip=&dmi->next) {
1500 memcpy_toio(p, dmi->dmi_addr, ETH_ALEN);
1501 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]);
1502 p += ETH_ALEN;
1503 i++;
1505 if (i > 256/ADDRLEN) i = 256/ADDRLEN;
1506 writeb((UCHAR)i, &pccs->var);
1507 DEBUG(1,"ray_cs update_multi %d addresses in list\n", i);
1508 /* Interrupt the firmware to process the command */
1509 local->num_multi = i;
1511 if (interrupt_ecf(local, ccsindex)) {
1512 DEBUG(1,"ray_cs update_multi failed - ECF not ready for intr\n");
1513 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
1515 } /* end ray_update_multi_list */
1516 /*===========================================================================*/
1517 static void set_multicast_list(struct net_device *dev)
1519 ray_dev_t *local = (ray_dev_t *)dev->priv;
1520 UCHAR promisc;
1522 DEBUG(1,"ray_cs set_multicast_list(%p)\n",dev);
1524 if (dev->flags & IFF_PROMISC)
1526 if (local->sparm.b5.a_promiscuous_mode == 0) {
1527 DEBUG(1,"ray_cs set_multicast_list promisc on\n");
1528 local->sparm.b5.a_promiscuous_mode = 1;
1529 promisc = 1;
1530 ray_update_parm(dev, OBJID_promiscuous_mode, \
1531 &promisc, sizeof(promisc));
1534 else {
1535 if (local->sparm.b5.a_promiscuous_mode == 1) {
1536 DEBUG(1,"ray_cs set_multicast_list promisc off\n");
1537 local->sparm.b5.a_promiscuous_mode = 0;
1538 promisc = 0;
1539 ray_update_parm(dev, OBJID_promiscuous_mode, \
1540 &promisc, sizeof(promisc));
1544 if (dev->flags & IFF_ALLMULTI) ray_update_multi_list(dev, 1);
1545 else
1547 if (local->num_multi != dev->mc_count) ray_update_multi_list(dev, 0);
1549 } /* end set_multicast_list */
1550 /*=============================================================================
1551 * All routines below here are run at interrupt time.
1552 =============================================================================*/
1553 void ray_interrupt(int irq, void *dev_id, struct pt_regs * regs)
1555 struct net_device *dev = (struct net_device *)dev_id;
1556 dev_link_t *link;
1557 ray_dev_t *local;
1558 struct ccs *pccs;
1559 struct rcs *prcs;
1560 UCHAR rcsindex;
1561 UCHAR tmp;
1562 UCHAR cmd;
1563 UCHAR status;
1565 if (dev == NULL) {
1566 link = dev_list;
1567 dev = (struct net_device *)link->priv;
1568 DEBUG(4,"ray_cs interrupt dev = %p, link = %p\n",dev,link);
1569 if (dev->irq != irq)
1571 DEBUG(0,"ray_cs interrupt irq %d for unknown device.\n", irq);
1572 return;
1575 DEBUG(4,"ray_cs: interrupt for *dev=%p\n",dev);
1577 if (dev->interrupt) {
1578 printk("ray_cs Reentering interrupt handler not allowed\n");
1579 return;
1581 dev->interrupt = 1;
1582 local = (ray_dev_t *)dev->priv;
1583 link = (dev_link_t *)local->finder;
1584 if ( ! (link->state & DEV_PRESENT) || link->state & DEV_SUSPEND ) {
1585 DEBUG(1,"ray_cs interrupt from device not present or suspended.\n");
1586 return;
1588 rcsindex = ((struct scb *)(local->sram))->rcs_index;
1590 if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS))
1592 DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex);
1593 clear_interrupt(local);
1594 dev->interrupt = 0;
1595 return;
1597 if (rcsindex < NUMBER_OF_CCS) /* If it's a returned CCS */
1599 pccs = ((struct ccs *) (local->sram + CCS_BASE)) + rcsindex;
1600 cmd = readb(&pccs->cmd);
1601 status = readb(&pccs->buffer_status);
1602 switch (cmd)
1604 case CCS_DOWNLOAD_STARTUP_PARAMS: /* Happens in firmware someday */
1605 del_timer(&local->timer);
1606 if (status == CCS_COMMAND_COMPLETE) {
1607 DEBUG(1,"ray_cs interrupt download_startup_parameters OK\n");
1609 else {
1610 DEBUG(1,"ray_cs interrupt download_startup_parameters fail\n");
1612 break;
1613 case CCS_UPDATE_PARAMS:
1614 DEBUG(1,"ray_cs interrupt update params done\n");
1615 if (status != CCS_COMMAND_COMPLETE) {
1616 tmp = readb(&pccs->var.update_param.failure_cause);
1617 DEBUG(0,"ray_cs interrupt update params failed - reason %d\n",tmp);
1619 break;
1620 case CCS_REPORT_PARAMS:
1621 DEBUG(1,"ray_cs interrupt report params done\n");
1622 break;
1623 case CCS_UPDATE_MULTICAST_LIST: /* Note that this CCS isn't returned */
1624 DEBUG(1,"ray_cs interrupt CCS Update Multicast List done\n");
1625 break;
1626 case CCS_UPDATE_POWER_SAVINGS_MODE:
1627 DEBUG(1,"ray_cs interrupt update power save mode done\n");
1628 break;
1629 case CCS_START_NETWORK:
1630 case CCS_JOIN_NETWORK:
1631 if (status == CCS_COMMAND_COMPLETE) {
1632 if (readb(&pccs->var.start_network.net_initiated) == 1) {
1633 DEBUG(0,"ray_cs interrupt network \"%s\"started\n",\
1634 local->sparm.b4.a_current_ess_id);
1636 else {
1637 DEBUG(0,"ray_cs interrupt network \"%s\" joined\n",\
1638 local->sparm.b4.a_current_ess_id);
1640 memcpy_fromio(&local->bss_id,pccs->var.start_network.bssid,ADDRLEN);
1642 if (local->fw_ver == 0x55) local->net_default_tx_rate = 3;
1643 else local->net_default_tx_rate =
1644 readb(&pccs->var.start_network.net_default_tx_rate);
1645 local->encryption = readb(&pccs->var.start_network.encryption);
1646 if (!sniffer && (local->net_type == INFRA)
1647 && !(local->sparm.b4.a_acting_as_ap_status)) {
1648 authenticate(local);
1650 local->card_status = CARD_ACQ_COMPLETE;
1652 else {
1653 local->card_status = CARD_ACQ_FAILED;
1655 del_timer(&local->timer);
1656 local->timer.expires = jiffies + HZ*5;
1657 local->timer.data = (long)local;
1658 if (status == CCS_START_NETWORK) {
1659 DEBUG(0,"ray_cs interrupt network \"%s\" start failed\n",\
1660 local->sparm.b4.a_current_ess_id);
1661 local->timer.function = &start_net;
1663 else {
1664 DEBUG(0,"ray_cs interrupt network \"%s\" join failed\n",\
1665 local->sparm.b4.a_current_ess_id);
1666 local->timer.function = &join_net;
1668 add_timer(&local->timer);
1670 break;
1671 case CCS_START_ASSOCIATION:
1672 if (status == CCS_COMMAND_COMPLETE) {
1673 local->card_status = CARD_ASSOC_COMPLETE;
1674 DEBUG(0,"ray_cs association successful\n");
1676 else
1678 DEBUG(0,"ray_cs association failed,\n");
1679 local->card_status = CARD_ASSOC_FAILED;
1680 join_net((u_long)local);
1682 break;
1683 case CCS_TX_REQUEST:
1684 if (status == CCS_COMMAND_COMPLETE) {
1685 DEBUG(3,"ray_cs interrupt tx request complete\n");
1687 else {
1688 DEBUG(1,"ray_cs interrupt tx request failed\n");
1690 if (!sniffer) dev->tbusy = 0;
1691 mark_bh(NET_BH);
1692 break;
1693 case CCS_TEST_MEMORY:
1694 DEBUG(1,"ray_cs interrupt mem test done\n");
1695 break;
1696 case CCS_SHUTDOWN:
1697 DEBUG(1,"ray_cs interrupt Unexpected CCS returned - Shutdown\n");
1698 break;
1699 case CCS_DUMP_MEMORY:
1700 DEBUG(1,"ray_cs interrupt dump memory done\n");
1701 break;
1702 case CCS_START_TIMER:
1703 DEBUG(2,"ray_cs interrupt DING - raylink timer expired\n");
1704 break;
1705 default:
1706 DEBUG(1,"ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",\
1707 rcsindex, cmd);
1709 writeb(CCS_BUFFER_FREE, &pccs->buffer_status);
1711 else /* It's an RCS */
1713 prcs = ((struct rcs *)(local->sram + CCS_BASE)) + rcsindex;
1715 switch (readb(&prcs->interrupt_id))
1717 case PROCESS_RX_PACKET:
1718 ray_rx(dev, local, prcs);
1719 break;
1720 case REJOIN_NET_COMPLETE:
1721 DEBUG(1,"ray_cs interrupt rejoin net complete\n");
1722 local->card_status = CARD_ACQ_COMPLETE;
1723 /* do we need to clear tx buffers CCS's? */
1724 if (local->sparm.b4.a_network_type == ADHOC) {
1725 if (!sniffer) dev->tbusy = 0;
1727 else {
1728 memcpy_fromio(&local->bss_id, prcs->var.rejoin_net_complete.bssid, ADDRLEN);
1729 DEBUG(1,"ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n",\
1730 local->bss_id[0], local->bss_id[1], local->bss_id[2],\
1731 local->bss_id[3], local->bss_id[4], local->bss_id[5]);
1732 if (!sniffer) authenticate(local);
1734 break;
1735 case ROAMING_INITIATED:
1736 DEBUG(1,"ray_cs interrupt roaming initiated\n");
1737 dev->tbusy = 1;
1738 local->card_status = CARD_DOING_ACQ;
1739 break;
1740 case JAPAN_CALL_SIGN_RXD:
1741 DEBUG(1,"ray_cs interrupt japan call sign rx\n");
1742 break;
1743 default:
1744 DEBUG(1,"ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",\
1745 rcsindex, readb(&prcs->interrupt_id));
1746 break;
1748 writeb(CCS_BUFFER_FREE, &prcs->buffer_status);
1750 clear_interrupt(local);
1751 dev->interrupt = 0;
1752 } /* ray_interrupt */
1753 /*===========================================================================*/
1754 void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs *prcs)
1756 int rx_len;
1757 unsigned int pkt_addr;
1758 UCHAR *pmsg;
1759 DEBUG(4,"ray_rx process rx packet\n");
1761 /* Calculate address of packet within Rx buffer */
1762 pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
1763 + readb(&prcs->var.rx_packet.rx_data_ptr[1])) & RX_BUFF_END;
1764 /* Length of first packet fragment */
1765 rx_len = (readb(&prcs->var.rx_packet.rx_data_length[0]) << 8)
1766 + readb(&prcs->var.rx_packet.rx_data_length[1]);
1768 pmsg = local->rmem + pkt_addr;
1769 switch(readb(pmsg))
1771 case DATA_TYPE:
1772 DEBUG(4,"ray_rx data type\n");
1773 rx_data(dev, prcs, pkt_addr, rx_len);
1774 break;
1775 case AUTHENTIC_TYPE:
1776 DEBUG(4,"ray_rx authentic type\n");
1777 if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
1778 else rx_authenticate(local, prcs, pkt_addr, rx_len);
1779 break;
1780 case DEAUTHENTIC_TYPE:
1781 DEBUG(4,"ray_rx deauth type\n");
1782 if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
1783 else rx_deauthenticate(local, prcs, pkt_addr, rx_len);
1784 break;
1785 case NULL_MSG_TYPE:
1786 DEBUG(3,"ray_cs rx NULL msg\n");
1787 break;
1788 case BEACON_TYPE:
1789 DEBUG(4,"ray_rx beacon type\n");
1790 if (sniffer) rx_data(dev, prcs, pkt_addr, rx_len);
1792 copy_from_rx_buff(local, (UCHAR *)&local->last_bcn, pkt_addr,
1793 rx_len < sizeof(struct beacon_rx) ?
1794 rx_len : sizeof(struct beacon_rx));
1796 /* Get the statistics so the card counters never overflow */
1797 ray_get_stats(dev);
1798 break;
1799 default:
1800 DEBUG(0,"ray_cs unknown pkt type %2x\n", readb(pmsg));
1801 break;
1804 } /* end ray_rx */
1805 /*===========================================================================*/
1806 void rx_data(struct net_device *dev, struct rcs *prcs, unsigned int pkt_addr,
1807 int rx_len)
1809 struct sk_buff *skb = NULL;
1810 struct rcs *prcslink = prcs;
1811 ray_dev_t *local = dev->priv;
1812 UCHAR *rx_ptr;
1813 int total_len;
1814 int tmp;
1816 if (!sniffer) {
1817 if (translate) {
1818 /* TBD length needs fixing for translated header */
1819 if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
1820 rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN))
1822 DEBUG(0,"ray_cs invalid packet length %d received \n",rx_len);
1823 return;
1826 else /* encapsulated ethernet */ {
1827 if (rx_len < (ETH_HLEN + RX_MAC_HEADER_LENGTH) ||
1828 rx_len > (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN + FCS_LEN))
1830 DEBUG(0,"ray_cs invalid packet length %d received \n",rx_len);
1831 return;
1835 DEBUG(4,"ray_cs rx_data packet\n");
1836 /* If fragmented packet, verify sizes of fragments add up */
1837 if (prcs->var.rx_packet.next_frag_rcs_index != 0xFF) {
1838 DEBUG(1,"ray_cs rx'ed fragment\n");
1839 tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
1840 + readb(&prcs->var.rx_packet.totalpacketlength[1]);
1841 total_len = tmp;
1842 prcslink = prcs;
1843 do {
1844 tmp -= (readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8)
1845 + readb(&prcslink->var.rx_packet.rx_data_length[1]);
1846 if (readb(&prcslink->var.rx_packet.next_frag_rcs_index) == 0xFF
1847 || tmp < 0) break;
1848 prcslink = ((struct rcs *)(local->sram + CCS_BASE))
1849 + readb(&prcslink->link_field);
1850 } while (1);
1852 if (tmp < 0)
1854 DEBUG(0,"ray_cs rx_data fragment lengths don't add up\n");
1855 local->stats.rx_dropped++;
1856 release_frag_chain(local, prcs);
1857 return;
1860 else { /* Single unfragmented packet */
1861 total_len = rx_len;
1864 skb = dev_alloc_skb( total_len+5 );
1865 if (skb == NULL)
1867 DEBUG(0,"ray_cs rx_data could not allocate skb\n");
1868 local->stats.rx_dropped++;
1869 if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF)
1870 release_frag_chain(local, prcs);
1871 return;
1873 skb_reserve( skb, 2); /* Align IP on 16 byte (TBD check this)*/
1874 skb->dev = dev;
1876 DEBUG(4,"ray_cs rx_data total_len = %x, rx_len = %x\n",total_len,rx_len);
1878 /************************/
1879 /* Reserve enough room for the whole damn packet. */
1880 rx_ptr = skb_put( skb, total_len);
1881 /* Copy the whole packet to sk_buff */
1882 rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr & RX_BUFF_END, rx_len);
1884 /* Now, deal with encapsulation/translation/sniffer */
1885 if (!sniffer) {
1886 if (!translate) {
1887 /* Encapsulated ethernet, so just lop off 802.11 MAC header */
1888 /* TBD reserve skb_reserve( skb, RX_MAC_HEADER_LENGTH); */
1889 skb_pull( skb, RX_MAC_HEADER_LENGTH);
1891 else {
1892 /* Do translation */
1893 untranslate(local, skb, total_len);
1896 else
1897 { /* sniffer mode, so just pass whole packet */ };
1899 /************************/
1900 /* Now pick up the rest of the fragments if any */
1901 tmp = 17;
1902 if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
1903 prcslink = prcs;
1904 DEBUG(1,"ray_cs rx_data in fragment loop\n");
1905 do {
1906 prcslink = ((struct rcs *)(local->sram + CCS_BASE))
1907 + readb(&prcslink->var.rx_packet.next_frag_rcs_index);
1908 rx_len = (( readb(&prcslink->var.rx_packet.rx_data_length[0]) << 8)
1909 + readb(&prcslink->var.rx_packet.rx_data_length[1]))
1910 & RX_BUFF_END;
1911 pkt_addr = (( readb(&prcslink->var.rx_packet.rx_data_ptr[0]) << 8)
1912 + readb(&prcslink->var.rx_packet.rx_data_ptr[1]))
1913 & RX_BUFF_END;
1915 rx_ptr += copy_from_rx_buff(local, rx_ptr, pkt_addr, rx_len);
1917 } while (tmp-- &&
1918 readb(&prcslink->var.rx_packet.next_frag_rcs_index) != 0xFF);
1919 release_frag_chain(local, prcs);
1922 skb->protocol = eth_type_trans(skb,dev);
1923 netif_rx(skb);
1925 local->stats.rx_packets++;
1926 local->stats.rx_bytes += skb->len;
1927 } /* end rx_data */
1928 /*===========================================================================*/
1929 void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
1931 snaphdr_t *psnap = (snaphdr_t *)(skb->data + RX_MAC_HEADER_LENGTH);
1932 struct mac_header *pmac = (struct mac_header *)skb->data;
1933 unsigned short type = *(unsigned short *)psnap->ethertype;
1934 unsigned int xsap = *(unsigned int *)psnap & 0x00ffffff;
1935 unsigned int org = (*(unsigned int *)psnap->org) & 0x00ffffff;
1936 int delta;
1937 struct ethhdr *peth;
1938 UCHAR srcaddr[ADDRLEN];
1939 UCHAR destaddr[ADDRLEN];
1940 int i;
1942 if (local->sparm.b5.a_acting_as_ap_status != TYPE_STA)
1943 memcpy(destaddr, pmac->addr_3, ADDRLEN);
1944 else
1945 memcpy(destaddr, pmac->addr_1, ADDRLEN);
1946 memcpy(srcaddr, pmac->addr_2, ADDRLEN);
1948 DEBUG(3,"skb->data before untranslate");
1949 for (i=0;i<64;i++)
1950 DEBUG(3,"%02x ",skb->data[i]);
1951 DEBUG(3,"\ntype = %08x, xsap = %08x, org = %08x\n",type,xsap,org);
1952 DEBUG(3,"untranslate skb->data = %p\n",skb->data);
1954 if ( xsap != SNAP_ID) {
1955 /* not a snap type so leave it alone */
1956 DEBUG(3,"ray_cs untranslate NOT SNAP %x\n", *(unsigned int *)psnap & 0x00ffffff);
1958 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
1959 peth = (struct ethhdr *)(skb->data + delta);
1960 peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
1962 else { /* Its a SNAP */
1963 if (org == BRIDGE_ENCAP) { /* EtherII and nuke the LLC */
1964 DEBUG(3,"ray_cs untranslate Bridge encap\n");
1965 delta = RX_MAC_HEADER_LENGTH
1966 + sizeof(struct snaphdr_t) - ETH_HLEN;
1967 peth = (struct ethhdr *)(skb->data + delta);
1968 peth->h_proto = type;
1970 else {
1971 if (org == RFC1042_ENCAP) {
1972 switch (type) {
1973 case RAY_IPX_TYPE:
1974 case APPLEARP_TYPE:
1975 DEBUG(3,"ray_cs untranslate RFC IPX/AARP\n");
1976 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
1977 peth = (struct ethhdr *)(skb->data + delta);
1978 peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
1979 break;
1980 default:
1981 DEBUG(3,"ray_cs untranslate RFC default\n");
1982 delta = RX_MAC_HEADER_LENGTH +
1983 sizeof(struct snaphdr_t) - ETH_HLEN;
1984 peth = (struct ethhdr *)(skb->data + delta);
1985 peth->h_proto = type;
1986 break;
1989 else {
1990 printk("ray_cs untranslate very confused by packet\n");
1991 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
1992 peth = (struct ethhdr *)(skb->data + delta);
1993 peth->h_proto = type;
1997 /* TBD reserve skb_reserve(skb, delta); */
1998 skb_pull(skb, delta);
1999 DEBUG(3,"untranslate after skb_pull(%d), skb->data = %p\n",delta,skb->data);
2000 memcpy(peth->h_dest, destaddr, ADDRLEN);
2001 memcpy(peth->h_source, srcaddr, ADDRLEN);
2002 DEBUG(3,"skb->data after untranslate:");
2003 for (i=0;i<64;i++)
2004 DEBUG(3,"%02x ",skb->data[i]);
2005 DEBUG(3,"\n");
2006 } /* end untranslate */
2007 /*===========================================================================*/
2008 /* Copy data from circular receive buffer to PC memory.
2009 * dest = destination address in PC memory
2010 * pkt_addr = source address in receive buffer
2011 * len = length of packet to copy
2013 int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int length)
2015 int wrap_bytes = (pkt_addr + length) - (RX_BUFF_END + 1);
2016 if (wrap_bytes <= 0)
2018 memcpy_fromio(dest,local->rmem + pkt_addr,length);
2020 else /* Packet wrapped in circular buffer */
2022 memcpy_fromio(dest,local->rmem+pkt_addr,length - wrap_bytes);
2023 memcpy_fromio(dest + length - wrap_bytes, local->rmem, wrap_bytes);
2025 return length;
2027 /*===========================================================================*/
2028 void release_frag_chain(ray_dev_t *local, struct rcs* prcs)
2030 struct rcs *prcslink = prcs;
2031 int tmp = 17;
2032 unsigned rcsindex = readb(&prcs->var.rx_packet.next_frag_rcs_index);
2034 while (tmp--) {
2035 writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
2036 if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
2037 DEBUG(1,"ray_cs interrupt bad rcsindex = 0x%x\n",rcsindex);
2038 break;
2040 prcslink = ((struct rcs *)(local->sram + CCS_BASE)) + rcsindex;
2041 rcsindex = readb(&prcslink->var.rx_packet.next_frag_rcs_index);
2043 writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
2045 /*===========================================================================*/
2046 void authenticate(ray_dev_t *local)
2048 dev_link_t *link = local->finder;
2049 DEBUG(0,"ray_cs Starting authentication.\n");
2050 if (!(link->state & DEV_PRESENT)) {
2051 DEBUG(1,"ray_cs authenticate - device not present\n");
2052 return;
2055 del_timer(&local->timer);
2056 if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) {
2057 local->timer.function = &join_net;
2059 else {
2060 local->timer.function = &authenticate_timeout;
2062 local->timer.expires = jiffies + HZ*2;
2063 local->timer.data = (long)local;
2064 add_timer(&local->timer);
2065 local->authentication_state = AWAITING_RESPONSE;
2066 } /* end authenticate */
2067 /*===========================================================================*/
2068 void rx_authenticate(ray_dev_t *local, struct rcs *prcs,
2069 unsigned int pkt_addr, int rx_len)
2071 UCHAR buff[256];
2072 struct rx_msg *msg = (struct rx_msg *)buff;
2074 del_timer(&local->timer);
2076 copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
2077 /* if we are trying to get authenticated */
2078 if (local->sparm.b4.a_network_type == ADHOC) {
2079 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]);
2080 if (msg->var[2] == 1) {
2081 DEBUG(0,"ray_cs Sending authentication response.\n");
2082 if (!build_auth_frame (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
2083 local->authentication_state = NEED_TO_AUTH;
2084 memcpy(local->auth_id, msg->mac.addr_2, ADDRLEN);
2088 else /* Infrastructure network */
2090 if (local->authentication_state == AWAITING_RESPONSE) {
2091 /* Verify authentication sequence #2 and success */
2092 if (msg->var[2] == 2) {
2093 if ((msg->var[3] | msg->var[4]) == 0) {
2094 DEBUG(1,"Authentication successful\n");
2095 local->card_status = CARD_AUTH_COMPLETE;
2096 associate(local);
2097 local->authentication_state = AUTHENTICATED;
2099 else {
2100 DEBUG(0,"Authentication refused\n");
2101 local->card_status = CARD_AUTH_REFUSED;
2102 join_net((u_long)local);
2103 local->authentication_state = UNAUTHENTICATED;
2109 } /* end rx_authenticate */
2110 /*===========================================================================*/
2111 void associate(ray_dev_t *local)
2113 struct ccs *pccs;
2114 dev_link_t *link = local->finder;
2115 struct net_device *dev = link->priv;
2116 int ccsindex;
2117 if (!(link->state & DEV_PRESENT)) {
2118 DEBUG(1,"ray_cs associate - device not present\n");
2119 return;
2121 /* If no tx buffers available, return*/
2122 if ((ccsindex = get_free_ccs(local)) == -1)
2124 /* TBD should never be here but... what if we are? */
2125 DEBUG(1,"ray_cs associate - No free ccs\n");
2126 return;
2128 DEBUG(1,"ray_cs Starting association with access point\n");
2129 pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
2130 /* fill in the CCS */
2131 writeb(CCS_START_ASSOCIATION, &pccs->cmd);
2132 /* Interrupt the firmware to process the command */
2133 if (interrupt_ecf(local, ccsindex)) {
2134 DEBUG(1,"ray_cs associate failed - ECF not ready for intr\n");
2135 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
2137 del_timer(&local->timer);
2138 local->timer.expires = jiffies + HZ*2;
2139 local->timer.data = (long)local;
2140 local->timer.function = &join_net;
2141 add_timer(&local->timer);
2142 local->card_status = CARD_ASSOC_FAILED;
2143 return;
2145 if (!sniffer) dev->tbusy = 0;
2147 } /* end associate */
2148 /*===========================================================================*/
2149 void rx_deauthenticate(ray_dev_t *local, struct rcs *prcs,
2150 unsigned int pkt_addr, int rx_len)
2152 /* UCHAR buff[256];
2153 struct rx_msg *msg = (struct rx_msg *)buff;
2155 DEBUG(0,"Deauthentication frame received\n");
2156 local->authentication_state = UNAUTHENTICATED;
2157 /* Need to reauthenticate or rejoin depending on reason code */
2158 /* copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
2161 /*===========================================================================*/
2162 void clear_interrupt(ray_dev_t *local)
2164 writeb(0, local->amem + CIS_OFFSET + HCS_INTR_OFFSET);
2166 /*===========================================================================*/
2167 #ifdef CONFIG_PROC_FS
2168 #define MAXDATA (PAGE_SIZE - 80)
2170 static char *card_status[] = {
2171 "Card inserted - uninitialized", /* 0 */
2172 "Card not downloaded", /* 1 */
2173 "Waiting for download parameters", /* 2 */
2174 "Card doing acquisition", /* 3 */
2175 "Acquisition complete", /* 4 */
2176 "Authentication complete", /* 5 */
2177 "Association complete", /* 6 */
2178 "???", "???", "???", "???", /* 7 8 9 10 undefined */
2179 "Card init error", /* 11 */
2180 "Download parameters error", /* 12 */
2181 "???", /* 13 */
2182 "Acquisition failed", /* 14 */
2183 "Authentication refused", /* 15 */
2184 "Association failed" /* 16 */
2187 static char *nettype[] = {"Adhoc", "Infra "};
2188 static char *framing[] = {"Encapsulation", "Translation"}
2190 /*===========================================================================*/
2191 int ray_cs_proc_read(char *buf, char **start, off_t offset,
2192 int len, int unused)
2194 /* Print current values which are not available via other means
2195 * eg ifconfig
2197 int i;
2198 dev_link_t *link = dev_list;
2199 struct net_device *dev = (struct net_device *)link->priv;
2200 ray_dev_t *local = (ray_dev_t *)dev->priv;
2201 UCHAR *p;
2202 struct freq_hop_element *pfh;
2203 UCHAR c[33];
2205 len = 0;
2207 len += sprintf(buf + len, "Raylink Wireless LAN driver status\n");
2208 len += sprintf(buf + len, "%s\n", rcsid);
2209 /* build 4 does not report version, and field is 0x55 after memtest */
2210 len += sprintf(buf + len, "Firmware version = ");
2211 if (local->fw_ver == 0x55)
2212 len += sprintf(buf + len, "4 - Use dump_cis for more details\n");
2213 else
2214 len += sprintf(buf + len, "%2d.%02d.%02d\n",
2215 local->fw_ver, local->fw_bld, local->fw_var);
2217 for (i=0; i<32; i++) c[i] = local->sparm.b5.a_current_ess_id[i];
2218 c[32] = 0;
2219 len += sprintf(buf + len, "%s network ESSID = \"%s\"\n",
2220 nettype[local->sparm.b5.a_network_type], c);
2222 p = local->bss_id;
2223 len += sprintf(buf + len,
2224 "BSSID = %02x:%02x:%02x:%02x:%02x:%02x\n",
2225 p[0],p[1],p[2],p[3],p[4],p[5]);
2227 len += sprintf(buf + len, "Country code = %d\n",
2228 local->sparm.b5.a_curr_country_code);
2230 i = local->card_status;
2231 if (i < 0) i = 10;
2232 if (i > 16) i = 10;
2233 len += sprintf(buf + len, "Card status = %s\n", card_status[i]);
2235 len += sprintf(buf + len, "Framing mode = %s\n",framing[translate]);
2237 /* Pull some fields out of last beacon received */
2238 len += sprintf(buf + len, "Beacon Interval = %d Kus\n",
2239 local->last_bcn.beacon_intvl[0]
2240 + 256 * local->last_bcn.beacon_intvl[1]);
2242 p = local->last_bcn.elements;
2243 if (p[0] == C_ESSID_ELEMENT_ID) p += p[1] + 2;
2244 else {
2245 len += sprintf(buf + len, "Parse beacon failed at essid element id = %d\n",p[0]);
2246 return len;
2249 if (p[0] == C_SUPPORTED_RATES_ELEMENT_ID) {
2250 len += sprintf(buf + len, "Supported rate codes = ");
2251 for (i=2; i<p[1] + 2; i++)
2252 len += sprintf(buf + len, "0x%02x ", p[i]);
2253 len += sprintf(buf + len, "\n");
2254 p += p[1] + 2;
2256 else {
2257 len += sprintf(buf + len, "Parse beacon failed at rates element\n");
2258 return len;
2261 if (p[0] == C_FH_PARAM_SET_ELEMENT_ID) {
2262 pfh = (struct freq_hop_element *)p;
2263 len += sprintf(buf + len, "Hop dwell = %d Kus\n",
2264 pfh->dwell_time[0] + 256 * pfh->dwell_time[1]);
2265 len += sprintf(buf + len, "Hop set = %d \n", pfh->hop_set);
2266 len += sprintf(buf + len, "Hop pattern = %d \n", pfh->hop_pattern);
2267 len += sprintf(buf + len, "Hop index = %d \n", pfh->hop_index);
2268 p += p[1] + 2;
2270 else {
2271 len += sprintf(buf + len, "Parse beacon failed at FH param element\n");
2272 return len;
2274 return len;
2277 #endif
2278 /*===========================================================================*/
2279 int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
2281 int addr;
2282 struct ccs *pccs;
2283 struct tx_msg *ptx;
2284 int ccsindex;
2286 /* If no tx buffers available, return */
2287 if ((ccsindex = get_free_tx_ccs(local)) == -1)
2289 /* TBD should never be here but... what if we are? */
2290 DEBUG(1,"ray_cs send authenticate - No free tx ccs\n");
2291 return -1;
2294 pccs = ((struct ccs *)(local->sram + CCS_BASE)) + ccsindex;
2296 /* Address in card space */
2297 addr = TX_BUF_BASE + (ccsindex << 11);
2298 /* fill in the CCS */
2299 writeb(CCS_TX_REQUEST, &pccs->cmd);
2300 writeb(addr >> 8, pccs->var.tx_request.tx_data_ptr);
2301 writeb(0x20, pccs->var.tx_request.tx_data_ptr + 1);
2302 writeb(TX_AUTHENTICATE_LENGTH_MSB, pccs->var.tx_request.tx_data_length);
2303 writeb(TX_AUTHENTICATE_LENGTH_LSB,pccs->var.tx_request.tx_data_length + 1);
2304 writeb(0, &pccs->var.tx_request.pow_sav_mode);
2306 ptx = (struct tx_msg *)(local->sram + addr);
2307 /* fill in the mac header */
2308 writeb(PROTOCOL_VER | AUTHENTIC_TYPE, &ptx->mac.frame_ctl_1);
2309 writeb(0, &ptx->mac.frame_ctl_2);
2311 memcpy_toio(ptx->mac.addr_1, dest, ADDRLEN);
2312 memcpy_toio(ptx->mac.addr_2, local->sparm.b4.a_mac_addr, ADDRLEN);
2313 memcpy_toio(ptx->mac.addr_3, local->bss_id, ADDRLEN);
2315 /* Fill in msg body with protocol 00 00, sequence 01 00 ,status 00 00 */
2316 memset_io(ptx->var, 0, 6);
2317 writeb(auth_type & 0xff, ptx->var + 2);
2319 /* Interrupt the firmware to process the command */
2320 if (interrupt_ecf(local, ccsindex)) {
2321 DEBUG(1,"ray_cs send authentication request failed - ECF not ready for intr\n");
2322 writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
2323 return -1;
2325 return 0;
2326 } /* End build_auth_frame */
2327 /*===========================================================================*/