]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/net/wireless/ray_cs.c
[PATCH] WE-19 for kernel 2.6.13
[net-next-2.6.git] / drivers / net / wireless / ray_cs.c
CommitLineData
1da177e4
LT
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
1da177e4
LT
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 */
66typedef struct iw_statistics iw_stats;
67typedef struct iw_quality iw_qual;
68typedef 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
84static int ray_debug;
85static int pc_debug = PCMCIA_DEBUG;
86module_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 *******************************/
93static void ray_config(dev_link_t *link);
94static void ray_release(dev_link_t *link);
95static int ray_event(event_t event, int priority, event_callback_args_t *args);
96static dev_link_t *ray_attach(void);
97static void ray_detach(dev_link_t *);
98
99/***** Prototypes indicated by device structure ******************************/
100static int ray_dev_close(struct net_device *dev);
101static int ray_dev_config(struct net_device *dev, struct ifmap *map);
102static struct net_device_stats *ray_get_stats(struct net_device *dev);
103static int ray_dev_init(struct net_device *dev);
104static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
105
106static struct ethtool_ops netdev_ethtool_ops;
107
108static int ray_open(struct net_device *dev);
109static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev);
110static void set_multicast_list(struct net_device *dev);
111static void ray_update_multi_list(struct net_device *dev, int all);
112static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
113 unsigned char *data, int len);
114static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type,
115 unsigned char *data);
116static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len);
117#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */
118static iw_stats * ray_get_wireless_stats(struct net_device * dev);
119#endif /* WIRELESS_EXT > 7 */
120
121/***** Prototypes for raylink functions **************************************/
122static int asc_to_int(char a);
123static void authenticate(ray_dev_t *local);
124static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type);
125static void authenticate_timeout(u_long);
126static int get_free_ccs(ray_dev_t *local);
127static int get_free_tx_ccs(ray_dev_t *local);
128static void init_startup_params(ray_dev_t *local);
129static int parse_addr(char *in_str, UCHAR *out);
130static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev, UCHAR type);
131static int ray_init(struct net_device *dev);
132static int interrupt_ecf(ray_dev_t *local, int ccs);
133static void ray_reset(struct net_device *dev);
134static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, int len);
135static void verify_dl_startup(u_long);
136
137/* Prototypes for interrpt time functions **********************************/
138static irqreturn_t ray_interrupt (int reg, void *dev_id, struct pt_regs *regs);
139static void clear_interrupt(ray_dev_t *local);
140static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
141 unsigned int pkt_addr, int rx_len);
142static int copy_from_rx_buff(ray_dev_t *local, UCHAR *dest, int pkt_addr, int len);
143static void ray_rx(struct net_device *dev, ray_dev_t *local, struct rcs __iomem *prcs);
144static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs);
145static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
146 unsigned int pkt_addr, int rx_len);
147static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned int pkt_addr,
148 int rx_len);
149static void associate(ray_dev_t *local);
150
151/* Card command functions */
152static int dl_startup_params(struct net_device *dev);
153static void join_net(u_long local);
154static 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 */
161static int net_type = ADHOC;
162
163/* Hop dwell time in Kus (1024 us units defined by 802.11) */
164static int hop_dwell = 128;
165
166/* Beacon period in Kus */
167static int beacon_period = 256;
168
169/* power save mode (0 = off, 1 = save power) */
170static int psm;
171
172/* String for network's Extended Service Set ID. 32 Characters max */
173static char *essid;
174
175/* Default to encapsulation unless translation requested */
176static int translate = 1;
177
178static int country = USA;
179
180static int sniffer;
181
182static 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 */
194static 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*/
201static 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*/
207static 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*/
215static unsigned int ray_mem_speed = 500;
216
217MODULE_AUTHOR("Corey Thomas <corey@world.std.com>");
218MODULE_DESCRIPTION("Raylink/WebGear wireless LAN driver");
219MODULE_LICENSE("GPL");
220
221module_param(net_type, int, 0);
222module_param(hop_dwell, int, 0);
223module_param(beacon_period, int, 0);
224module_param(psm, int, 0);
225module_param(essid, charp, 0);
226module_param(translate, int, 0);
227module_param(country, int, 0);
228module_param(sniffer, int, 0);
229module_param(bc, int, 0);
230module_param(phy_addr, charp, 0);
231module_param(ray_mem_speed, int, 0);
232
233static 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
268static 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/*===========================================================================*/
299static unsigned char eth2_llc[] = {0xaa, 0xaa, 3, 0, 0, 0};
300
301static 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
309static 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=============================================================================*/
319static 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;
1da177e4
LT
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
412fail_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=============================================================================*/
422static 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) \
462do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
463#define MAX_TUPLE_SIZE 128
464static 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
574cs_failed:
575 cs_error(link->handle, last_fn, last_ret);
576
577 ray_release(link);
578} /* ray_config */
579
580static inline struct ccs __iomem *ccs_base(ray_dev_t *dev)
581{
582 return dev->sram + CCS_BASE;
583}
584
585static 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/*===========================================================================*/
598static 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 */
661static 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/*===========================================================================*/
707static 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/*===========================================================================*/
768static 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 */
808static 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 */
834static 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=============================================================================*/
866static 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=============================================================================*/
906static 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/*===========================================================================*/
955int 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/*===========================================================================*/
992static 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/*===========================================================================*/
1006static 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/*===========================================================================*/
1049static 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/*===========================================================================*/
1123static 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/*===========================================================================*/
1154static 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
1160Adhoc 0 0 dest src (terminal) BSSID N/A
1161AP to Terminal 0 1 dest AP(BSSID) source N/A
1162Terminal to AP 1 0 AP(BSSID) src (terminal) dest N/A
1163AP 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
1192static void netdev_get_drvinfo(struct net_device *dev,
1193 struct ethtool_drvinfo *info)
1194{
1195 strcpy(info->driver, "ray_cs");
1196}
1197
1198static struct ethtool_ops netdev_ethtool_ops = {
1199 .get_drvinfo = netdev_get_drvinfo,
1200};
1201
1202/*====================================================================*/
1203
1204static 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 */
1634static 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/*===========================================================================*/
1664static 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/*===========================================================================*/
1702static 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/*===========================================================================*/
1724static 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 */
1731static 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 */
1757static 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 */
1788static 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/*===========================================================================*/
1816static 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/*===========================================================================*/
1825static 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/*===========================================================================*/
1836static 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/*===========================================================================*/
1864static 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/*===========================================================================*/
1894static 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/*===========================================================================*/
1927static 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/*===========================================================================*/
1975static 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=============================================================================*/
2011static 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/*===========================================================================*/
2199static 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/*===========================================================================*/
2253static 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/*===========================================================================*/
2413static 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 */
2519static 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/*===========================================================================*/
2534static 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/*===========================================================================*/
2552static 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/*===========================================================================*/
2574static 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/*===========================================================================*/
2617static 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/*===========================================================================*/
2655static 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/*===========================================================================*/
2668static 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
2676static 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
2693static char *nettype[] = {"Adhoc", "Infra "};
2694static char *framing[] = {"Encapsulation", "Translation"}
2695;
2696/*===========================================================================*/
2697static 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/*===========================================================================*/
2800static 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
2850static 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
2859static 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
2873static 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
f57ea2a2
DB
2901static struct pcmcia_device_id ray_ids[] = {
2902 PCMCIA_DEVICE_MANF_CARD(0x01a6, 0x0000),
2903 PCMCIA_DEVICE_NULL,
2904};
2905MODULE_DEVICE_TABLE(pcmcia, ray_ids);
2906
1da177e4
LT
2907static struct pcmcia_driver ray_driver = {
2908 .owner = THIS_MODULE,
2909 .drv = {
2910 .name = "ray_cs",
2911 },
2912 .attach = ray_attach,
1e212f36 2913 .event = ray_event,
1da177e4 2914 .detach = ray_detach,
f57ea2a2 2915 .id_table = ray_ids,
1da177e4
LT
2916};
2917
2918static 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
2940static 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
2956module_init(init_ray_cs);
2957module_exit(exit_ray_cs);
2958
2959/*===========================================================================*/