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