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