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